Merge branch 'wip-mdl-41266' of https://github.com/rajeshtaneja/moodle
[moodle.git] / mod / imscp / module.js
blob8933d561d39241c82bae4e823dcc70fc34f08110
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.
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/>.
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  */
25 M.mod_imscp = {};
27 M.mod_imscp.init = function(Y) {
29     var imscp_layout_widget;
30     var imscp_current_node;
31     var imscp_buttons = [];
32     var imscp_bloody_labelclick = false;
34     Y.use('yui2-resize', 'yui2-dragdrop', 'yui2-container', 'yui2-button', 'yui2-layout', 'yui2-treeview', 'yui2-json', 'yui2-event', function(Y) {
36         var imscp_activate_item = function(node) {
37             if (!node) {
38                 return;
39             }
40             imscp_current_node = node;
41             imscp_current_node.highlight();
43             var content = new Y.YUI2.util.Element('imscp_content');
44             try {
45                 // first try IE way - it can not set name attribute later
46                 // and also it has some restrictions on DOM access from object tag
47                 var obj = document.createElement('<iframe id="imscp_object" src="'+node.href+'">');
48             } catch (e) {
49                 var obj = document.createElement('object');
50                 obj.setAttribute('id', 'imscp_object');
51                 obj.setAttribute('type', 'text/html');
52                 obj.setAttribute('data', node.href);
53             }
54             var old = Y.YUI2.util.Dom.get('imscp_object');
55             if (old) {
56                 content.replaceChild(obj, old);
57             } else {
58                 content.appendChild(obj);
59             }
60             imscp_resize_frame();
62             imscp_current_node.focus();
63             imscp_fixnav();
64         };
66         /**
67          * Enables/disables navigation buttons as needed.
68          * @return void
69          */
70         var imscp_fixnav = function() {
71             imscp_buttons[0].set('disabled', (imscp_skipprev(imscp_current_node) == null));
72             imscp_buttons[1].set('disabled', (imscp_prev(imscp_current_node) == null));
73             imscp_buttons[2].set('disabled', (imscp_up(imscp_current_node) == null));
74             imscp_buttons[3].set('disabled', (imscp_next(imscp_current_node) == null));
75             imscp_buttons[4].set('disabled', (imscp_skipnext(imscp_current_node) == null));
76         };
79         var imscp_resize_layout = function(alsowidth) {
80             if (alsowidth) {
81                 var layout = Y.YUI2.util.Dom.get('imscp_layout');
82                 var newwidth = imscp_get_htmlelement_size('maincontent', 'width');
83                 layout.style.width = '600px';
84                 if (newwidth > 600) {
85                     layout.style.width = newwidth+'px';
86                 }
87             }
88             // make sure that the max width of the TOC doesn't go to far
90             var left = imscp_layout_widget.getUnitByPosition('left');
91             var maxwidth = parseInt(Y.YUI2.util.Dom.getStyle('imscp_layout', 'width'));
92             left.set('maxWidth', (maxwidth - 10));
93             var cwidth = left.get('width');
94             if (cwidth > (maxwidth - 10)) {
95                 left.set('width', (maxwidth - 10));
96             }
98             var headerheight = imscp_get_htmlelement_size('page-header', 'height');
99             var footerheight = imscp_get_htmlelement_size('page-footer', 'height');
100             var newheight = parseInt(Y.YUI2.util.Dom.getViewportHeight()) - footerheight - headerheight - 20;
101             if (newheight < 400) {
102                 newheight = 400;
103             }
104             imscp_layout_widget.setStyle('height', newheight+'px');
106             imscp_layout_widget.render();
107             imscp_resize_frame();
108         };
110         var imscp_get_htmlelement_size = function(el, prop) {
111             var val = Y.YUI2.util.Dom.getStyle(el, prop);
112             if (val == 'auto') {
113                 if (el.get) {
114                     el = el.get('element'); // get real HTMLElement from YUI element
115                 }
116                 val = Y.YUI2.util.Dom.getComputedStyle(Y.YUI2.util.Dom.get(el), prop);
117             }
118             return parseInt(val);
119         };
121         var imscp_resize_frame = function() {
122             var obj = Y.YUI2.util.Dom.get('imscp_object');
123             if (obj) {
124                 var content = imscp_layout_widget.getUnitByPosition('center').get('wrap');
125                 // basically trap IE6 and 7
126                 if (Y.YUI2.env.ua.ie > 5 && Y.YUI2.env.ua.ie < 8) {
127                     if( obj.style.setAttribute ) {
128                         obj.style.setAttribute("cssText", 'width: ' +(content.offsetWidth - 6)+'px; height: ' + (content.offsetHeight - 10)+'px;');
129                     }
130                     else {
131                         obj.style.setAttribute('width', (content.offsetWidth - 6)+'px', 0);
132                         obj.style.setAttribute('height', (content.offsetHeight - 10)+'px', 0);
133                     }
134                 }
135                 else {
136                     obj.style.width = (content.offsetWidth - 6)+'px';
137                     obj.style.height = (content.offsetHeight - 10)+'px';
138                 }
139             }
140         };
142         var imscp_up = function(node) {
143             if (node.depth > 0) {
144                 return node.parent;
145             }
146             return null;
147         };
149         var imscp_lastchild = function(node) {
150             if (node.children.length) {
151                 return imscp_lastchild(node.children[node.children.length-1]);
152             } else {
153                 return node;
154             }
155         };
157         var imscp_prev = function(node) {
158             if (node.previousSibling && node.previousSibling.children.length) {
159                 return imscp_lastchild(node.previousSibling);
160             }
161             return imscp_skipprev(node);
162         };
164         var imscp_skipprev = function(node) {
165             if (node.previousSibling) {
166                 return node.previousSibling;
167             } else if (node.depth > 0) {
168                 return node.parent;
169             }
170             return null;
171         };
173         var imscp_next = function(node) {
174             if (node.children.length) {
175                 return node.children[0];
176             }
177             return imscp_skipnext(node);
178         };
180         var imscp_skipnext = function(node) {
181             if (node.nextSibling) {
182                 return node.nextSibling;
183             } else if (node.depth > 0) {
184                 return imscp_skipnext(node.parent);
185             }
186             return null;
187         };
190         // layout
191         Y.YUI2.widget.LayoutUnit.prototype.STR_COLLAPSE = M.str.moodle.hide;
192         Y.YUI2.widget.LayoutUnit.prototype.STR_EXPAND = M.str.moodle.show;
194         imscp_layout_widget = new Y.YUI2.widget.Layout('imscp_layout', {
195             minWidth: 600,
196             minHeight: 400,
197             units: [
198                 { position: 'left', body: 'imscp_toc', header: M.str.imscp.toc, width: 250, resize: true, gutter: '2px 5px 5px 2px', collapse: true, minWidth:150},
199                 { position: 'center', body: '<div id="imscp_content"></div>', gutter: '2px 5px 5px 2px', scroll: true}
200             ]
201         });
202         imscp_layout_widget.render();
203         var left = imscp_layout_widget.getUnitByPosition('left');
204         left.on('collapse', function() {
205             imscp_resize_frame();
206         });
207         left.on('expand', function() {
208             imscp_resize_frame();
209         });
211         // ugly resizing hack that works around problems with resizing of iframes and objects
212         left._resize.on('startResize', function() {
213             var obj = Y.YUI2.util.Dom.get('imscp_object');
214             obj.style.display = 'none';
215         });
216         left._resize.on('endResize', function() {
217             var obj = Y.YUI2.util.Dom.get('imscp_object');
218             obj.style.display = 'block';
219             imscp_resize_frame();
220         });
222         // TOC tree
223         var tree = new Y.YUI2.widget.TreeView('imscp_tree');
224         tree.singleNodeHighlight = true;
225         tree.subscribe('clickEvent', function(oArgs) {
226             imscp_activate_item(oArgs.node);
227             if (oArgs.node.children.length) {
228                 imscp_bloody_labelclick = true;
229             }
230             Y.YUI2.util.Event.preventDefault(oArgs.event);
231             return false;
232         });
233         tree.subscribe('collapse', function(node) {
234             if (imscp_bloody_labelclick) {
235                 imscp_bloody_labelclick = false;
236                 return false;
237             }
238         });
239         tree.subscribe('expand', function(node) {
240             if (imscp_bloody_labelclick) {
241                 imscp_bloody_labelclick = false;
242                 return false;
243             }
244         });
245         tree.expandAll();
246         tree.render();
248         var navbar = Y.YUI2.util.Dom.get('imscp_nav');
249         navbar.style.display = 'block';
251         // navigation
252         imscp_buttons[0] = new Y.YUI2.widget.Button('nav_skipprev');
253         imscp_buttons[1] = new Y.YUI2.widget.Button('nav_prev');
254         imscp_buttons[2] = new Y.YUI2.widget.Button('nav_up');
255         imscp_buttons[3] = new Y.YUI2.widget.Button('nav_next');
256         imscp_buttons[4] = new Y.YUI2.widget.Button('nav_skipnext');
257         imscp_buttons[0].on('click', function(ev) {
258             imscp_activate_item(imscp_skipprev(imscp_current_node));
259         });
260         imscp_buttons[1].on('click', function(ev) {
261             imscp_activate_item(imscp_prev(imscp_current_node));
262         });
263         imscp_buttons[2].on('click', function(ev) {
264             imscp_activate_item(imscp_up(imscp_current_node));
265         });
266         imscp_buttons[3].on('click', function(ev) {
267             imscp_activate_item(imscp_next(imscp_current_node));
268         });
269         imscp_buttons[4].on('click', function(ev) {
270             imscp_activate_item(imscp_skipnext(imscp_current_node));
271         });
273         // finally activate the first item
274         imscp_activate_item(tree.getRoot().children[0]);
276         // resizing
277         imscp_resize_layout(false);
279         // fix layout if window resized
280         window.onresize = function() {
281             imscp_resize_layout(true);
282         };
283     });