Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

MDL-31096 Convert course resource/section javascript to YUI3 Module

AMOS BEGIN
  MOV [hideweekfromothers,moodle],[hidefromothers,format_week]
  MOV [showweekfromothers,moodle],[showfromothers,format_week]
  MOV [hidetopicfromothers,moodle],[hidefromothers,format_topics]
  MOV [showtopicfromothers,moodle],[showfromothers,format_topics]
AMOS END
  • Loading branch information...
commit ebaa29d107d3b15520e6e841201f281934df044f 1 parent cd6081f
Andrew Nicols authored January 05, 2012
12  course/format/topics/format.php
@@ -55,8 +55,8 @@
55 55
 $editing         = $PAGE->user_is_editing();
56 56
 
57 57
 if ($editing) {
58  
-    $strtopichide = get_string('hidetopicfromothers');
59  
-    $strtopicshow = get_string('showtopicfromothers');
  58
+    $strtopichide = get_string('hidefromothers', 'format_topics');
  59
+    $strtopicshow = get_string('showfromothers', 'format_topics');
60 60
     $strmarkthistopic = get_string('markthistopic');
61 61
     $strmarkedthistopic = get_string('markedthistopic');
62 62
     $strmoveup   = get_string('moveup');
@@ -189,16 +189,16 @@
189 189
         if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
190 190
 
191 191
             if ($course->marker == $section) {  // Show the "light globe" on/off
192  
-                echo '<a href="view.php?id='.$course->id.'&amp;marker=0&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strmarkedthistopic.'">'.'<img src="'.$OUTPUT->pix_url('i/marked') . '" alt="'.$strmarkedthistopic.'" class="icon"/></a><br />';
  192
+                echo '<a href="view.php?id='.$course->id.'&amp;marker=0&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strmarkedthistopic.'" class="editing_highlight">'.'<img src="'.$OUTPUT->pix_url('i/marked') . '" alt="'.$strmarkedthistopic.'" class="icon"/></a><br />';
193 193
             } else {
194  
-                echo '<a href="view.php?id='.$course->id.'&amp;marker='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strmarkthistopic.'">'.'<img src="'.$OUTPUT->pix_url('i/marker') . '" alt="'.$strmarkthistopic.'" class="icon"/></a><br />';
  194
+                echo '<a href="view.php?id='.$course->id.'&amp;marker='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strmarkthistopic.'" class="editing_highlight">'.'<img src="'.$OUTPUT->pix_url('i/marker') . '" alt="'.$strmarkthistopic.'" class="icon"/></a><br />';
195 195
             }
196 196
 
197 197
             if ($thissection->visible) {        // Show the hide/show eye
198  
-                echo '<a href="view.php?id='.$course->id.'&amp;hide='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strtopichide.'">'.
  198
+                echo '<a href="view.php?id='.$course->id.'&amp;hide='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strtopichide.'" class="editing_showhide">'.
199 199
                      '<img src="'.$OUTPUT->pix_url('i/hide') . '" class="icon hide" alt="'.$strtopichide.'" /></a><br />';
200 200
             } else {
201  
-                echo '<a href="view.php?id='.$course->id.'&amp;show='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strtopicshow.'">'.
  201
+                echo '<a href="view.php?id='.$course->id.'&amp;show='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strtopicshow.'" class="editing_showhide">'.
202 202
                      '<img src="'.$OUTPUT->pix_url('i/show') . '" class="icon hide" alt="'.$strtopicshow.'" /></a><br />';
203 203
             }
204 204
             if ($section > 1) {                       // Add a arrow to move section up
2  course/format/topics/lang/en/format_topics.php
@@ -28,3 +28,5 @@
28 28
 $string['section0name'] = 'General';
29 29
 $string['page-course-view-topics'] = 'Any course main page in topics format';
30 30
 $string['page-course-view-topics-x'] = 'Any course page in topics format';
  31
+$string['hidefromothers'] = 'Hide topic';
  32
+$string['showfromothers'] = 'Show topic';
8  course/format/weeks/format.php
@@ -47,8 +47,8 @@
47 47
     $editing         = $PAGE->user_is_editing();
48 48
 
49 49
     if ($editing) {
50  
-        $strweekhide = get_string('hideweekfromothers');
51  
-        $strweekshow = get_string('showweekfromothers');
  50
+        $strweekhide = get_string('hidefromothers', 'format_topics');
  51
+        $strweekshow = get_string('showfromothers', 'format_topics');
52 52
         $strmoveup   = get_string('moveup');
53 53
         $strmovedown = get_string('movedown');
54 54
     }
@@ -194,10 +194,10 @@
194 194
 
195 195
             if ($PAGE->user_is_editing() && has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $course->id))) {
196 196
                 if ($thissection->visible) {        // Show the hide/show eye
197  
-                    echo '<a href="view.php?id='.$course->id.'&amp;hide='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strweekhide.'">'.
  197
+                    echo '<a href="view.php?id='.$course->id.'&amp;hide='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strweekhide.'" class="editing_showhide">'.
198 198
                          '<img src="'.$OUTPUT->pix_url('i/hide') . '" class="icon hide" alt="'.$strweekhide.'" /></a><br />';
199 199
                 } else {
200  
-                    echo '<a href="view.php?id='.$course->id.'&amp;show='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strweekshow.'">'.
  200
+                    echo '<a href="view.php?id='.$course->id.'&amp;show='.$section.'&amp;sesskey='.sesskey().'#section-'.$section.'" title="'.$strweekshow.'" class="editing_showhide">'.
201 201
                          '<img src="'.$OUTPUT->pix_url('i/show') . '" class="icon hide" alt="'.$strweekshow.'" /></a><br />';
202 202
                 }
203 203
                 if ($section > 1) {                       // Add a arrow to move section up
2  course/format/weeks/lang/en/format_weeks.php
@@ -28,3 +28,5 @@
28 28
 $string['section0name'] = 'General';
29 29
 $string['page-course-view-weeks'] = 'Any course main page in weeks format';
30 30
 $string['page-course-view-weeks-x'] = 'Any course page in weeks format';
  31
+$string['hidefromothers'] = 'Hide week';
  32
+$string['showfromothers'] = 'Show week';
112  course/lib.php
@@ -1355,10 +1355,16 @@ function course_set_marker($courseid, $marker) {
1355 1355
 /**
1356 1356
  * For a given course section, marks it visible or hidden,
1357 1357
  * and does the same for every activity in that section
  1358
+ *
  1359
+ * @param int $courseid course id
  1360
+ * @param int $sectionnumber The section number to adjust
  1361
+ * @param int $visibility The new visibility
  1362
+ * @return array A list of resources which were hidden in the section
1358 1363
  */
1359 1364
 function set_section_visible($courseid, $sectionnumber, $visibility) {
1360 1365
     global $DB;
1361 1366
 
  1367
+    $resourcestotoggle = array();
1362 1368
     if ($section = $DB->get_record("course_sections", array("course"=>$courseid, "section"=>$sectionnumber))) {
1363 1369
         $DB->set_field("course_sections", "visible", "$visibility", array("id"=>$section->id));
1364 1370
         if (!empty($section->sequence)) {
@@ -1368,7 +1374,19 @@ function set_section_visible($courseid, $sectionnumber, $visibility) {
1368 1374
             }
1369 1375
         }
1370 1376
         rebuild_course_cache($courseid);
  1377
+
  1378
+        // Determine which modules are visible for AJAX update
  1379
+        if (!empty($modules)) {
  1380
+            list($insql, $params) = $DB->get_in_or_equal($modules);
  1381
+            $select = 'id ' . $insql . ' AND visible = ?';
  1382
+            array_push($params, $visibility);
  1383
+            if (!$visibility) {
  1384
+                $select .= ' AND visibleold = 1';
  1385
+            }
  1386
+            $resourcestotoggle = $DB->get_fieldset_select('course_modules', 'id', $select, $params);
  1387
+        }
1371 1388
     }
  1389
+    return $resourcestotoggle;
1372 1390
 }
1373 1391
 
1374 1392
 /**
@@ -4386,3 +4404,97 @@ function course_page_type_list($pagetype, $parentcontext, $currentcontext) {
4386 4404
         );
4387 4405
     }
4388 4406
 }
  4407
+
  4408
+/**
  4409
+ * Include the relevant javascript and language strings for the resource
  4410
+ * toolbox YUI module
  4411
+ *
  4412
+ * @param integer $id The ID of the course being applied to
  4413
+ * @param array $modules An array containing the names of the modules in
  4414
+ *                       use on the page
  4415
+ * @param object $config An object containing configuration parameters for ajax modules including:
  4416
+ *          * resourceurl   The URL to post changes to for resource changes
  4417
+ *          * sectionurl    The URL to post changes to for section changes
  4418
+ *          * pageparams    Additional parameters to pass through in the post
  4419
+ * @return void
  4420
+ */
  4421
+function include_course_ajax($course, $modules = array(), $config = null) {
  4422
+    global $PAGE, $CFG, $USER;
  4423
+
  4424
+    // Ensure that ajax should be included
  4425
+    $courseformatajaxsupport = course_format_ajax_support($course->format);
  4426
+    if (!$CFG->enablecourseajax
  4427
+        || !$PAGE->theme->enablecourseajax
  4428
+        || !$CFG->enableajax
  4429
+        || empty($USER->editing)
  4430
+        || !$PAGE->user_is_editing()
  4431
+        || ($course->id != SITEID && !$courseformatajaxsupport->capable)) {
  4432
+        return;
  4433
+    }
  4434
+
  4435
+    if (!$config) {
  4436
+        $config = new stdClass();
  4437
+    }
  4438
+
  4439
+    // The URL to use for resource changes
  4440
+    if (!isset($config->resourceurl)) {
  4441
+        $config->resourceurl = '/course/rest.php';
  4442
+    }
  4443
+
  4444
+    // The URL to use for section changes
  4445
+    if (!isset($config->sectionurl)) {
  4446
+        $config->sectionurl = '/course/rest.php';
  4447
+    }
  4448
+
  4449
+    // Any additional parameters which need to be included on page submission
  4450
+    if (!isset($config->pageparams)) {
  4451
+        $config->pageparams = array();
  4452
+    }
  4453
+
  4454
+    // Include toolboxes
  4455
+    $PAGE->requires->yui_module('moodle-course-toolboxes',
  4456
+            'M.course.init_resource_toolbox',
  4457
+            array(array(
  4458
+                'courseid' => $course->id,
  4459
+                'ajaxurl' => $config->resourceurl,
  4460
+                'config' => $config,
  4461
+            ))
  4462
+    );
  4463
+    $PAGE->requires->yui_module('moodle-course-toolboxes',
  4464
+            'M.course.init_section_toolbox',
  4465
+            array(array(
  4466
+                'courseid' => $course->id,
  4467
+                'format' => $course->format,
  4468
+                'ajaxurl' => $config->sectionurl,
  4469
+                'config' => $config,
  4470
+            ))
  4471
+    );
  4472
+
  4473
+    // Require various strings for the command toolbox
  4474
+    $PAGE->requires->strings_for_js(array(
  4475
+            'moveleft',
  4476
+            'deletechecktype',
  4477
+            'deletechecktypename',
  4478
+            'show',
  4479
+            'hide',
  4480
+            'groupsnone',
  4481
+            'groupsvisible',
  4482
+            'groupsseparate',
  4483
+            'clicktochangeinbrackets',
  4484
+            'markthistopic',
  4485
+            'markedthistopic',
  4486
+        ), 'moodle');
  4487
+
  4488
+    // Include format-specific strings
  4489
+    if ($course->id != SITEID) {
  4490
+        $PAGE->requires->strings_for_js(array(
  4491
+                'showfromothers',
  4492
+                'hidefromothers',
  4493
+            ), 'format_' . $course->format);
  4494
+    }
  4495
+
  4496
+    // For confirming resource deletion we need the name of the module in question
  4497
+    foreach ($modules as $module => $modname) {
  4498
+        $PAGE->requires->string_for_js('pluginname', $module);
  4499
+    }
  4500
+}
15  course/rest.php
@@ -87,7 +87,8 @@
87 87
 
88 88
                 switch ($field) {
89 89
                     case 'visible':
90  
-                        set_section_visible($course->id, $id, $value);
  90
+                        $resourcestotoggle = set_section_visible($course->id, $id, $value);
  91
+                        echo json_encode(array('resourcestotoggle' => $resourcestotoggle));
91 92
                         break;
92 93
 
93 94
                     case 'move':
@@ -115,20 +116,14 @@
115 116
                         set_coursemodule_groupmode($cm->id, $value);
116 117
                         break;
117 118
 
118  
-                    case 'indentleft':
  119
+                    case 'indent':
119 120
                         require_capability('moodle/course:manageactivities', $modcontext);
120  
-                        if ($cm->indent > 0) {
121  
-                            $cm->indent--;
  121
+                        $cm->indent = $value;
  122
+                        if ($cm->indent >= 0) {
122 123
                             $DB->update_record('course_modules', $cm);
123 124
                         }
124 125
                         break;
125 126
 
126  
-                    case 'indentright':
127  
-                        require_capability('moodle/course:manageactivities', $modcontext);
128  
-                        $cm->indent++;
129  
-                        $DB->update_record('course_modules', $cm);
130  
-                        break;
131  
-
132 127
                     case 'move':
133 128
                         require_capability('moodle/course:manageactivities', $modcontext);
134 129
                         if (!$section = $DB->get_record('course_sections', array('course'=>$course->id, 'section'=>$sectionid))) {
39  course/view.php
@@ -162,32 +162,6 @@
162 162
         redirect($CFG->wwwroot .'/');
163 163
     }
164 164
 
165  
-    // AJAX-capable course format?
166  
-    $useajax = false;
167  
-    $formatajax = course_format_ajax_support($course->format);
168  
-
169  
-    if (!empty($CFG->enablecourseajax)
170  
-            and $formatajax->capable
171  
-            and !empty($USER->editing)
172  
-            and ajaxenabled($formatajax->testedbrowsers)
173  
-            and $PAGE->theme->enablecourseajax
174  
-            and has_capability('moodle/course:manageactivities', $context)) {
175  
-        $PAGE->requires->yui2_lib('dragdrop');
176  
-        $PAGE->requires->yui2_lib('connection');
177  
-        $PAGE->requires->yui2_lib('selector');
178  
-        $PAGE->requires->js('/lib/ajax/block_classes.js', true);
179  
-        $PAGE->requires->js('/lib/ajax/section_classes.js', true);
180  
-
181  
-        // Okay, global variable alert. VERY UGLY. We need to create
182  
-        // this object here before the <blockname>_print_block()
183  
-        // function is called, since that function needs to set some
184  
-        // stuff in the javascriptportal object.
185  
-        $COURSE->javascriptportal = new jsportal();
186  
-        $useajax = true;
187  
-    }
188  
-
189  
-    $CFG->blocksdrag = $useajax;   // this will add a new class to the header so we can style differently
190  
-
191 165
     $completion = new completion_info($course);
192 166
     if ($completion->is_enabled() && ajaxenabled()) {
193 167
         $PAGE->requires->string_for_js('completion-title-manual-y', 'completion');
@@ -257,16 +231,7 @@
257 231
 
258 232
     echo html_writer::end_tag('div');
259 233
 
260  
-    // Use AJAX?
261  
-    if ($useajax && has_capability('moodle/course:manageactivities', $context)) {
262  
-        // At the bottom because we want to process sections and activities
263  
-        // after the relevant html has been generated. We're forced to do this
264  
-        // because of the way in which lib/ajax/ajaxcourse.js is written.
265  
-        echo html_writer::script(false, new moodle_url('/lib/ajax/ajaxcourse.js'));
266  
-        $COURSE->javascriptportal->print_javascript($course->id);
267  
-    }
268  
-
  234
+    // Include the command toolbox YUI module
  235
+    include_course_ajax($course, $modnamesused);
269 236
 
270 237
     echo $OUTPUT->footer();
271  
-
272  
-
691  course/yui/toolboxes/toolboxes.js
... ...
@@ -0,0 +1,691 @@
  1
+YUI.add('moodle-course-toolboxes', function(Y) {
  2
+    WAITICON = {'pix':"i/loading_small",'component':'moodle'};
  3
+    // The CSS selectors we use
  4
+    var CSS = {
  5
+        ACTIVITYLI : 'li.activity',
  6
+        COMMANDSPAN : 'span.commands',
  7
+        DELETE : 'a.editing_delete',
  8
+        DIMCLASS : 'dimmed',
  9
+        DIMMEDLABELCLASS : 'dimmed_text',
  10
+        EDITTITLECLASS : 'edittitle',
  11
+        GENERICICONCLASS : 'iconsmall',
  12
+        GROUPSNONE : 'a.editing_groupsnone',
  13
+        GROUPSSEPARATE : 'a.editing_groupsseparate',
  14
+        GROUPSVISIBLE : 'a.editing_groupsvisible',
  15
+        HASLABEL : 'label',
  16
+        HIDE : 'a.editing_hide',
  17
+        HIGHLIGHT : 'a.editing_highlight',
  18
+        INSTANCENAME : 'span.instancename',
  19
+        LIGHTBOX : 'lightbox',
  20
+        MODINDENTCOUNT : 'mod-indent-',
  21
+        MODINDENTDIV : 'div.mod-indent',
  22
+        MODULEIDPREFIX : 'module-',
  23
+        MOVELEFT : 'a.editing_moveleft',
  24
+        MOVELEFTCLASS : 'editing_moveleft',
  25
+        MOVERIGHT : 'a.editing_moveright',
  26
+        PAGECONTENT : 'div#page-content',
  27
+        RIGHTDIV : 'div.right',
  28
+        SECTIONHIDDENCLASS : 'hidden',
  29
+        SECTIONIDPREFIX : 'section-',
  30
+        SECTIONLI : 'li.section',
  31
+        SHOW : 'a.editing_show',
  32
+        SHOWHIDE : 'a.editing_showhide'
  33
+    };
  34
+
  35
+    /**
  36
+     * The toolbox classes
  37
+     *
  38
+     * TOOLBOX is a generic class which should never be directly instantiated
  39
+     * RESOURCETOOLBOX is a class extending TOOLBOX containing code specific to resources
  40
+     * SECTIONTOOLBOX is a class extending TOOLBOX containing code specific to sections
  41
+     */
  42
+    var TOOLBOX = function() {
  43
+        TOOLBOX.superclass.constructor.apply(this, arguments);
  44
+    }
  45
+
  46
+    Y.extend(TOOLBOX, Y.Base, {
  47
+        /**
  48
+         * Replace the button click at the selector with the specified
  49
+         * callback
  50
+         *
  51
+         * @param toolboxtarget The selector of the working area
  52
+         * @param selector The 'button' to replace
  53
+         * @param callback The callback to apply
  54
+         * @param cursor An optional cursor style to apply
  55
+         */
  56
+        replace_button : function(toolboxtarget, selector, callback, cursor) {
  57
+            if (!cursor) {
  58
+                // Set the default cursor type to pointer to match the
  59
+                // anchor
  60
+                cursor = 'pointer';
  61
+            }
  62
+            var button = Y.one(toolboxtarget).all(selector)
  63
+                .removeAttribute('href')
  64
+                .setStyle('cursor', cursor);
  65
+
  66
+            // on isn't chainable and will return an event
  67
+            button.on('click', callback, this);
  68
+
  69
+            return button;
  70
+        },
  71
+          /**
  72
+           * Toggle the visibility and availability for the specified
  73
+           * resource show/hide button
  74
+           */
  75
+        toggle_hide_resource_ui : function(button) {
  76
+            var element = button.ancestor(CSS.ACTIVITYLI);
  77
+            var hideicon = button.one('img');
  78
+
  79
+            var dimarea;
  80
+            var toggle_class;
  81
+            if (this.is_label(element)) {
  82
+                toggle_class = CSS.DIMMEDLABELCLASS;
  83
+                dimarea = element.one(CSS.MODINDENTDIV + ' div');
  84
+            } else {
  85
+                toggle_class = CSS.DIMCLASS;
  86
+                dimarea = element.one('a');
  87
+            }
  88
+
  89
+            var status = '';
  90
+            var value;
  91
+            if (dimarea.hasClass(toggle_class)) {
  92
+                status = 'hide';
  93
+                value = 1;
  94
+            } else {
  95
+                status = 'show';
  96
+                value = 0;
  97
+            }
  98
+
  99
+            // Change the UI
  100
+            dimarea.toggleClass(toggle_class);
  101
+            var newstring = M.util.get_string(status, 'moodle');
  102
+            hideicon.setAttrs({
  103
+                'alt' : newstring,
  104
+                'title' : newstring,
  105
+                'src'   : M.util.image_url('t/' + status)
  106
+            });
  107
+            button.set('title', newstring);
  108
+            button.set('className', 'editing_'+status);
  109
+
  110
+            return value;
  111
+        },
  112
+        /**
  113
+         * Send a request using the REST API
  114
+         *
  115
+         * @param data The data to submit
  116
+         * @param loadingiconat (optional) Show the loading icon spinner at the specified location (replaces text)
  117
+         * @param lightbox (optional) A lightbox which may contain a section loader
  118
+         * @param optionalconfig (optional) Any additional configuration to submit
  119
+         * @return response responseText field from responce
  120
+         */
  121
+        send_request : function(data, loadingiconat, lightbox, optionalconfig) {
  122
+            // Default data structure
  123
+            if (!data) {
  124
+                data = {};
  125
+            }
  126
+            // Handle any variables which we must pass back through to
  127
+            var pageparams = this.get('config').pageparams;
  128
+            for (varname in pageparams) {
  129
+                data[varname] = pageparams[varname];
  130
+            }
  131
+
  132
+            // Make a note of the icon for displaying the loadingicon spinner
  133
+            var originalicon;
  134
+            if (loadingiconat) {
  135
+                originalicon = loadingiconat.getAttribute('src');
  136
+            }
  137
+
  138
+            data.sesskey = M.cfg.sesskey;
  139
+            data.courseId = this.get('courseid');
  140
+
  141
+            var uri = M.cfg.wwwroot + this.get('ajaxurl');
  142
+
  143
+            // Define the configuration to send with the request
  144
+            var responsetext = [];
  145
+            var config = {
  146
+                method: 'POST',
  147
+                data: data,
  148
+                on: {
  149
+                    success: function(tid, response) {
  150
+                        try {
  151
+                            responsetext = Y.JSON.parse(response.responseText);
  152
+                            if (responsetext.error) {
  153
+                                new M.core.ajaxException(responsetext);
  154
+                            }
  155
+                        } catch (e) {}
  156
+                        if (originalicon) {
  157
+                            // Replace the spinner with the original icon We use a pause to give
  158
+                            // positive feedback that something is happening
  159
+                            window.setTimeout(function(e) {
  160
+                                loadingiconat.setAttribute('src', originalicon);
  161
+                            }, 250);
  162
+                        }
  163
+                        if (lightbox) {
  164
+                            window.setTimeout(function(e) {
  165
+                                lightbox.hide();
  166
+                            }, 250);
  167
+                        }
  168
+                    },
  169
+                    failure : function(tid, response) {
  170
+                        if (originalicon) {
  171
+                            loadingiconat.setAttribute('src', originalicon);
  172
+                        }
  173
+                        if (lightbox) {
  174
+                            lightbox.hide();
  175
+                        }
  176
+                        new M.core.ajaxException(response);
  177
+                    }
  178
+                },
  179
+                context: this,
  180
+                sync: true
  181
+            }
  182
+
  183
+            // Apply optional config
  184
+            if (optionalconfig) {
  185
+                for (varname in optionalconfig) {
  186
+                    config[varname] = optionalconfig[varname];
  187
+                }
  188
+            }
  189
+
  190
+            if (loadingiconat) {
  191
+                loadingiconat.removeAttribute('innerHTML');
  192
+                loadingiconat.set('src', M.util.image_url(WAITICON.pix, WAITICON.component));
  193
+            }
  194
+
  195
+            // Send the request
  196
+            Y.io(uri, config);
  197
+            return responsetext;
  198
+        },
  199
+        is_label : function(target) {
  200
+            return target.hasClass(CSS.HASLABEL);
  201
+        },
  202
+        /**
  203
+         * Return the module ID for the specified element
  204
+         *
  205
+         * @param element The <li> element to determine a module-id number for
  206
+         * @return string The module ID
  207
+         */
  208
+        get_element_id : function(element) {
  209
+            return element.get('id').replace(CSS.MODULEIDPREFIX, '');
  210
+        },
  211
+        /**
  212
+         * Return the module ID for the specified element
  213
+         *
  214
+         * @param element The <li> element to determine a module-id number for
  215
+         * @return string The module ID
  216
+         */
  217
+        get_section_id : function(section) {
  218
+            return section.get('id').replace(CSS.SECTIONIDPREFIX, '');
  219
+        },
  220
+        add_lightbox: function(node) {
  221
+            node.setStyle('position', 'relative');
  222
+            var waiticon = Y.Node.create('<img />')
  223
+                .setAttrs({
  224
+                    'src' : M.util.image_url(WAITICON.pix, WAITICON.component),
  225
+                    'title' : M.str.moodle.move,
  226
+                    'hspace' : '3'
  227
+                })
  228
+                .setStyles({
  229
+                    'position' : 'relative',
  230
+                    'top' : '50%'
  231
+                });
  232
+
  233
+            var lightbox = Y.Node.create('<div></div>')
  234
+                .setStyles({
  235
+                    'opacity' : '.75',
  236
+                    'position' : 'absolute',
  237
+                    'width' : '100%',
  238
+                    'height' : '100%',
  239
+                    'top' : 0,
  240
+                    'left' : 0,
  241
+                    'backgroundColor' : 'white',
  242
+                    'text-align' : 'center'
  243
+                })
  244
+                .setAttribute('class', 'lightbox')
  245
+                .hide();
  246
+            lightbox.appendChild(waiticon);
  247
+            node.append(lightbox);
  248
+            return lightbox;
  249
+        }
  250
+    },
  251
+    {
  252
+        NAME : 'course-toolbox',
  253
+        ATTRS : {
  254
+            // The ID of the current course
  255
+            courseid : {
  256
+                'value' : 0
  257
+            },
  258
+            ajaxurl : {
  259
+                'value' : 0
  260
+            },
  261
+            config : {
  262
+                'value' : 0
  263
+            }
  264
+        }
  265
+    }
  266
+    );
  267
+
  268
+
  269
+    var RESOURCETOOLBOX = function() {
  270
+        RESOURCETOOLBOX.superclass.constructor.apply(this, arguments);
  271
+    }
  272
+
  273
+    Y.extend(RESOURCETOOLBOX, TOOLBOX, {
  274
+        // Variables
  275
+        GROUPS_NONE     : 0,
  276
+        GROUPS_SEPARATE : 1,
  277
+        GROUPS_VISIBLE  : 2,
  278
+
  279
+        /**
  280
+         * Initialize the resource toolbox
  281
+         *
  282
+         * Updates all span.commands with relevant handlers and other required changes
  283
+         */
  284
+        initializer : function(config) {
  285
+            this.setup_for_resource();
  286
+            M.course.coursebase.register_module(this);
  287
+        },
  288
+
  289
+        /**
  290
+         * Update any span.commands within the scope of the specified
  291
+         * selector with AJAX equivelants
  292
+         *
  293
+         * @param baseselector The selector to limit scope to
  294
+         * @return void
  295
+         */
  296
+        setup_for_resource : function(baseselector) {
  297
+            if (!baseselector) {
  298
+                var baseselector = CSS.PAGECONTENT;
  299
+            }
  300
+
  301
+            Y.all(baseselector).each(this._setup_for_resource, this);
  302
+        },
  303
+        _setup_for_resource : function(toolboxtarget) {
  304
+            // Move left and right
  305
+            this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.MOVELEFT, this.move_left);
  306
+            this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.MOVERIGHT, this.move_right);
  307
+
  308
+            // Delete
  309
+            this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.DELETE, this.delete_resource);
  310
+
  311
+            // Show/Hide
  312
+            var showhide = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.HIDE, this.toggle_hide_resource);
  313
+            var shown = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.SHOW, this.toggle_hide_resource);
  314
+
  315
+            showhide = showhide.concat(shown);
  316
+            showhide.each(function(node) {
  317
+                var section = node.ancestor(CSS.SECTIONLI);
  318
+                if (section && section.hasClass(CSS.SECTIONHIDDENCLASS)) {
  319
+                    node.setStyle('cursor', 'auto');
  320
+                }
  321
+            });
  322
+
  323
+            // Change Group Mode
  324
+            var groups;
  325
+            groups = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.GROUPSNONE, this.toggle_groupmode);
  326
+            groups.setAttribute('groupmode', this.GROUPS_NONE);
  327
+
  328
+            groups = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.GROUPSSEPARATE, this.toggle_groupmode);
  329
+            groups.setAttribute('groupmode', this.GROUPS_SEPARATE);
  330
+
  331
+            groups = this.replace_button(toolboxtarget, CSS.COMMANDSPAN + ' ' + CSS.GROUPSVISIBLE, this.toggle_groupmode);
  332
+            groups.setAttribute('groupmode', this.GROUPS_VISIBLE);
  333
+        },
  334
+        move_left : function(e) {
  335
+            this.move_leftright(e, -1, CSS.MOVELEFT);
  336
+        },
  337
+        move_right : function(e) {
  338
+            this.move_leftright(e, 1, CSS.MOVERIGHT);
  339
+        },
  340
+        move_leftright : function(e, direction, buttonselector) {
  341
+            // Get the element we're working on
  342
+            var element = e.target.ancestor(CSS.ACTIVITYLI);
  343
+
  344
+            // And we need to determine the current and new indent level
  345
+            var indentdiv = element.one(CSS.MODINDENTDIV);
  346
+            var indent = indentdiv.getAttribute('class').match(/mod-indent-(\d{1,})/);
  347
+
  348
+            if (indent) {
  349
+                var oldindent = parseInt(indent[1]);
  350
+                var newindent = Math.max(0, (oldindent + parseInt(direction)));
  351
+                indentdiv.removeClass(indent[0]);
  352
+            } else {
  353
+                var oldindent = 0;
  354
+                var newindent = 1;
  355
+            }
  356
+
  357
+            // Perform the move
  358
+            indentdiv.addClass(CSS.MODINDENTCOUNT + newindent);
  359
+            var data = {
  360
+                'class' : 'resource',
  361
+                'field' : 'indent',
  362
+                'value' : newindent,
  363
+                'id'    : this.get_element_id(element)
  364
+            };
  365
+            var editbutton = element.one(buttonselector + ' img');
  366
+            this.send_request(data, editbutton);
  367
+
  368
+            // Handle removal/addition of the moveleft button
  369
+            if (newindent == 0) {
  370
+                window.setTimeout(function(e) {
  371
+                    element.one(CSS.MOVELEFT).remove();
  372
+                }, 250);
  373
+            } else if (newindent == 1 && oldindent == 0) {
  374
+                this.add_moveleft(element);
  375
+            }
  376
+        },
  377
+        delete_resource : function(e) {
  378
+            // Get the element we're working on
  379
+            var element   = e.target.ancestor(CSS.ACTIVITYLI);
  380
+
  381
+            var confirmstring = '';
  382
+            if (this.is_label(element)) {
  383
+                // Labels are slightly different to other activities
  384
+                var plugindata = {
  385
+                    type : M.util.get_string('pluginname', 'label')
  386
+                }
  387
+                confirmstring = M.util.get_string('deletechecktype', 'moodle', plugindata)
  388
+            } else {
  389
+                var plugindata = {
  390
+                    type : M.util.get_string('pluginname', element.getAttribute('class').match(/modtype_([^\s]*)/)[1]),
  391
+                    name : element.one(CSS.INSTANCENAME).get('firstChild').get('data')
  392
+                }
  393
+                confirmstring = M.util.get_string('deletechecktypename', 'moodle', plugindata);
  394
+            }
  395
+
  396
+            // Confirm element removal
  397
+            if (!confirm(confirmstring)) {
  398
+                return false;
  399
+            }
  400
+
  401
+            // Actually remove the element
  402
+            element.remove();
  403
+            var data = {
  404
+                'class' : 'resource',
  405
+                'action' : 'DELETE',
  406
+                'id'    : this.get_element_id(element)
  407
+            };
  408
+            this.send_request(data);
  409
+        },
  410
+        toggle_hide_resource : function(e) {
  411
+            // Return early if the current section is hidden
  412
+            var section = e.target.ancestor(CSS.SECTIONLI);
  413
+            if (section && section.hasClass(CSS.SECTIONHIDDENCLASS)) {
  414
+                return;
  415
+            }
  416
+
  417
+            // Get the element we're working on
  418
+            var element = e.target.ancestor(CSS.ACTIVITYLI);
  419
+
  420
+            var button = e.target.ancestor('a', true);
  421
+
  422
+            var value = this.toggle_hide_resource_ui(button);
  423
+
  424
+            // Send the request
  425
+            var data = {
  426
+                'class' : 'resource',
  427
+                'field' : 'visible',
  428
+                'value' : value,
  429
+                'id'    : this.get_element_id(element)
  430
+            };
  431
+            this.send_request(data, button.one('img'));
  432
+        },
  433
+        toggle_groupmode : function(e) {
  434
+            // Get the element we're working on
  435
+            var element = e.target.ancestor(CSS.ACTIVITYLI);
  436
+
  437
+            var button = e.target.ancestor('a', true);
  438
+            var icon = button.one('img');
  439
+
  440
+            // Current Mode
  441
+            var groupmode = button.getAttribute('groupmode');
  442
+            groupmode++;
  443
+            if (groupmode > 2) {
  444
+                groupmode = 0;
  445
+            }
  446
+            button.setAttribute('groupmode', groupmode);
  447
+
  448
+            var newtitle = '';
  449
+            var iconsrc = '';
  450
+            switch (groupmode) {
  451
+                case this.GROUPS_NONE:
  452
+                    newtitle = 'groupsnone';
  453
+                    iconsrc = M.util.image_url('t/groupn');
  454
+                    break;
  455
+                case this.GROUPS_SEPARATE:
  456
+                    newtitle = 'groupsseparate';
  457
+                    iconsrc = M.util.image_url('t/groups');
  458
+                    break;
  459
+                case this.GROUPS_VISIBLE:
  460
+                    newtitle = 'groupsvisible';
  461
+                    iconsrc = M.util.image_url('t/groupv');
  462
+                    break;
  463
+            }
  464
+            newtitle = M.util.get_string('clicktochangeinbrackets', 'moodle',
  465
+                    M.util.get_string(newtitle, 'moodle'));
  466
+
  467
+            // Change the UI
  468
+            icon.setAttrs({
  469
+                'alt' : newtitle,
  470
+                'title' : newtitle,
  471
+                'src' : iconsrc
  472
+            });
  473
+            button.setAttribute('title', newtitle);
  474
+
  475
+            // And send the request
  476
+            var data = {
  477
+                'class' : 'resource',
  478
+                'field' : 'groupmode',
  479
+                'value' : groupmode,
  480
+                'id'    : this.get_element_id(element)
  481
+            };
  482
+            this.send_request(data, icon);
  483
+        },
  484
+        /**
  485
+         * Add the moveleft button
  486
+         * This is required after moving left from an initial position of 0
  487
+         *
  488
+         * @param target The encapsulating <li> element
  489
+         */
  490
+        add_moveleft : function(target) {
  491
+            var left_string = M.util.get_string('moveleft', 'moodle');
  492
+            var newicon = Y.Node.create('<img />')
  493
+                .addClass(CSS.GENERICICONCLASS)
  494
+                .setAttrs({
  495
+                    'src'   : M.util.image_url('t/left', 'moodle'),
  496
+                    'title' : left_string,
  497
+                    'alt'   : left_string
  498
+                });
  499
+            var anchor = new Y.Node.create('<a />')
  500
+                .setStyle('cursor', 'pointer')
  501
+                .addClass(CSS.MOVELEFTCLASS)
  502
+                .set('title', left_string);
  503
+            anchor.appendChild(newicon);
  504
+            anchor.on('click', this.move_left, this);
  505
+            target.one(CSS.MOVERIGHT).insert(anchor, 'before');
  506
+        }
  507
+    }, {
  508
+        NAME : 'course-resource-toolbox',
  509
+        ATTRS : {
  510
+            courseid : {
  511
+                'value' : 0
  512
+            },
  513
+            format : {
  514
+                'value' : 'topics'
  515
+            }
  516
+        }
  517
+    });
  518
+
  519
+    var SECTIONTOOLBOX = function() {
  520
+        SECTIONTOOLBOX.superclass.constructor.apply(this, arguments);
  521
+    }
  522
+
  523
+    Y.extend(SECTIONTOOLBOX, TOOLBOX, {
  524
+        /**
  525
+         * Initialize the toolboxes module
  526
+         *
  527
+         * Updates all span.commands with relevant handlers and other required changes
  528
+         */
  529
+        initializer : function(config) {
  530
+            this.setup_for_section();
  531
+            M.course.coursebase.register_module(this);
  532
+        },
  533
+        /**
  534
+         * Update any section areas within the scope of the specified
  535
+         * selector with AJAX equivelants
  536
+         *
  537
+         * @param baseselector The selector to limit scope to
  538
+         * @return void
  539
+         */
  540
+        setup_for_section : function(baseselector) {
  541
+            if (!baseselector) {
  542
+                var baseselector = CSS.PAGECONTENT;
  543
+            }
  544
+
  545
+            Y.all(baseselector).each(this._setup_for_section, this);
  546
+        },
  547
+        _setup_for_section : function(toolboxtarget) {
  548
+            // Section Highlighting
  549
+            this.replace_button(toolboxtarget, CSS.RIGHTDIV + ' ' + CSS.HIGHLIGHT, this.toggle_highlight);
  550
+
  551
+            // Section Visibility
  552
+            this.replace_button(toolboxtarget, CSS.RIGHTDIV + ' ' + CSS.SHOWHIDE, this.toggle_hide_section);
  553
+        },
  554
+        toggle_hide_section : function(e) {
  555
+            // Get the section we're working on
  556
+            var section = e.target.ancestor(CSS.SECTIONLI);
  557
+            var button = e.target.ancestor('a', true);
  558
+            var hideicon = button.one('img');
  559
+
  560
+            // The value to submit
  561
+            var value;
  562
+            // The status text for strings and images
  563
+            var status;
  564
+
  565
+            if (!section.hasClass(CSS.SECTIONHIDDENCLASS)) {
  566
+                section.addClass(CSS.SECTIONHIDDENCLASS);
  567
+                value = 0;
  568
+                status = 'show';
  569
+
  570
+            } else {
  571
+                section.removeClass(CSS.SECTIONHIDDENCLASS);
  572
+                value = 1;
  573
+                status = 'hide';
  574
+            }
  575
+
  576
+            var newstring = M.util.get_string(status + 'fromothers', 'format_' + this.get('format'));
  577
+            hideicon.setAttrs({
  578
+                'alt' : newstring,
  579
+                'title' : newstring,
  580
+                'src'   : M.util.image_url('i/' + status)
  581
+            });
  582
+            button.set('title', newstring);
  583
+
  584
+            // Change the highlight status
  585
+            var data = {
  586
+                'class' : 'section',
  587
+                'field' : 'visible',
  588
+                'id'    : this.get_section_id(section),
  589
+                'value' : value
  590
+            };
  591
+
  592
+            var lightbox = this.add_lightbox(section);
  593
+            lightbox.show();
  594
+
  595
+            var response = this.send_request(data, null, lightbox);
  596
+
  597
+            var activities = section.all(CSS.ACTIVITYLI);
  598
+            activities.each(function(node) {
  599
+                if (node.one(CSS.SHOW)) {
  600
+                    var button = node.one(CSS.SHOW);
  601
+                } else {
  602
+                    var button = node.one(CSS.HIDE);
  603
+                }
  604
+                var activityid = this.get_element_id(node);
  605
+
  606
+                if (Y.Array.indexOf(response.resourcestotoggle, activityid) != -1) {
  607
+                    this.toggle_hide_resource_ui(button);
  608
+                }
  609
+
  610
+                if (value == 0) {
  611
+                    button.setStyle('cursor', 'auto');
  612
+                } else {
  613
+                    button.setStyle('cursor', 'pointer');
  614
+                }
  615
+            }, this);
  616
+        },
  617
+        toggle_highlight : function(e) {
  618
+            // Get the section we're working on
  619
+            var section = e.target.ancestor(CSS.SECTIONLI);
  620
+            var button = e.target.ancestor('a', true);
  621
+            var buttonicon = button.one('img');
  622
+
  623
+            // Determine whether the marker is currently set
  624
+            var togglestatus = section.hasClass('current');
  625
+            var value = 0;
  626
+
  627
+            // Set the current highlighted item text
  628
+            var old_string = M.util.get_string('markthistopic', 'moodle');
  629
+            Y.one(CSS.PAGECONTENT)
  630
+                .all(CSS.SECTIONLI + '.current ' + CSS.HIGHLIGHT)
  631
+                .set('title', old_string);
  632
+            Y.one(CSS.PAGECONTENT)
  633
+                .all(CSS.SECTIONLI + '.current ' + CSS.HIGHLIGHT + ' img')
  634
+                .set('title', old_string)
  635
+                .set('alt', old_string)
  636
+                .set('src', M.util.image_url('i/marker'));
  637
+
  638
+            // Remove the highlighting from all sections
  639
+            var allsections = Y.one(CSS.PAGECONTENT).all(CSS.SECTIONLI)
  640
+                .removeClass('current');
  641
+
  642
+            // Then add it if required to the selected section
  643
+            if (!togglestatus) {
  644
+                section.addClass('current');
  645
+                value = this.get_section_id(section);
  646
+                var new_string = M.util.get_string('markedthistopic', 'moodle');
  647
+                button
  648
+                    .set('title', new_string);
  649
+                buttonicon
  650
+                    .set('title', new_string)
  651
+                    .set('alt', new_string)
  652
+                    .set('src', M.util.image_url('i/marked'));
  653
+            }
  654
+
  655
+            // Change the highlight status
  656
+            var data = {
  657
+                'class' : 'course',
  658
+                'field' : 'marker',
  659
+                'value' : value
  660
+            };
  661
+            var lightbox = this.add_lightbox(section);
  662
+            lightbox.show();
  663
+            this.send_request(data, null, lightbox);
  664
+        }
  665
+    }, {
  666
+        NAME : 'course-section-toolbox',
  667
+        ATTRS : {
  668
+            courseid : {
  669
+                'value' : 0
  670
+            },
  671
+            format : {
  672
+                'value' : 'topics'
  673
+            }
  674
+        }
  675
+    });
  676
+
  677
+    M.course = M.course || {};
  678
+
  679
+    M.course.init_resource_toolbox = function(config) {
  680
+        return new RESOURCETOOLBOX(config);
  681
+    };
  682
+
  683
+    M.course.init_section_toolbox = function(config) {
  684
+        return new SECTIONTOOLBOX(config);
  685
+    };
  686
+
  687
+},
  688
+'@VERSION@', {
  689
+    requires : ['base', 'node', 'io', 'moodle-course-coursebase']
  690
+}
  691
+);
4  index.php
@@ -95,6 +95,7 @@
95 95
     echo $OUTPUT->header();
96 96
 
97 97
 /// Print Section or custom info
  98
+    get_all_mods($SITE->id, $mods, $modnames, $modnamesplural, $modnamesused);
98 99
     if (!empty($CFG->customfrontpageinclude)) {
99 100
         include($CFG->customfrontpageinclude);
100 101
 
@@ -138,7 +139,6 @@
138 139
                      " class=\"iconsmall\" alt=\"$streditsummary\" /></a><br /><br />";
139 140
             }
140 141
 
141  
-            get_all_mods($SITE->id, $mods, $modnames, $modnamesplural, $modnamesused);
142 142
             print_section($SITE, $section, $mods, $modnamesused, true);
143 143
 
144 144
             if ($editing) {
@@ -147,6 +147,8 @@
147 147
             echo $OUTPUT->box_end();
148 148
         }
149 149
     }
  150
+    include_course_ajax($SITE, $modnamesused);
  151
+
150 152
 
151 153
     if (isloggedin() and !isguestuser() and isset($CFG->frontpageloggedin)) {
152 154
         $frontpagelayout = $CFG->frontpageloggedin;
6  lang/en/moodle.php
@@ -430,6 +430,8 @@
430 430
 $string['deletedcourse'] = '{$a} has been completely deleted';
431 431
 $string['deletednot'] = 'Could not delete {$a} !';
432 432
 $string['deletecheck'] = 'Delete {$a} ?';
  433
+$string['deletechecktype'] = 'Are you sure that you want to delete this {$a->type}?';
  434
+$string['deletechecktypename'] = 'Are you sure that you want to delete the {$a->type} "{$a->name}"?';
433 435
 $string['deletecheckfiles'] = 'Are you absolutely sure you want to delete these files?';
434 436
 $string['deletecheckfull'] = 'Are you absolutely sure you want to completely delete {$a} ?';
435 437
 $string['deletecheckwarning'] = 'You are about to delete these files';
@@ -806,8 +808,6 @@
806 808
 $string['hidesection'] = 'Hide section {$a}';
807 809
 $string['hidesettings'] = 'Hide settings';
808 810
 $string['hideshowblocks'] = 'Hide or show blocks';
809  
-$string['hidetopicfromothers'] = 'Hide topic';
810  
-$string['hideweekfromothers'] = 'Hide week';
811 811
 $string['hits'] = 'Hits';
812 812
 $string['hitsoncourse'] = 'Hits on {$a->coursename} by {$a->username}';
813 813
 $string['hitsoncoursetoday'] = 'Today\'s hits on {$a->coursename} by {$a->username}';
@@ -1506,8 +1506,6 @@
1506 1506
 $string['showsettings'] = 'Show settings';
1507 1507
 $string['showtheselogs'] = 'Show these logs';
1508 1508
 $string['showthishelpinlanguage'] = 'Show this help in language: {$a}';
1509  
-$string['showtopicfromothers'] = 'Show topic';
1510  
-$string['showweekfromothers'] = 'Show week';
1511 1509
 $string['schedule'] = 'Schedule';
1512 1510
 $string['since'] = 'Since';
1513 1511
 $string['sincelast'] = 'since last login';
314  lib/ajax/ajaxcourse.js
... ...
@@ -1,314 +0,0 @@
1  
-/**
2  
- * Contains Main class and supporting functions for ajax course layout
3  
- */
4  
-
5  
-
6  
-//hide content body until done loading (manipulation looks ugly elsewise)
7  
-//document.getElementById('content').style.display = 'none';
8  
-
9  
-// If firebug console is undefined, define a fake one here
10  
-if (window.console) {
11  
-    console.vardump = function(data) {
12  
-        retval = '';
13  
-        for (key in data) {
14  
-            retval += key+' = '+data[key] + "\n";
15  
-        }
16  
-        console.log(retval);
17  
-    };
18  
-}
19  
-
20  
-//onload object for handling scripts on page load, this insures they run in my order
21  
-function onload_class() {
22  
-    this.scripts = new Array();
23  
-    this.debug = true;
24  
-}
25  
-
26  
-
27  
-onload_class.prototype.add = function(script) {
28  
-    if (this.debug) {
29  
-        YAHOO.log("onloadobj.add - adding "+script, "junk");
30  
-    }
31  
-    this.scripts[this.scripts.length] = script;
32  
-};
33  
-
34  
-
35  
-onload_class.prototype.load = function() {
36  
-    var scriptcount = this.scripts.length;
37  
-    if (this.debug) {
38  
-        YAHOO.log("onloadobj.load - loading "+scriptcount+" scripts", "info");
39  
-    }
40  
-    for (i=0; i<scriptcount; i++) {
41  
-        eval(this.scripts[i]);
42  
-    }
43  
-};
44  
-
45  
-
46  
-var onloadobj = new onload_class();
47  
-
48  
-
49  
-//main page object
50  
-function main_class() {
51  
-    this.debug = true;
52  
-    this.portal = new php_portal_class();
53  
-
54  
-    this.blocks = new Array();
55  
-    this.sections = new Array();
56  
-    this.sectiondates = {};
57  
-    this.leftcolumn = null;
58  
-    this.rightcolumn = null;
59  
-    this.adminBlock = null;
60  
-    this.tempBlock = null;
61  
-    this.icons = [];
62  
-    this.courseformat = null;
63  
-    this.marker = null;
64  
-    this.numsections = null;
65  
-    this.lastsection = null; // real last section num including unavailable
66  
-
67  
-    //things to process onload
68  
-    onloadobj.add('main.process_document();');
69  
-    onloadobj.add("if (document.getElementById('content')) document.getElementById('content').style.display='block';");
70  
-
71  
-    //connection queue allows xhttp requests to be sent in order
72  
-    this.connectQueue = [];
73  
-    this.connectQueueHead = 0;
74  
-    this.connectQueueConnection = null;
75  
-}
76  
-
77  
-
78  
-main_class.prototype.process_blocks = function() {
79  
-    //remove unneeded icons (old school position icons and delete/hide
80  
-    //although they will be read)
81  
-    var rmIconClasses = ['icon up', 'icon down', 'icon right', 'icon left', 'icon delete', 'icon hide'];
82  
-    for (var c=0; c<rmIconClasses.length; c++) {
83  
-        els = YAHOO.util.Dom.getElementsByClassName(rmIconClasses[c]);
84  
-
85  
-        for (var x=0; x<els.length; x++) {
86  
-            els[x].parentNode.removeChild(els[x]);
87  
-        }
88  
-    }
89  
-    //process the block ids passed from php
90  
-    var blockcount = this.portal.blocks.length;
91  <