Projet

Général

Profil

Paste
Télécharger (15,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / panels / plugins / layouts / flexible / flexible-admin.js @ e4c061ad

1
(function ($) {
2

    
3
Drupal.flexible = Drupal.flexible || {};
4

    
5
Drupal.flexible.splitters = [];
6

    
7
/**
8
 * Fix the height of all splitters to be the same as the items they are
9
 * splitting.
10
 */
11
Drupal.flexible.fixHeight = function() {
12
  for (i in Drupal.flexible.splitters) {
13
    Drupal.flexible.splitters[i].fixHeight();
14
  }
15
}
16

    
17
Drupal.behaviors.flexibleAdmin = {
18
  attach: function(context) {
19
    // Show/hide layout manager button
20
    $('#panels-flexible-toggle-layout:not(.panels-flexible-processed)', context)
21
      .addClass('panels-flexible-processed')
22
      .click(function() {
23
        $('.panel-flexible-admin')
24
          .toggleClass('panel-flexible-no-edit-layout')
25
          .toggleClass('panel-flexible-edit-layout');
26

    
27
        if ($('.panel-flexible-admin').hasClass('panel-flexible-edit-layout')) {
28
          $(this).val(Drupal.t('Hide layout designer'));
29
          Drupal.flexible.fixHeight();
30
        }
31
        else {
32
          $(this).val(Drupal.t('Show layout designer'));
33
        }
34
        return false;
35
      });
36

    
37
    // Window splitter behavior.
38
    $('div.panels-flexible-splitter:not(.panels-splitter-processed)')
39
      .addClass('panels-splitter-processed')
40
      .each(function() {
41
        Drupal.flexible.splitters.push(new Drupal.flexible.splitter($(this)));
42
      });
43

    
44
    Drupal.flexible.fixHeight();
45
  }
46
};
47

    
48
Drupal.flexible.splitter = function($splitter) {
49
  var splitter = this;
50

    
51
  this.fixHeight = function() {
52
    // Set the splitter height to the shorter of the two:
53
    $splitter.height(Math.max(this.left.outerHeight(), this.right.outerHeight()));
54
  }
55

    
56
  function splitterStart(event) {
57
    // Bind motion events.
58
    $(document)
59
      .bind("mousemove", splitterMove)
60
      .bind("mouseup", splitterEnd);
61

    
62
    // Calculate some data about our split regions:
63
    splitter.getSizes();
64

    
65
    // The X coordinate where we clicked.
66
    splitter.startX = event.pageX;
67

    
68
    // The current sizes of the left/right panes.
69
    splitter.currentLeft = parseFloat(splitter.left_width) * parseFloat(splitter.left_scale);
70
    splitter.currentRight = parseFloat(splitter.right_width) * parseFloat(splitter.right_scale);
71

    
72
    // The starting sizes of the left right panes.
73
    splitter.startLeft = splitter.currentLeft;
74
    splitter.startRight = splitter.currentRight;
75

    
76
    if (splitter.left_width_type == splitter.right_width_type) {
77
      // If they're the same type, add the two together so we know how
78
      // much space we have for splitting.
79
      splitter.max = splitter.startLeft + splitter.startRight;
80

    
81
      // calculate unit size and min/max width.
82
      if (splitter.left_width_type == '%') {
83
        splitter.left_total = splitter.left.width() / (splitter.left_width / 100);
84
        // One pixel is equivalent to what percentage of the total?
85
        splitter.left_unit = (1 / splitter.left_total) * 100;
86
        splitter.left_min = 5; // minimum % we'll use.
87
      }
88
      else {
89
        splitter.left_unit = 1;
90
        splitter.left_min = 25; // minimum pixels we'll use.
91
      }
92
      if (splitter.right_width_type == '%') {
93
        splitter.right_total = splitter.right.width() / (splitter.right_width / 100);
94
        // One pixel is equivalent to what percentage of the total?
95
        splitter.right_unit = (1 / splitter.right_total) * 100;
96
        splitter.right_min = 5; // minimum % we'll use.
97
      }
98
      else {
99
        splitter.right_unit = 1;
100
        splitter.right_min = 25; // minimum pixels we'll use.
101
      }
102
    }
103
    else {
104
      // Figure out the parent blob's width and set the max to that
105
      splitter.parent = $splitter.parent().parent();
106

    
107
      if (splitter.left_width_type != 'px') {
108
        // Only the 'px' side can resize.
109
        splitter.left_unit = 0;
110
        splitter.right_unit = 1;
111
        splitter.right_min = 25;
112
        splitter.right_padding = parseInt(splitter.parent.css('padding-right'));
113
        splitter.right_parent = parseInt(splitter.right.parent().css('margin-right'));
114
        splitter.max = splitter.right.width() + splitter.left.parent().width() -
115
          (splitter.left.siblings(':not(.panels-flexible-splitter)').length * 25) - 25;
116
      }
117
      else {
118
        splitter.right_unit = 0;
119
        splitter.left_unit = 1;
120
        splitter.left_min = 25;
121
        splitter.left_padding = parseInt(splitter.parent.css('padding-left'));
122
        splitter.left_parent = parseInt(splitter.left.parent().css('margin-left'));
123
        if (splitter.right_id) {
124
          splitter.max = splitter.left.width() + splitter.right.parent().width() -
125
            (splitter.right.siblings(':not(.panels-flexible-splitter)').length * 25) - 25;
126
        }
127
        else {
128
          var subtract = 0;
129
          splitter.left.siblings(':not(.panels-flexible-splitter)').each(function() { subtract += $(this).width()});
130
          splitter.max = splitter.left.parent().width() - subtract;
131
        }
132
      }
133
    }
134

    
135
    var offset = $(splitter.splitter).offset();
136

    
137
    // Create boxes to display widths left and right of the mouse pointer.
138
    // Create left box only if left box is mobile.
139
    if (splitter.left_unit) {
140
      splitter.left_box = $('<div class="flexible-splitter-hover-box">&nbsp;</div>');
141
      $('body').append(splitter.left_box);
142
      splitter.left_box.css('top', offset.top);
143
      splitter.left_box.css('left', event.pageX - 65);
144

    
145
    if (splitter.left_width_type == '%') {
146
        var left = splitter.currentLeft / splitter.left_scale;
147
        splitter.left_box.html(left.toFixed(2) + splitter.left_width_type);
148
      }
149
      else {
150
        // make sure pixel values are always whole integers.
151
        splitter.currentLeft = parseInt(splitter.currentLeft);
152
        splitter.left_box.html(splitter.currentLeft + splitter.left_width_type);
153
      }
154
    }
155

    
156
    // Create the right box if the right side is mobile.
157
    if (splitter.right_unit) {
158
      splitter.right_box = $('<div class="flexible-splitter-hover-box"></div>');
159
      $('body').append(splitter.right_box);
160
      splitter.right_box.css('top', offset.top);
161
      splitter.right_box.css('left', event.pageX + 5);
162
      if (splitter.right_width_type == '%') {
163
        var right = splitter.currentRight / splitter.right_scale;
164
        splitter.right_box.html(right.toFixed(2) + splitter.right_width_type);
165
      }
166
      else {
167
        // make sure pixel values are always whole integers.
168
        splitter.currentRight = parseInt(splitter.currentRight);
169
        splitter.right_box.html(splitter.currentRight + splitter.right_width_type);
170
      }
171
    }
172

    
173
    return false;
174
  };
175

    
176
  function splitterMove(event) {
177
    var diff = splitter.startX - event.pageX;
178
    var moved = 0;
179

    
180
    if (event.keyCode == 37) diff = 10;
181
    if (event.keyCode == 39) diff = -10;
182

    
183
    // Bah, javascript has no logical xor operator
184
    if ((splitter.left_unit && !splitter.right_unit) ||
185
      (!splitter.left_unit && splitter.right_unit)) {
186
      // This happens when one side is fixed and the other side is fluid. The
187
      // fixed side actually adjusts while the fluid side does not. However,
188
      // in order to move the fluid side we have to adjust the padding
189
      // on our parent object.
190
      if (splitter.left_unit) {
191
        // Only the left box is allowed to move.
192
        splitter.currentLeft = splitter.startLeft - diff;
193

    
194
        if (splitter.currentLeft < splitter.left_min) {
195
          splitter.currentLeft = splitter.left_min;
196
        }
197
        if (splitter.currentLeft > splitter.max) {
198
          splitter.currentLeft = splitter.max;
199
        }
200

    
201
        // If the shift key is pressed, go with 1% or 10px boundaries.
202
        if (event.shiftKey) {
203
          splitter.currentLeft = parseInt(splitter.currentLeft / 10) * 10;
204
        }
205
        moved = (splitter.startLeft - splitter.currentLeft);
206
      }
207
      else {
208
        // Only the left box is allowed to move.
209
        splitter.currentRight = splitter.startRight + diff;
210

    
211
        if (splitter.currentRight < splitter.right_min) {
212
          splitter.currentRight = splitter.right_min;
213
        }
214
        if (splitter.currentRight > splitter.max) {
215
          splitter.currentRight = splitter.max;
216
        }
217

    
218
        // If the shift key is pressed, go with 1% or 10px boundaries.
219
        if (event.shiftKey) {
220
          splitter.currentRight = parseInt(splitter.currentRight / 10) * 10;
221
        }
222
        moved = (splitter.currentRight - splitter.startRight);
223
      }
224
    }
225
    else {
226
      // If they are both the same type, do this..
227
      // Adjust the left side by the amount we moved.
228
      var left = -1 * diff * splitter.left_unit;
229

    
230
      splitter.currentLeft = splitter.startLeft + left;
231

    
232
      if (splitter.currentLeft < splitter.left_min) {
233
        splitter.currentLeft = splitter.left_min;
234
      }
235
      if (splitter.currentLeft > splitter.max - splitter.right_min) {
236
        splitter.currentLeft = splitter.max - splitter.right_min;
237
      }
238

    
239
      // If the shift key is pressed, go with 1% or 10px boundaries.
240
      if (event.shiftKey) {
241
        if (splitter.left_width_type == '%') {
242
          splitter.currentLeft = parseInt(splitter.currentLeft / splitter.left_scale) * splitter.left_scale;
243
        }
244
        else {
245
          splitter.currentLeft = parseInt(splitter.currentLeft / 10) * 10;
246
        }
247
      }
248

    
249
      // Now automatically make the right side to be the other half.
250
      splitter.currentRight = splitter.max - splitter.currentLeft;
251

    
252
      // recalculate how far we've moved into pixels so we can adjust our visible
253
      // boxes.
254
      moved = (splitter.startLeft - splitter.currentLeft) / splitter.left_unit;
255
    }
256

    
257
    if (splitter.left_unit) {
258
      splitter.left_box.css('left', splitter.startX - 65 - moved);
259
      if (splitter.left_width_type == '%') {
260
        var left = splitter.currentLeft / splitter.left_scale;
261
        splitter.left_box.html(left.toFixed(2) + splitter.left_width_type);
262
      }
263
      else {
264
        splitter.left_box.html(parseInt(splitter.currentLeft) + splitter.left_width_type);
265
      }
266

    
267
      // Finally actually move the left side
268
      splitter.left.css('width', splitter.currentLeft + splitter.left_width_type);
269
    }
270
    else {
271
      // if not moving the left side, adjust the parent padding instead.
272
      splitter.parent.css('padding-right', (splitter.right_padding + moved) + 'px');
273
      splitter.right.parent().css('margin-right', (splitter.right_parent - moved) + 'px');
274
    }
275

    
276
    if (splitter.right_unit) {
277
      splitter.right_box.css('left', splitter.startX + 5 - moved);
278
      if (splitter.right_width_type == '%') {
279
        var right = splitter.currentRight / splitter.right_scale;
280
        splitter.right_box.html(right.toFixed(2) + splitter.right_width_type);
281
      }
282
      else {
283
        splitter.right_box.html(parseInt(splitter.currentRight) + splitter.right_width_type);
284
      }
285

    
286
      // Finally actually move the right side
287
      splitter.right.css('width', splitter.currentRight + splitter.right_width_type);
288
    }
289
    else {
290
      // if not moving the right side, adjust the parent padding instead.
291
      splitter.parent.css('padding-left', (splitter.left_padding - moved) + 'px');
292
      splitter.left.parent().css('margin-left', (splitter.left_parent + moved) + 'px');
293
    }
294
    return false;
295
  };
296

    
297
  function splitterKeyPress(event) {
298
    splitterStart(event);
299
    splitterMove(event);
300
    splitterEnd(event);
301
  };
302

    
303
  function splitterEnd(event) {
304
    if (splitter.left_unit) {
305
      splitter.left_box.remove();
306
    }
307

    
308
    if (splitter.right_unit) {
309
      splitter.right_box.remove();
310
    }
311

    
312

    
313
    splitter.left.css("-webkit-user-select", "text");        // let Safari select text again
314
    splitter.right.css("-webkit-user-select", "text");        // let Safari select text again
315

    
316
    if (splitter.left_unit) {
317
      splitter.left_width = splitter.currentLeft / parseFloat(splitter.left_scale);
318
    }
319

    
320
    if (splitter.right_unit) {
321
      splitter.right_width = splitter.currentRight / parseFloat(splitter.right_scale);
322
    }
323

    
324
    splitter.putSizes();
325
    Drupal.flexible.fixHeight();
326

    
327
    $(document)
328
      .unbind("mousemove", splitterMove)
329
      .unbind("mouseup", splitterEnd);
330

    
331
    // Store the data on the server.
332
    Drupal.ajax['flexible-splitter-ajax'].options.data = {
333
      'left': splitter.left_id,
334
      'left_width': splitter.left_width,
335
      'right': splitter.right_id,
336
      'right_width': splitter.right_width
337
    };
338

    
339
    $('.panel-flexible-edit-layout').trigger('UpdateFlexibleSplitter');
340
  };
341

    
342
  this.getSizes = function() {
343
    splitter.left_width = $splitter.children('.panels-flexible-splitter-left-width').html();
344
    splitter.left_scale = $splitter.children('.panels-flexible-splitter-left-scale').html();
345
    splitter.left_width_type = $splitter.children('.panels-flexible-splitter-left-width-type').html();
346
    splitter.right_width = $splitter.children('.panels-flexible-splitter-right-width').html();
347
    splitter.right_scale = $splitter.children('.panels-flexible-splitter-right-scale').html();
348
    splitter.right_width_type = $splitter.children('.panels-flexible-splitter-right-width-type').html();
349
  };
350

    
351
  this.putSizes = function() {
352
    $(splitter.left_class + '-width').html(splitter.left_width);
353
    if (splitter.left_class != splitter.right_class) {
354
      $(splitter.right_class + '-width').html(splitter.right_width);
355
    }
356
  }
357

    
358
  splitter.splitter = $splitter;
359
  splitter.left_class = $splitter.children('.panels-flexible-splitter-left').html();
360
  splitter.left_id = $splitter.children('.panels-flexible-splitter-left-id').html();
361
  splitter.left = $(splitter.left_class);
362
  splitter.right_class = $splitter.children('.panels-flexible-splitter-right').html();
363
  splitter.right_id = $splitter.children('.panels-flexible-splitter-right-id').html();
364
  splitter.right = $(splitter.right_class);
365

    
366
  $splitter
367
    .bind("mousedown", splitterStart)
368
    .bind("keydown", splitterKeyPress);
369

    
370
};
371

    
372
$(function() {
373
  /**
374
   * Provide an AJAX response command to allow the server to request
375
   * height fixing.
376
   */
377
  Drupal.ajax.prototype.commands.flexible_fix_height = function(ajax, command, status) {
378
    Drupal.flexible.fixHeight();
379
  };
380

    
381
  /**
382
   * Provide an AJAX response command to allow the server to change width on existing splitters.
383
   */
384
  Drupal.ajax.prototype.commands.flexible_set_width = function(ajax, command, status) {
385
    $(command.selector).html(command.width);
386
  };
387

    
388
  /**
389
   * Provide an AJAX response command to fix the first/last bits of a
390
   * group.
391
   */
392
  Drupal.ajax.prototype.commands.flexible_fix_firstlast = function(ajax, data, status) {
393
    $(data.selector + ' > div > .' + data.base)
394
      .removeClass(data.base + '-first')
395
      .removeClass(data.base + '-last');
396

    
397
    $(data.selector + ' > div > .' + data.base + ':first')
398
      .addClass(data.base + '-first');
399
    $(data.selector + ' > div > .' + data.base + ':last')
400
      .addClass(data.base + '-last');
401
  };
402

    
403
  // Create a generic ajax callback for use with the splitters which
404
  // background AJAX to store their data.
405
  var element_settings = {
406
    url: Drupal.settings.flexible.resize,
407
    event: 'UpdateFlexibleSplitter',
408
    keypress: false,
409
    // No throbber at all.
410
    progress: { 'type': 'none' }
411
  };
412

    
413
  Drupal.ajax['flexible-splitter-ajax'] = new Drupal.ajax('flexible-splitter-ajax', $('.panel-flexible-admin').get(0), element_settings);
414

    
415
  // Prevent ajax goo from doing odd things to our layout.
416
  Drupal.ajax['flexible-splitter-ajax'].beforeSend = function() { };
417
  Drupal.ajax['flexible-splitter-ajax'].beforeSerialize = function() { };
418

    
419
});
420

    
421
})(jQuery);