Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/* global YUI */
2
 
3
/**
4
 * A collection of utility classes for use with pages.
5
 *
6
 * @module moodle-mod_quiz-util
7
 * @submodule moodle-mod_quiz-util-page
8
 */
9
 
10
Y.namespace('Moodle.mod_quiz.util.page');
11
 
12
/**
13
 * A collection of utility classes for use with pages.
14
 *
15
 * @class Moodle.mod_quiz.util.page
16
 * @static
17
 */
18
Y.Moodle.mod_quiz.util.page = {
19
    CSS: {
20
        PAGE: 'page'
21
    },
22
    CONSTANTS: {
23
        ACTIONMENUIDPREFIX: 'action-menu-',
24
        ACTIONMENUBARIDSUFFIX: '-menubar',
25
        ACTIONMENUMENUIDSUFFIX: '-menu',
26
        PAGEIDPREFIX: 'page-',
27
        PAGENUMBERPREFIX: M.util.get_string('page', 'moodle') + ' '
28
    },
29
    SELECTORS: {
30
        ACTIONMENU: 'div.moodle-actionmenu',
31
        ACTIONMENUBAR: '.menubar',
32
        ACTIONMENUMENU: '.menu',
33
        ADDASECTION: '[data-action="addasection"]',
34
        PAGE: 'li.page',
35
        INSTANCENAME: '.instancename',
36
        NUMBER: 'h4'
37
    },
38
 
39
    /**
40
     * Retrieve the page item from one of it's child Nodes.
41
     *
42
     * @method getPageFromComponent
43
     * @param pagecomponent {Node} The component Node.
44
     * @return {Node|null} The Page Node.
45
     */
46
    getPageFromComponent: function(pagecomponent) {
47
        return Y.one(pagecomponent).ancestor(this.SELECTORS.PAGE, true);
48
    },
49
 
50
    /**
51
     * Retrieve the page item from one of it's previous siblings.
52
     *
53
     * @method getPageFromSlot
54
     * @param pagecomponent {Node} The component Node.
55
     * @return {Node|null} The Page Node.
56
     */
57
    getPageFromSlot: function(slot) {
58
        return Y.one(slot).previous(this.SELECTORS.PAGE);
59
    },
60
 
61
    /**
62
     * Returns the page ID for the provided page.
63
     *
64
     * @method getId
65
     * @param page {Node} The page to find an ID for.
66
     * @return {Number|false} The ID of the page in question or false if no ID was found.
67
     */
68
    getId: function(page) {
69
        // We perform a simple substitution operation to get the ID.
70
        var id = page.get('id').replace(
71
                this.CONSTANTS.PAGEIDPREFIX, '');
72
 
73
        // Attempt to validate the ID.
74
        id = parseInt(id, 10);
75
        if (typeof id === 'number' && isFinite(id)) {
76
            return id;
77
        }
78
        return false;
79
    },
80
 
81
    /**
82
     * Updates the page id for the provided page.
83
     *
84
     * @method setId
85
     * @param page {Node} The page to update the number for.
86
     * @param id int The id value.
87
     * @return void
88
     */
89
    setId: function(page, id) {
90
        page.set('id', this.CONSTANTS.PAGEIDPREFIX + id);
91
    },
92
 
93
    /**
94
     * Determines the page name for the provided page.
95
     *
96
     * @method getName
97
     * @param page {Node} The page to find a name for.
98
     * @return {string|false} The name of the page in question or false if no ID was found.
99
     */
100
    getName: function(page) {
101
        var instance = page.one(this.SELECTORS.INSTANCENAME);
102
        if (instance) {
103
            return instance.get('firstChild').get('data');
104
        }
105
        return null;
106
    },
107
 
108
    /**
109
     * Determines the page number for the provided page.
110
     *
111
     * @method getNumber
112
     * @param page {Node} The page to find a number for.
113
     * @return {Number|false} The number of the page in question or false if no number was found.
114
     */
115
    getNumber: function(page) {
116
        // We perform a simple substitution operation to get the number.
117
        var number = page.one(this.SELECTORS.NUMBER).get('text').replace(
118
                this.CONSTANTS.PAGENUMBERPREFIX, '');
119
 
120
        // Attempt to validate the ID.
121
        number = parseInt(number, 10);
122
        if (typeof number === 'number' && isFinite(number)) {
123
            return number;
124
        }
125
        return false;
126
    },
127
 
128
    /**
129
     * Updates the page number for the provided page.
130
     *
131
     * @method setNumber
132
     * @param page {Node} The page to update the number for.
133
     * @return void
134
     */
135
    setNumber: function(page, number) {
136
        page.one(this.SELECTORS.NUMBER).set('text', this.CONSTANTS.PAGENUMBERPREFIX + number);
137
    },
138
 
139
    /**
140
     * Returns a list of all page elements.
141
     *
142
     * @method getPages
143
     * @return {node[]} An array containing page nodes.
144
     */
145
    getPages: function() {
146
        return Y.all(Y.Moodle.mod_quiz.util.slot.SELECTORS.PAGECONTENT + ' ' +
147
                     Y.Moodle.mod_quiz.util.slot.SELECTORS.SECTIONUL + ' ' +
148
                    this.SELECTORS.PAGE);
149
    },
150
 
151
    /**
152
     * Is the given element a page element?
153
     *
154
     * @method isPage
155
     * @param page Page node
156
     * @return boolean
157
     */
158
    isPage: function(page) {
159
        if (!page) {
160
            return false;
161
        }
162
        return page.hasClass(this.CSS.PAGE);
163
    },
164
 
165
    /**
166
     * Does the page have atleast one slot?
167
     *
168
     * @method isEmpty
169
     * @param page Page node
170
     * @return boolean
171
     */
172
    isEmpty: function(page) {
173
        var activity = page.next('li.activity');
174
        if (!activity) {
175
            return true;
176
        }
177
        return !activity.hasClass('slot');
178
    },
179
 
180
    /**
181
     * Add a page and related elements to the list of slots.
182
     *
183
     * @method add
184
     * @param beforenode Int | Node | HTMLElement | String to add
185
     * @return page Page node
186
     */
187
    add: function(beforenode) {
188
        var pagenumber = this.getNumber(this.getPageFromSlot(beforenode)) + 1;
189
        var pagehtml = M.mod_quiz.resource_toolbox.get('config').pagehtml;
190
 
191
        // Normalise the page number.
192
        pagehtml = pagehtml.replace(/%%PAGENUMBER%%/g, pagenumber);
193
 
194
        // Create the page node.
195
        var page = Y.Node.create(pagehtml);
196
 
197
        // Assign is as a drop target.
198
        YUI().use('dd-drop', function(Y) {
199
            var drop = new Y.DD.Drop({
200
                node: page,
201
                groups: M.mod_quiz.dragres.groups
202
            });
203
            page.drop = drop;
204
        });
205
 
206
        // Insert in the correct place.
207
        beforenode.insert(page, 'after');
208
 
209
        // Enhance the add menu to make if fully visible and clickable.
210
        if (typeof M.core.actionmenu !== "undefined") {
211
            M.core.actionmenu.newDOMNode(page);
212
        }
213
        return page;
214
    },
215
 
216
    /**
217
     * Remove a page and related elements from the list of slots.
218
     *
219
     * @method remove
220
     * @param page Page node
221
     * @return void
222
     */
223
    remove: function(page, keeppagebreak) {
224
        // Remove page break from previous slot.
225
        var previousslot = page.previous(Y.Moodle.mod_quiz.util.slot.SELECTORS.SLOT);
226
        if (!keeppagebreak && previousslot) {
227
            Y.Moodle.mod_quiz.util.slot.removePageBreak(previousslot);
228
        }
229
        page.remove();
230
    },
231
 
232
    /**
233
     * Reset the order of the numbers given to each page.
234
     *
235
     * @method reorderPages
236
     * @return void
237
     */
238
    reorderPages: function() {
239
        // Get list of page nodes.
240
        var pages = this.getPages();
241
        var currentpagenumber = 0;
242
        // Loop through pages incrementing the number each time.
243
        pages.each(function(page) {
244
            // Is the page empty?
245
            if (this.isEmpty(page)) {
246
                var keeppagebreak = page.next('li.slot') ? true : false;
247
                this.remove(page, keeppagebreak);
248
                return;
249
            }
250
 
251
            currentpagenumber++;
252
            // Set page number.
253
            this.setNumber(page, currentpagenumber);
254
            this.setId(page, currentpagenumber);
255
        }, this);
256
 
257
        // Reorder action menus
258
        this.reorderActionMenus();
259
    },
260
 
261
    /**
262
     * Reset the order of the numbers given to each action menu.
263
     *
264
     * @method reorderActionMenus
265
     * @return void
266
     */
267
    reorderActionMenus: function() {
268
        // Get list of action menu nodes.
269
        var actionmenus = this.getActionMenus();
270
        // Loop through pages incrementing the number each time.
271
        actionmenus.each(function(actionmenu, key) {
272
            var previousActionMenu = actionmenus.item(key - 1),
273
                previousActionMenunumber = 0;
274
            if (previousActionMenu) {
275
                previousActionMenunumber = this.getActionMenuId(previousActionMenu);
276
            }
277
            var id = previousActionMenunumber + 1;
278
 
279
            // Set menu id.
280
            this.setActionMenuId(actionmenu, id);
281
 
282
            // Update action-menu-1-menubar
283
            var menubar = actionmenu.one(this.SELECTORS.ACTIONMENUBAR);
284
            menubar.set('id', this.CONSTANTS.ACTIONMENUIDPREFIX + id + this.CONSTANTS.ACTIONMENUBARIDSUFFIX);
285
 
286
            // Update action-menu-1-menu
287
            var menumenu = actionmenu.one(this.SELECTORS.ACTIONMENUMENU);
288
            menumenu.set('id', this.CONSTANTS.ACTIONMENUIDPREFIX + id + this.CONSTANTS.ACTIONMENUMENUIDSUFFIX);
289
 
290
            // Update the URL of the add-section action.
291
            menumenu.one(this.SELECTORS.ADDASECTION).set('href',
292
                menumenu.one(this.SELECTORS.ADDASECTION).get('href').replace(/\baddsectionatpage=\d+\b/, 'addsectionatpage=' + id));
293
 
294
        }, this);
295
    },
296
 
297
    /**
298
     * Returns a list of all page elements.
299
     *
300
     * @method getActionMenus
301
     * @return {node[]} An array containing page nodes.
302
     */
303
    getActionMenus: function() {
304
        return Y.all(Y.Moodle.mod_quiz.util.slot.SELECTORS.PAGECONTENT + ' ' +
305
                     Y.Moodle.mod_quiz.util.slot.SELECTORS.SECTIONUL + ' ' +
306
                     this.SELECTORS.ACTIONMENU);
307
    },
308
 
309
    /**
310
     * Returns the ID for the provided action menu.
311
     *
312
     * @method getId
313
     * @param actionmenu {Node} The actionmenu to find an ID for.
314
     * @return {Number|false} The ID of the actionmenu in question or false if no ID was found.
315
     */
316
    getActionMenuId: function(actionmenu) {
317
        // We perform a simple substitution operation to get the ID.
318
        var id = actionmenu.get('id').replace(
319
                this.CONSTANTS.ACTIONMENUIDPREFIX, '');
320
 
321
        // Attempt to validate the ID.
322
        id = parseInt(id, 10);
323
        if (typeof id === 'number' && isFinite(id)) {
324
            return id;
325
        }
326
        return false;
327
    },
328
 
329
    /**
330
     * Updates the page id for the provided page.
331
     *
332
     * @method setId
333
     * @param page {Node} The page to update the number for.
334
     * @param id int The id value.
335
     * @return void
336
     */
337
    setActionMenuId: function(actionmenu, id) {
338
        actionmenu.set('id', this.CONSTANTS.ACTIONMENUIDPREFIX + id);
339
    }
340
};