Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 22... Línea 22...
22
 */
22
 */
23
define([
23
define([
24
    'jquery',
24
    'jquery',
25
    'core/dragdrop',
25
    'core/dragdrop',
26
    'core/key_codes',
26
    'core/key_codes',
27
    'core_form/changechecker'
27
    'core_form/changechecker',
-
 
28
    'core_filters/events',
28
], function(
29
], function(
29
    $,
30
    $,
30
    dragDrop,
31
    dragDrop,
31
    keys,
32
    keys,
32
    FormChangeChecker
33
    FormChangeChecker,
-
 
34
    filterEvent
33
) {
35
) {
Línea 34... Línea 36...
34
 
36
 
Línea 35... Línea 37...
35
    "use strict";
37
    "use strict";
Línea 43... Línea 45...
43
     * @constructor
45
     * @constructor
44
     */
46
     */
45
    function DragDropOntoImageQuestion(containerId, readOnly, places) {
47
    function DragDropOntoImageQuestion(containerId, readOnly, places) {
46
        this.containerId = containerId;
48
        this.containerId = containerId;
47
        this.questionAnswer = {};
49
        this.questionAnswer = {};
-
 
50
        this.questionDragDropWidthHeight = [];
48
        M.util.js_pending('qtype_ddimageortext-init-' + this.containerId);
51
        M.util.js_pending('qtype_ddimageortext-init-' + this.containerId);
49
        this.places = places;
52
        this.places = places;
50
        this.allImagesLoaded = false;
53
        this.allImagesLoaded = false;
51
        this.imageLoadingTimeoutId = null;
54
        this.imageLoadingTimeoutId = null;
52
        this.isPrinting = false;
55
        this.isPrinting = false;
Línea 60... Línea 63...
60
        });
63
        });
61
        this.waitForAllImagesToBeLoaded();
64
        this.waitForAllImagesToBeLoaded();
62
    }
65
    }
Línea 63... Línea 66...
63
 
66
 
-
 
67
    /**
-
 
68
     * Change all the drags and drops related to the item that has been changed by filter to correct size and content.
-
 
69
     *
-
 
70
     *  @param {object} filteredElement the element has been modified by filter.
-
 
71
     */
-
 
72
    DragDropOntoImageQuestion.prototype.changeAllDragsAndDropsToFilteredContent = function(filteredElement) {
-
 
73
        let currentFilteredItem = $(filteredElement);
-
 
74
        const parentIsDD = currentFilteredItem.parent().closest('div').hasClass('placed') ||
-
 
75
            currentFilteredItem.parent().hasClass('draghome');
-
 
76
        const isDD = currentFilteredItem.hasClass('placed') || currentFilteredItem.hasClass('draghome');
-
 
77
        // The filtered element or parent element should a drag or drop item.
-
 
78
        if (!parentIsDD && !isDD) {
-
 
79
            return;
-
 
80
        }
-
 
81
        if (parentIsDD) {
-
 
82
            currentFilteredItem = currentFilteredItem.parent().closest('div');
-
 
83
        }
-
 
84
        if (this.getRoot().find(currentFilteredItem).length <= 0) {
-
 
85
            // If the DD item doesn't belong to this question
-
 
86
            // In case we have multiple questions in the same page.
-
 
87
            return;
-
 
88
        }
-
 
89
        const group = this.getGroup(currentFilteredItem),
-
 
90
            choice = this.getChoice(currentFilteredItem);
-
 
91
        let listOfModifiedDragDrop = [];
-
 
92
        // Get the list of drag and drop item within the same group and choice.
-
 
93
        this.getRoot().find('.group' + group + '.choice' + choice).each(function(i, node) {
-
 
94
            // Same modified item, skip it.
-
 
95
            if ($(node).get(0) === currentFilteredItem.get(0)) {
-
 
96
                return;
-
 
97
            }
-
 
98
            const originalClass = $(node).attr('class');
-
 
99
            const originalStyle = $(node).attr('style');
-
 
100
            // We want to keep all the handler and event for filtered item, so using clone is the only choice.
-
 
101
            const filteredDragDropClone = currentFilteredItem.clone();
-
 
102
            // Sometimes, for the question that has a lot of input groups and unlimited draggable items,
-
 
103
            // this 'clone' process takes longer than usual,it will not add the eventHandler for this cloned drag.
-
 
104
            // We need to make sure to add the eventHandler for the cloned drag too.
-
 
105
            questionManager.addEventHandlersToDrag(filteredDragDropClone);
-
 
106
            // Replace the class and style of the drag drop item we want to replace for the clone.
-
 
107
            filteredDragDropClone.attr('class', originalClass);
-
 
108
            filteredDragDropClone.attr('style', originalStyle);
-
 
109
            // Insert into DOM.
-
 
110
            $(node).before(filteredDragDropClone);
-
 
111
            // Add the item has been replaced to a list so we can remove it later.
-
 
112
            listOfModifiedDragDrop.push(node);
-
 
113
        });
-
 
114
 
-
 
115
        listOfModifiedDragDrop.forEach(function(node) {
-
 
116
            $(node).remove();
-
 
117
        });
-
 
118
        // Save the current height and width.
-
 
119
        const currentHeight = currentFilteredItem.height();
-
 
120
        const currentWidth = currentFilteredItem.width();
-
 
121
        // Set to auto, so we can get the real height and width of the filtered item.
-
 
122
        currentFilteredItem.height('auto');
-
 
123
        currentFilteredItem.width('auto');
-
 
124
        // We need to set display block so we can get height and width.
-
 
125
        // Some browsers can't get the offsetWidth/Height if they are an inline element like span tag.
-
 
126
        if (!filteredElement.offsetWidth || !filteredElement.offsetHeight) {
-
 
127
            filteredElement.classList.add('d-block');
-
 
128
        }
-
 
129
        if (this.questionDragDropWidthHeight[group].maxWidth < Math.ceil(filteredElement.offsetWidth) ||
-
 
130
            this.questionDragDropWidthHeight[group].maxHeight < Math.ceil(0 + filteredElement.offsetHeight)) {
-
 
131
            // Remove the d-block class before calculation.
-
 
132
            filteredElement.classList.remove('d-block');
-
 
133
            // Now resize all the items in the same group if we have new maximum width or height.
-
 
134
            this.resizeAllDragsAndDropsInGroup(group);
-
 
135
        } else {
-
 
136
            // Calculate the top padding.
-
 
137
            const top = Math.floor((this.questionDragDropWidthHeight[group].maxHeight - filteredElement.offsetHeight) / 2);
-
 
138
            // Set top padding so the content of filtered item is center again.
-
 
139
            currentFilteredItem.width(currentWidth).height(currentHeight).css({
-
 
140
                'padding-top': top + 'px',
-
 
141
            });
-
 
142
        }
-
 
143
        // Remove the d-block class after resize.
-
 
144
        filteredElement.classList.remove('d-block');
-
 
145
    };
-
 
146
 
64
    /**
147
    /**
65
     * Waits until all images are loaded before calling setupQuestion().
148
     * Waits until all images are loaded before calling setupQuestion().
66
     *
149
     *
67
     * This function is called from the onLoad of each image, and also polls with
150
     * This function is called from the onLoad of each image, and also polls with
68
     * a time-out, because image on-loads are allegedly unreliable.
151
     * a time-out, because image on-loads are allegedly unreliable.
Línea 92... Línea 175...
92
        }
175
        }
Línea 93... Línea 176...
93
 
176
 
94
        // We now have all images. Carry on, but only after giving the layout a chance to settle down.
177
        // We now have all images. Carry on, but only after giving the layout a chance to settle down.
95
        this.allImagesLoaded = true;
178
        this.allImagesLoaded = true;
-
 
179
        thisQ.setupQuestion();
-
 
180
        // Wait for all dynamic content loaded by filter to be completed.
-
 
181
        document.addEventListener(filterEvent.eventTypes.filterContentRenderingComplete, (elements) => {
-
 
182
            elements.detail.nodes.forEach((element) => {
-
 
183
                thisQ.changeAllDragsAndDropsToFilteredContent(element);
-
 
184
            });
96
        thisQ.setupQuestion();
185
        });
Línea 97... Línea 186...
97
    };
186
    };
98
 
187
 
99
    /**
188
    /**
Línea 133... Línea 222...
133
     */
222
     */
134
    DragDropOntoImageQuestion.prototype.resizeAllDragsAndDrops = function() {
223
    DragDropOntoImageQuestion.prototype.resizeAllDragsAndDrops = function() {
135
        var thisQ = this;
224
        var thisQ = this;
136
        this.getRoot().find('.draghomes > div').each(function(i, node) {
225
        this.getRoot().find('.draghomes > div').each(function(i, node) {
137
            thisQ.resizeAllDragsAndDropsInGroup(
226
            thisQ.resizeAllDragsAndDropsInGroup(
138
                    thisQ.getClassnameNumericSuffix($(node), 'dragitemgroup'));
227
                thisQ.getClassnameNumericSuffix($(node), 'dragitemgroup'));
139
        });
228
        });
140
    };
229
    };
Línea 141... Línea 230...
141
 
230
 
142
    /**
231
    /**
143
     * In a given group, set all the drags and drops to be the same size.
232
     * In a given group, set all the drags and drops to be the same size.
144
     *
233
     *
145
     * @param {int} group the group number.
234
     * @param {int} group the group number.
146
     */
235
     */
147
    DragDropOntoImageQuestion.prototype.resizeAllDragsAndDropsInGroup = function(group) {
236
    DragDropOntoImageQuestion.prototype.resizeAllDragsAndDropsInGroup = function(group) {
148
        var root = this.getRoot(),
237
        var root = this.getRoot(),
149
            dragHomes = root.find('.dragitemgroup' + group + ' .draghome'),
238
            dragHomes = root.find(".draghome.group" + group),
150
            maxWidth = 0,
239
            maxWidth = 0,
Línea 151... Línea 240...
151
            maxHeight = 0;
240
            maxHeight = 0;
152
 
241
 
Línea 157... Línea 246...
157
        });
246
        });
Línea 158... Línea 247...
158
 
247
 
159
        // The size we will want to set is a bit bigger than this.
248
        // The size we will want to set is a bit bigger than this.
160
        maxWidth += 10;
249
        maxWidth += 10;
-
 
250
        maxHeight += 10;
Línea 161... Línea 251...
161
        maxHeight += 10;
251
        this.questionDragDropWidthHeight[group] = {maxWidth, maxHeight};
162
 
252
 
163
        // Set each drag home to that size.
-
 
164
        dragHomes.each(function(i, drag) {
253
        // Set each drag home to that size.
165
            var left = Math.round((maxWidth - drag.offsetWidth) / 2),
254
        dragHomes.each(function(i, drag) {
166
                top = Math.floor((maxHeight - drag.offsetHeight) / 2);
-
 
167
            // Set top and left padding so the item is centred.
-
 
168
            $(drag).css({
255
            const top = Math.floor((maxHeight - drag.offsetHeight) / 2);
169
                'padding-left': left + 'px',
256
            // Set top padding so the item is centred.
170
                'padding-right': (maxWidth - drag.offsetWidth - left) + 'px',
-
 
171
                'padding-top': top + 'px',
257
            $(drag).width(maxWidth).height(maxHeight).css({
172
                'padding-bottom': (maxHeight - drag.offsetHeight - top) + 'px'
258
                'padding-top': top + 'px',
Línea 173... Línea 259...
173
            });
259
            });
174
        });
260
        });
Línea 184... Línea 270...
184
                continue;
270
                continue;
185
            }
271
            }
186
            if (label === '') {
272
            if (label === '') {
187
                label = M.util.get_string('blank', 'qtype_ddimageortext');
273
                label = M.util.get_string('blank', 'qtype_ddimageortext');
188
            }
274
            }
-
 
275
            if (root.find('.dropzones .dropzone.group' + place.group + '.place' + i).length === 0) {
189
            root.find('.dropzones').append('<div class="dropzone active group' + place.group +
276
                root.find('.dropzones').append('<div class="dropzone active group' + place.group +
190
                            ' place' + i + '" tabindex="0">' +
277
                    ' place' + i + '" tabindex="0">' +
191
                    '<span class="accesshide">' + label + '</span>&nbsp;</div>');
278
                    '<span class="accesshide">' + label + '</span>&nbsp;</div>');
-
 
279
            }
192
            root.find('.dropzone.place' + i).width(maxWidth - 2).height(maxHeight - 2);
280
            root.find('.dropzone.place' + i).width(maxWidth - 2).height(maxHeight - 2);
193
        }
281
        }
194
    };
282
    };
Línea 195... Línea 283...
195
 
283