Projet

Général

Profil

Paste
Télécharger (7,81 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / media / js / media.filter.js @ 74f6bef0

1
/**
2
 *  @file
3
 *  File with utilities to handle media in html editing.
4
 */
5
(function ($) {
6

    
7
  Drupal.media = Drupal.media || {};
8
  /**
9
   * Utility to deal with media tokens / placeholders.
10
   */
11
  Drupal.media.filter = {
12
    /**
13
     * Replaces media tokens with the placeholders for html editing.
14
     * @param content
15
     */
16
    replaceTokenWithPlaceholder: function(content) {
17
      var tagmap = Drupal.media.filter.ensure_tagmap(),
18
        matches = content.match(/\[\[.*?\]\]/g),
19
        media_definition,
20
        id = 0;
21

    
22
      if (matches) {
23
        var i = 1;
24
        for (var macro in tagmap) {
25
          var index = $.inArray(macro, matches);
26
          if (index !== -1) {
27
            var media_json = macro.replace('[[', '').replace(']]', '');
28

    
29
            // Make sure that the media JSON is valid.
30
            try {
31
              media_definition = JSON.parse(media_json);
32
            }
33
            catch (err) {
34
              media_definition = null;
35
            }
36
            if (media_definition) {
37
              // Apply attributes.
38
              var element = Drupal.media.filter.create_element(tagmap[macro], media_definition);
39
              var markup = Drupal.media.filter.outerHTML(element);
40

    
41
              content = content.replace(macro, Drupal.media.filter.getWrapperStart(i) + markup + Drupal.media.filter.getWrapperEnd(i));
42
            }
43
          }
44
          i++;
45
        }
46
      }
47
      return content;
48
    },
49

    
50
    /**
51
     * Replaces the placeholders for html editing with the media tokens to store.
52
     * @param content
53
     */
54
    replacePlaceholderWithToken: function(content) {
55
      var tagmap = Drupal.media.filter.ensure_tagmap();
56
      var i = 1;
57
      for (var macro in tagmap) {
58
        var startTag = Drupal.media.filter.getWrapperStart(i), endTag = Drupal.media.filter.getWrapperEnd(i);
59
        var startPos = content.indexOf(startTag), endPos = content.indexOf(endTag);
60
        if (startPos !== -1 && endPos !== -1) {
61
          // If the placeholder wrappers are empty, remove the macro too.
62
          if (endPos - startPos - startTag.length === 0) {
63
            macro = '';
64
          }
65
          content = content.substr(0, startPos) + macro + content.substr(endPos + (new String(endTag)).length);
66
        }
67
        i++;
68
      }
69
      return content;
70
    },
71

    
72
    getWrapperStart: function(i) {
73
      return '<!--MEDIA-WRAPPER-START-' + i + '-->';
74
    },
75

    
76
    getWrapperEnd: function(i) {
77
      return '<!--MEDIA-WRAPPER-END-' + i + '-->';
78
    },
79

    
80
    /**
81
     * Register new element and returns the placeholder markup.
82
     *
83
     * @param formattedMedia a formatted media object as given by the onSubmit
84
     * function of the media Style popup.
85
     * @param fid the file id.
86
     *
87
     * @return The registered element.
88
     */
89
    registerNewElement: function (formattedMedia, fid) {
90
      var element = Drupal.media.filter.create_element(formattedMedia.html, {
91
        fid: fid,
92
        view_mode: formattedMedia.type,
93
        attributes: formattedMedia.options
94
      });
95

    
96
      var markup = Drupal.media.filter.outerHTML(element),
97
        macro = Drupal.media.filter.create_macro(element);
98

    
99
      // Store macro/markup pair in the tagmap.
100
      Drupal.media.filter.ensure_tagmap();
101
      Drupal.settings.tagmap[macro] = markup;
102

    
103
      return element;
104
    },
105

    
106
    /**
107
     * Serializes file information as a url-encoded JSON object and stores it as a
108
     * data attribute on the html element.
109
     *
110
     * @param html (string)
111
     *    A html element to be used to represent the inserted media element.
112
     * @param info (object)
113
     *    A object containing the media file information (fid, view_mode, etc).
114
     */
115
    create_element: function (html, info) {
116
      if ($('<div></div>').append(html).text().length === html.length) {
117
        // Element is not an html tag. Surround it in a span element
118
        // so we can pass the file attributes.
119
        html = '<span>' + html + '</span>';
120
      }
121
      var element = $(html);
122

    
123
      // Move attributes from the file info array to the placeholder element.
124
      if (info.attributes) {
125
        $.each(Drupal.media.filter.allowed_attributes(), function(i, a) {
126
          if (info.attributes[a]) {
127
            element.attr(a, info.attributes[a]);
128
          }
129
        });
130
        delete(info.attributes);
131
      }
132

    
133
      // Important to url-encode the file information as it is being stored in an
134
      // html data attribute.
135
      info.type = info.type || "media";
136
      element.attr('data-file_info', encodeURI(JSON.stringify(info)));
137

    
138
      // Adding media-element class so we can find markup element later.
139
      var classes = ['media-element'];
140

    
141
      if(info.view_mode){
142
        classes.push('file-' + info.view_mode.replace(/_/g, '-'));
143
      }
144
      element.addClass(classes.join(' '));
145

    
146
      return element;
147
    },
148

    
149
    /**
150
     * Create a macro representation of the inserted media element.
151
     *
152
     * @param element (jQuery object)
153
     *    A media element with attached serialized file info.
154
     */
155
    create_macro: function (element) {
156
      var file_info = Drupal.media.filter.extract_file_info(element);
157
      if (file_info) {
158
        return '[[' + JSON.stringify(file_info) + ']]';
159
      }
160
      return false;
161
    },
162

    
163
    /**
164
     * Extract the file info from a WYSIWYG placeholder element as JSON.
165
     *
166
     * @param element (jQuery object)
167
     *    A media element with attached serialized file info.
168
     */
169
    extract_file_info: function (element) {
170
      var file_json = $.data(element, 'file_info') || element.data('file_info'),
171
        file_info,
172
        value;
173

    
174
      try {
175
        file_info = JSON.parse(decodeURIComponent(file_json));
176
      }
177
      catch (err) {
178
        file_info = null;
179
      }
180

    
181
      if (file_info) {
182
        file_info.attributes = {};
183

    
184
        // Extract whitelisted attributes.
185
        $.each(Drupal.media.filter.allowed_attributes(), function(i, a) {
186
          if (value = element.attr(a)) {
187
            file_info.attributes[a] = value;
188
          }
189
        });
190
        delete(file_info.attributes['data-file_info']);
191
      }
192

    
193
      return file_info;
194
    },
195

    
196
    /**
197
     * Gets the HTML content of an element.
198
     *
199
     * @param element (jQuery object)
200
     */
201
    outerHTML: function (element) {
202
      return $('<div>').append(element.eq(0).clone()).html();
203
    },
204

    
205
    /**
206
     * Gets the wrapped HTML content of an element to insert into the wysiwyg.
207
     *
208
     * It also registers the element in the tag map so that the token
209
     * replacement works.
210
     *
211
     * @param element (jQuery object) The element to insert.
212
     *
213
     * @see Drupal.media.filter.replacePlaceholderWithToken()
214
     */
215
    getWysiwygHTML: function (element) {
216
      // Create the markup and the macro.
217
      var markup = Drupal.media.filter.outerHTML(element),
218
        macro = Drupal.media.filter.create_macro(element);
219

    
220
      // Store macro/markup in the tagmap.
221
      Drupal.media.filter.ensure_tagmap();
222
      var i = 1;
223
      for (var key in Drupal.settings.tagmap) {
224
        i++;
225
      }
226
      Drupal.settings.tagmap[macro] = markup;
227

    
228
      // Return the wrapped html code to insert in an editor and use it with
229
      // replacePlaceholderWithToken()
230
      return Drupal.media.filter.getWrapperStart(i) + markup + Drupal.media.filter.getWrapperEnd(i);
231
    },
232

    
233
    /**
234
     * Ensures the tag map has been initialized and returns it.
235
     */
236
    ensure_tagmap: function () {
237
      Drupal.settings.tagmap = Drupal.settings.tagmap || {};
238
      return Drupal.settings.tagmap;
239
    },
240

    
241
    /**
242
     * Ensures the wysiwyg_allowed_attributes and returns it.
243
     * In case of an error the default settings are returned.
244
     */
245
    allowed_attributes: function () {
246
      Drupal.settings.wysiwyg_allowed_attributes = Drupal.settings.wysiwyg_allowed_attributes || ['height', 'width', 'hspace', 'vspace', 'border', 'align', 'style', 'alt', 'title', 'class', 'id', 'usemap'];
247
      return Drupal.settings.wysiwyg_allowed_attributes;
248
    }
249
  }
250
})(jQuery);