[ Index ] |
PHP Cross Reference of moodle-2.8 |
[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 if (!window_name && node.title != null) { 160 obj.setAttribute('src', url_prefix + node.title); 161 } 162 if (window_name) { 163 var mine = window.open('','','width=1,height=1,left=0,top=0,scrollbars=no'); 164 if(! mine) { 165 alert(M.str.scorm.popupsblocked); 166 } 167 mine.close(); 168 } 169 170 if (old) { 171 if(window_name) { 172 var cwidth = scormplayerdata.cwidth; 173 var cheight = scormplayerdata.cheight; 174 var poptions = scormplayerdata.popupoptions; 175 poptions = poptions + ',resizable=yes'; // Added for IE (MDL-32506). 176 scorm_openpopup(M.cfg.wwwroot + "/mod/scorm/loadSCO.php?" + node.title, window_name, poptions, cwidth, cheight); 177 } 178 } else { 179 content.prepend(obj); 180 } 181 182 if (scorm_hide_nav == false) { 183 if (nav_display === 1 && navposition_left > 0 && navposition_top > 0) { 184 Y.one('#scorm_object').addClass(cssclasses.scorm_nav_under_content); 185 } 186 scorm_fixnav(); 187 } 188 scorm_tree_node.openAll(); 189 }; 190 191 mod_scorm_activate_item = scorm_activate_item; 192 193 /** 194 * Enables/disables navigation buttons as needed. 195 * @return void 196 */ 197 var scorm_fixnav = function() { 198 var skipprevnode = scorm_skipprev(scorm_current_node); 199 var prevnode = scorm_prev(scorm_current_node); 200 var skipnextnode = scorm_skipnext(scorm_current_node); 201 var nextnode = scorm_next(scorm_current_node); 202 var upnode = scorm_up(scorm_current_node); 203 204 scorm_buttons[0].set('disabled', ((skipprevnode === null) || 205 (typeof(skipprevnode.scoid) === 'undefined') || 206 (scoes_nav[skipprevnode.scoid].isvisible === "false") || 207 (skipprevnode.title === null) || 208 (scoes_nav[launch_sco].hideprevious === 1))); 209 210 scorm_buttons[1].set('disabled', ((prevnode === null) || 211 (typeof(prevnode.scoid) === 'undefined') || 212 (scoes_nav[prevnode.scoid].isvisible === "false") || 213 (prevnode.title === null) || 214 (scoes_nav[launch_sco].hideprevious === 1))); 215 216 scorm_buttons[2].set('disabled', (upnode === null) || 217 (typeof(upnode.scoid) === 'undefined') || 218 (scoes_nav[upnode.scoid].isvisible === "false") || 219 (upnode.title === null)); 220 221 scorm_buttons[3].set('disabled', ((nextnode === null) || 222 ((nextnode.title === null) && (scoes_nav[launch_sco].flow !== 1)) || 223 (typeof(nextnode.scoid) === 'undefined') || 224 (scoes_nav[nextnode.scoid].isvisible === "false") || 225 (scoes_nav[launch_sco].hidecontinue === 1))); 226 227 scorm_buttons[4].set('disabled', ((skipnextnode === null) || 228 (skipnextnode.title === null) || 229 (typeof(skipnextnode.scoid) === 'undefined') || 230 (scoes_nav[skipnextnode.scoid].isvisible === "false") || 231 scoes_nav[launch_sco].hidecontinue === 1)); 232 }; 233 234 var scorm_toggle_toc = function(windowresize) { 235 var toc = Y.one('#scorm_toc'); 236 var scorm_content = Y.one('#scorm_content'); 237 var scorm_toc_toggle_btn = Y.one('#scorm_toc_toggle_btn'); 238 var toc_disabled = toc.hasClass('disabled'); 239 var disabled_by = toc.getAttribute('disabled-by'); 240 // Remove width element style from resize handle. 241 toc.setStyle('width', null); 242 scorm_content.setStyle('width', null); 243 if (windowresize === true) { 244 if (disabled_by === 'user') { 245 return; 246 } 247 var body = Y.one('body'); 248 if (body.get('winWidth') < collapsetocwinsize) { 249 toc.addClass(cssclasses.disabled) 250 .setAttribute('disabled-by', 'screen-size'); 251 scorm_toc_toggle_btn.setHTML('>') 252 .set('title', M.util.get_string('show', 'moodle')); 253 scorm_content.removeClass(cssclasses.scorm_grid_content_toc_visible) 254 .addClass(cssclasses.scorm_grid_content_toc_hidden); 255 } else if (body.get('winWidth') > collapsetocwinsize) { 256 toc.removeClass(cssclasses.disabled) 257 .removeAttribute('disabled-by'); 258 scorm_toc_toggle_btn.setHTML('<') 259 .set('title', M.util.get_string('hide', 'moodle')); 260 scorm_content.removeClass(cssclasses.scorm_grid_content_toc_hidden) 261 .addClass(cssclasses.scorm_grid_content_toc_visible); 262 } 263 return; 264 } 265 if (toc_disabled) { 266 toc.removeClass(cssclasses.disabled) 267 .removeAttribute('disabled-by'); 268 scorm_toc_toggle_btn.setHTML('<') 269 .set('title', M.util.get_string('hide', 'moodle')); 270 scorm_content.removeClass(cssclasses.scorm_grid_content_toc_hidden) 271 .addClass(cssclasses.scorm_grid_content_toc_visible); 272 } else { 273 toc.addClass(cssclasses.disabled) 274 .setAttribute('disabled-by', 'user'); 275 scorm_toc_toggle_btn.setHTML('>') 276 .set('title', M.util.get_string('show', 'moodle')); 277 scorm_content.removeClass(cssclasses.scorm_grid_content_toc_visible) 278 .addClass(cssclasses.scorm_grid_content_toc_hidden); 279 } 280 }; 281 282 var scorm_resize_layout = function() { 283 if (window_name) { 284 return; 285 } 286 287 // make sure that the max width of the TOC doesn't go to far 288 289 var scorm_toc_node = Y.one('#scorm_toc'); 290 var maxwidth = parseInt(Y.one('#scorm_layout').getComputedStyle('width'), 10); 291 scorm_toc_node.setStyle('maxWidth', (maxwidth - 200)); 292 var cwidth = parseInt(scorm_toc_node.getComputedStyle('width'), 10); 293 if (cwidth > (maxwidth - 1)) { 294 scorm_toc_node.setStyle('width', (maxwidth - 50)); 295 } 296 297 // Calculate the rough new height from the viewport height. 298 newheight = Y.one('body').get('winHeight') - 5; 299 if (newheight < 600) { 300 newheight = 600; 301 } 302 Y.one('#scorm_layout').setStyle('height', newheight); 303 304 }; 305 306 // Handle AJAX Request 307 var scorm_ajax_request = function(url, datastring) { 308 var myRequest = NewHttpReq(); 309 var result = DoRequest(myRequest, url + datastring); 310 return result; 311 }; 312 313 var scorm_up = function(node, update_launch_sco) { 314 if (node.parent && node.parent.parent && typeof scoes_nav[launch_sco].parentscoid !== 'undefined') { 315 var parentscoid = scoes_nav[launch_sco].parentscoid; 316 var parent = node.parent; 317 if (parent.title !== scoes_nav[parentscoid].url) { 318 parent = scorm_tree_node.getNodeByAttribute('title', scoes_nav[parentscoid].url); 319 if (parent === null) { 320 parent = scorm_tree_node.rootNode.children[0]; 321 parent.title = scoes_nav[parentscoid].url; 322 } 323 } 324 if (update_launch_sco) { 325 launch_sco = parentscoid; 326 } 327 return parent; 328 } 329 return null; 330 }; 331 332 var scorm_lastchild = function(node) { 333 if (node.children.length) { 334 return scorm_lastchild(node.children[node.children.length - 1]); 335 } else { 336 return node; 337 } 338 }; 339 340 var scorm_prev = function(node, update_launch_sco) { 341 if (node.previous() && node.previous().children.length && 342 typeof scoes_nav[launch_sco].prevscoid !== 'undefined') { 343 node = scorm_lastchild(node.previous()); 344 if (node) { 345 var prevscoid = scoes_nav[launch_sco].prevscoid; 346 if (node.title !== scoes_nav[prevscoid].url) { 347 node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[prevscoid].url); 348 if (node === null) { 349 node = scorm_tree_node.rootNode.children[0]; 350 node.title = scoes_nav[prevscoid].url; 351 } 352 } 353 if (update_launch_sco) { 354 launch_sco = prevscoid; 355 } 356 return node; 357 } else { 358 return null; 359 } 360 } 361 return scorm_skipprev(node, update_launch_sco); 362 }; 363 364 var scorm_skipprev = function(node, update_launch_sco) { 365 if (node.previous() && typeof scoes_nav[launch_sco].prevsibling !== 'undefined') { 366 var prevsibling = scoes_nav[launch_sco].prevsibling; 367 var previous = node.previous(); 368 var prevscoid = scoes_nav[launch_sco].prevscoid; 369 if (previous.title !== scoes_nav[prevscoid].url) { 370 previous = scorm_tree_node.getNodeByAttribute('title', scoes_nav[prevsibling].url); 371 if (previous === null) { 372 previous = scorm_tree_node.rootNode.children[0]; 373 previous.title = scoes_nav[prevsibling].url; 374 } 375 } 376 if (update_launch_sco) { 377 launch_sco = prevsibling; 378 } 379 return previous; 380 } else if (node.parent && node.parent.parent && typeof scoes_nav[launch_sco].parentscoid !== 'undefined') { 381 var parentscoid = scoes_nav[launch_sco].parentscoid; 382 var parent = node.parent; 383 if (parent.title !== scoes_nav[parentscoid].url) { 384 parent = scorm_tree_node.getNodeByAttribute('title', scoes_nav[parentscoid].url); 385 if (parent === null) { 386 parent = scorm_tree_node.rootNode.children[0]; 387 parent.title = scoes_nav[parentscoid].url; 388 } 389 } 390 if (update_launch_sco) { 391 launch_sco = parentscoid; 392 } 393 return parent; 394 } 395 return null; 396 }; 397 398 var scorm_next = function(node, update_launch_sco) { 399 if (node === false) { 400 return scorm_tree_node.children[0]; 401 } 402 if (node.children.length && typeof scoes_nav[launch_sco].nextscoid != 'undefined') { 403 node = node.children[0]; 404 var nextscoid = scoes_nav[launch_sco].nextscoid; 405 if (node.title !== scoes_nav[nextscoid].url) { 406 node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[nextscoid].url); 407 if (node === null) { 408 node = scorm_tree_node.rootNode.children[0]; 409 node.title = scoes_nav[nextscoid].url; 410 } 411 } 412 if (update_launch_sco) { 413 launch_sco = nextscoid; 414 } 415 return node; 416 } 417 return scorm_skipnext(node, update_launch_sco); 418 }; 419 420 var scorm_skipnext = function(node, update_launch_sco) { 421 var next = node.next(); 422 if (next && next.title && typeof scoes_nav[launch_sco] !== 'undefined' && typeof scoes_nav[launch_sco].nextsibling !== 'undefined') { 423 var nextsibling = scoes_nav[launch_sco].nextsibling; 424 if (next.title !== scoes_nav[nextsibling].url) { 425 next = scorm_tree_node.getNodeByAttribute('title', scoes_nav[nextsibling].url); 426 if (next === null) { 427 next = scorm_tree_node.rootNode.children[0]; 428 next.title = scoes_nav[nextsibling].url; 429 } 430 } 431 if (update_launch_sco) { 432 launch_sco = nextsibling; 433 } 434 return next; 435 } else if (node.parent && node.parent.parent && typeof scoes_nav[launch_sco].parentscoid !== 'undefined') { 436 var parentscoid = scoes_nav[launch_sco].parentscoid; 437 var parent = node.parent; 438 if (parent.title !== scoes_nav[parentscoid].url) { 439 parent = scorm_tree_node.getNodeByAttribute('title', scoes_nav[parentscoid].url); 440 if (parent === null) { 441 parent = scorm_tree_node.rootNode.children[0]; 442 } 443 } 444 if (update_launch_sco) { 445 launch_sco = parentscoid; 446 } 447 return scorm_skipnext(parent, update_launch_sco); 448 } 449 return null; 450 }; 451 452 // Launch prev sco 453 var scorm_launch_prev_sco = function() { 454 var result = null; 455 if (scoes_nav[launch_sco].flow === 1) { 456 var datastring = scoes_nav[launch_sco].url + '&function=scorm_seq_flow&request=backward'; 457 result = scorm_ajax_request(M.cfg.wwwroot + '/mod/scorm/datamodels/sequencinghandler.php?', datastring); 458 mod_scorm_seq = encodeURIComponent(result); 459 result = Y.JSON.parse (result); 460 if (typeof result.nextactivity.id != undefined) { 461 var node = scorm_prev(scorm_tree_node.getSelectedNodes()[0]); 462 if (node == null) { 463 // Avoid use of TreeView for Navigation. 464 node = scorm_tree_node.getSelectedNodes()[0]; 465 } 466 if (node.title !== scoes_nav[result.nextactivity.id].url) { 467 node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[result.nextactivity.id].url); 468 if (node === null) { 469 node = scorm_tree_node.rootNode.children[0]; 470 node.title = scoes_nav[result.nextactivity.id].url; 471 } 472 } 473 launch_sco = result.nextactivity.id; 474 scorm_activate_item(node); 475 scorm_fixnav(); 476 } else { 477 scorm_activate_item(scorm_prev(scorm_tree_node.getSelectedNodes()[0], true)); 478 } 479 } else { 480 scorm_activate_item(scorm_prev(scorm_tree_node.getSelectedNodes()[0], true)); 481 } 482 }; 483 484 // Launch next sco 485 var scorm_launch_next_sco = function () { 486 var result = null; 487 if (scoes_nav[launch_sco].flow === 1) { 488 var datastring = scoes_nav[launch_sco].url + '&function=scorm_seq_flow&request=forward'; 489 result = scorm_ajax_request(M.cfg.wwwroot + '/mod/scorm/datamodels/sequencinghandler.php?', datastring); 490 mod_scorm_seq = encodeURIComponent(result); 491 result = Y.JSON.parse (result); 492 if (typeof result.nextactivity !== 'undefined' && typeof result.nextactivity.id !== 'undefined') { 493 var node = scorm_next(scorm_tree_node.getSelectedNodes()[0]); 494 if (node === null) { 495 // Avoid use of TreeView for Navigation. 496 node = scorm_tree_node.getSelectedNodes()[0]; 497 } 498 node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[result.nextactivity.id].url); 499 if (node === null) { 500 node = scorm_tree_node.rootNode.children[0]; 501 node.title = scoes_nav[result.nextactivity.id].url; 502 } 503 launch_sco = result.nextactivity.id; 504 scorm_activate_item(node); 505 scorm_fixnav(); 506 } else { 507 scorm_activate_item(scorm_next(scorm_tree_node.getSelectedNodes()[0], true)); 508 } 509 } else { 510 scorm_activate_item(scorm_next(scorm_tree_node.getSelectedNodes()[0], true)); 511 } 512 }; 513 514 mod_scorm_launch_prev_sco = scorm_launch_prev_sco; 515 mod_scorm_launch_next_sco = scorm_launch_next_sco; 516 517 var cssclasses = { 518 // YUI grid class: use 100% of the available width to show only content, TOC hidden. 519 scorm_grid_content_toc_hidden: 'yui3-u-1', 520 // YUI grid class: use 1/5 of the available width to show TOC. 521 scorm_grid_toc: 'yui3-u-1-5', 522 // YUI grid class: use 1/24 of the available width to show TOC toggle button. 523 scorm_grid_toggle: 'yui3-u-1-24', 524 // YUI grid class: use 3/4 of the available width to show content, TOC visible. 525 scorm_grid_content_toc_visible: 'yui3-u-3-4', 526 // Reduce height of #scorm_object to accomodate nav buttons under content. 527 scorm_nav_under_content: 'scorm_nav_under_content', 528 disabled: 'disabled' 529 }; 530 // layout 531 Y.one('#scorm_toc_title').setHTML(toc_title); 532 533 if (scorm_disable_toc) { 534 Y.one('#scorm_toc').addClass(cssclasses.disabled); 535 Y.one('#scorm_toc_toggle').addClass(cssclasses.disabled); 536 Y.one('#scorm_content').addClass(cssclasses.scorm_grid_content_toc_hidden); 537 } else { 538 Y.one('#scorm_toc').addClass(cssclasses.scorm_grid_toc); 539 Y.one('#scorm_toc_toggle').addClass(cssclasses.scorm_grid_toggle); 540 Y.one('#scorm_toc_toggle_btn') 541 .setHTML('<') 542 .setAttribute('title', M.util.get_string('hide', 'moodle')); 543 Y.one('#scorm_content').addClass(cssclasses.scorm_grid_content_toc_visible); 544 scorm_toggle_toc(true); 545 } 546 547 // hide the TOC if that is the default 548 if (!scorm_disable_toc) { 549 if (scorm_hide_toc == true) { 550 Y.one('#scorm_toc').addClass(cssclasses.disabled); 551 Y.one('#scorm_toc_toggle_btn') 552 .setHTML('>') 553 .setAttribute('title', M.util.get_string('show', 'moodle')); 554 Y.one('#scorm_content') 555 .removeClass(cssclasses.scorm_grid_content_toc_visible) 556 .addClass(cssclasses.scorm_grid_content_toc_hidden); 557 } 558 } 559 560 // TOC Resize handle. 561 var layout_width = parseInt(Y.one('#scorm_layout').getComputedStyle('width'), 10); 562 var scorm_resize_handle = new Y.Resize({ 563 node: '#scorm_toc', 564 handles: 'r', 565 defMinWidth: 0.2 * layout_width 566 }); 567 // TOC tree 568 var toc_source = Y.one('#scorm_tree > ul'); 569 var toc = scorm_parse_toc_tree(toc_source); 570 // Empty container after parsing toc. 571 var el = document.getElementById('scorm_tree'); 572 el.innerHTML = ''; 573 var tree = new Y.TreeView({ 574 container: '#scorm_tree', 575 nodes: toc, 576 multiSelect: false 577 }); 578 scorm_tree_node = tree; 579 // Trigger after instead of on, avoid recursive calls. 580 tree.after('select', function(e) { 581 var node = e.node; 582 if (node.title == '' || node.title == null) { 583 return; //this item has no navigation 584 } 585 586 // If item is already active, return; avoid recursive calls. 587 if (obj = Y.one('#scorm_object')) { 588 var scorm_active_url = obj.getAttribute('src'); 589 var node_full_url = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?' + node.title; 590 if (node_full_url === scorm_active_url) { 591 return; 592 } 593 } else if(scorm_current_node == node){ 594 return; 595 } 596 597 // Update launch_sco. 598 if (typeof node.scoid !== 'undefined') { 599 launch_sco = node.scoid; 600 } 601 scorm_activate_item(node); 602 if (node.children.length) { 603 scorm_bloody_labelclick = true; 604 } 605 }); 606 if (!scorm_disable_toc) { 607 tree.on('close', function(e) { 608 if (scorm_bloody_labelclick) { 609 scorm_bloody_labelclick = false; 610 return false; 611 } 612 }); 613 tree.subscribe('open', function(e) { 614 if (scorm_bloody_labelclick) { 615 scorm_bloody_labelclick = false; 616 return false; 617 } 618 }); 619 } 620 tree.render(); 621 tree.openAll(); 622 623 // On getting the window, always set the focus on the current item 624 Y.one(Y.config.win).on('focus', function (e) { 625 var current = scorm_tree_node.getSelectedNodes()[0]; 626 var toc_disabled = Y.one('#scorm_toc').hasClass('disabled'); 627 if (current.id && !toc_disabled) { 628 Y.one('#' + current.id).focus(); 629 } 630 }); 631 632 // navigation 633 if (scorm_hide_nav == false) { 634 // TODO: make some better&accessible buttons. 635 var navbuttonshtml = '<span id="scorm_nav"><button id="nav_skipprev"><<</button> ' + 636 '<button id="nav_prev"><</button> <button id="nav_up">^</button> ' + 637 '<button id="nav_next">></button> <button id="nav_skipnext">>></button></span>'; 638 if (nav_display === 1) { 639 Y.one('#scorm_navpanel').setHTML(navbuttonshtml); 640 } else { 641 // Nav panel is floating type. 642 var navposition = null; 643 if (navposition_left < 0 && navposition_top < 0) { 644 // Set default XY. 645 navposition = Y.one('#scorm_toc').getXY(); 646 navposition[1] += 200; 647 } else { 648 // Set user defined XY. 649 navposition = []; 650 navposition[0] = parseInt(navposition_left, 10); 651 navposition[1] = parseInt(navposition_top, 10); 652 } 653 scorm_nav_panel = new Y.Panel({ 654 fillHeight: "body", 655 headerContent: M.util.get_string('navigation', 'scorm'), 656 visible: true, 657 xy: navposition, 658 zIndex: 999 659 }); 660 scorm_nav_panel.set('bodyContent', navbuttonshtml); 661 scorm_nav_panel.removeButton('close'); 662 scorm_nav_panel.plug(Y.Plugin.Drag, {handles: ['.yui3-widget-hd']}); 663 scorm_nav_panel.render(); 664 } 665 666 scorm_buttons[0] = new Y.Button({ 667 srcNode: '#nav_skipprev', 668 render: true, 669 on: { 670 'click' : function(ev) { 671 scorm_activate_item(scorm_skipprev(scorm_tree_node.getSelectedNodes()[0], true)); 672 }, 673 'keydown' : function(ev) { 674 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 675 scorm_activate_item(scorm_skipprev(scorm_tree_node.getSelectedNodes()[0], true)); 676 } 677 } 678 } 679 }); 680 scorm_buttons[1] = new Y.Button({ 681 srcNode: '#nav_prev', 682 render: true, 683 on: { 684 'click' : function(ev) { 685 scorm_launch_prev_sco(); 686 }, 687 'keydown' : function(ev) { 688 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 689 scorm_launch_prev_sco(); 690 } 691 } 692 } 693 }); 694 scorm_buttons[2] = new Y.Button({ 695 srcNode: '#nav_up', 696 render: true, 697 on: { 698 'click' : function(ev) { 699 scorm_activate_item(scorm_up(scorm_tree_node.getSelectedNodes()[0], true)); 700 }, 701 'keydown' : function(ev) { 702 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 703 scorm_activate_item(scorm_up(scorm_tree_node.getSelectedNodes()[0], true)); 704 } 705 } 706 } 707 }); 708 scorm_buttons[3] = new Y.Button({ 709 srcNode: '#nav_next', 710 render: true, 711 on: { 712 'click' : function(ev) { 713 scorm_launch_next_sco(); 714 }, 715 'keydown' : function(ev) { 716 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 717 scorm_launch_next_sco(); 718 } 719 } 720 } 721 }); 722 scorm_buttons[4] = new Y.Button({ 723 srcNode: '#nav_skipnext', 724 render: true, 725 on: { 726 'click' : function(ev) { 727 scorm_activate_item(scorm_skipnext(scorm_tree_node.getSelectedNodes()[0], true)); 728 }, 729 'keydown' : function(ev) { 730 if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) { 731 scorm_activate_item(scorm_skipnext(scorm_tree_node.getSelectedNodes()[0], true)); 732 } 733 } 734 } 735 }); 736 } 737 738 // finally activate the chosen item 739 var scorm_first_url = null; 740 if (typeof tree.rootNode.children[0] !== 'undefined') { 741 if (tree.rootNode.children[0].title !== scoes_nav[launch_sco].url) { 742 var node = tree.getNodeByAttribute('title', scoes_nav[launch_sco].url); 743 if (node !== null) { 744 scorm_first_url = node; 745 } 746 } else { 747 scorm_first_url = tree.rootNode.children[0]; 748 } 749 } 750 751 if (scorm_first_url == null) { // This is probably a single sco with no children (AICC Direct uses this). 752 scorm_first_url = tree.rootNode; 753 } 754 scorm_first_url.title = scoes_nav[launch_sco].url; 755 scorm_activate_item(scorm_first_url); 756 757 // resizing 758 scorm_resize_layout(); 759 760 // Collapse/expand TOC. 761 Y.one('#scorm_toc_toggle').on('click', scorm_toggle_toc); 762 Y.one('#scorm_toc_toggle').on('key', scorm_toggle_toc, 'down:enter,32'); 763 // fix layout if window resized 764 Y.on("windowresize", function() { 765 scorm_resize_layout(); 766 var toc_displayed = Y.one('#scorm_toc').getComputedStyle('display') !== 'none'; 767 if ((!scorm_disable_toc && !scorm_hide_toc) || toc_displayed) { 768 scorm_toggle_toc(true); 769 } 770 // Set 20% as minWidth constrain of TOC. 771 var layout_width = parseInt(Y.one('#scorm_layout').getComputedStyle('width'), 10); 772 scorm_resize_handle.set('defMinWidth', 0.2 * layout_width); 773 }); 774 // On resize drag, change width of scorm_content. 775 scorm_resize_handle.on('resize:resize', function() { 776 var tocwidth = parseInt(Y.one('#scorm_toc').getComputedStyle('width'), 10); 777 var layoutwidth = parseInt(Y.one('#scorm_layout').getStyle('width'), 10); 778 Y.one('#scorm_content').setStyle('width', (layoutwidth - tocwidth - 60)); 779 }); 780 }); 781 }; 782 783 M.mod_scorm.connectPrereqCallback = { 784 785 success: function(id, o) { 786 if (o.responseText !== undefined) { 787 var snode = null, 788 stitle = null; 789 if (scorm_tree_node && o.responseText) { 790 snode = scorm_tree_node.getSelectedNodes()[0]; 791 stitle = null; 792 if (snode) { 793 stitle = snode.title; 794 } 795 // All gone with clear, add new root node. 796 scorm_tree_node.clear(scorm_tree_node.createNode()); 797 } 798 // Make sure the temporary tree element is not there. 799 var el_old_tree = document.getElementById('scormtree123'); 800 if (el_old_tree) { 801 el_old_tree.parentNode.removeChild(el_old_tree); 802 } 803 var el_new_tree = document.createElement('div'); 804 var pagecontent = document.getElementById("page-content"); 805 if (!pagecontent) { 806 pagecontent = document.getElementById("content"); 807 } 808 el_new_tree.setAttribute('id','scormtree123'); 809 el_new_tree.innerHTML = o.responseText; 810 // Make sure it does not show. 811 el_new_tree.style.display = 'none'; 812 pagecontent.appendChild(el_new_tree); 813 // Ignore the first level element as this is the title. 814 var startNode = el_new_tree.firstChild.firstChild; 815 if (startNode.tagName == 'LI') { 816 // Go back to the beginning. 817 startNode = el_new_tree; 818 } 819 var toc_source = Y.one('#scormtree123 > ul'); 820 var toc = mod_scorm_parse_toc_tree(toc_source); 821 scorm_tree_node.appendNode(scorm_tree_node.rootNode, toc); 822 var el = document.getElementById('scormtree123'); 823 el.parentNode.removeChild(el); 824 scorm_tree_node.render(); 825 scorm_tree_node.openAll(); 826 if (stitle !== null) { 827 snode = scorm_tree_node.getNodeByAttribute('title', stitle); 828 // Do not let destroyed node to be selected. 829 if (snode && !snode.state.destroyed) { 830 snode.select(); 831 var toc_disabled = Y.one('#scorm_toc').hasClass('disabled'); 832 if (!toc_disabled) { 833 if (!snode.state.selected) { 834 snode.select(); 835 } 836 } 837 } 838 } 839 } 840 }, 841 842 failure: function(id, o) { 843 // TODO: do some sort of error handling. 844 } 845 846 };
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |