MDL-39910 mod_scorm: rewrite SCORM code in YUI3, use responsive grids, add new nav...
authorMayank Gupta <mayankgupta2005@gmail.com>
Sun, 30 Jun 2013 06:38:18 +0000 (12:08 +0530)
committerDan Marsden <dan@danmarsden.com>
Fri, 20 Sep 2013 10:45:36 +0000 (22:45 +1200)
14 files changed:
mod/scorm/backup/moodle2/backup_scorm_stepslib.php
mod/scorm/datamodels/scorm_13lib.php
mod/scorm/db/install.xml
mod/scorm/db/upgrade.php
mod/scorm/lang/en/scorm.php
mod/scorm/lib.php
mod/scorm/loaddatamodel.php
mod/scorm/locallib.php
mod/scorm/mod_form.php
mod/scorm/module.js
mod/scorm/player.php
mod/scorm/settings.php
mod/scorm/styles.css
mod/scorm/version.php

index 11712d0..6469442 100644 (file)
@@ -42,7 +42,7 @@ class backup_scorm_activity_structure_step extends backup_activity_structure_ste
             'whatgrade', 'maxattempt', 'forcecompleted', 'forcenewattempt',
             'lastattemptlock', 'displayattemptstatus', 'displaycoursestructure', 'updatefreq',
             'sha1hash', 'md5hash', 'revision', 'launch',
-            'skipview', 'hidebrowse', 'hidetoc', 'hidenav',
+            'skipview', 'hidebrowse', 'hidetoc', 'nav', 'navpositionleft', 'navpositiontop',
             'auto', 'popup', 'options', 'width',
             'height', 'timeopen', 'timeclose', 'timemodified',
             'completionstatusrequired', 'completionscorerequired'));
index 906d288..eca069f 100644 (file)
@@ -986,7 +986,11 @@ function scorm_seq_rollup_rule_check ($sco, $userid, $action) {
 function scorm_seq_flow_tree_traversal($activity, $direction, $childrenflag, $prevdirection, $seq, $userid, $skip = false) {
     $revdirection = false;
     $parent = scorm_get_parent($activity);
-    $children = scorm_get_available_children($parent);
+    if (!empty($parent)) {
+        $children = scorm_get_available_children($parent);
+    } else {
+        $children = array();
+    }
     $childrensize = count($children);
 
     if (($prevdirection != null && $prevdirection == 'backward') && ($children[$childrensize-1]->id == $activity->id)) {
index d69f1ea..a36bd6f 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="mod/scorm/db" VERSION="20130826" COMMENT="XMLDB file for Moodle mod/scorm"
+<XMLDB PATH="mod/scorm/db" VERSION="20130901" COMMENT="XMLDB file for Moodle mod/scorm"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
 >
@@ -31,7 +31,9 @@
         <FIELD NAME="skipview" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
         <FIELD NAME="hidebrowse" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="hidetoc" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
-        <FIELD NAME="hidenav" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
+        <FIELD NAME="nav" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
+        <FIELD NAME="navpositionleft" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="-100" SEQUENCE="false"/>
+        <FIELD NAME="navpositiontop" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="-100" SEQUENCE="false"/>
         <FIELD NAME="auto" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="popup" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="options" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
index 870a988..242f89e 100644 (file)
@@ -129,6 +129,47 @@ function xmldb_scorm_upgrade($oldversion) {
         upgrade_mod_savepoint(true, 2013081303, 'scorm');
     }
 
+    if ($oldversion < 2013090100) {
+        $table = new xmldb_table('scorm');
+
+        $field = new xmldb_field('nav', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, true, null, 1, 'hidetoc');
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        $field = new xmldb_field('navpositionleft', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, -100, 'nav');
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        $field = new xmldb_field('navpositiontop', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, -100, 'navpositionleft');
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field);
+        }
+
+        $field = new xmldb_field('hidenav');
+        if ($dbman->field_exists($table, $field)) {
+            // Update nav setting to disable navigation buttons.
+            $DB->set_field('scorm', 'nav', 0, array('hidenav' => 1));
+            // Update nav setting to show floating navigation buttons under TOC.
+            $DB->set_field('scorm', 'nav', 2, array('hidenav' => 0));
+            $DB->set_field('scorm', 'navpositionleft', 215, array('hidenav' => 0));
+            $DB->set_field('scorm', 'navpositiontop', 300, array('hidenav' => 0));
+            // Drop hidenav field.
+            $dbman->drop_field($table, $field);
+        }
+
+        $params = array('plugin' => 'scorm', 'name' => 'hidenav');
+        if ($DB->record_exists('config_plugins', $params)) {
+            $DB->delete_records('config_plugins', $params);
+        }
+        $params = array('plugin' => 'scorm', 'name' => 'hidenav_adv');
+        if ($DB->record_exists('config_plugins', $params)) {
+            $DB->delete_records('config_plugins', $params);
+        }
+        upgrade_mod_savepoint(true, 2013090100, 'scorm');
+    }
+
     return true;
 }
 
index f39efda..5016d55 100644 (file)
@@ -67,6 +67,8 @@ $string['browsemode'] = 'Preview mode';
 $string['browserepository'] = 'Browse repository';
 $string['calculatedweight'] = 'Calculated weight';
 $string['cannotfindsco'] = 'Could not find SCO';
+$string['collapsetocwinsize'] = 'Collapse TOC when window size below';
+$string['collapsetocwinsizedesc'] = 'This setting lets you specify the window size below which the TOC should automatically collapse.';
 $string['compatibilitysettings'] = 'Compatibility settings';
 $string['completed'] = 'Completed';
 $string['completionscorerequired'] = 'Require minimum score';
@@ -118,6 +120,7 @@ $string['finishscorm'] = 'If you have finished viewing this resource, {$a}';
 $string['finishscormlinkname'] = 'click here to return to the course page';
 $string['firstaccess'] = 'First access';
 $string['firstattempt'] = 'First attempt';
+$string['floating'] = 'Floating';
 $string['forcecompleted'] = 'Force completed';
 $string['forcecompleted_help'] = 'If enabled, the status of the current attempt is forced to "completed". (Only applicable to SCORM 1.2 packages.)';
 $string['forcecompleteddesc'] = 'This preference sets the default value for the force completed setting';
@@ -130,6 +133,8 @@ $string['forcejavascriptmessage'] = 'JavaScript is required to view this object,
 $string['found'] = 'Manifest found';
 $string['frameheight'] = 'The height of the stage frame or window.';
 $string['framewidth'] = 'The width of the stage frame or window.';
+$string['fromleft'] = 'From left';
+$string['fromtop'] = 'From top';
 $string['fullscreen'] = 'Fill the whole screen';
 $string['general'] = 'General data';
 $string['gradeaverage'] = 'Average grade';
@@ -155,8 +160,6 @@ $string['hidebrowse'] = 'Disable preview mode';
 $string['hidebrowse_help'] = 'Preview mode allows a student to browse an activity before attempting it. If preview mode is disabled, the preview button is hidden.';
 $string['hidebrowsedesc'] = 'Preview mode allows a student to browse an activity before attempting it.';
 $string['hideexit'] = 'Hide exit link';
-$string['hidenav'] = 'Hide navigation buttons';
-$string['hidenavdesc'] = 'Whether to show or hide the navigation buttons.';
 $string['hidereview'] = 'Hide review button';
 $string['hidetoc'] = 'Display course structure in player';
 $string['hidetoc_help'] = 'How the table of contents is displayed in the SCORM player';
@@ -227,6 +230,17 @@ SCORM activities may be used
 * As an assessment tool';
 $string['modulename_link'] = 'mod/scorm/view';
 $string['modulenameplural'] = 'SCORM packages';
+$string['nav'] = 'Show Navigation';
+$string['nav_help'] = 'This setting specifies wether to show or hide the navigation buttons and their position.
+
+There are 3 options:
+
+* No - Do not show the navigation buttons
+* Under content - Show the navigation buttons under SCORM package content
+* Float - Allows to manually specify the navigation buttons position from left and from top with respect to the window.';
+$string['navdesc'] = 'This setting specifies wether to show/hide navigation buttons and their position.';
+$string['navpositionleft'] = 'Position of navigation buttons from left in pixels.';
+$string['navpositiontop'] = 'Position of navigation buttons from top in pixels.';
 $string['newattempt'] = 'Start a new attempt';
 $string['next'] = 'Continue';
 $string['noactivity'] = 'Nothing to report';
@@ -340,6 +354,7 @@ $string['typeaiccurl'] = 'External AICC URL';
 $string['typeexternal'] = 'External SCORM manifest';
 $string['typelocal'] = 'Uploaded package';
 $string['typelocalsync'] = 'Downloaded package';
+$string['undercontent'] = 'Under content';
 $string['unziperror'] = 'An error occurs during package unzip';
 $string['updatefreq'] = 'Auto-update frequency';
 $string['updatefreq_error'] = 'Auto-update frequency can only be set when the package file is hosted externally';
index a3d17cd..3d8aff7 100644 (file)
@@ -34,6 +34,11 @@ define('SCORM_TOC_HIDDEN', 1);
 define('SCORM_TOC_POPUP', 2);
 define('SCORM_TOC_DISABLED', 3);
 
+// Used to show/hide navigation buttons and set their position.
+define('SCORM_NAV_DISABLED', 0);
+define('SCORM_NAV_UNDER_CONTENT', 1);
+define('SCORM_NAV_FLOATING', 2);
+
 //used to check what SCORM version is being used.
 define('SCORM_12', 1);
 define('SCORM_13', 2);
index 297375d..f9d6ba1 100644 (file)
@@ -29,6 +29,7 @@ $id = optional_param('id', 0, PARAM_INT);       // Course Module ID, or
 $a = optional_param('a', 0, PARAM_INT);         // scorm ID.
 $scoid = required_param('scoid', PARAM_INT);     // sco ID.
 $mode = optional_param('mode', '', PARAM_ALPHA); // navigation mode.
+$currentorg = optional_param('currentorg', '', PARAM_RAW); // Selected organization.
 $attempt = required_param('attempt', PARAM_INT); // new attempt.
 
 if (!empty($id)) {
index b1cde82..2b770d8 100644 (file)
@@ -149,6 +149,17 @@ function scorm_get_popup_display_array() {
                  1 => get_string('popup', 'scorm'));
 }
 
+/**
+ * Returns an array of the array of navigation buttons display options
+ *
+ * @return array an array of navigation buttons display options
+ */
+function scorm_get_navigation_display_array() {
+    return array(SCORM_NAV_DISABLED => get_string('no'),
+                 SCORM_NAV_UNDER_CONTENT => get_string('undercontent', 'scorm'),
+                 SCORM_NAV_FLOATING => get_string('floating', 'scorm'));
+}
+
 /**
  * Returns an array of the array of attempt options
  *
@@ -1445,7 +1456,7 @@ function scorm_get_toc_object($user, $scorm, $currentorg='', $scoid='', $mode='n
     }
 
     // Get the parent scoes!
-    $result = scorm_get_toc_get_parent_child($result);
+    $result = scorm_get_toc_get_parent_child($result, $currentorg);
 
     // Be safe, prevent warnings from showing up while returning array
     if (!isset($scoid)) {
@@ -1455,10 +1466,15 @@ function scorm_get_toc_object($user, $scorm, $currentorg='', $scoid='', $mode='n
     return array('scoes' => $result, 'usertracks' => $usertracks, 'scoid' => $scoid);
 }
 
-function scorm_get_toc_get_parent_child(&$result) {
+function scorm_get_toc_get_parent_child(&$result, $currentorg) {
     $final = array();
     $level = 0;
-    $prevparent = '/';
+    // Organization is always the root, prevparent.
+    if (!empty($currentorg)) {
+        $prevparent = $currentorg;
+    } else {
+        $prevparent = '/';
+    }
 
     foreach ($result as $sco) {
         if ($sco->parent == '/') {
@@ -1587,7 +1603,7 @@ function scorm_format_toc_for_treeview($user, $scorm, $scoes, $usertracks, $cmid
                             if ($sco->scormtype == 'sco') {
                                 $result->toc .= $sco->statusicon.'&nbsp;<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score."\n";
                             } else {
-                                $result->toc .= '&nbsp;<a href="'.$url.'">'.format_string($sco->title).'</a>'.$score."\n";
+                                $result->toc .= '&nbsp;<a data-scoid="'.$sco->id.'" href="'.$url.'">'.format_string($sco->title).'</a>'.$score."\n";
                             }
                         } else {
                             if ($sco->scormtype == 'sco') {
@@ -1599,9 +1615,9 @@ function scorm_format_toc_for_treeview($user, $scorm, $scoes, $usertracks, $cmid
                     } else {
                         if (!empty($sco->launch)) {
                             if ($sco->scormtype == 'sco') {
-                                $result->toc .= '<a title="'.$sco->url.'">'.$sco->statusicon.'&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>';
+                                $result->toc .= '<a data-scoid="'.$sco->id.'" title="'.$sco->url.'">'.$sco->statusicon.'&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>';
                             } else {
-                                $result->toc .= '<a title="'.$sco->url.'">&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>';
+                                $result->toc .= '<a data-scoid="'.$sco->id.'" title="'.$sco->url.'">&nbsp;'.format_string($sco->title).'&nbsp;'.$score.'</a>';
                             }
                         } else {
                             if ($sco->scormtype == 'sco') {
@@ -1710,8 +1726,9 @@ function scorm_get_toc($user, $scorm, $cmid, $toclink=TOCJSLINK, $currentorg='',
     $organizationsco = null;
 
     if ($tocheader) {
-        $result->toc = "<div id=\"scorm_layout\">\n";
-        $result->toc .= "<div id=\"scorm_toc\">\n";
+        $result->toc = "<div id=\"scorm_layout\" class=\"yui3-g-r\">\n";
+        $result->toc .= "<div id=\"scorm_toc\" class=\"yui3-u-1-5\">\n";
+        $result->toc .= "<div id=\"scorm_toc_title\"></div>\n";
         $result->toc .= "<div id=\"scorm_tree\">\n";
     }
 
@@ -1761,8 +1778,12 @@ function scorm_get_toc($user, $scorm, $cmid, $toclink=TOCJSLINK, $currentorg='',
     $result->attemptleft = $treeview->attemptleft;
 
     if ($tocheader) {
-        $result->toc .= "</div></div></div>\n";
+        $result->toc .= "</div></div>\n";
+        $result->toc .= "<div id=\"scorm_toc_toggle\">\n";
+        $result->toc .= "<button id=\"scorm_toc_toggle_btn\"></button></div>\n";
+        $result->toc .= "<div id=\"scorm_content\">";
         $result->toc .= "<div id=\"scorm_navpanel\"></div>\n";
+        $result->toc .= "</div></div>\n";
     }
 
     return $result;
index 99d9d87..06fcf4c 100644 (file)
@@ -162,11 +162,28 @@ class mod_scorm_mod_form extends moodleform_mod {
         $mform->setAdvanced('hidetoc', $cfgscorm->hidetoc_adv);
         $mform->disabledIf('hidetoc', 'scormtype', 'eq', SCORM_TYPE_AICCURL);
 
-        // Hide Navigation panel.
-        $mform->addElement('selectyesno', 'hidenav', get_string('hidenav', 'scorm'));
-        $mform->setDefault('hidenav', $cfgscorm->hidenav);
-        $mform->setAdvanced('hidenav', $cfgscorm->hidenav_adv);
-        $mform->disabledIf('hidenav', 'hidetoc', 'noteq', 0);
+        // Navigation panel display.
+        $mform->addElement('select', 'nav', get_string('nav', 'scorm'), scorm_get_navigation_display_array());
+        $mform->addHelpButton('nav', 'nav', 'scorm');
+        $mform->setDefault('nav', $cfgscorm->nav);
+        $mform->setAdvanced('nav', $cfgscorm->nav_adv);
+        $mform->disabledIf('nav', 'hidetoc', 'noteq', SCORM_TOC_SIDE);
+
+        // Navigation panel position from left.
+        $mform->addElement('text', 'navpositionleft', get_string('fromleft', 'scorm'), 'maxlength="5" size="5"');
+        $mform->setDefault('navpositionleft', $cfgscorm->navpositionleft);
+        $mform->setType('navpositionleft', PARAM_INT);
+        $mform->setAdvanced('navpositionleft', $cfgscorm->navpositionleft_adv);
+        $mform->disabledIf('navpositionleft', 'hidetoc', 'noteq', SCORM_TOC_SIDE);
+        $mform->disabledIf('navpositionleft', 'nav', 'noteq', SCORM_NAV_FLOATING);
+
+        // Navigation panel position from top.
+        $mform->addElement('text', 'navpositiontop', get_string('fromtop', 'scorm'), 'maxlength="5" size="5"');
+        $mform->setDefault('navpositiontop', $cfgscorm->navpositiontop);
+        $mform->setType('navpositiontop', PARAM_INT);
+        $mform->setAdvanced('navpositiontop', $cfgscorm->navpositiontop_adv);
+        $mform->disabledIf('navpositiontop', 'hidetoc', 'noteq', SCORM_TOC_SIDE);
+        $mform->disabledIf('navpositiontop', 'nav', 'noteq', SCORM_NAV_FLOATING);
 
         // Display attempt status.
         $mform->addElement('select', 'displayattemptstatus', get_string('displayattemptstatus', 'scorm'),
index 817b377..efdaa8e 100644 (file)
 mod_scorm_launch_next_sco = null;
 mod_scorm_launch_prev_sco = null;
 mod_scorm_activate_item = null;
+mod_scorm_parse_toc_tree = null;
 scorm_layout_widget = null;
 
 M.mod_scorm = {};
 
-M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launch_sco, scoes_nav) {
+M.mod_scorm.init = function(Y, nav_display, navposition_left, navposition_top, hide_toc, collapsetocwinsize, toc_title, window_name, launch_sco, scoes_nav) {
     var scorm_disable_toc = false;
     var scorm_hide_nav = true;
     var scorm_hide_toc = true;
     if (hide_toc == 0) {
-        if (hide_nav != 1) {
+        if (nav_display !== 0) {
             scorm_hide_nav = false;
         }
         scorm_hide_toc = false;
@@ -47,32 +48,98 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
     var scorm_bloody_labelclick = false;
     var scorm_nav_panel;
 
-    Y.use('yui2-resize', 'yui2-dragdrop', 'yui2-container', 'yui2-button', 'yui2-layout', 'yui2-treeview', 'yui2-json', 'yui2-event', function(Y) {
+    Y.use('button', 'dd-plugin', 'panel', 'resize', 'gallery-sm-treeview', function(Y) {
 
-        Y.YUI2.widget.TextNode.prototype.getContentHtml = function() {
-            var sb = [];
-            sb[sb.length] = this.href ? '<a' : '<span';
-            sb[sb.length] = ' id="' + Y.YUI2.lang.escapeHTML(this.labelElId) + '"';
-            sb[sb.length] = ' class="' + Y.YUI2.lang.escapeHTML(this.labelStyle) + '"';
-            if (this.href) {
-                sb[sb.length] = ' href="' + Y.YUI2.lang.escapeHTML(this.href) + '"';
-                sb[sb.length] = ' target="' + Y.YUI2.lang.escapeHTML(this.target) + '"';
+        Y.TreeView.prototype.getNodeByAttribute = function(attribute, value) {
+            var node = null,
+                domnode = Y.one('a[' + attribute + '="' + value + '"]');
+            if (domnode !== null) {
+                node = scorm_tree_node.getNodeById(domnode.ancestor('li').get('id'));
             }
-            if (this.title) {
-                sb[sb.length] = ' title="' + Y.YUI2.lang.escapeHTML(this.title) + '"';
+            return node;
+        };
+
+        Y.TreeView.prototype.openAll = function () {
+            var tree = this;
+            Y.all('.yui3-treeview-can-have-children').each(function() {
+                var node = tree.getNodeById(this.get('id'));
+                node.open();
+            });
+        };
+
+        // TODO: Remove next(), previous() prototype functions after YUI has been updated to 3.11.0 - MDL-41208.
+        Y.Tree.Node.prototype.next = function () {
+            if (this.parent) {
+                return this.parent.children[this.index() + 1];
+            }
+        };
+
+        Y.Tree.Node.prototype.previous = function () {
+            if (this.parent) {
+                return this.parent.children[this.index() - 1];
             }
-            sb[sb.length] = ' >';
-            sb[sb.length] = this.label;
-            sb[sb.length] = this.href?'</a>':'</span>';
-            return sb.join("");
         };
 
+        var scorm_parse_toc_tree = function(srcNode) {
+            var SELECTORS = {
+                    child: '> li',
+                    label: '> li, > a',
+                    textlabel : '> li, > span',
+                    subtree: '> ul, > li'
+                },
+                children = [];
+
+            srcNode.all(SELECTORS.child).each(function(childNode) {
+                var child = {},
+                    labelNode = childNode.one(SELECTORS.label),
+                    textNode = childNode.one(SELECTORS.textlabel),
+                    subTreeNode = childNode.one(SELECTORS.subtree);
+
+                if (labelNode) {
+                    var title = labelNode.getAttribute('title');
+                    var scoid = labelNode.getData('scoid');
+                    child.label = labelNode.get('outerHTML');
+                    // Will be good to change to url instead of title.
+                    if (title && title !== '#') {
+                        child.title = title;
+                    }
+                    if (typeof scoid !== 'undefined') {
+                        child.scoid = scoid;
+                    }
+                } else if (textNode) {
+                    // The selector did not find a label node with anchor.
+                    child.label = textNode.get('outerHTML');
+                }
+
+                if (subTreeNode) {
+                    child.children = scorm_parse_toc_tree(subTreeNode);
+                }
+
+                children.push(child);
+            });
+
+            return children;
+        };
+
+        mod_scorm_parse_toc_tree = scorm_parse_toc_tree;
+
         var scorm_activate_item = function(node) {
             if (!node) {
                 return;
             }
+            // Check if the item is already active, avoid recursive calls.
+            if (Y.one('#scorm_object')) {
+                var scorm_active_url = Y.one('#scorm_object').getAttribute('src');
+                var node_full_url = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?' + node.title;
+                if (node_full_url === scorm_active_url) {
+                    return;
+                }
+            }
             scorm_current_node = node;
-            scorm_current_node.highlight();
+            // Avoid recursive calls.
+            if (!scorm_current_node.state.selected) {
+                scorm_current_node.select();
+            }
 
             // remove any reference to the old API
             if (window.API) {
@@ -99,7 +166,7 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
                 document.getElementById('external-scormapi').src = api_url;
             }
 
-            var content = new Y.YUI2.util.Element('scorm_content');
+            var content = Y.one('#scorm_content');
             var obj = document.createElement('iframe');
             obj.setAttribute('id', 'scorm_object');
             obj.setAttribute('type', 'text/html');
@@ -111,10 +178,10 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
                 if(! mine) {
                     alert(M.str.scorm.popupsblocked);
                 }
-                mine.close()
+                mine.close();
             }
 
-            var old = Y.YUI2.util.Dom.get('scorm_object');
+            var old = Y.one('#scorm_object');
             if (old) {
                 if(window_name) {
                     var cwidth = scormplayerdata.cwidth;
@@ -125,16 +192,13 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
                     content.replaceChild(obj, old);
                 }
             } else {
-                content.appendChild(obj);
+                content.prepend(obj);
             }
 
-            scorm_resize_frame();
-
-            var left = scorm_layout_widget.getUnitByPosition('left');
-            if (left.expand) {
-                scorm_current_node.focus();
-            }
             if (scorm_hide_nav == false) {
+                if (nav_display === 1 && navposition_left > 0 && navposition_top > 0) {
+                    Y.one('#scorm_object').addClass(cssclasses.scorm_nav_under_content);
+                }
                 scorm_fixnav();
             }
         };
@@ -146,95 +210,88 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
          * @return void
          */
         var scorm_fixnav = function() {
-            scorm_buttons[0].set('disabled', (scorm_skipprev(scorm_current_node) == null || scorm_skipprev(scorm_current_node).title == null ||
-                        scoes_nav[launch_sco].hideprevious == 1));
-            scorm_buttons[1].set('disabled', (scorm_prev(scorm_current_node) == null || scorm_prev(scorm_current_node).title == null ||
-                        scoes_nav[launch_sco].hideprevious == 1));
-            scorm_buttons[2].set('disabled', (scorm_up(scorm_current_node) == null) || scorm_up(scorm_current_node).title == null);
-            scorm_buttons[3].set('disabled', (((scorm_next(scorm_current_node) == null || scorm_next(scorm_current_node).title == null) &&
-                        (scoes_nav[launch_sco].flow != 1)) || (scoes_nav[launch_sco].hidecontinue == 1)));
-            scorm_buttons[4].set('disabled', (scorm_skipnext(scorm_current_node) == null || scorm_skipnext(scorm_current_node).title == null ||
-                        scoes_nav[launch_sco].hidecontinue == 1));
+            scorm_buttons[0].set('disabled', ((scorm_skipprev(scorm_current_node) === null) || (scorm_skipprev(scorm_current_node).parent.isRoot()) ||
+                        (scorm_skipprev(scorm_current_node).title === null) || (scoes_nav[launch_sco].hideprevious === 1)));
+            scorm_buttons[1].set('disabled', ((scorm_prev(scorm_current_node) === null) || (scorm_skipprev(scorm_current_node).parent.isRoot()) ||
+                        (scorm_prev(scorm_current_node).title === null) || (scoes_nav[launch_sco].hideprevious === 1)));
+            scorm_buttons[2].set('disabled', (scorm_up(scorm_current_node) === null) || (scorm_up(scorm_current_node).parent.isRoot()) ||
+                         (scorm_up(scorm_current_node).title === null));
+            scorm_buttons[3].set('disabled', ((scorm_next(scorm_current_node) === null) || ((scorm_next(scorm_current_node).title === null) &&
+                        (scoes_nav[launch_sco].flow !== 1)) || (scoes_nav[launch_sco].hidecontinue === 1)));
+            scorm_buttons[4].set('disabled', (scorm_skipnext(scorm_current_node) === null || scorm_skipnext(scorm_current_node).title === null ||
+                        scoes_nav[launch_sco].hidecontinue === 1));
         };
 
-        var scorm_resize_parent = function() {
-            // fudge  IE7 to redraw the screen
-            parent.resizeBy(-10, -10);
-            parent.resizeBy(10, 10);
-            var ifr = Y.YUI2.util.Dom.get('scorm_object');
-            if (ifr) {
-                ifr.detachEvent("onload", scorm_resize_parent);
+        var scorm_toggle_toc = function(windowresize) {
+            var toc = Y.one('#scorm_toc');
+            var scorm_content = Y.one('#scorm_content');
+            var scorm_toc_toggle_btn = Y.one('#scorm_toc_toggle_btn');
+            var toc_disabled = toc.hasClass('disabled');
+            var disabled_by = toc.getAttribute('disabled-by');
+            // Remove width element style from resize handle.
+            toc.setStyle('width', null);
+            scorm_content.setStyle('width', null);
+            if (windowresize === true) {
+                if (disabled_by === 'user') {
+                    return;
+                }
+                var body = Y.one('body');
+                if (body.get('winWidth') < collapsetocwinsize) {
+                    toc.addClass(cssclasses.disabled)
+                        .setAttribute('disabled-by', 'screen-size');
+                    scorm_toc_toggle_btn.setHTML('&gt;')
+                        .set('title', M.util.get_string('show', 'moodle'));
+                    scorm_content.removeClass(cssclasses.scorm_grid_content_toc_visible)
+                        .addClass(cssclasses.scorm_grid_content_toc_hidden);
+                } else if (body.get('winWidth') > collapsetocwinsize) {
+                    toc.removeClass(cssclasses.disabled)
+                        .removeAttribute('disabled-by');
+                    scorm_toc_toggle_btn.setHTML('&lt;')
+                        .set('title', M.util.get_string('hide', 'moodle'));
+                    scorm_content.removeClass(cssclasses.scorm_grid_content_toc_hidden)
+                        .addClass(cssclasses.scorm_grid_content_toc_visible);
+                }
+                return;
+            }
+            if (toc_disabled) {
+                toc.removeClass(cssclasses.disabled)
+                    .removeAttribute('disabled-by');
+                scorm_toc_toggle_btn.setHTML('&lt;')
+                    .set('title', M.util.get_string('hide', 'moodle'));
+                scorm_content.removeClass(cssclasses.scorm_grid_content_toc_hidden)
+                    .addClass(cssclasses.scorm_grid_content_toc_visible);
+            } else {
+                toc.addClass(cssclasses.disabled)
+                    .setAttribute('disabled-by', 'user');
+                scorm_toc_toggle_btn.setHTML('&gt;')
+                    .set('title', M.util.get_string('show', 'moodle'));
+                scorm_content.removeClass(cssclasses.scorm_grid_content_toc_visible)
+                    .addClass(cssclasses.scorm_grid_content_toc_hidden);
             }
         };
 
-        var scorm_resize_layout = function(alsowidth) {
+        var scorm_resize_layout = function() {
             if (window_name) {
                 return;
             }
 
-            if (alsowidth) {
-                scorm_layout_widget.setStyle('width', '');
-                var newwidth = scorm_get_htmlelement_size('content', 'width');
-            }
             // make sure that the max width of the TOC doesn't go to far
 
-            var left = scorm_layout_widget.getUnitByPosition('left');
-            var maxwidth = parseInt(Y.YUI2.util.Dom.getStyle('scorm_layout', 'width'));
-            left.set('maxWidth', (maxwidth - 50));
-            var cwidth = left.get('width');
+            var scorm_toc_node = Y.one('#scorm_toc');
+            var maxwidth = parseInt(Y.one('#scorm_layout').getComputedStyle('width'), 10);
+            scorm_toc_node.setStyle('maxWidth', (maxwidth - 200));
+            var cwidth = parseInt(scorm_toc_node.getComputedStyle('width'), 10);
             if (cwidth > (maxwidth - 1)) {
-                left.set('width', (maxwidth - 50));
+                scorm_toc_node.setStyle('width', (maxwidth - 50));
             }
 
-            scorm_layout_widget.setStyle('height', '100%');
-            var center = scorm_layout_widget.getUnitByPosition('center');
-            center.setStyle('height', '100%');
-
-            // calculate the rough new height
-            newheight = Y.YUI2.util.Dom.getViewportHeight() -5;
+            // Calculate the rough new height from the viewport height.
+            newheight = Y.one('body').get('winHeight') -5;
             if (newheight < 600) {
                 newheight = 600;
             }
-            scorm_layout_widget.set('height', newheight);
-
-            scorm_layout_widget.render();
-            scorm_resize_frame();
-
-            if (scorm_nav_panel) {
-                scorm_nav_panel.align('bl', 'bl');
-            }
-        };
+            Y.one('#scorm_layout').setStyle('height', newheight);
 
-        var scorm_get_htmlelement_size = function(el, prop) {
-            var val = Y.YUI2.util.Dom.getStyle(el, prop);
-            if (val == 'auto') {
-                if (el.get) {
-                    el = el.get('element'); // get real HTMLElement from YUI element
-                }
-                val = Y.YUI2.util.Dom.getComputedStyle(Y.YUI2.util.Dom.get(el), prop);
-            }
-            return parseInt(val);
-        };
-
-        var scorm_resize_frame = function() {
-            var obj = Y.YUI2.util.Dom.get('scorm_object');
-            if (obj) {
-                var content = scorm_layout_widget.getUnitByPosition('center').get('wrap');
-                // basically trap IE6 and 7
-                if (Y.YUI2.env.ua.ie > 5 && Y.YUI2.env.ua.ie < 8) {
-                    if( obj.style.setAttribute ) {
-                        obj.style.setAttribute("cssText", 'width: ' +(content.offsetWidth - 6)+'px; height: ' + (content.offsetHeight - 10)+'px;');
-                    }
-                    else {
-                        obj.style.setAttribute('width', (content.offsetWidth - 6)+'px', 0);
-                        obj.style.setAttribute('height', (content.offsetHeight - 10)+'px', 0);
-                    }
-                }
-                else {
-                    obj.style.width = (content.offsetWidth)+'px';
-                    obj.style.height = (content.offsetHeight - 10)+'px';
-                }
-            }
         };
 
         // Handle AJAX Request
@@ -245,14 +302,20 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
         };
 
         var scorm_up = function(node, update_launch_sco) {
-            var node = scorm_tree_node.getHighlightedNode();
-            if (node.depth > 0 && typeof scoes_nav[launch_sco].parentscoid != 'undefined') {
+            if (node.parent && node.parent.parent && typeof scoes_nav[launch_sco].parentscoid !== 'undefined') {
                 var parentscoid = scoes_nav[launch_sco].parentscoid;
-                node.parent.title = scoes_nav[parentscoid].url;
+                var parent = node.parent;
+                if (parent.title !== scoes_nav[parentscoid].url) {
+                    parent = scorm_tree_node.getNodeByAttribute('title', scoes_nav[parentscoid].url);
+                    if (parent === null) {
+                        parent = scorm_tree_node.rootNode.children[0];
+                        parent.title = scoes_nav[parentscoid].url;
+                    }
+                }
                 if (update_launch_sco) {
                     launch_sco = parentscoid;
                 }
-                return node.parent;
+                return parent;
             }
             return null;
         };
@@ -266,12 +329,18 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
         };
 
         var scorm_prev = function(node, update_launch_sco) {
-            if (node.previousSibling && node.previousSibling.children.length &&
-                    typeof scoes_nav[launch_sco].prevscoid != 'undefined') {
-                var node = scorm_lastchild(node.previousSibling);
+            if (node.previous() && node.previous().children.length &&
+                    typeof scoes_nav[launch_sco].prevscoid !== 'undefined') {
+                node = scorm_lastchild(node.previous());
                 if (node) {
                     var prevscoid = scoes_nav[launch_sco].prevscoid;
-                    node.title = scoes_nav[prevscoid].url;
+                    if (node.title !== scoes_nav[prevscoid].url) {
+                        node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[prevscoid].url);
+                        if (node === null) {
+                            node = scorm_tree_node.rootNode.children[0];
+                            node.title = scoes_nav[prevscoid].url;
+                        }
+                    }
                     if (update_launch_sco) {
                         launch_sco = prevscoid;
                     }
@@ -284,32 +353,53 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
         };
 
         var scorm_skipprev = function(node, update_launch_sco) {
-            if (node.previousSibling && typeof scoes_nav[launch_sco].prevsibling != 'undefined') {
+            if (node.previous() && typeof scoes_nav[launch_sco].prevsibling !== 'undefined') {
                 var prevsibling = scoes_nav[launch_sco].prevsibling;
-                node.previousSibling.title = scoes_nav[prevsibling].url;
+                var previous = node.previous();
+                var prevscoid = scoes_nav[launch_sco].prevscoid;
+                if (previous.title !== scoes_nav[prevscoid].url) {
+                    previous = scorm_tree_node.getNodeByAttribute('title', scoes_nav[prevsibling].url);
+                    if (previous === null) {
+                        previous = scorm_tree_node.rootNode.children[0];
+                        previous.title = scoes_nav[prevsibling].url;
+                    }
+                }
                 if (update_launch_sco) {
                     launch_sco = prevsibling;
                 }
-                return node.previousSibling;
-            } else if (node.depth > 0 && typeof scoes_nav[launch_sco].parentscoid != 'undefined') {
+                return previous;
+            } else if (node.parent && node.parent.parent && typeof scoes_nav[launch_sco].parentscoid !== 'undefined') {
                 var parentscoid = scoes_nav[launch_sco].parentscoid;
-                node.parent.title = scoes_nav[parentscoid].url;
+                var parent = node.parent;
+                if (parent.title !== scoes_nav[parentscoid].url) {
+                    parent = scorm_tree_node.getNodeByAttribute('title', scoes_nav[parentscoid].url);
+                    if (parent === null) {
+                        parent = scorm_tree_node.rootNode.children[0];
+                        parent.title = scoes_nav[parentscoid].url;
+                    }
+                }
                 if (update_launch_sco) {
                     launch_sco = parentscoid;
                 }
-                return node.parent;
+                return parent;
             }
             return null;
         };
 
         var scorm_next = function(node, update_launch_sco) {
             if (node === false) {
-                return scorm_tree_node.getRoot().children[0];
+                return scorm_tree_node.children[0];
             }
             if (node.children.length && typeof scoes_nav[launch_sco].nextscoid != 'undefined') {
-                var node = node.children[0];
+                node = node.children[0];
                 var nextscoid = scoes_nav[launch_sco].nextscoid;
-                node.title = scoes_nav[nextscoid].url;
+                if (node.title !== scoes_nav[nextscoid].url) {
+                    node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[nextscoid].url);
+                    if (node === null) {
+                        node = scorm_tree_node.rootNode.children[0];
+                        node.title = scoes_nav[nextscoid].url;
+                    }
+                }
                 if (update_launch_sco) {
                     launch_sco = nextscoid;
                 }
@@ -319,297 +409,419 @@ M.mod_scorm.init = function(Y, hide_nav, hide_toc, toc_title, window_name, launc
         };
 
         var scorm_skipnext = function(node, update_launch_sco) {
-            if (node.nextSibling && typeof scoes_nav[launch_sco].nextsibling != 'undefined') {
+            var next = node.next();
+            if (next && next.title && typeof scoes_nav[launch_sco] !== 'undefined' && typeof scoes_nav[launch_sco].nextsibling !== 'undefined') {
                 var nextsibling = scoes_nav[launch_sco].nextsibling;
-                node.nextSibling.title = scoes_nav[nextsibling].url;
+                if (next.title !== scoes_nav[nextsibling].url) {
+                    next = scorm_tree_node.getNodeByAttribute('title', scoes_nav[nextsibling].url);
+                    if (next === null) {
+                        next = scorm_tree_node.rootNode.children[0];
+                        next.title = scoes_nav[nextsibling].url;
+                    }
+                }
                 if (update_launch_sco) {
                     launch_sco = nextsibling;
                 }
-                return node.nextSibling;
-            } else if (node.depth > 0 && typeof scoes_nav[launch_sco].parentscoid != 'undefined') {
+                return next;
+            } else if (node.parent && node.parent.parent && typeof scoes_nav[launch_sco].parentscoid !== 'undefined') {
                 var parentscoid = scoes_nav[launch_sco].parentscoid;
+                var parent = node.parent;
+                if (parent.title !== scoes_nav[parentscoid].url) {
+                    parent = scorm_tree_node.getNodeByAttribute('title', scoes_nav[parentscoid].url);
+                    if (parent === null) {
+                        parent = scorm_tree_node.rootNode.children[0];
+                    }
+                }
                 if (update_launch_sco) {
                     launch_sco = parentscoid;
                 }
-                return scorm_skipnext(node.parent, update_launch_sco);
+                return scorm_skipnext(parent, update_launch_sco);
             }
             return null;
         };
 
         // Launch prev sco
         var scorm_launch_prev_sco = function() {
-                var result = null;
-                if (scoes_nav[launch_sco].flow == 1) {
+            var result = null;
+            if (scoes_nav[launch_sco].flow === 1) {
                 var datastring = scoes_nav[launch_sco].url + '&function=scorm_seq_flow&request=backward';
                 result = scorm_ajax_request(M.cfg.wwwroot + '/mod/scorm/datamodels/sequencinghandler.php?', datastring);
                 mod_scorm_seq = encodeURIComponent(result);
                 result = Y.JSON.parse (result);
                 if (typeof result.nextactivity.id != undefined) {
-                        var node = scorm_prev(scorm_tree_node.getHighlightedNode())
+                        var node = scorm_prev(scorm_tree_node.getSelectedNodes()[0]);
                         if (node == null) {
-                                // Avoid use of TreeView for Navigation
-                                node = scorm_tree_node.getHighlightedNode();
+                            // Avoid use of TreeView for Navigation.
+                            node = scorm_tree_node.getSelectedNodes()[0];
+                        }
+                        if (node.title !== scoes_nav[result.nextactivity.id].url) {
+                            node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[result.nextactivity.id].url);
+                            if (node === null) {
+                                node = scorm_tree_node.rootNode.children[0];
+                                node.title = scoes_nav[result.nextactivity.id].url;
+                            }
                         }
-                        node.title = scoes_nav[result.nextactivity.id].url;
                         launch_sco = result.nextactivity.id;
                         scorm_activate_item(node);
                         scorm_fixnav();
                 } else {
-                        scorm_activate_item(scorm_prev(scorm_tree_node.getHighlightedNode(), true));
+                        scorm_activate_item(scorm_prev(scorm_tree_node.getSelectedNodes()[0], true));
                 }
-             } else {
-                 scorm_activate_item(scorm_prev(scorm_tree_node.getHighlightedNode(), true));
-             }
+            } else {
+                scorm_activate_item(scorm_prev(scorm_tree_node.getSelectedNodes()[0], true));
+            }
         };
 
         // Launch next sco
         var scorm_launch_next_sco = function () {
-                var result = null;
-                if (scoes_nav[launch_sco].flow == 1) {
+            var result = null;
+            if (scoes_nav[launch_sco].flow === 1) {
                 var datastring = scoes_nav[launch_sco].url + '&function=scorm_seq_flow&request=forward';
                 result = scorm_ajax_request(M.cfg.wwwroot + '/mod/scorm/datamodels/sequencinghandler.php?', datastring);
                 mod_scorm_seq = encodeURIComponent(result);
                 result = Y.JSON.parse (result);
-                if (typeof result.nextactivity.id != undefined) {
-                        var node = scorm_next(scorm_tree_node.getHighlightedNode())
-                        if (node == null) {
-                                // Avoid use of TreeView for Navigation
-                                node = scorm_tree_node.getHighlightedNode();
-                        }
+                if (typeof result.nextactivity !== 'undefined' && typeof result.nextactivity.id !== 'undefined') {
+                    var node = scorm_next(scorm_tree_node.getSelectedNodes()[0]);
+                    if (node === null) {
+                        // Avoid use of TreeView for Navigation.
+                        node = scorm_tree_node.getSelectedNodes()[0];
+                    }
+                    node = scorm_tree_node.getNodeByAttribute('title', scoes_nav[result.nextactivity.id].url);
+                    if (node === null) {
+                        node = scorm_tree_node.rootNode.children[0];
                         node.title = scoes_nav[result.nextactivity.id].url;
-                        launch_sco = result.nextactivity.id;
-                        scorm_activate_item(node);
-                        scorm_fixnav();
+                    }
+                    launch_sco = result.nextactivity.id;
+                    scorm_activate_item(node);
+                    scorm_fixnav();
                 } else {
-                        scorm_activate_item(scorm_next(scorm_tree_node.getHighlightedNode(), true));
+                    scorm_activate_item(scorm_next(scorm_tree_node.getSelectedNodes()[0], true));
                 }
-             } else {
-                 scorm_activate_item(scorm_next(scorm_tree_node.getHighlightedNode(), true));
-             }
+            } else {
+                scorm_activate_item(scorm_next(scorm_tree_node.getSelectedNodes()[0], true));
+            }
         };
 
         mod_scorm_launch_prev_sco = scorm_launch_prev_sco;
         mod_scorm_launch_next_sco = scorm_launch_next_sco;
 
+        var cssclasses = {
+                // YUI grid class: use 100% of the available width to show only content, TOC hidden.
+                scorm_grid_content_toc_hidden: 'yui3-u-1',
+                // YUI grid class: use 1/5 of the available width to show TOC.
+                scorm_grid_toc: 'yui3-u-1-5',
+                // YUI grid class: use 1/24 of the available width to show TOC toggle button.
+                scorm_grid_toggle: 'yui3-u-1-24',
+                // YUI grid class: use 3/4 of the available width to show content, TOC visible.
+                scorm_grid_content_toc_visible: 'yui3-u-3-4',
+                // Reduce height of #scorm_object to accomodate nav buttons under content.
+                scorm_nav_under_content: 'scorm_nav_under_content',
+                disabled: 'disabled'
+            };
         // layout
-        Y.YUI2.widget.LayoutUnit.prototype.STR_COLLAPSE = M.str.moodle.hide;
-        Y.YUI2.widget.LayoutUnit.prototype.STR_EXPAND = M.str.moodle.show;
+        Y.one('#scorm_toc_title').setHTML(toc_title);
 
         if (scorm_disable_toc) {
-            scorm_layout_widget = new Y.YUI2.widget.Layout('scorm_layout', {
-                minWidth: 255,
-                minHeight: 600,
-                units: [
-                    { position: 'left', body: 'scorm_toc', header: toc_title, width: 0, resize: true, gutter: '0px 0px 0px 0px', collapse: false},
-                    { position: 'center', body: '<div id="scorm_content"></div>', gutter: '0px 0px 0px 0px', scroll: true}
-                ]
-            });
+            Y.one('#scorm_toc').addClass(cssclasses.disabled);
+            Y.one('#scorm_toc_toggle').addClass(cssclasses.disabled);
+            Y.one('#scorm_content').addClass(cssclasses.scorm_grid_content_toc_hidden);
         } else {
-            scorm_layout_widget = new Y.YUI2.widget.Layout('scorm_layout', {
-                minWidth: 255,
-                minHeight: 600,
-                units: [
-                    { position: 'left', body: 'scorm_toc', header: toc_title, width: 250, resize: true, gutter: '2px 5px 5px 2px', collapse: true, minWidth:250, maxWidth: 590},
-                    { position: 'center', body: '<div id="scorm_content"></div>', gutter: '2px 5px 5px 2px', scroll: true}
-                ]
-            });
-        }
-
-        scorm_layout_widget.render();
-        var left = scorm_layout_widget.getUnitByPosition('left');
-        if (!scorm_disable_toc) {
-            left.on('collapse', function() {
-                scorm_resize_frame();
-            });
-            left.on('expand', function() {
-                scorm_resize_frame();
-            });
+            Y.one('#scorm_toc').addClass(cssclasses.scorm_grid_toc);
+            Y.one('#scorm_toc_toggle').addClass(cssclasses.scorm_grid_toggle);
+            Y.one('#scorm_toc_toggle_btn')
+                .setHTML('&lt;')
+                .setAttribute('title', M.util.get_string('hide', 'moodle'));
+            Y.one('#scorm_content').addClass(cssclasses.scorm_grid_content_toc_visible);
+            scorm_toggle_toc(true);
         }
-        // ugly resizing hack that works around problems with resizing of iframes and objects
-        left._resize.on('startResize', function() {
-            var obj = Y.YUI2.util.Dom.get('scorm_object');
-            obj.style.display = 'none';
-        });
-        left._resize.on('endResize', function() {
-            var obj = Y.YUI2.util.Dom.get('scorm_object');
-            obj.style.display = 'block';
-            scorm_resize_frame();
-        });
 
         // hide the TOC if that is the default
         if (!scorm_disable_toc) {
             if (scorm_hide_toc == true) {
-               left.collapse();
+                Y.one('#scorm_toc').addClass(cssclasses.disabled);
+                Y.one('#scorm_toc_toggle_btn')
+                    .setHTML('&gt;')
+                    .setAttribute('title', M.util.get_string('show', 'moodle'));
+                Y.one('#scorm_content')
+                    .removeClass(cssclasses.scorm_grid_content_toc_visible)
+                    .addClass(cssclasses.scorm_grid_content_toc_hidden);
             }
         }
+
+        // TOC Resize handle.
+        var layout_width = parseInt(Y.one('#scorm_layout').getComputedStyle('width'), 10);
+        var scorm_resize_handle = new Y.Resize({
+            node: '#scorm_toc',
+            handles: 'r',
+            defMinWidth: 0.2 * layout_width
+        });
         // TOC tree
-        var tree = new Y.YUI2.widget.TreeView('scorm_tree');
+        var toc_source = Y.one('#scorm_tree > ul');
+        var toc = scorm_parse_toc_tree(toc_source);
+        // Empty container after parsing toc.
+        var el = document.getElementById('scorm_tree');
+        el.innerHTML = '';
+        var tree = new Y.TreeView({
+            container: '#scorm_tree',
+            nodes: toc,
+            multiSelect: false
+        });
         scorm_tree_node = tree;
-        tree.singleNodeHighlight = true;
-        tree.subscribe('labelClick', function(node) {
+        // Trigger after instead of on, avoid recursive calls.
+        tree.after('select', function(e) {
+            var node = e.node;
             if (node.title == '' || node.title == null) {
                 return; //this item has no navigation
             }
+            // If item is already active, return; avoid recursive calls.
+            if (Y.one('#scorm_data')) {
+                var scorm_active_url = Y.one('#scorm_object').getAttribute('src');
+                var node_full_url = M.cfg.wwwroot + '/mod/scorm/loadSCO.php?' + node.title;
+                if (node_full_url === scorm_active_url) {
+                    return;
+                }
+            }
+            // Update launch_sco.
+            if (typeof node.scoid !== 'undefined') {
+                launch_sco = node.scoid;
+            }
             scorm_activate_item(node);
             if (node.children.length) {
                 scorm_bloody_labelclick = true;
             }
         });
         if (!scorm_disable_toc) {
-            tree.subscribe('collapse', function(node) {
+            tree.on('close', function(e) {
                 if (scorm_bloody_labelclick) {
                     scorm_bloody_labelclick = false;
                     return false;
                 }
             });
-            tree.subscribe('expand', function(node) {
+            tree.subscribe('open', function(e) {
                 if (scorm_bloody_labelclick) {
                     scorm_bloody_labelclick = false;
                     return false;
                 }
             });
         }
-        tree.expandAll();
         tree.render();
+        tree.openAll();
 
         // On getting the window, always set the focus on the current item
-        Y.YUI2.util.Event.on(window, 'focus', function (e) {
-            var current = scorm_tree_node.getHighlightedNode();
-            var left = scorm_layout_widget.getUnitByPosition('left');
-            if (current && left.expand) {
-                current.focus();
+        Y.one(Y.config.win).on('focus', function (e) {
+            var current = scorm_tree_node.getSelectedNodes()[0];
+            var toc_disabled = Y.one('#scorm_toc').hasClass('disabled');
+            if (current.id && !toc_disabled) {
+                Y.one('#' + current.id).focus();
             }
         });
 
         // navigation
         if (scorm_hide_nav == false) {
-            var left = scorm_layout_widget.getUnitByPosition('left');
-            navposition = Y.YUI2.util.Dom.getXY(left);
-            navposition[1] += 200;
-            scorm_nav_panel = new Y.YUI2.widget.Panel('scorm_navpanel', { visible:true, draggable:true, close:false, xy: navposition,
-                                                                    autofillheight: "body"} );
-            scorm_nav_panel.setHeader(M.str.scorm.navigation);
-
-            //TODO: make some better&accessible buttons
-            scorm_nav_panel.setBody('<span id="scorm_nav"><button id="nav_skipprev">&lt;&lt;</button><button id="nav_prev">&lt;</button><button id="nav_up">^</button><button id="nav_next">&gt;</button><button id="nav_skipnext">&gt;&gt;</button></span>');
-            scorm_nav_panel.render();
-            scorm_buttons[0] = new Y.YUI2.widget.Button('nav_skipprev');
-            scorm_buttons[1] = new Y.YUI2.widget.Button('nav_prev');
-            scorm_buttons[2] = new Y.YUI2.widget.Button('nav_up');
-            scorm_buttons[3] = new Y.YUI2.widget.Button('nav_next');
-            scorm_buttons[4] = new Y.YUI2.widget.Button('nav_skipnext');
-            scorm_buttons[0].on('click', function(ev) {
-                scorm_activate_item(scorm_skipprev(scorm_tree_node.getHighlightedNode(), true));
+            // TODO: make some better&accessible buttons.
+            var navbuttonshtml = '<span id="scorm_nav"><button id="nav_skipprev">&lt;&lt;</button>&nbsp;<button id="nav_prev">&lt;</button>'
+                    + '&nbsp;<button id="nav_up">^</button>&nbsp;<button id="nav_next">&gt;</button>'
+                    + '&nbsp;<button id="nav_skipnext">&gt;&gt;</button></span>';
+            if (nav_display === 1) {
+                Y.one('#scorm_navpanel').setHTML(navbuttonshtml);
+            } else {
+                // Nav panel is floating type.
+                var navposition = null;
+                if (navposition_left < 0 && navposition_top < 0) {
+                    // Set default XY.
+                    navposition = Y.one('#scorm_toc').getXY();
+                    navposition[1] += 200;
+                } else {
+                    // Set user defined XY.
+                    navposition = [];
+                    navposition[0] = parseInt(navposition_left, 10);
+                    navposition[1] = parseInt(navposition_top, 10);
+                }
+                scorm_nav_panel = new Y.Panel({
+                    fillHeight: "body",
+                    headerContent: M.util.get_string('navigation', 'scorm'),
+                    visible: true,
+                    xy: navposition,
+                    zIndex: 999
+                });
+                scorm_nav_panel.set('bodyContent', navbuttonshtml);
+                scorm_nav_panel.removeButton('close');
+                scorm_nav_panel.plug(Y.Plugin.Drag, {handles: ['.yui3-widget-hd']});
+                scorm_nav_panel.render();
+            }
+
+            scorm_buttons[0] = new Y.Button({
+                srcNode: '#nav_skipprev',
+                render: true,
+                on: {
+                        'click' : function(ev) {
+                            scorm_activate_item(scorm_skipprev(scorm_tree_node.getSelectedNodes()[0], true));
+                        },
+                        'keydown' : function(ev) {
+                            if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) {
+                                scorm_activate_item(scorm_skipprev(scorm_tree_node.getSelectedNodes()[0], true));
+                            }
+                        }
+                    }
             });
-            scorm_buttons[1].on('click', function(ev) {
-                scorm_launch_prev_sco();
+            scorm_buttons[1] = new Y.Button({
+                srcNode: '#nav_prev',
+                render: true,
+                on: {
+                    'click' : function(ev) {
+                        scorm_launch_prev_sco();
+                    },
+                    'keydown' : function(ev) {
+                        if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) {
+                            scorm_launch_prev_sco();
+                        }
+                    }
+                }
             });
-            scorm_buttons[2].on('click', function(ev) {
-                scorm_activate_item(scorm_up(scorm_tree_node.getHighlightedNode(), true));
+            scorm_buttons[2] = new Y.Button({
+                srcNode: '#nav_up',
+                render: true,
+                on: {
+                    'click' : function(ev) {
+                        scorm_activate_item(scorm_up(scorm_tree_node.getSelectedNodes()[0], true));
+                    },
+                    'keydown' : function(ev) {
+                        if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) {
+                            scorm_activate_item(scorm_up(scorm_tree_node.getSelectedNodes()[0], true));
+                        }
+                    }
+                }
             });
-            scorm_buttons[3].on('click', function(ev) {
-                scorm_launch_next_sco();
+            scorm_buttons[3] = new Y.Button({
+                srcNode: '#nav_next',
+                render: true,
+                on: {
+                    'click' : function(ev) {
+                        scorm_launch_next_sco();
+                    },
+                    'keydown' : function(ev) {
+                        if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) {
+                            scorm_launch_next_sco();
+                        }
+                    }
+                }
             });
-            scorm_buttons[4].on('click', function(ev) {
-                scorm_activate_item(scorm_skipnext(scorm_tree_node.getHighlightedNode(), true));
+            scorm_buttons[4] = new Y.Button({
+                srcNode: '#nav_skipnext',
+                render: true,
+                on: {
+                    'click' : function(ev) {
+                        scorm_activate_item(scorm_skipnext(scorm_tree_node.getSelectedNodes()[0], true));
+                    },
+                    'keydown' : function(ev) {
+                        if (ev.domEvent.keyCode === 13 || ev.domEvent.keyCode === 32) {
+                            scorm_activate_item(scorm_skipnext(scorm_tree_node.getSelectedNodes()[0], true));
+                        }
+                    }
+                }
             });
-            scorm_nav_panel.render();
         }
 
         // finally activate the chosen item
-        var scorm_first_url = tree.getRoot().children[0];
+        var scorm_first_url = null;
+        if (tree.rootNode.children[0].title !== scoes_nav[launch_sco].url) {
+            var node = tree.getNodeByAttribute('title', scoes_nav[launch_sco].url);
+            if (node !== null) {
+                scorm_first_url = node;
+            }
+        } else {
+            scorm_first_url = tree.rootNode.children[0];
+        }
+
         if (scorm_first_url == null) { // This is probably a single sco with no children (AICC Direct uses this).
-            scorm_first_url = tree.getRoot();
+            scorm_first_url = tree.rootNode;
         }
         scorm_first_url.title = scoes_nav[launch_sco].url;
         scorm_activate_item(scorm_first_url);
 
         // resizing
-        scorm_resize_layout(false);
+        scorm_resize_layout();
 
+        // Collapse/expand TOC.
+        Y.one('#scorm_toc_toggle').on('click', scorm_toggle_toc);
+        Y.one('#scorm_toc_toggle').on('key', scorm_toggle_toc, 'down:enter,32');
         // fix layout if window resized
-        window.onresize = function() {
-            scorm_resize_layout(true);
-        };
+        Y.on("windowresize", function() {
+            scorm_resize_layout();
+            var toc_displayed = Y.one('#scorm_toc').getComputedStyle('display') !== 'none';
+            if ((!scorm_disable_toc && !scorm_hide_toc) || toc_displayed) {
+                scorm_toggle_toc(true);
+            }
+            // Set 20% as minWidth constrain of TOC.
+            var layout_width = parseInt(Y.one('#scorm_layout').getComputedStyle('width'), 10);
+            scorm_resize_handle.set('defMinWidth', 0.2 * layout_width);
+        });
+        // On resize drag, change width of scorm_content.
+        scorm_resize_handle.on('resize:resize', function() {
+            var tocwidth = parseInt(Y.one('#scorm_toc').getComputedStyle('width'), 10);
+            var layoutwidth = parseInt(Y.one('#scorm_layout').getStyle('width'), 10);
+            Y.one('#scorm_content').setStyle('width', (layoutwidth - tocwidth - 60));
+        });
     });
 };
 
 M.mod_scorm.connectPrereqCallback = {
 
-    success: function(o) {
-        YUI().use('yui2-treeview', 'yui2-layout', function(Y) {
-            // MDL-29159 The core version of getContentHtml doesn't escape text properly.
-            Y.YUI2.widget.TextNode.prototype.getContentHtml = function() {
-                var sb = [];
-                sb[sb.length] = this.href ? '<a' : '<span';
-                sb[sb.length] = ' id="' + Y.YUI2.lang.escapeHTML(this.labelElId) + '"';
-                sb[sb.length] = ' class="' + Y.YUI2.lang.escapeHTML(this.labelStyle) + '"';
-                if (this.href) {
-                    sb[sb.length] = ' href="' + Y.YUI2.lang.escapeHTML(this.href) + '"';
-                    sb[sb.length] = ' target="' + Y.YUI2.lang.escapeHTML(this.target) + '"';
-                }
-                if (this.title) {
-                    sb[sb.length] = ' title="' + Y.YUI2.lang.escapeHTML(this.title) + '"';
-                }
-                sb[sb.length] = ' >';
-                sb[sb.length] = this.label;
-                sb[sb.length] = this.href?'</a>':'</span>';
-                return sb.join("");
-            };
-
-            if (o.responseText !== undefined) {
-                var tree = new Y.YUI2.widget.TreeView('scorm_tree');
-                if (scorm_tree_node && o.responseText) {
-                    var hnode = scorm_tree_node.getHighlightedNode();
-                    var hidx = null;
-                    if (hnode) {
-                        hidx = hnode.index + scorm_tree_node.getNodeCount();
-                    }
-                    // all gone
-                    var root_node = scorm_tree_node.getRoot();
-                    while (root_node.children.length > 0) {
-                        scorm_tree_node.removeNode(root_node.children[0]);
-                    }
+    success: function(id, o) {
+        if (o.responseText !== undefined) {
+            var snode = null,
+                stitle = null;
+            if (scorm_tree_node && o.responseText) {
+                snode = scorm_tree_node.getSelectedNodes()[0];
+                stitle = null;
+                if (snode) {
+                    stitle = snode.title;
                 }
-                // make sure the temporary tree element is not there
-                var el_old_tree = document.getElementById('scormtree123');
-                if (el_old_tree) {
-                    el_old_tree.parentNode.removeChild(el_old_tree);
-                }
-                var el_new_tree = document.createElement('div');
-                var pagecontent = document.getElementById("page-content");
-                el_new_tree.setAttribute('id','scormtree123');
-                el_new_tree.innerHTML = o.responseText;
-                // make sure it doesnt show
-                el_new_tree.style.display = 'none';
-                pagecontent.appendChild(el_new_tree)
-                // ignore the first level element as this is the title
-                var startNode = el_new_tree.firstChild.firstChild;
-                if (startNode.tagName == 'LI') {
-                    // go back to the beginning
-                    startNode = el_new_tree;
-                }
-                //var sXML = new XMLSerializer().serializeToString(startNode);
-                scorm_tree_node.buildTreeFromMarkup('scormtree123');
-                var el = document.getElementById('scormtree123');
-                el.parentNode.removeChild(el);
-                scorm_tree_node.expandAll();
-                scorm_tree_node.render();
-                if (hidx != null) {
-                    hnode = scorm_tree_node.getNodeByIndex(hidx);
-                    if (hnode) {
-                        hnode.highlight();
-                        var left = scorm_layout_widget.getUnitByPosition('left');
-                        if (left.expand) {
-                            hnode.focus();
+                // All gone with clear, add new root node.
+                scorm_tree_node.clear(scorm_tree_node.createNode());
+            }
+            // Make sure the temporary tree element is not there.
+            var el_old_tree = document.getElementById('scormtree123');
+            if (el_old_tree) {
+                el_old_tree.parentNode.removeChild(el_old_tree);
+            }
+            var el_new_tree = document.createElement('div');
+            var pagecontent = document.getElementById("page-content");
+            el_new_tree.setAttribute('id','scormtree123');
+            el_new_tree.innerHTML = o.responseText;
+            // Make sure it does not show.
+            el_new_tree.style.display = 'none';
+            pagecontent.appendChild(el_new_tree);
+            // Ignore the first level element as this is the title.
+            var startNode = el_new_tree.firstChild.firstChild;
+            if (startNode.tagName == 'LI') {
+                // Go back to the beginning.
+                startNode = el_new_tree;
+            }
+            var toc_source = Y.one('#scormtree123 > ul');
+            var toc = mod_scorm_parse_toc_tree(toc_source);
+            scorm_tree_node.appendNode(scorm_tree_node.rootNode, toc);
+            var el = document.getElementById('scormtree123');
+            el.parentNode.removeChild(el);
+            scorm_tree_node.render();
+            scorm_tree_node.openAll();
+            if (stitle !== null) {
+                snode = scorm_tree_node.getNodeByAttribute('title', stitle);
+                // Do not let destroyed node to be selected.
+                if (snode && !snode.state.destroyed) {
+                    snode.select();
+                    var toc_disabled = Y.one('#scorm_toc').hasClass('disabled');
+                    if (!toc_disabled) {
+                        if (!snode.state.selected) {
+                            snode.select();
                         }
                     }
                 }
             }
-        });
+        }
     },
 
-    failure: function(o) {
+    failure: function(id, o) {
         // TODO: do some sort of error handling.
     }
 
index 6a5b84f..d5e4b34 100644 (file)
@@ -84,6 +84,13 @@ $forcejs = get_config('scorm', 'forcejavascript');
 if (!empty($forcejs)) {
     $PAGE->add_body_class('forcejavascript');
 }
+$collapsetocwinsize = get_config('scorm', 'collapsetocwinsize');
+if (empty($collapsetocwinsize)) {
+    // Set as default window size to collapse TOC.
+    $collapsetocwinsize = 767;
+} else {
+    $collapsetocwinsize = intval($collapsetocwinsize);
+}
 
 require_login($course, false, $cm);
 
@@ -246,7 +253,7 @@ if ($result->prerequisites) {
 ?>
     </div> <!-- SCORM page -->
 <?php
-$scoes = scorm_get_toc_object($USER, $scorm, "", $sco->id, $mode, $attempt);
+$scoes = scorm_get_toc_object($USER, $scorm, $currentorg, $sco->id, $mode, $attempt);
 $adlnav = scorm_get_adlnav_json($scoes['scoes']);
 
 if (empty($scorm->popup) || $displaymode == 'popup') {
@@ -258,7 +265,9 @@ if (empty($scorm->popup) || $displaymode == 'popup') {
         'fullpath' => '/mod/scorm/module.js',
         'requires' => array('json'),
     );
-    $PAGE->requires->js_init_call('M.mod_scorm.init', array($scorm->hidenav, $scorm->hidetoc, $result->toctitle, $name, $sco->id, $adlnav), false, $jsmodule);
+    $scorm->nav = intval($scorm->nav);
+    $PAGE->requires->js_init_call('M.mod_scorm.init', array($scorm->nav, $scorm->navpositionleft, $scorm->navpositiontop, $scorm->hidetoc,
+                                                            $collapsetocwinsize, $result->toctitle, $name, $sco->id, $adlnav), false, $jsmodule);
 }
 if (!empty($forcejs)) {
     echo $OUTPUT->box(get_string("forcejavascriptmessage", "scorm"), "generalbox boxaligncenter forcejavascriptmessage");
index aacb8e2..8781dd9 100644 (file)
@@ -60,9 +60,21 @@ if ($ADMIN->fulltree) {
         get_string('hidetoc', 'scorm'), get_string('hidetocdesc', 'scorm'),
         array('value' => 0, 'adv' => true), scorm_get_hidetoc_array()));
 
-    $settings->add(new admin_setting_configselect_with_advanced('scorm/hidenav',
-        get_string('hidenav', 'scorm'), get_string('hidenavdesc', 'scorm'),
-        array('value' => 0, 'adv' => false), $yesno));
+    $settings->add(new admin_setting_configselect_with_advanced('scorm/nav',
+        get_string('nav', 'scorm'), get_string('navdesc', 'scorm'),
+        array('value' => SCORM_NAV_UNDER_CONTENT, 'adv' => true), scorm_get_navigation_display_array()));
+
+    $settings->add(new admin_setting_configtext_with_advanced('scorm/navpositionleft',
+        get_string('fromleft', 'scorm'), get_string('navpositionleft', 'scorm'),
+        array('value' => -100, 'adv' => true)));
+
+    $settings->add(new admin_setting_configtext_with_advanced('scorm/navpositiontop',
+        get_string('fromtop', 'scorm'), get_string('navpositiontop', 'scorm'),
+        array('value' => -100, 'adv' => true)));
+
+    $settings->add(new admin_setting_configtext_with_advanced('scorm/collapsetocwinsize',
+        get_string('collapsetocwinsize', 'scorm'), get_string('collapsetocwinsizedesc', 'scorm'),
+        array('value' => 767, 'adv' => true)));
 
     $settings->add(new admin_setting_configselect_with_advanced('scorm/displayattemptstatus',
         get_string('displayattemptstatus', 'scorm'), get_string('displayattemptstatusdesc', 'scorm'),
index c36fe31..77d694b 100644 (file)
@@ -3,24 +3,32 @@
 .path-mod-scorm .scorm-center {text-align: center;}
 .path-mod-scorm .scorm-right {text-align: right;}
 .path-mod-scorm .scoframe {position: relative;width: 100%;height: 100%;}
+.ios #scormpage #scorm_content {-webkit-overflow-scrolling: touch; overflow: scroll;}
 
-#page-mod-scorm-player #scormobject {height: 100%;}
 #page-mod-scorm-player #scormtop {position: relative;width: 100%;height: 30px;}
 #page-mod-scorm-player #scormbrowse {position: absolute;left: 5px;top: 0px;}
 #page-mod-scorm-player #scormnav {position: absolute;right: 5px;top: 0px;text-align: center;top: 3px;width: 100%;}
 #page-mod-scorm-player #scormbox {width: 74%;height: 100%;position: absolute;right: 0px;top: 0px;}
 #page-mod-scorm-player #scormpage {position: relative;width: 100%;height: 100%;}
-#page-mod-scorm-player #scormpage #toctree {position:relative;width:100%;overflow-x: auto;overflow-y: auto;}
+#page-mod-scorm-player #scormpage #toctree {position:relative;width:100%;}
 #page-mod-scorm-player #tocbox {position: relative;left: 0px;width: 100%;height: 100%;font-size: 0.8em;}
 #page-mod-scorm-player #toctree { overflow: visible; }
 #page-mod-scorm-player #tochead {position: relative;text-align: center;top: 3px;height: 30px;}
 #page-mod-scorm-player #scormpage .scoframe {frameborder: 0;}
+#page-mod-scorm-player #scormpage #scorm_object {border: none; width: 98%; height: 98%;}
+#page-mod-scorm-player #scormpage #scorm_object.scorm_nav_under_content {height: 95%;}
+#page-mod-scorm-player #scormpage #scorm_content {height: 100%;}
+#page-mod-scorm-player #scormpage #scorm_toc {position: relative;}
+#page-mod-scorm-player #scormpage #scorm_toc_title {font-size: 1.2em; font-weight: bold;}
+#page-mod-scorm-player #scormpage #scorm_tree {border-right: 5px solid rgb(239, 245, 255);}
+#page-mod-scorm-player #scormpage #scorm_navpanel {text-align: center;}
 
 #page-mod-scorm-player .toc,
 #page-mod-scorm-player .no-toc {width: 100%;}
 #page-mod-scorm-player .structlist  {list-style-type: none;white-space: nowrap;}
 #page-mod-scorm-player .structurelist {position: relative;list-style-type: none;width: 96%;margin:0;padding:0;}
 #page-mod-scorm-player .structurelist ul {padding-left: 0.5em;margin-left: 0.5em;}
+#page-mod-scorm-player #scormpage #scorm_toc.disabled {display:none}
 
 #page-mod-scorm-view .structurelist  {list-style-type: none;white-space: nowrap;}
 #page-mod-scorm-view .structurelist  {list-style-type: none;white-space: nowrap;}
     word-break: break-all;
 }
 
+#page-mod-scorm-player #scormpage span.yui3-treeview-icon {display: none;}
+#page-mod-scorm-player #scormpage li.yui3-treeview-has-children > div.yui3-treeview-row > span.yui3-treeview-icon {display: block;}
+
+#page-mod-scorm-player #scormpage div.yui3-u-1,
+#page-mod-scorm-player #scormpage div.yui3-u-3-4,
+#page-mod-scorm-player #scormpage div.yui3-u-1-5,
+#page-mod-scorm-player #scormpage div.yui3-u-1-24 {
+    display: inline-block;
+    *display: inline;
+    zoom: 1;
+    letter-spacing: normal;
+    word-spacing: normal;
+    vertical-align: top;
+    text-rendering: auto;
+}
+
+#page-mod-scorm-player #scormpage div.yui3-u-1 {display: block;}
+
+#page-mod-scorm-player #scormpage div.yui3-u-3-4 {width: 75%;}
+
+#page-mod-scorm-player #scormpage div.yui3-u-1-5 {width: 20%;}
+
+#page-mod-scorm-player #scormpage div.yui3-u-1-24 {width: 4.1666%;}
+
+#page-mod-scorm-player #scormpage div.yui3-g-r {*letter-spacing: normal; *word-spacing: -0.43em;}
+
+/**
+* Opera as of 12 on Windows needs word-spacing.
+* The ".opera-only" selector is used to prevent actual prefocus styling
+* and is not required in markup.
+*/
+#page-mod-scorm-player .opera-only :-o-prefocus,
+
+#page-mod-scorm-player #scormpage div.yui3-g-r img {max-width: 100%;}
index 56084ad..3b43237 100644 (file)
@@ -25,7 +25,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$module->version   = 2013081303;       // The current module version (Date: YYYYMMDDXX)
+$module->version   = 2013090100;       // The current module version (Date: YYYYMMDDXX)
 $module->requires  = 2013050100;    // Requires this Moodle version
 $module->component = 'mod_scorm'; // Full name of the plugin (used for diagnostics)
 $module->cron      = 300;