Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/* global ns */
2
/**
3
 * Adds a file upload field to the form.
4
 *
5
 * @param {mixed} parent
6
 * @param {object} field
7
 * @param {mixed} params
8
 * @param {function} setValue
9
 * @returns {ns.File}
10
 */
11
ns.File = function (parent, field, params, setValue) {
12
  var self = this;
13
 
14
  // Initialize inheritance
15
  ns.FileUploader.call(self, field);
16
 
17
  this.parent = parent;
18
  this.field = field;
19
  this.params = params;
20
  this.setValue = setValue;
21
  this.library = parent.library + '/' + field.name;
22
  this.id = ns.getNextFieldId(field);
23
 
24
  if (params !== undefined) {
25
    this.copyright = params.copyright;
26
  }
27
 
28
  this.changes = [];
29
  this.passReadies = true;
30
  parent.ready(function () {
31
    self.passReadies = false;
32
  });
33
 
34
  // Create remove file dialog
35
  this.confirmRemovalDialog = new H5P.ConfirmationDialog({
36
    headerText: H5PEditor.t('core', 'removeFile'),
37
    dialogText: H5PEditor.t('core', 'confirmRemoval', {':type': 'file'})
38
  }).appendTo(document.body);
39
 
40
  // Remove file on confirmation
41
  this.confirmRemovalDialog.on('confirmed', function () {
42
    delete self.params;
43
    self.setValue(self.field);
44
    self.addFile();
45
 
46
    for (var i = 0; i < self.changes.length; i++) {
47
      self.changes[i]();
48
    }
49
  });
50
 
51
  // When uploading starts
52
  self.on('upload', function () {
53
    // Insert throbber
54
    self.$file.html('<div class="h5peditor-uploading h5p-throbber">' + ns.t('core', 'uploading') + '</div>');
55
 
56
    // Clear old error messages
57
    self.$errors.html('');
58
  });
59
 
60
  // Monitor upload progress
61
  self.on('uploadProgress', function (e) {
62
    self.$file.children().html(ns.t('core', 'uploading') + ' ' + Math.round(e.data * 100) + ' %');
63
  });
64
 
65
  // Handle upload complete
66
  self.on('uploadComplete', function (event) {
67
    var result = event.data;
68
 
69
    try {
70
      if (result.error) {
71
        throw result.error;
72
      }
73
 
74
      self.params = self.params || {};
75
      self.params.path = result.data.path;
76
      self.params.mime = result.data.mime;
77
      self.params.copyright = self.copyright;
78
 
79
      // Make it possible for other widgets to process the result
80
      self.trigger('fileUploaded', result.data);
81
 
82
      self.setValue(self.field, self.params);
83
 
84
      for (var i = 0; i < self.changes.length; i++) {
85
        self.changes[i](self.params);
86
      }
87
    }
88
    catch (error) {
89
      self.$errors.append(ns.createError(error));
90
    }
91
 
92
    self.addFile();
93
  });
94
};
95
 
96
ns.File.prototype = Object.create(ns.FileUploader.prototype);
97
ns.File.prototype.constructor = ns.File;
98
 
99
/**
100
 * Append field to the given wrapper.
101
 *
102
 * @param {jQuery} $wrapper
103
 * @returns {undefined}
104
 */
105
ns.File.prototype.appendTo = function ($wrapper) {
106
  var self = this;
107
 
108
  var fileHtml =
109
    '<div class="file"></div>' +
110
    '<a class="h5p-copyright-button" href="#">' + ns.t('core', 'editCopyright') + '</a>' +
111
    '<div class="h5p-editor-dialog">' +
112
      '<a href="#" class="h5p-close" title="' + ns.t('core', 'close') + '"></a>' +
113
    '</div>';
114
 
115
  var html = ns.createFieldMarkup(this.field, fileHtml, this.id);
116
 
117
  var $container = ns.$(html).appendTo($wrapper);
118
  this.$copyrightButton = $container.find('.h5p-copyright-button');
119
  this.$file = $container.find('.file');
120
  this.$errors = $container.find('.h5p-errors');
121
  this.addFile();
122
 
123
  var $dialog = $container.find('.h5p-editor-dialog');
124
  $container.find('.h5p-copyright-button').add($dialog.find('.h5p-close')).click(function () {
125
    $dialog.toggleClass('h5p-open');
126
    return false;
127
  });
128
 
129
  ns.File.addCopyright(self, $dialog, function (field, value) {
130
    if (self.params !== undefined) {
131
      self.params.copyright = value;
132
    }
133
    self.copyright = value;
134
  });
135
 
136
};
137
 
138
/**
139
 * Help add copyright dialog to the given field
140
 *
141
 * @param {Object} field
142
 * @param {function} setCopyright
143
 */
144
ns.File.addCopyright = function (field, $dialog, setCopyright) {
145
 
146
  /**
147
   * Help find object in list with the given property value.
148
   *
149
   * @param {Object[]} list of objects to search through
150
   * @param {string} property to look for
151
   * @param {string} value to match property value against
152
   */
153
  var find = function (list, property, value) {
154
    var properties = property.split('.');
155
 
156
    for (var i = 0; i < list.length; i++) {
157
      var objProp = list[i];
158
 
159
      for (var j = 0; j < properties.length; j++) {
160
        objProp = objProp[properties[j]];
161
      }
162
 
163
      if (objProp === value) {
164
        return list[i];
165
      }
166
    }
167
  };
168
 
169
  // Re-map old licenses that have been moved
170
  if (field.copyright) {
171
    if (field.copyright.license === 'ODC PDDL') {
172
      field.copyright.license = 'PD';
173
      field.copyright.version = 'CC0 1.0';
174
    }
175
    else if (field.copyright.license === 'CC PDM') {
176
      field.copyright.license = 'PD';
177
      field.copyright.version = 'CC PDM';
178
    }
179
  }
180
 
181
  var group = new H5PEditor.widgets.group(field, H5PEditor.copyrightSemantics, field.copyright, setCopyright);
182
  // TODO: We'll have to do something here with metadataSemantics if we change the widgtets
183
  group.appendTo($dialog);
184
  group.expand();
185
  group.$group.find('.title').remove();
186
  field.children = [group];
187
 
188
  // Locate license and version selectors
189
  var licenseField = find(group.children, 'field.name', 'license');
190
  var versionField = find(group.children, 'field.name', 'version');
191
  versionField.field.optional = true; // Avoid any error messages
192
 
193
  // Listen for changes to license
194
  licenseField.changes.push(function (value) {
195
    // Find versions for selected value
196
    var option = find(licenseField.field.options, 'value', value);
197
    var versions = option.versions;
198
 
199
    versionField.$select.prop('disabled', versions === undefined);
200
    if (versions === undefined) {
201
      // If no versions add default
202
      versions = [{
203
        value: '-',
204
        label: '-'
205
      }];
206
    }
207
 
208
    // Find default selected version
209
    var selected = (field.copyright.license === value &&
210
                    field.copyright.version ? field.copyright.version : versions[0].value);
211
 
212
    // Update versions selector
213
    versionField.$select.html(H5PEditor.Select.createOptionsHtml(versions, selected)).change();
214
  });
215
 
216
  // Trigger update straight away
217
  licenseField.changes[licenseField.changes.length - 1](field.copyright.license);
218
};
219
 
220
/**
221
 * Creates thumbnail HTML and actions.
222
 *
223
 * @returns {Boolean}
224
 */
225
ns.File.prototype.addFile = function () {
226
  var that = this;
227
 
228
  if (this.params === undefined) {
229
 
230
    let html = '<a href="#" id="' + this.id + '" class="add"';
231
    if (this.field.description !== undefined) {
232
      html += ' aria-describedby="' + ns.getDescriptionId(this.id) + '"';
233
    }
234
    html += ' title="' + ns.t('core', 'addFile') + '">' +
235
      '<div class="h5peditor-field-file-upload-text">' + ns.t('core', 'add') + '</div>' +
236
    '</a>'
237
 
238
    this.$file.html(html).children('.add').click(function () {
239
      that.openFileSelector();
240
      return false;
241
    });
242
    this.$copyrightButton.addClass('hidden');
243
    return;
244
  }
245
 
246
  var thumbnail;
247
  if (this.field.type === 'image') {
248
    thumbnail = {};
249
    thumbnail.path = H5P.getPath(this.params.path, H5PEditor.contentId);
250
    thumbnail.height = 100;
251
    if (this.params.width !== undefined) {
252
      thumbnail.width = thumbnail.height * (this.params.width / this.params.height);
253
    }
254
  }
255
  else {
256
    thumbnail = ns.fileIcon;
257
  }
258
 
259
  var fileHtmlString = '<a href="#" id="' + this.id + '" title="' + ns.t('core', 'changeFile') + '" class="thumbnail"';
260
  if (this.field.description !== undefined) {
261
    fileHtmlString += ' aria-describedby="' + ns.getDescriptionId(this.id) + '"';
262
  }
263
  fileHtmlString += '><img ' +
264
      (thumbnail.width === undefined ? '' : ' width="' + thumbnail.width + '"') +
265
      'height="' + thumbnail.height + '"  '+
266
      'alt="' + (this.field.label === undefined ? '' : this.field.label) + '"/></a>' +
267
    '<a href="#" class="remove" title="' + ns.t('core', 'removeFile') + '"></a>';
268
 
269
  this.$file.html(fileHtmlString).children(':eq(0)').click(function () {
270
    that.openFileSelector();
271
    return false;
272
  }).children('img').attr('src', thumbnail.path).end().next().click(function () {
273
    that.confirmRemovalDialog.show(H5P.jQuery(this).offset().top);
274
    return false;
275
  });
276
  that.$copyrightButton.removeClass('hidden');
277
};
278
 
279
/**
280
 * Validate this item
281
 */
282
ns.File.prototype.validate = function () {
283
  return true;
284
};
285
 
286
/**
287
 * Remove this item.
288
 */
289
ns.File.prototype.remove = function () {
290
  // TODO: Check what happens when removed during upload.
291
  this.$file.parent().remove();
292
};
293
 
294
/**
295
 * Collect functions to execute once the tree is complete.
296
 *
297
 * @param {function} ready
298
 * @returns {undefined}
299
 */
300
ns.File.prototype.ready = function (ready) {
301
  if (this.passReadies) {
302
    this.parent.ready(ready);
303
  }
304
  else {
305
    ready();
306
  }
307
};
308
 
309
// Tell the editor what widget we are.
310
ns.widgets.file = ns.File;