Projet

Général

Profil

Paste
Télécharger (8,84 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / media_ckeditor / js / plugins / media / plugin.js @ da542b7b

1
/*
2
Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
3
For licensing, see LICENSE.html or http://ckeditor.com/license
4
*/
5

    
6
/**
7
 * @file Plugin for inserting images from Drupal media module
8
 *
9
 * @TODO Remove all the legecy media wrapper once it's sure nobody uses that
10
 * anymore.
11
 */
12
( function() {
13
  var mediaPluginDefinition = {
14
    icons: 'media',
15
    requires: ['button'],
16
    // Check if this instance has widget support. All the default distributions
17
    // of the editor have the widget plugin disabled by default.
18
    hasWidgetSupport: typeof(CKEDITOR.plugins.registered.widget) != 'undefined',
19
    mediaLegacyWrappers: false,
20

    
21
    // Wrap Drupal plugin in a proxy plugin.
22
    init: function(editor){
23
      editor.addCommand( 'media',
24
      {
25
        exec: function (editor) {
26
          var data = {
27
            format: 'html',
28
            node: null,
29
            content: ''
30
          };
31
          var selection = editor.getSelection();
32

    
33
          if (selection) {
34
            data.node = selection.getSelectedElement();
35
            if (data.node) {
36
              data.node = data.node.$;
37
            }
38
            if (selection.getType() == CKEDITOR.SELECTION_TEXT) {
39
              if (CKEDITOR.env.ie && CKEDITOR.env.version < 10) {
40
                data.content = selection.getNative().createRange().text;
41
              }
42
              else {
43
                data.content = selection.getNative().toString();
44
              }
45
            }
46
            else if (data.node) {
47
              // content is supposed to contain the "outerHTML".
48
              data.content = data.node.parentNode.innerHTML;
49
            }
50
          }
51
          Drupal.settings.ckeditor.plugins['media'].invoke(data, Drupal.settings.ckeditor.plugins['media'], editor.name);
52
        }
53
      });
54

    
55
      editor.ui.addButton( 'Media',
56
      {
57
        label: 'Add media',
58
        command: 'media',
59
        icon: this.path + 'images/icon.gif'
60
      });
61

    
62
      var ckeditorversion = parseFloat(CKEDITOR.version);
63

    
64
      // Because the media comment wrapper don't work well for CKEditor we
65
      // replace them by using a custom mediawrapper element.
66
      // Instead having
67
      // <!--MEDIA-WRAPPER-START-1--><img /><!--MEDIA-WRAPPER-END-1-->
68
      // We wrap the placeholder with
69
      // <mediawrapper data="1"><img /></mediawrapper>
70
      // That way we can deal better with selections - see selectionChange.
71
      CKEDITOR.dtd['mediawrapper'] = CKEDITOR.dtd;
72
      CKEDITOR.dtd.$blockLimit['mediawrapper'] = 1;
73
      CKEDITOR.dtd.$inline['mediawrapper'] = 1;
74
      CKEDITOR.dtd.$nonEditable['mediawrapper'] = 1;
75
      if (ckeditorversion >= 4.1) {
76
        // Register allowed tag for advanced filtering.
77
        editor.filter.allow( 'mediawrapper[!data]', 'mediawrapper', true);
78
        // Don't remove the data-file_info attribute added by media!
79
        editor.filter.allow( '*[!data-file_info]', 'mediawrapper', true);
80
        // Ensure image tags accept all kinds of attributes.
81
        editor.filter.allow( 'img[*]{*}(*)', 'mediawrapper', true);
82
        // Objects should be selected as a whole in the editor.
83
        CKEDITOR.dtd.$object['mediawrapper'] = 1;
84
      }
85
      function prepareDataForWysiwygMode(data) {
86
        data = Drupal.media.filter.replaceTokenWithPlaceholder(data);
87
        // Legacy media wrapper.
88
        mediaPluginDefinition.mediaLegacyWrappers = (data.indexOf("<!--MEDIA-WRAPPER-START-") !== -1);
89
        if (mediaPluginDefinition.mediaLegacyWrappers) {
90
          data = data.replace(/<!--MEDIA-WRAPPER-START-(\d+)-->(.*?)<!--MEDIA-WRAPPER-END-\d+-->/gi, '<mediawrapper data="$1">$2</mediawrapper>');
91
        }
92
        return data;
93
      }
94
      function prepareDataForSourceMode(data) {
95
        var replacement = '$2';
96
        // Legacy wrapper
97
        if (mediaPluginDefinition.mediaLegacyWrappers) {
98
          replacement = '<!--MEDIA-WRAPPER-START-$1-->$2<!--MEDIA-WRAPPER-END-$1-->';
99
        }
100
        data = data.replace(/<mediawrapper data="(.*?)">(.*?)<\/mediawrapper>/gi, replacement);
101
        data = Drupal.media.filter.replacePlaceholderWithToken(data);
102
        return data;
103
      }
104

    
105
      // Ensure the tokens are replaced by placeholders while editing.
106
      // Check for widget support.
107
      if (mediaPluginDefinition.hasWidgetSupport) {
108
        editor.widgets.add( 'mediabox',
109
        {
110
          button: 'Create a mediabox',
111
          editables: {},
112
          allowedContent: '*',
113
          upcast: function( element ) {
114
            // Ensure media tokens are converted to media placeholders.
115
            html = Drupal.media.filter.replaceTokenWithPlaceholder(element.getHtml());
116
            // Only replace html if it's different
117
            if (html != element.getHtml()) {
118
              element.setHtml(html);
119
            }
120
            return element.name == 'mediawrapper' || 'data-media-element' in element.attributes;
121
          },
122

    
123
          downcast: function( widgetElement ) {
124
            var token = Drupal.media.filter.replacePlaceholderWithToken(widgetElement.getOuterHtml());
125
            if (token) {
126
              return new CKEDITOR.htmlParser.text(token);
127
            }
128
            return false;
129
          }
130
        });
131
      }
132
      else if (ckeditorversion >= 4) {
133
        // CKEditor >=4.0
134
        editor.on('setData', function( event ) {
135
          event.data.dataValue = prepareDataForWysiwygMode(event.data.dataValue);
136
        });
137
      }
138
      else {
139
        // CKEditor >=3.6 behaviour.
140
        editor.on( 'beforeSetMode', function( event, data ) {
141
          event.removeListener();
142
          var wysiwyg = editor._.modes[ 'wysiwyg' ];
143
          var source = editor._.modes[ 'source' ];
144
          wysiwyg.loadData = CKEDITOR.tools.override( wysiwyg.loadData, function( org )
145
          {
146
            return function( data ) {
147
              return ( org.call( this, prepareDataForWysiwygMode(data)) );
148
            };
149
          } );
150
          source.loadData = CKEDITOR.tools.override( source.loadData, function( org )
151
          {
152
            return function( data ) {
153
              return ( org.call( this, prepareDataForSourceMode(data) ) );
154
            };
155
          } );
156
        });
157
      }
158

    
159
      // Provide alternative to the widget functionality introduced in 4.3.
160
      if (!mediaPluginDefinition.hasWidgetSupport) {
161
        // Ensure tokens instead the html element is saved.
162
        editor.on('getData', function( event ) {
163
          event.data.dataValue = prepareDataForSourceMode(event.data.dataValue);
164
        });
165

    
166
        // Ensure our enclosing wrappers are always included in the selection.
167
        editor.on('selectionChange', function( event ) {
168
          var ranges = editor.getSelection().getRanges().createIterator();
169
          var newRanges = [];
170
          var currRange;
171
          while(currRange = ranges.getNextRange()) {
172
            var commonAncestor = currRange.getCommonAncestor(false);
173
            if (commonAncestor && typeof(commonAncestor.getName) != 'undefined' && commonAncestor.getName() == 'mediawrapper') {
174
              var range = new CKEDITOR.dom.range( editor.document );
175
              if (currRange.collapsed === true) {
176
                // Don't allow selection within the wrapper element.
177
                if (currRange.startOffset == 0) {
178
                  // While v3 plays nice with setting start and end to avoid
179
                  // editing within the media wrapper element, v4 ignores that.
180
                  // Thus we try to move the cursor further away.
181
                  if (parseInt(CKEDITOR.version) > 3) {
182
                    range.setStart(commonAncestor.getPrevious());
183
                    range.setEnd(commonAncestor.getPrevious());
184
                  }
185
                  else {
186
                    range.setStartBefore(commonAncestor);
187
                  }
188
                }
189
                else {
190
                  // While v3 plays nice with setting start and end to avoid
191
                  // editing within the media wrapper element, v4 ignores that.
192
                  // Thus we try to move the cursor further away.
193
                  if (parseInt(CKEDITOR.version) > 3) {
194
                    range.setStart(commonAncestor.getNext(), 1);
195
                    range.setEnd(commonAncestor.getNext(), 1);
196
                  }
197
                  else {
198
                    range.setStartAfter(commonAncestor);
199
                  }
200
                }
201
              }
202
              else {
203
                // Always select the whole wrapper element.
204
                range.setStartBefore(commonAncestor);
205
                range.setEndAfter(commonAncestor);
206
              }
207
              newRanges.push(range);
208
            }
209
          }
210
          if (newRanges.length) {
211
            editor.getSelection().selectRanges(newRanges);
212
          }
213
        });
214
      }
215
    }
216
  };
217
  // Add dependency to widget plugin if possible.
218
  if (parseFloat(CKEDITOR.version) >= 4.3 && mediaPluginDefinition.hasWidgetSupport) {
219
    mediaPluginDefinition.requires.push('widget');
220
  }
221
  CKEDITOR.plugins.add( 'media', mediaPluginDefinition);
222
} )();