Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/**
17
 * Javascript helper function for IMS Content Package module.
18
 *
19
 * @package    mod
20
 * @subpackage imscp
21
 * @copyright  2009 Petr Skoda  {@link http://skodak.org}
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
M.mod_imscp = {};
26
 
27
M.mod_imscp.init = function(Y) {
28
 
29
    var imscp_layout_widget;
30
    var imscp_current_node;
31
    var imscp_buttons = [];
32
    var imscp_bloody_labelclick = false;
33
 
34
    Y.use('yui2-resize', 'yui2-dragdrop', 'yui2-container', 'yui2-button', 'yui2-layout', 'yui2-treeview', 'yui2-json', 'yui2-event', function(Y) {
35
 
36
        var imscp_activate_item_by_index = function(index) {
37
            imscp_activate_item(Y.YUI2.widget.TreeView.getNode('imscp_tree', index));
38
        };
39
 
40
        var imscp_activate_item = function(node) {
41
            if (!node) {
42
                return;
43
            }
44
            imscp_current_node = node;
45
            imscp_current_node.highlight();
46
 
47
            var content = new Y.YUI2.util.Element('imscp_content');
48
            var obj;
49
            if (node.href) {
50
                try {
51
                    // First try IE way - it can not set name attribute later
52
                    // and also it has some restrictions on DOM access from object tag.
53
                    obj = document.createElement('<iframe id="imscp_object" src="' + node.href + '">');
54
                } catch (e) {
55
                    obj = document.createElement('object');
56
                    obj.setAttribute('id', 'imscp_object');
57
                    obj.setAttribute('type', 'text/html');
58
                    obj.setAttribute('data', node.href);
59
                }
60
            } else {
61
                // No href, so create links to children.
62
                obj = document.createElement('div');
63
                obj.setAttribute('id', 'imscp_child_list');
64
 
65
                var title = document.createElement('h2');
66
                title.appendChild(document.createTextNode(node.label));
67
                title.setAttribute('class', 'sectionname');
68
                obj.appendChild(title);
69
 
70
                var ul = document.createElement('ul');
71
                obj.appendChild(ul);
72
                for (var i = 0; i < node.children.length; i++) {
73
                    var childnode = node.children[i];
74
                    var li = document.createElement('li');
75
                    var a = document.createElement('a');
76
                    a.appendChild(document.createTextNode(childnode.label));
77
                    a.setAttribute('id', 'ref_' + childnode.index);
78
                    Y.YUI2.util.Event.addListener(a, "click", function () {
79
                        imscp_activate_item_by_index(this.id.substr(4));
80
                    });
81
                    ul.appendChild(li);
82
                    li.appendChild(a);
83
                }
84
            }
85
            var old = Y.YUI2.util.Dom.get('imscp_object');
86
            if (old) {
87
                content.replaceChild(obj, old);
88
            } else {
89
                old = Y.YUI2.util.Dom.get('imscp_child_list');
90
                if (old) {
91
                    content.replaceChild(obj, old);
92
                } else {
93
                    content.appendChild(obj);
94
                }
95
            }
96
            imscp_resize_frame();
97
 
98
            imscp_current_node.focus();
99
            imscp_fixnav();
100
        };
101
 
102
        /**
103
         * Enables/disables navigation buttons as needed.
104
         * @return void
105
         */
106
        var imscp_fixnav = function() {
107
            imscp_buttons[0].set('disabled', (imscp_skipprev(imscp_current_node) == null));
108
            imscp_buttons[1].set('disabled', (imscp_prev(imscp_current_node) == null));
109
            imscp_buttons[2].set('disabled', (imscp_up(imscp_current_node) == null));
110
            imscp_buttons[3].set('disabled', (imscp_next(imscp_current_node) == null));
111
            imscp_buttons[4].set('disabled', (imscp_skipnext(imscp_current_node) == null));
112
        };
113
 
114
        var imscp_resize_layout = function(alsowidth) {
115
            if (alsowidth) {
116
                var layout = Y.YUI2.util.Dom.get('imscp_layout');
117
                var newwidth = imscp_get_htmlelement_size('maincontent', 'width');
118
                layout.style.width = '600px';
119
                if (newwidth > 600) {
120
                    layout.style.width = newwidth + 'px';
121
                }
122
            }
123
            // Make sure that the max width of the TOC doesn't go to far.
124
 
125
            var left = imscp_layout_widget.getUnitByPosition('left');
126
            var maxwidth = parseInt(Y.YUI2.util.Dom.getStyle('imscp_layout', 'width'));
127
            left.set('maxWidth', (maxwidth - 10));
128
            var cwidth = left.get('width');
129
            if (cwidth > (maxwidth - 10)) {
130
                left.set('width', (maxwidth - 10));
131
            }
132
 
133
            var headerheight = imscp_get_htmlelement_size('page-header', 'height');
134
            var footerheight = imscp_get_htmlelement_size('page-footer', 'height');
135
            var newheight = parseInt(Y.YUI2.util.Dom.getViewportHeight()) - footerheight - headerheight - 20;
136
            if (newheight < 400) {
137
                newheight = 400;
138
            }
139
            imscp_layout_widget.setStyle('height', newheight + 'px');
140
 
141
            imscp_layout_widget.render();
142
            imscp_resize_frame();
143
        };
144
 
145
        var imscp_get_htmlelement_size = function(el, prop) {
146
            var val = Y.YUI2.util.Dom.getStyle(el, prop);
147
            if (val == 'auto') {
148
                if (el.get) {
149
                    el = el.get('element'); // Get real HTMLElement from YUI element.
150
                }
151
                val = Y.YUI2.util.Dom.getComputedStyle(Y.YUI2.util.Dom.get(el), prop);
152
            }
153
            return parseInt(val);
154
        };
155
 
156
        var imscp_resize_frame = function() {
157
            obj = Y.YUI2.util.Dom.get('imscp_object');
158
            if (obj) {
159
                var content = imscp_layout_widget.getUnitByPosition('center').get('wrap');
160
                // Basically trap IE6 and 7.
161
                if (Y.YUI2.env.ua.ie > 5 && Y.YUI2.env.ua.ie < 8) {
162
                    if( obj.style.setAttribute ) {
163
                        obj.style.setAttribute("cssText", 'width: ' + (content.offsetWidth - 6) + 'px; height: ' + (content.offsetHeight - 10) + 'px;');
164
                    }
165
                    else {
166
                        obj.style.setAttribute('width', (content.offsetWidth - 6) + 'px', 0);
167
                        obj.style.setAttribute('height', (content.offsetHeight - 10) + 'px', 0);
168
                    }
169
                }
170
                else {
171
                    obj.style.width = (content.offsetWidth - 6) + 'px';
172
                    obj.style.height = (content.offsetHeight - 10) + 'px';
173
                }
174
            }
175
        };
176
 
177
        var imscp_firstlinked = function(node) {
178
            // Return first item with an href.
179
            if (node.href) {
180
                return node;
181
            } else if (node.children) {
182
                return imscp_firstlinked(node.children[0]);
183
            } else {
184
                return null;
185
            }
186
        };
187
 
188
        var imscp_up = function(node) {
189
            if (node.depth > 0) {
190
                return node.parent;
191
            }
192
            return null;
193
        };
194
 
195
        var imscp_lastchild = function(node) {
196
            if (node.children.length) {
197
                return imscp_lastchild(node.children[node.children.length - 1]);
198
            } else {
199
                return node;
200
            }
201
        };
202
 
203
        var imscp_prev = function(node) {
204
            if (node.previousSibling && node.previousSibling.children.length) {
205
                return imscp_lastchild(node.previousSibling);
206
            }
207
            return imscp_skipprev(node);
208
        };
209
 
210
        var imscp_skipprev = function(node) {
211
            if (node.previousSibling) {
212
                return node.previousSibling;
213
            } else if (node.depth > 0) {
214
                return node.parent;
215
            }
216
            return null;
217
        };
218
 
219
        var imscp_next = function(node) {
220
            if (node.children.length) {
221
                return node.children[0];
222
            }
223
            return imscp_skipnext(node);
224
        };
225
 
226
        var imscp_skipnext = function(node) {
227
            if (node.nextSibling) {
228
                return node.nextSibling;
229
            } else if (node.depth > 0) {
230
                return imscp_skipnext(node.parent);
231
            }
232
            return null;
233
        };
234
 
235
        // Layout.
236
        Y.YUI2.widget.LayoutUnit.prototype.STR_COLLAPSE = M.util.get_string('hide', 'moodle');
237
        Y.YUI2.widget.LayoutUnit.prototype.STR_EXPAND = M.util.get_string('show', 'moodle');
238
 
239
        imscp_layout_widget = new Y.YUI2.widget.Layout('imscp_layout', {
240
            minWidth: 600,
241
            minHeight: 400,
242
            units: [
243
                { position: 'left', body: 'imscp_toc', header: M.util.get_string('toc', 'imscp'), width: 250, resize: true, gutter: '2px 5px 5px 2px', collapse: true, minWidth:150},
244
                { position: 'center', body: '<div id="imscp_content"></div>', gutter: '2px 5px 5px 2px', scroll: true}
245
            ]
246
        });
247
        imscp_layout_widget.render();
248
        var left = imscp_layout_widget.getUnitByPosition('left');
249
        left.on('collapse', function() {
250
            imscp_resize_frame();
251
        });
252
        left.on('expand', function() {
253
            imscp_resize_frame();
254
        });
255
 
256
        // Ugly resizing hack that works around problems with resizing of iframes and objects.
257
        left._resize.on('startResize', function() {
258
            obj = Y.YUI2.util.Dom.get('imscp_object');
259
            obj.style.display = 'none';
260
        });
261
        left._resize.on('endResize', function() {
262
            obj = Y.YUI2.util.Dom.get('imscp_object');
263
            obj.style.display = 'block';
264
            imscp_resize_frame();
265
        });
266
 
267
        // TOC tree.
268
        var tree = new Y.YUI2.widget.TreeView('imscp_tree');
269
        tree.singleNodeHighlight = true;
270
        tree.subscribe('clickEvent', function(oArgs) {
271
            imscp_activate_item(oArgs.node);
272
            if (oArgs.node.children.length) {
273
                imscp_bloody_labelclick = true;
274
            }
275
            Y.YUI2.util.Event.preventDefault(oArgs.event);
276
            return false;
277
        });
278
        tree.subscribe('collapse', function(node) {
279
            if (imscp_bloody_labelclick) {
280
                imscp_bloody_labelclick = false;
281
                return false;
282
            }
283
        });
284
        tree.subscribe('expand', function(node) {
285
            if (imscp_bloody_labelclick) {
286
                imscp_bloody_labelclick = false;
287
                return false;
288
            }
289
        });
290
        tree.expandAll();
291
        tree.render();
292
 
293
        var navbar = Y.YUI2.util.Dom.get('imscp_nav');
294
        navbar.style.display = 'block';
295
 
296
        // Navigation.
297
        imscp_buttons[0] = new Y.YUI2.widget.Button('nav_skipprev');
298
        imscp_buttons[1] = new Y.YUI2.widget.Button('nav_prev');
299
        imscp_buttons[2] = new Y.YUI2.widget.Button('nav_up');
300
        imscp_buttons[3] = new Y.YUI2.widget.Button('nav_next');
301
        imscp_buttons[4] = new Y.YUI2.widget.Button('nav_skipnext');
302
        imscp_buttons[0].on('click', function(ev) {
303
            imscp_activate_item(imscp_skipprev(imscp_current_node));
304
        });
305
        imscp_buttons[1].on('click', function(ev) {
306
            imscp_activate_item(imscp_prev(imscp_current_node));
307
        });
308
        imscp_buttons[2].on('click', function(ev) {
309
            imscp_activate_item(imscp_up(imscp_current_node));
310
        });
311
        imscp_buttons[3].on('click', function(ev) {
312
            imscp_activate_item(imscp_next(imscp_current_node));
313
        });
314
        imscp_buttons[4].on('click', function(ev) {
315
            imscp_activate_item(imscp_skipnext(imscp_current_node));
316
        });
317
 
318
        // Finally activate the first item.
319
        imscp_activate_item(imscp_firstlinked(tree.getRoot().children[0]));
320
 
321
        // Resizing.
322
        imscp_resize_layout(false);
323
 
324
        // Fix layout if window resized.
325
        window.onresize = function() {
326
            imscp_resize_layout(true);
327
        };
328
    });
329
};