Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/* global ns */
2
/**
3
 * Construct a library selector.
4
 *
5
 * @param {Array} libraries
6
 * @param {String} defaultLibrary
7
 * @param {Object} defaultParams
8
 * @returns {ns.LibrarySelector}
9
 */
10
ns.LibrarySelector = function (libraries, defaultLibrary, defaultParams) {
11
  var that = this;
12
 
13
  this.libraries = libraries;
14
 
15
  H5P.EventDispatcher.call(this);
16
 
17
  try {
18
    this.defaultParams = JSON.parse(defaultParams);
19
    if (!(this.defaultParams instanceof Object)) {
20
      throw true;
21
    }
22
  }
23
  catch (event) {
24
    // Content parameters are broken. Reset. (This allows for broken content to be reused without deleting it)
25
    this.defaultParams = {};
26
  }
27
 
28
  this.defaultLibrary = this.currentLibrary = defaultLibrary;
29
  this.defaultLibraryParameterized = defaultLibrary ? defaultLibrary.replace('.', '-').toLowerCase() : undefined;
30
 
31
  //Add tutorial and example link:
32
  this.$tutorialUrl = ns.$(
33
    '<a class="h5p-tutorial-url" target="_blank">' +
34
      '<span class="h5p-tutorial-url-label">' +
35
        ns.t('core', 'tutorial') +
36
      '</span>' +
37
    '</a>'
38
  ).hide();
39
  this.$exampleUrl = ns.$(
40
    '<a class="h5p-example-url" target="_blank">' +
41
      '<span class="h5p-example-url-label">' +
42
        ns.t('core', 'example') +
43
      '</span>' +
44
    '</a>'
45
  ).hide();
46
 
47
  // Create confirm dialog
48
  var changeLibraryDialog = new H5P.ConfirmationDialog({
49
    headerText: H5PEditor.t('core', 'changeLibrary'),
50
    dialogText: H5PEditor.t('core', 'confirmChangeLibrary')
51
  }).appendTo(document.body);
52
 
53
  if (H5PIntegration.hubIsEnabled) {
54
    this.selector = new ns.SelectorHub(libraries, defaultLibrary, changeLibraryDialog);
55
  }
56
  else {
57
    this.selector = new ns.SelectorLegacy(libraries, defaultLibrary, changeLibraryDialog);
58
  }
59
 
60
  this.$selector = ns.$(this.selector.getElement());
61
 
62
  /**
63
   * @private
64
   * @param {object} library
65
   */
66
  var librarySelectHandler = function (library) {
67
    that.currentLibrary = library.uberName;
68
    that.loadSemantics(library.uberName, that.selector.getParams(), that.selector.getMetadata());
69
 
70
    that.$tutorialUrl.attr('href', library.tutorialUrl ? library.tutorialUrl : '#').toggle(!!library.tutorialUrl);
71
    that.$exampleUrl.attr('href', library.exampleUrl ? library.exampleUrl : '#').toggle(!!library.exampleUrl);
72
  };
73
 
74
  /**
75
   * Event handler for loading a new library editor
76
   * @private
77
   */
78
  var loadLibrary = function () {
79
    that.trigger('editorload', that.selector.currentLibrary);
80
    that.selector.getSelectedLibrary(librarySelectHandler);
81
  };
82
 
83
  /**
84
   * Confirm replace if there is content selected
85
   *
86
   * @param {number} top Offset
87
   * @param {function} next Next callback
88
   */
89
  this.confirmPasteError = function (message, top, next) {
90
    // Confirm changing library
91
    var confirmReplace = new H5P.ConfirmationDialog({
92
      headerText: H5PEditor.t('core', 'pasteError'),
93
      dialogText: message,
94
      cancelText: ' ',
95
      confirmText: H5PEditor.t('core', 'ok')
96
    }).appendTo(document.body);
97
    confirmReplace.on('confirmed', next);
98
    confirmReplace.show(top);
99
  };
100
 
101
  // Change library on confirmation
102
  changeLibraryDialog.on('confirmed', loadLibrary);
103
 
104
  // Revert selector on cancel
105
  changeLibraryDialog.on('canceled', function () {
106
    that.selector.resetSelection(that.currentLibrary, that.defaultParams, that.form.metadata, true);
107
  });
108
 
109
  // First time a library is selected in the editor
110
  this.selector.on('selected', loadLibrary);
111
 
112
  this.selector.on('resize', function () {
113
    that.trigger('resize');
114
  });
115
 
116
  this.on('select', loadLibrary);
117
  H5P.externalDispatcher.on('datainclipboard', this.updateCopyPasteButtons.bind(this));
118
  this.selector.on('paste', this.pasteContent.bind(this));
119
};
120
 
121
// Extends the event dispatcher
122
ns.LibrarySelector.prototype = Object.create(H5P.EventDispatcher.prototype);
123
ns.LibrarySelector.prototype.constructor = ns.LibrarySelector;
124
 
125
/**
126
 * Sets the current library
127
 *
128
 * @param {string} library
129
 */
130
ns.LibrarySelector.prototype.setLibrary = function (library) {
131
  this.trigger('select');
132
};
133
 
134
/**
135
 * Append the selector html to the given container.
136
 *
137
 * @param {jQuery} $element
138
 * @returns {undefined}
139
 */
140
ns.LibrarySelector.prototype.appendTo = function ($element) {
141
  var self = this;
142
  this.$parent = $element;
143
 
144
  /*
145
    Start Moodle change
146
    This line is commented out to prevent display of the hub selector in Moodle.
147
    For more information see MDL-67814.
148
  */
149
  // this.$selector.appendTo($element);
150
  /* End Moodle change */
151
  this.$tutorialUrl.appendTo($element);
152
  this.$exampleUrl.appendTo($element);
153
 
154
  if (window.localStorage) {
155
    var $buttons = ns.$(ns.createCopyPasteButtons()).appendTo($element);
156
 
157
    // Hide copy paste until library is selected:
158
    $buttons.addClass('hidden');
159
    self.on('editorloaded', function () {
160
      $buttons.removeClass('hidden');
161
    });
162
 
163
    this.$copyButton = $buttons.find('.h5peditor-copy-button').click(function () {
164
      H5P.clipboardify({
165
        library: self.getCurrentLibrary(),
166
        params: self.getParams(),
167
        metadata: self.getMetadata()
168
      });
169
      ns.attachToastTo(
170
        self.$copyButton.get(0),
171
        H5PEditor.t('core', 'copiedToClipboard'), {
172
          position: {
173
            horizontal: 'center',
174
            vertical: 'above',
175
            noOverflowX: true
176
          }
177
        }
178
      );
179
    });
180
    this.$pasteButton = $buttons.find('.h5peditor-paste-button')
181
      .click(self.pasteContent.bind(this));
182
 
183
    self.updateCopyPasteButtons();
184
  }
185
};
186
 
187
/**
188
 * Update state of copy and paste buttons dependent on what is currently in
189
 * the clipboard
190
 */
191
ns.LibrarySelector.prototype.updateCopyPasteButtons = function () {
192
  if (!window.localStorage) {
193
    return;
194
  }
195
 
196
  // Check if content type is supported here
197
  const pasteCheck = ns.canPastePlus(H5P.getClipboard(), this.libraries);
198
  const canPaste = pasteCheck.canPaste;
199
 
200
  this.$copyButton
201
    .prop('disabled', false)
202
    .toggleClass('disabled', false);
203
 
204
  this.$pasteButton
205
    .text(ns.t('core', 'pasteAndReplaceButton'))
206
    .attr('title', canPaste ? ns.t('core', 'pasteAndReplaceFromClipboard') : pasteCheck.description)
207
    .toggleClass('disabled', !canPaste)
208
    .prop('disabled', !canPaste);
209
 
210
  this.selector.setCanPaste && this.selector.setCanPaste(canPaste, !canPaste ? pasteCheck.description : undefined);
211
};
212
 
213
/**
214
 * Sets the current library
215
 *
216
 * @param {string} library
217
 */
218
ns.LibrarySelector.prototype.pasteContent = function () {
219
  var self = this;
220
  var clipboard = H5P.getClipboard();
221
 
222
  ns.confirmReplace(self.getCurrentLibrary(), self.$parent.offset().top, function () {
223
    self.selector.resetSelection(clipboard.generic.library, clipboard.generic.params, clipboard.generic.metadata, false);
224
    self.setLibrary();
225
  });
226
};
227
 
228
/**
229
 * Display loading message and load library semantics.
230
 *
231
 * @param {String} library
232
 * @param {Object} params Pass in params to semantics
233
 * @returns {unresolved}
234
 */
235
ns.LibrarySelector.prototype.loadSemantics = function (library, params, metadata) {
236
  var that = this;
237
 
238
  if (this.form !== undefined) {
239
    // Remove old form.
240
    this.form.remove();
241
  }
242
 
243
  if (library === '-') {
244
    // No library chosen.
245
    this.$parent.attr('class', 'h5peditor');
246
    return;
247
  }
248
  this.$parent.attr('class', 'h5peditor ' + library.split(' ')[0].toLowerCase().replace('.', '-') + '-editor');
249
 
250
  // Display loading message
251
  var $loading = ns.$('<div class="h5peditor-loading h5p-throbber">' + ns.t('core', 'loading') + '</div>').appendTo(this.$parent);
252
 
253
  this.$selector.attr('disabled', true);
254
 
255
  ns.resetLoadedLibraries();
256
  ns.loadLibrary(library, function (semantics) {
257
    if (!semantics) {
258
      that.form = ns.$('<div/>', {
259
        'class': 'h5p-errors',
260
        text: H5PEditor.t('core', 'noSemantics'),
261
        insertAfter: $loading
262
      });
263
    }
264
    else {
265
      var overrideParams = {};
266
      if (params) {
267
        overrideParams = params;
268
        that.defaultParams = overrideParams;
269
      }
270
      else if (library === that.defaultLibrary || library === that.defaultLibraryParameterized) {
271
        overrideParams = that.defaultParams;
272
      }
273
 
274
      if (!metadata) {
275
        metadata = overrideParams.metadata;
276
      }
277
      const defaultLanguage = metadata && metadata.defaultLanguage
278
        ? metadata.defaultLanguage
279
        : null;
280
      that.form = new ns.Form(
281
        library,
282
        ns.libraryCache[library].languages,
283
        defaultLanguage
284
      );
285
      that.form.replace($loading);
286
      that.form.currentLibrary = library;
287
      that.form.processSemantics(semantics, overrideParams, metadata);
288
      that.updateCopyPasteButtons();
289
    }
290
 
291
    that.$selector.attr('disabled', false);
292
    $loading.remove();
293
    that.trigger('editorloaded', library);
294
  });
295
};
296
 
297
/**
298
 * Returns currently selected library
299
 *
300
 * @returns {string} Currently selected library
301
 */
302
ns.LibrarySelector.prototype.getCurrentLibrary = function () {
303
  return this.currentLibrary;
304
};
305
 
306
/**
307
 * Return params needed to start library.
308
 */
309
ns.LibrarySelector.prototype.getParams = function () {
310
  if (this.form === undefined) {
311
    return;
312
  }
313
 
314
  // Only return if all fields has validated.
315
  //var valid = true;
316
 
317
  if (this.form.metadataForm.children !== undefined) {
318
    for (var i = 0; i < this.form.metadataForm.children.length; i++) {
319
      if (this.form.metadataForm.children[i].validate() === false) {
320
        //valid = false;
321
      }
322
    }
323
  }
324
 
325
  if (this.form.children !== undefined) {
326
    for (var i = 0; i < this.form.children.length; i++) {
327
      if (this.form.children[i].validate() === false) {
328
        //valid = false;
329
      }
330
    }
331
  }
332
 
333
  //return valid ? this.form.params : false;
334
  return this.form.params; // TODO: Switch to the line above when we are able to tell the user where the validation fails
335
};
336
 
337
/**
338
 * Get the metadata of the main form.
339
 *
340
 * @return {object} Metadata object.
341
 */
342
ns.LibrarySelector.prototype.getMetadata = function () {
343
  if (this.form === undefined) {
344
    return;
345
  }
346
 
347
  return this.form.metadata;
348
};
349
 
350
/**
351
 *
352
 * @param content
353
 * @param library
354
 * @returns {H5PEditor.Presave} Result after processing library and content
355
 */
356
ns.LibrarySelector.prototype.presave = function (content, library) {
357
  return (new ns.Presave).process(library, content);
358
};