[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 // This file is part of Moodle - http://moodle.org/ 2 // 3 // Moodle is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 // 8 // Moodle is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 15 16 /** 17 * Javascript helper function for SCORM module. 18 * 19 * @package mod-scorm 20 * @copyright 2009 Petr Skoda (http://skodak.org) 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 */ 23 24 mod_scorm_launch_next_sco = null; 25 mod_scorm_launch_prev_sco = null; 26 mod_scorm_activate_item = null; 27 mod_scorm_parse_toc_tree = null; 28 scorm_layout_widget = null; 29 30 window.scorm_current_node = null; 31 32 function underscore(str) { 33 str = String(str).replace(/.N/g,"."); 34 return str.replace(/\./g,"__"); 35 } 36 37 M.mod_scorm = {}; 38 39 M.mod_scorm.init = function(Y, nav_display, navposition_left, navposition_top, hide_toc, collapsetocwinsize, toc_title, window_name, launch_sco, scoes_nav) { 40 var scorm_disable_toc = false; 41 var scorm_hide_nav = true; 42 var scorm_hide_toc = true; 43 if (hide_toc == 0) { 44 if (nav_display !== 0) { 45 scorm_hide_nav = false; 46 } 47 scorm_hide_toc = false; 48 } else if (hide_toc == 3) { 49 scorm_disable_toc = true; 50 } 51 52 scoes_nav = Y.JSON.parse(scoes_nav); 53 var scorm_buttons = []; 54 var scorm_bloody_labelclick = false; 55 var scorm_nav_panel; 56 57 Y.use('button', 'dd-plugin', 'panel', 'resize', 'gallery-sm-treeview', function(Y) { 58 59 Y.TreeView.prototype.getNodeByAttribute = function(attribute, value) { 60 var node = null, 61 domnode = Y.one('a[' + attribute + '="' + value + '"]'); 62 if (domnode !== null) { 63 node = scorm_tree_node.getNodeById(domnode.ancestor('li').get('id')); 64 } 65 return node; 66 }; 67 68 Y.TreeView.prototype.openAll = function () { 69 this.get('container').all('.yui3-treeview-can-have-children').each(function(target) { 70 this.getNodeById(target.get('id')).open(); 71 }, this); 72 }; 73 74 Y.TreeView.prototype.closeAll = function () { 75 this.get('container').all('.yui3-treeview-can-have-children').each(function(target) { 76 this.getNodeById(target.get('id')).close(); 77 }, this); 78 } 79 80 var scorm_parse_toc_tree = function(srcNode) { 81 var SELECTORS = { 82 child: '> li', 83 label: '> li, > a', 84 textlabel : '> li, > span', 85 subtree: '> ul, > li' 86 }, 87 children = []; 88 89 srcNode.all(SELECTORS.child).each(function(childNode) { 90 var child = {}, 91 labelNode = childNode.one(SELECTORS.label), 92 textNode = childNode.one(SELECTORS.textlabel), 93 subTreeNode = childNode.one(SELECTORS.subtree); 94 95 if (labelNode) { 96 var title = labelNode.getAttribute('title'); 97 var scoid = labelNode.getData('scoid'); 98 child.label = labelNode.get('outerHTML'); 99 // Will be good to change to url instead of title. 100 if (title && title !== '#') { 101 child.title = title; 102 } 103 if (typeof scoid !== 'undefined') { 104 child.scoid = scoid; 105 } 106 } else if (textNode) { 107 // The selector did not find a label node with anchor. 108 child.label = textNode.get('outerHTML'); 109 } 110 111 if (subTreeNode) { 112 child.children = scorm_parse_toc_tree(subTreeNode); 113 } 114 115 children.push(child); 116 }); 117 118 return children; 119 }; 120 121 mod_scorm_parse_toc_tree = scorm_parse_toc_tree; 122 123 var scorm_activate_item = function(node) { 124 if (!node) { 125 return; 126 } 127 // Check if the item is already active, avoid recursive calls. 128 var content = Y.one('#scorm_content'); 129 var old = Y.one('#scorm_object'); 130 if (old) { 131 var scorm_active_url = Y.one('#scorm_object').getAttribute('src'); 132 var node_full_url = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?' + node.title; 133 if (node_full_url === scorm_active_url) { 134 return; 135 } 136 // Start to unload iframe here 137 if(!window_name){ 138 content.removeChild(old); 139 old = null; 140 } 141 } 142 // End of - Avoid recursive calls. 143 144 scorm_current_node = node; 145 if (!scorm_current_node.state.selected) { 146 scorm_current_node.select(); 147 } 148 149 scorm_tree_node.closeAll(); 150 var url_prefix = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?'; 151 var el_old_api = document.getElementById('scormapi123'); 152 if (el_old_api) { 153 el_old_api.parentNode.removeChild(el_old_api); 154 } 155 156 var obj = document.createElement('iframe'); 157 obj.setAttribute('id', 'scorm_object'); 158 obj.setAttribute('type', 'text/html'); 159 obj.setAttribute('allowfullscreen', 'allowfullscreen'); 160 obj.setAttribute('webkitallowfullscreen', 'webkitallowfullscreen'); 161 obj.setAttribute('mozallowfullscreen', 'mozallowfullscreen'); 162 if (!window_name && node.title != null) { 163 obj.setAttribute('src', url_prefix + node.title); 164 } 165 if (window_name) { 166 var mine = window.open('','','width=1,height=1,left=0,top=0,scrollbars=no'); 167 if(! mine) { 168 alert(M.util.get_string('popupsblocked', 'scorm')); 169 } 170 mine.close(); 171 } 172 173 if (old) { 174 if(window_name) { 175 var cwidth = scormplayerdata.cwidth; 176 var cheight = scormplayerdata.cheight; 177 var poptions = scormplayerdata.popupoptions; 178 poptions = poptions + ',resizable=yes'; // Added for IE (MDL-32506). 179 scorm_openpopup(M.cfg.wwwroot + "/mod/scorm/loadSCO.php?" + node.title, window_name, poptions, cwidth, cheight); 180 } 181 } else { 182 content.prepend(obj); 183 } 184 185 if (scorm_hide_nav == false) { 186 if (nav_display === 1 && navposition_left > 0 && navposition_top > 0) { 187 Y.one('#scorm_object').addClass(cssclasses.scorm_nav_under_content); 188 } 189 scorm_fixnav(); 190 } 191 scorm_tree_node.openAll(); 192 }; 193 194 mod_scorm_activate_item = scorm_activate_item; 195 196 /** 197 * Enables/disables navigation buttons as needed. 198 * @return void 199 */ 200 var scorm_fixnav = function() { 201 var skipprevnode = scorm_skipprev(scorm_current_node); 202 var prevnode = scorm_prev(scorm_current_node); 203 var skipnextnode = scorm_skipnext(scorm_current_node); 204 var nextnode = scorm_next(scorm_current_node); 205 var upnode = scorm_up(scorm_current_node); 206 207 scorm_buttons[0].set('disabled', ((skipprevnode === null) || 208 (typeof(skipprevnode.scoid) === 'undefined') || 209 (scoes_nav[skipprevnode.scoid].isvisible === "false") || 210 (skipprevnode.title === null) || 211 (scoes_nav[launch_sco].hideprevious === 1))); 212 213 scorm_buttons[1].set('disabled', ((prevnode === null) || 214 (typeof(prevnode.scoid) === 'undefined') || 215 (scoes_nav[prevnode.scoid].isvisible === "false") || 216 (prevnode.title === null) || 217 (scoes_nav[launch_sco].hideprevious === 1))); 218 219 scorm_buttons[2].set('disabled', (upnode === null) || 220 (typeof(upnode.scoid) === 'undefined') || 221 (scoes_nav[upnode.scoid].isvisible === "false") || 222 (upnode.title === null)); 223 224 scorm_buttons[3].set('disabled', ((nextnode === null) || 225 ((nextnode.title === null) && (scoes_nav[launch_sco].flow !== 1)) || 226 (typeof(nextnode.scoid) === 'undefined') || 227 (scoes_nav[nextnode.scoid].isvisible === "false") || 228 (scoes_nav[launch_sco].hidecontinue === 1))); 229 230 scorm_buttons[4].set('disabled', ((skipnextnode === null) || 231 (skipnextnode.title === null) || 232 (typeof(skipnextnode.scoid) === 'undefined') || 233 (scoes_nav[skipnextnode.scoid].isvisible === "false") || 234 scoes_nav[launch_sco].hidecontinue === 1)); 235 }; 236 237 var scorm_toggle_toc = function(windowresize) { 238 var toc = Y.one('#scorm_toc'); 239 var scorm_content = Y.one('#scorm_content'); 240 var scorm_toc_toggle_btn = Y.one('#scorm_toc_toggle_btn'); 241 var toc_disabled = toc.hasClass('disabled'); 242 var disabled_by = toc.getAttribute('disabled-by'); 243 // Remove width element style from resize handle. 244 toc.setStyle('width', null); 245 scorm_content.setStyle('width', null); 246 if (windowresize === true) { 247 if (disabled_by === 'user') { 248 return; 249 } 250 var body = Y.one('body'); 251 if (body.get('winWidth') < collapsetocwinsize) { 252 toc.addClass(cssclasses.disabled) 253 .setAttribute('disabled-by', 'screen-size'); 254 scorm_toc_toggle_btn.setHTML('>') 255 .set('title', M.util.get_string('show', 'moodle')); 256 scorm_content.removeClass(cssclasses.scorm_grid_content_toc_visible) 257 .addClass(cssclasses.scorm_grid_content_toc_hidden); 258 } else if (body.get('winWidth') > collapsetocwinsize) { 259 toc.removeClass(cssclasses.disabled) 260 .removeAttribute('disabled-by'); 261 scorm_toc_toggle_btn.setHTML('<') 262 .set('title', M.util.get_string('hide', 'moodle')); 263 scorm_content.removeClass(cssclasses.scorm_grid_content_toc_hidden) 264 .addClass(cssclasses.scorm_grid_content_toc_visible); 265 } 266 return; 267 } 268 if (toc_disabled) { 269 toc.removeClass(cssclasses.disabled) 270 .removeAttribute('disabled-by'); 271 scorm_toc_toggle_btn.setHTML('<') 272 .set('title', M.util.get_string('hide', 'moodle')); 273 scorm_content.removeClass(cssclasses.scorm_grid_content_toc_hidden) 274 .addClass(cssclasses.scorm_grid_content_toc_visible); 275 } else { 276 toc.addClass(cssclasses.disabled) 277 .setAttribute('disabled-by', 'user'); 278 scorm_toc_toggle_btn.setHTML('>') 279 .set('title', M.util.get_string('show', 'moodle')); 280 scorm_content.removeClass(cssclasses.scorm_grid_content_toc_visible) 281 .addClass(cssclasses.scorm_grid_content_toc_hidden); 282 } 283 }; 284 285 var scorm_resize_layout = function() { 286 if (window_name) { 287 return; 288 } 289 290 // make sure that the max width of the TOC doesn't go to far 291 292 var scorm_toc_node = Y.one('#scorm_toc'); 293 var maxwidth = parseInt(Y.one('#scorm_layout').getComputedStyle('width'), 10); 294 scorm_toc_node.setStyle('maxWidth', (maxwidth - 200)); 295 var cwidth = parseInt(scorm_toc_node.getComputedStyle('width'), 10); 296 if (cwidth > (maxwidth - 1)) { 297 scorm_toc_node.setStyle('width', (maxwidth - 50)); 298 } 299 300 // Calculate the rough new height from the viewport height. 301 newheight = Y.one('body').get('winHeight') - 5; 302 if (newheight < 600) { 303 newheight = 600; 304 } 305 Y.one('#scorm_layout').setStyle('height', newheight); 306 307 }; 308 309 // Handle AJAX Request 310 var scorm_ajax_request = function(url, datastring) { 311 var myRequest = NewHttpReq(); 312 var result = DoRequest(myRequest, url + datastring); 313 return result; 314 }; 315 316 var scorm_up = function(node, update_launch_sco) { 317 if (node.parent && node.parent.parent && typeof scoes_nav[launch_sco].parentscoid !== 'undefined') { 318 var parentscoid = scoes_nav[launch_sco].parentscoid; 319 var parent = node.parent; 320 if (parent.title !== scoes_nav[parentscoid].url) { 321 parent = scorm_tree_node.getNodeByAttribute('title', scoes_nav[parentscoid].url); 322 if (parent === null) { 323 parent = scorm_tree_node.rootNode.children[0]; 324 parent.title = scoes_nav[parentscoid].url; 325 } 326 } 327 if (update_launch_sco) { 328 launch_sco = parentscoid; 329 } 330 return parent; 331 } 332 return null; 333 }; 334 335 var scorm_lastchild = function(node) { 336 if (node.children.length) { 337 return scorm_lastchild(node.children[node.children.length - 1]); 338 } else { 339 return node; 340 } 341 }; 342 343 var scorm_prev = function(node, update_launch_sco) { 344 if (node.previous() && node.previous().children.length && 345 typeof scoes_nav[launch_sco].prevscoid !== 'undefined') { 346 node = scorm_lastchild(node.previous()); 347 if (node) { 348 var prevscoid = scoes_nav[launch_sco].prevscoid; 349 if (node.title !== scoes_nav[prevscoid].url) { 350 node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[prevscoid].url); 351 if (node === null) { 352 node = scorm_tree_node.rootNode.children[0]; 353 node.title = scoes_nav[prevscoid].url; 354 } 355 } 356 if (update_launch_sco) { 357 launch_sco = prevscoid; 358 } 359 return node; 360 } else { 361 return null; 362 } 363 } 364 return scorm_skipprev(node, update_launch_sco); 365 }; 366 367 var scorm_skipprev = function(node, update_launch_sco) { 368 if (node.previous() && typeof scoes_nav[launch_sco].prevsibling !== 'undefined') { 369 var prevsibling = scoes_nav[launch_sco].prevsibling; 370 var previous = node.previous(); 371 var prevscoid = scoes_nav[launch_sco].prevscoid; 372 if (previous.title !== scoes_nav[prevscoid].url) { 373 previous = scorm_tree_node.getNodeByAttribute('title', scoes_nav[prevsibling].url); 374 if (previous === null) { 375 previous = scorm_tree_node.rootNode.children[0]; 376 previous.title = scoes_nav[prevsibling].url; 377 } 378 } 379 if (update_launch_sco) { 380 launch_sco = prevsibling; 381 } 382 return previous; 383 } else if (node.parent && node.parent.parent && typeof scoes_nav[launch_sco].parentscoid !== 'undefined') { 384 var parentscoid = scoes_nav[launch_sco].parentscoid; 385 var parent = node.parent; 386 if (parent.title !== scoes_nav[parentscoid].url) { 387 parent = scorm_tree_node.getNodeByAttribute('title', scoes_nav[parentscoid].url); 388 if (parent === null) { 389 parent = scorm_tree_node.rootNode.children[0]; 390 parent.title = scoes_nav[parentscoid].url; 391 } 392 } 393 if (update_launch_sco) { 394 launch_sco = parentscoid; 395 } 396 return parent; 397 } 398 return null; 399 }; 400 401 var scorm_next = function(node, update_launch_sco) { 402 if (node === false) { 403 return scorm_tree_node.children[0]; 404 } 405 if (node.children.length && typeof scoes_nav[launch_sco].nextscoid != 'undefined') { 406 node = node.children[0]; 407 var nextscoid = scoes_nav[launch_sco].nextscoid; 408 if (node.title !== scoes_nav[nextscoid].url) { 409 node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[nextscoid].url); 410 if (node === null) { 411 node = scorm_tree_node.rootNode.children[0]; 412 node.title = scoes_nav[nextscoid].url; 413 } 414 } 415 if (update_launch_sco) { 416 launch_sco = nextscoid; 417 } 418 return node; 419 } 420 return scorm_skipnext(node, update_launch_sco); 421 }; 422 423 var scorm_skipnext = function(node, update_launch_sco) { 424 var next = node.next(); 425 if (next && next.title && typeof scoes_nav[launch_sco] !== 'undefined' && typeof scoes_nav[launch_sco].nextsibling !== 'undefined') { 426 var nextsibling = scoes_nav[launch_sco].nextsibling; 427 if (next.title !== scoes_nav[nextsibling].url) { 428 next = scorm_tree_node.getNodeByAttribute('title', scoes_nav[nextsibling].url); 429 if (next === null) { 430 next = scorm_tree_node.rootNode.children[0]; 431 next.title = scoes_nav[nextsibling].url; 432 } 433 } 434 if (update_launch_sco) { 435 launch_sco = nextsibling; 436 } 437 return next; 438 } else if (node.parent && node.parent.parent && typeof scoes_nav[launch_sco].parentscoid !== 'undefined') { 439 var parentscoid = scoes_nav[launch_sco].parentscoid; 440 var parent = node.parent; 441 if (parent.title !== scoes_nav[parentscoid].url) { 442 parent = scorm_tree_node.getNodeByAttribute('title', scoes_nav[parentscoid].url); 443 if (parent === null) { 444 parent = scorm_tree_node.rootNode.children[0]; 445 } 446 } 447 if (update_launch_sco) { 448 launch_sco = parentscoid; 449 } 450 return scorm_skipnext(parent, update_launch_sco); 451 } 452 return null; 453 }; 454 455 // Launch prev sco 456 var scorm_launch_prev_sco = function() { 457 var result = null; 458 if (scoes_nav[launch_sco].flow === 1) { 459 var datastring = scoes_nav[launch_sco].url + '&function=scorm_seq_flow&request=backward'; 460 result = scorm_ajax_request(M.cfg.wwwroot + '/mod/scorm/datamodels/sequencinghandler.php?', datastring); 461 mod_scorm_seq = encodeURIComponent(result); 462 result = Y.JSON.parse (result); 463 if (typeof result.nextactivity.id != undefined) { 464 var node = scorm_prev(scorm_tree_node.getSelectedNodes()[0]); 465 if (node == null) { 466 // Avoid use of TreeView for Navigation. 467 node = scorm_tree_node.getSelectedNodes()[0]; 468 } 469 if (node.title !== scoes_nav[result.nextactivity.id].url) { 470 node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[result.nextactivity.id].url); 471 if (node === null) { 472 node = scorm_tree_node.rootNode.children[0]; 473 node.title = scoes_nav[result.nextactivity.id].url; 474 } 475 } 476 launch_sco = result.nextactivity.id; 477 scorm_activate_item(node); 478 scorm_fixnav(); 479 } else { 480 scorm_activate_item(scorm_prev(scorm_tree_node.getSelectedNodes()[0], true)); 481 } 482 } else { 483 scorm_activate_item(scorm_prev(scorm_tree_node.getSelectedNodes()[0], true)); 484 } 485 }; 486 487 // Launch next sco 488 var scorm_launch_next_sco = function () { 489 var result = null; 490 if (scoes_nav[launch_sco].flow === 1) { 491 var datastring = scoes_nav[launch_sco].url + '&function=scorm_seq_flow&request=forward'; 492 result = scorm_ajax_request(M.cfg.wwwroot + '/mod/scorm/datamodels/sequencinghandler.php?', datastring); 493 mod_scorm_seq = encodeURIComponent(result); 494 result = Y.JSON.parse (result); 495 if (typeof result.nextactivity !== 'undefined' && typeof result.nextactivity.id !== 'undefined') { 496 var node = scorm_next(scorm_tree_node.getSelectedNodes()[0]); 497 if (node === null) { 498 // Avoid use of TreeView for Navigation. 499 node = scorm_tree_node.getSelectedNodes()[0]; 500 } 501 node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[result.nextactivity.id].url); 502 if (node === null) { 503 node = scorm_tree_node.rootNode.children[0]; 504 node.title = scoes_nav[result.nextactivity.id].url; 505 } 506 launch_sco = result.nextactivity.id; 507 scorm_activate_item(node); 508 scorm_fixnav(); 509 } else { 510 scorm_activate_item(scorm_next(scorm_tree_node.getSelectedNodes()[0], true)); 511 } 512 } else { 513 scorm_activate_item(scorm_next(scorm_tree_node.getSelectedNodes()[0], true)); 514 } 515 }; 516 517 mod_scorm_launch_prev_sco = scorm_launch_prev_sco; 518 mod_scorm_launch_next_sco = scorm_launch_next_sco; 519 520 var cssclasses = { 521 // YUI grid class: use 100% of the available width to show only content, TOC hidden. 522 scorm_grid_content_toc_hidden: 'yui3-u-1', 523 // YUI grid class: use 1/5 of the available width to show TOC. 524 scorm_grid_toc: 'yui3-u-1-5', 525 // YUI grid class: use 1/24 of the available width to show TOC toggle button. 526 scorm_grid_toggle: 'yui3-u-1-24', 527 // YUI grid class: use 3/4 of the available width to show content, TOC visible. 528 scorm_grid_content_toc_visible: 'yui3-u-3-4', 529 // Reduce height of #scorm_object to accomodate nav buttons under content. 530 scorm_nav_under_content: 'scorm_nav_under_content', 531 disabled: 'disabled' 532 }; 533 // layout 534 Y.one('#scorm_toc_title').setHTML(toc_title); 535 536 if (scorm_disable_toc) { 537 Y.one('#scorm_toc').addClass(cssclasses.disabled); 538 Y.one('#scorm_toc_toggle').addClass(cssclasses.disabled); 539 Y.one('#scorm_content').addClass(cssclasses.scorm_grid_content_toc_hidden); 540 } else { 541 Y.one('#scorm_toc').addClass(cssclasses.scorm_grid_toc); 542 Y.one('#scorm_toc_toggle').addClass(cssclasses.scorm_grid_toggle); 543 Y.one('#scorm_toc_toggle_btn') 544 .setHTML('<') 545 .setAttribute('title', M.util.get_string('hide', 'moodle')); 546 Y.one('#scorm_content').addClass(cssclasses.scorm_grid_content_toc_visible); 547 scorm_toggle_toc(true); 548 } 549 550 // hide the TOC if that is the default 551 if (!scorm_disable_toc) { 552 if (scorm_hide_toc == true) { 553 Y.one('#scorm_toc').addClass(cssclasses.disabled); 554 Y.one('#scorm_toc_toggle_btn') 555 .setHTML('>') 556 .setAttribute('title', M.util.get_string('show', 'moodle')); 557 Y.one('#scorm_content') 558 .removeClass(cssclasses.scorm_grid_content_toc_visible) 559 .addClass(cssclasses.scorm_grid_content_toc_hidden); 560 } 561 } 562 563 // TOC Resize handle. 564 var layout_width = parseInt(Y.one('#scorm_layout').getComputedStyle('width'), 10); 565 var scorm_resize_handle = new Y.Resize({ 566 node: '#scorm_toc', 567 handles: 'r', 568 defMinWidth: 0.2 * layout_width 569 }); 570 // TOC tree 571 var toc_source = Y.one('#scorm_tree > ul'); 572 var toc = scorm_parse_toc_tree(toc_source); 573 // Empty container after parsing toc. 574 var el = document.getElementById('scorm_tree'); 575 el.innerHTML = ''; 576 var tree = new Y.TreeView({ 577 container: '#scorm_tree', 578 nodes: toc, 579 multiSelect: false 580 }); 581 scorm_tree_node = tree; 582 // Trigger after instead of on, avoid recursive calls. 583 tree.after('select', function(e) { 584 var node = e.node; 585 if (node.title == '' || node.title == null) { 586 return; //this item has no navigation 587 } 588 589 // If item is already active, return; avoid recursive calls. 590 if (obj = Y.one('#scorm_object')) { 591 var scorm_active_url = obj.getAttribute('src'); 592 var node_full_url = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?' + node.title; 593 if (node_full_url === scorm_active_url) { 594 return; 595 } 596 } else if(scorm_current_node == node){ 597 return; 598 } 599 600 // Update launch_sco. 601 if (typeof node.scoid !== 'undefined') { 602 launch_sco = node.scoid; 603 } 604 scorm_activate_item(node); 605 if (node.children.length) { 606 scorm_bloody_labelclick = true; 607 } 608 }); 609 if (!scorm_disable_toc) { 610 tree.on('close', function(e) { 611 if (scorm_bloody_labelclick) { 612 scorm_bloody_labelclick = false; 613 return false; 614 } 615 }); 616 tree.subscribe('open', function(e) { 617 if (scorm_bloody_labelclick) { 618 scorm_bloody_labelclick = false; 619 return false; 620 } 621 }); 622 } 623 tree.render(); 624 tree.openAll(); 625 626 // On getting the window, always set the focus on the current item 627 Y.one(Y.config.win).on('focus', function (e) { 628 var current = scorm_tree_node.getSelectedNodes()[0]; 629 var toc_disabled = Y.one('#scorm_toc').hasClass('disabled'); 630 if (current.id && !toc_disabled) { 631 Y.one('#' + current.id).focus(); 632 } 633 }); 634 635 // navigation 636 if (scorm_hide_nav == false) { 637 // TODO: make some better&accessible buttons. 638 var navbuttonshtml = '<span id="scorm_nav"><button id="nav_skipprev"><<</button> ' + 639 '<button id="nav_prev"><</button> <button id="nav_up">^</button> ' + 640 '<button id="nav_next">></button> <button id="nav_skipnext">>></button></span>'; 641 if (nav_display === 1) { 642 Y.one('#scorm_navpanel').setHTML(navbuttonshtml); 643 } else { 644 // Nav panel is floating type. 645 var navposition = null; 646 if (navposition_left < 0 && navposition_top < 0) { 647 // Set default XY. 648 navposition = Y.one('#scorm_toc').getXY(); 649 navposition[1] += 200; 650 } else { 651 // Set user defined XY. 652 navposition = []; 653 navposition[0] = parseInt(navposition_left, 10); 654 navposition[1] = parseInt(navposition_top, 10); 655 } 656 scorm_nav_panel = new Y.Panel({ 657 fillHeight: "body", 658 headerContent: M.util.get_string('navigation', 'scorm'), 659 visible: true, 660 xy: navposition, 661 zIndex: 999 662 }); 663 scorm_nav_panel.set('bodyContent', navbuttonshtml); 664 scorm_nav_panel.removeButton('close'); 665 scorm_nav_panel.plug(Y.Plugin.Drag, {handles: ['.yui3-widget-hd']}); 666 scorm_nav_panel.render(); 667 } 668 669 scorm_buttons[0] = new Y.Button({ 670 srcNode: '#nav_skipprev', 671 render: true, 672 on: { 673 'click' : function(ev) { 674 scorm_activate_item(scorm_skipprev(scorm_tree_node.getSelectedNodes()[0], true)); 675 }, 676 'keydown' : function(ev) { 677 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 678 scorm_activate_item(scorm_skipprev(scorm_tree_node.getSelectedNodes()[0], true)); 679 } 680 } 681 } 682 }); 683 scorm_buttons[1] = new Y.Button({ 684 srcNode: '#nav_prev', 685 render: true, 686 on: { 687 'click' : function(ev) { 688 scorm_launch_prev_sco(); 689 }, 690 'keydown' : function(ev) { 691 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 692 scorm_launch_prev_sco(); 693 } 694 } 695 } 696 }); 697 scorm_buttons[2] = new Y.Button({ 698 srcNode: '#nav_up', 699 render: true, 700 on: { 701 'click' : function(ev) { 702 scorm_activate_item(scorm_up(scorm_tree_node.getSelectedNodes()[0], true)); 703 }, 704 'keydown' : function(ev) { 705 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 706 scorm_activate_item(scorm_up(scorm_tree_node.getSelectedNodes()[0], true)); 707 } 708 } 709 } 710 }); 711 scorm_buttons[3] = new Y.Button({ 712 srcNode: '#nav_next', 713 render: true, 714 on: { 715 'click' : function(ev) { 716 scorm_launch_next_sco(); 717 }, 718 'keydown' : function(ev) { 719 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 720 scorm_launch_next_sco(); 721 } 722 } 723 } 724 }); 725 scorm_buttons[4] = new Y.Button({ 726 srcNode: '#nav_skipnext', 727 render: true, 728 on: { 729 'click' : function(ev) { 730 scorm_activate_item(scorm_skipnext(scorm_tree_node.getSelectedNodes()[0], true)); 731 }, 732 'keydown' : function(ev) { 733 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 734 scorm_activate_item(scorm_skipnext(scorm_tree_node.getSelectedNodes()[0], true)); 735 } 736 } 737 } 738 }); 739 } 740 741 // finally activate the chosen item 742 var scorm_first_url = null; 743 if (typeof tree.rootNode.children[0] !== 'undefined') { 744 if (tree.rootNode.children[0].title !== scoes_nav[launch_sco].url) { 745 var node = tree.getNodeByAttribute('title', scoes_nav[launch_sco].url); 746 if (node !== null) { 747 scorm_first_url = node; 748 } 749 } else { 750 scorm_first_url = tree.rootNode.children[0]; 751 } 752 } 753 754 if (scorm_first_url == null) { // This is probably a single sco with no children (AICC Direct uses this). 755 scorm_first_url = tree.rootNode; 756 } 757 scorm_first_url.title = scoes_nav[launch_sco].url; 758 scorm_activate_item(scorm_first_url); 759 760 // resizing 761 scorm_resize_layout(); 762 763 // Collapse/expand TOC. 764 Y.one('#scorm_toc_toggle').on('click', scorm_toggle_toc); 765 Y.one('#scorm_toc_toggle').on('key', scorm_toggle_toc, 'down:enter,32'); 766 // fix layout if window resized 767 Y.on("windowresize", function() { 768 scorm_resize_layout(); 769 var toc_displayed = Y.one('#scorm_toc').getComputedStyle('display') !== 'none'; 770 if ((!scorm_disable_toc && !scorm_hide_toc) || toc_displayed) { 771 scorm_toggle_toc(true); 772 } 773 // Set 20% as minWidth constrain of TOC. 774 var layout_width = parseInt(Y.one('#scorm_layout').getComputedStyle('width'), 10); 775 scorm_resize_handle.set('defMinWidth', 0.2 * layout_width); 776 }); 777 // On resize drag, change width of scorm_content. 778 scorm_resize_handle.on('resize:resize', function() { 779 var tocwidth = parseInt(Y.one('#scorm_toc').getComputedStyle('width'), 10); 780 var layoutwidth = parseInt(Y.one('#scorm_layout').getStyle('width'), 10); 781 Y.one('#scorm_content').setStyle('width', (layoutwidth - tocwidth - 60)); 782 }); 783 }); 784 }; 785 786 M.mod_scorm.connectPrereqCallback = { 787 788 success: function(id, o) { 789 if (o.responseText !== undefined) { 790 var snode = null, 791 stitle = null; 792 if (scorm_tree_node && o.responseText) { 793 snode = scorm_tree_node.getSelectedNodes()[0]; 794 stitle = null; 795 if (snode) { 796 stitle = snode.title; 797 } 798 // All gone with clear, add new root node. 799 scorm_tree_node.clear(scorm_tree_node.createNode()); 800 } 801 // Make sure the temporary tree element is not there. 802 var el_old_tree = document.getElementById('scormtree123'); 803 if (el_old_tree) { 804 el_old_tree.parentNode.removeChild(el_old_tree); 805 } 806 var el_new_tree = document.createElement('div'); 807 var pagecontent = document.getElementById("page-content"); 808 if (!pagecontent) { 809 pagecontent = document.getElementById("content"); 810 } 811 el_new_tree.setAttribute('id','scormtree123'); 812 el_new_tree.innerHTML = o.responseText; 813 // Make sure it does not show. 814 el_new_tree.style.display = 'none'; 815 pagecontent.appendChild(el_new_tree); 816 // Ignore the first level element as this is the title. 817 var startNode = el_new_tree.firstChild.firstChild; 818 if (startNode.tagName == 'LI') { 819 // Go back to the beginning. 820 startNode = el_new_tree; 821 } 822 var toc_source = Y.one('#scormtree123 > ul'); 823 var toc = mod_scorm_parse_toc_tree(toc_source); 824 scorm_tree_node.appendNode(scorm_tree_node.rootNode, toc); 825 var el = document.getElementById('scormtree123'); 826 el.parentNode.removeChild(el); 827 scorm_tree_node.render(); 828 scorm_tree_node.openAll(); 829 if (stitle !== null) { 830 snode = scorm_tree_node.getNodeByAttribute('title', stitle); 831 // Do not let destroyed node to be selected. 832 if (snode && !snode.state.destroyed) { 833 snode.select(); 834 var toc_disabled = Y.one('#scorm_toc').hasClass('disabled'); 835 if (!toc_disabled) { 836 if (!snode.state.selected) { 837 snode.select(); 838 } 839 } 840 } 841 } 842 } 843 }, 844 845 failure: function(id, o) { 846 // TODO: do some sort of error handling. 847 } 848 849 };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |