Projet

Général

Profil

Paste
Télécharger (50,3 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / sweaver / plugins / sweaver_plugin_editor / sweaver_plugin_editor.js @ 651307cd

1
// $Id: sweaver_plugin_editor.js,v 1.1.2.21.2.20 2010/11/08 16:01:24 jyve Exp $
2

    
3
/**
4
 * Add the sweaver bar at the bottom of the theme
5
 */
6

    
7
(function ($) {
8

    
9
Drupal.Sweaver = Drupal.Sweaver || {};
10

    
11
Drupal.Sweaver.types = new Array(); // A type groups different properties.
12
Drupal.Sweaver.properties = new Array(); // The actual css properties.
13
Drupal.Sweaver.selectors = new Array(); // The list of defined selector objects.
14
Drupal.Sweaver.css = new Object(); // Object with all targets and their properties.
15
Drupal.Sweaver.path = new Array(); // Full path to the root of the document.
16
Drupal.Sweaver.pathIndexes = new Array(); // An array with the indexes of all selected items.
17
Drupal.Sweaver.activePath = ''; // Currently active path including pseudo-classes.
18
Drupal.Sweaver.safeActivePath = ''; // Currently active path excluding pseudo-classes.
19
Drupal.Sweaver.activeElement = new Object(); // Currently active element.
20
Drupal.Sweaver.updateMode = true; // should the form updates be saved in css?
21

    
22
/**
23
 * Hook onload behavior
24
 */
25
$(document).ready(function() {
26

    
27
  Drupal.Sweaver.init();
28

    
29
  Drupal.Sweaver.writeCss();
30

    
31
  Drupal.Sweaver.changed = false;
32

    
33
  Drupal.Sweaver.addSliders();
34

    
35
  Drupal.Sweaver.addColorPicker();
36

    
37
  Drupal.Sweaver.updateForm();
38

    
39
  Drupal.Sweaver.bindClicks();
40
  
41
  Drupal.Sweaver.LoadPosition();
42
});
43

    
44
/**
45
 * Implements Drupal.Sweaver.invokes.processCSS().
46
 */
47
Drupal.Sweaver.invokes.editor = {
48
  execute: function (context, settings) {
49
    var css = '';
50
    var fullCss = '';
51
    var cssContent = '';
52

    
53
    for (var key in Drupal.Sweaver.css) {
54
      var target = Drupal.Sweaver.css[key];
55
      var contains_hidden_property = false;
56
      for (var prop in target) {
57
        if (Drupal.Sweaver.properties[prop]) {
58

    
59
          var properties = Drupal.Sweaver.properties[prop]['property'].split(' ');
60
          $.each(properties, function(i, property) {
61
            // Don't write anything if the value is empty.
62
            // 0 is not empty!
63
            if (target[prop]['value'] == '' && target[prop]['value'] != '0') {
64
              cssContent += '';
65
            }
66
            // Don't right anything if the property is hidden
67
            else if (target[prop]['hidden']) {
68
              cssContent += '';
69
              contains_hidden_property = true;
70
            }
71
            // Don't add a prefix and suffix for these exceptions.
72
            else if ((property == 'background-color' && target[prop]['value'] == 'transparent') || (property == 'background-image' && target[prop]['value'] == 'none')) {
73
              cssContent += '  ' + property + ': ' + target[prop]['value'] + ';\n';
74
            }
75
            else {
76
              cssContent += '  ' + property + ': ' + Drupal.Sweaver.properties[prop].prefix + target[prop]['value'] + Drupal.Sweaver.properties[prop].suffix + ';\n';
77
            }
78
          });
79
        }
80
      }
81

    
82
      if (cssContent != '' || contains_hidden_property) {
83
        css += key + '{\n';
84
        css += cssContent;
85
        css += '}\n';
86
        fullCss += css;
87
        css = '';
88
        cssContent = '';
89
      }
90
      // Remove key from Drupal.Sweaver.css
91
      else {
92
        delete Drupal.Sweaver.css[key];
93
      }
94
    }
95

    
96
    // Store css in hidden field in save form
97
    $("#sweaver [name=sweaver-css]").val($.toJSON(Drupal.Sweaver.css));
98

    
99
    // Add inline css
100
    $("#sweaver-form [name=sweaver-css]").val(fullCss);
101

    
102
    return fullCss;
103
  }
104
};
105

    
106
/**
107
 * Initialize member variables and properties.
108
 */
109
Drupal.Sweaver.init = function() {
110

    
111
  // Get previously stored information or create empty object with all targets
112
  db_css = $("[name=sweaver-css]");
113
  if (db_css.val() && db_css.val() != '[]'){
114
    Drupal.Sweaver.css = $.evalJSON(db_css.val());
115
    
116
    // Check if values are correctly set
117
    // If not they are converted in aim to correct depreciated behaviour
118
    for (key in Drupal.Sweaver.css){
119
      var target = Drupal.Sweaver.css[key];
120
      for (prop in target) {
121
        if (jQuery.type(target[prop]) != 'object'){
122
          Drupal.Sweaver.css[key][prop] = {
123
            'value' : Drupal.Sweaver.css[key][prop],
124
            'hidden' : false,
125
          };
126
        }  
127
      }
128
    }
129
    db_css.val('');
130
  }
131

    
132
  // Get Sweaver selectors.
133
  Drupal.Sweaver.selectors = Drupal.settings.sweaver['selectors'];
134

    
135
  // Get Sweaver types.
136
  Drupal.Sweaver.types = Drupal.settings.sweaver['types'];
137

    
138
  // Get Sweaver properties.
139
  Drupal.Sweaver.properties = Drupal.settings.sweaver['properties'];
140

    
141
  // Get classes that will never be used in the paths or generated css.
142
  Drupal.Sweaver.excludeClasses = Drupal.settings.sweaver['exclude_classes'];
143

    
144
  // Add a link popup to be able to follow links.
145
  $('body').append('<a href="#" id="follow-link">' + Drupal.t('Click here to follow this link') + '</a>');
146
}
147

    
148
/**
149
 * Get all css values and update the form
150
 */
151
Drupal.Sweaver.updateForm = function() {
152

    
153
  // Empty form values and hide unnecessary fields
154
  Drupal.Sweaver.initForm();
155

    
156
  // Prevent changes from being saved
157
  Drupal.Sweaver.updateMode = false;
158

    
159
  // Update form with saved settings
160
  if (Drupal.Sweaver.activePath != '') {
161
    if ($("#tab-sweaver_plugin_editor").hasClass('active-tab')) {
162
      $("#sweaver_plugin_editor #sweaver-editor").show();
163
    }
164
    var target = '';
165
    if (!isEmpty(Drupal.Sweaver.activeElement)) {
166
      var type = Drupal.Sweaver.activeElement.type;
167
      if (Drupal.Sweaver.types[type]) {
168
        $.each(Drupal.Sweaver.types[type], function (index, object){
169
          if (Drupal.Sweaver.properties[object]){
170
                  var properties = Drupal.Sweaver.properties[object]['property'].split(' ');
171
                  var tempValue = '';
172
                  var value = '';
173
                  $.each(properties, function(i, property) {
174
                    // Are there pseudo-classes in the active path? If so check the saved css for any values that have been set.
175
                    // We have do this since jQuery cannot get any values for selectors with pseudo-classes.
176
                    if (Drupal.Sweaver.safeActivePath != Drupal.Sweaver.activePath && Drupal.Sweaver.css[Drupal.Sweaver.activePath] && Drupal.Sweaver.css[Drupal.Sweaver.activePath][property]['value']) {
177
                value = Drupal.Sweaver.properties[property].prefix + Drupal.Sweaver.css[Drupal.Sweaver.activePath][property]['value'] + Drupal.Sweaver.properties[property].suffix;
178
              }
179
              else {
180
                value = $(Drupal.Sweaver.safeActivePath).css(property);
181
              }
182
                    if (tempValue == '') {
183
                      tempValue = value;
184
                    }
185
                    else {
186
                      if (tempValue != value) {
187
                        value = '';
188
                        return false;
189
                      }
190
                    }
191
                  });
192
                  if(value != '' && !isEmpty(Drupal.Sweaver.properties[object]) && Drupal.Sweaver.properties[object].type == 'color') {
193
                    $('#' + object + ' .colorSelector div').css('cssText', 'background-color: ' + value + ' !important;');
194
                  }
195
                  else if (value && !isEmpty(Drupal.Sweaver.properties[object]) && Drupal.Sweaver.properties[object].type == 'image') {
196
                // Remove the url() from around the image url.
197
                    // Mozilla browsers wrap in url(""), while webkit browsers wrap in url()
198
                    // so we need two replacements.
199
                    stripped = value.replace('url("', '').replace('")', '').replace('url(', '').replace(')', '');
200
                var container = $('#sweaver_plugin_editor #edit-' + object + '-ajax-wrapper .form-managed-file');
201
                if (1){
202
                if (stripped != 'none') {
203
                  container.children('input[type="file"]').hide();
204
                  container.children('span').remove();
205
                  
206
                  container.prepend('<span class="file"><a href="' + stripped + '" target="_blank">' + Drupal.t('Display image') + '</a></span>');
207

    
208
                  container.children('#edit-' + object + '-upload-button').val(Drupal.t('Remove'));
209
                  container.children('#edit-' + object + '-upload-button').attr('name', object + '_remove_button');
210
                  container.children('#edit-' + object + '-upload-button').attr('id', 'edit-' + object + '-remove-button');
211
                }
212
                else{
213
                  container.children('input[type="file"]').show();
214
                  container.children('span').remove();
215
                  container.children('input[name="' + object + '[fid]"]').val(0);
216

    
217
                  if(container.children('input[type="file"]').length == 0){
218
                    container.prepend('<input type="file" id="edit-' + object + '-upload" name="files[' + object + ']" size="22" class="form-file" style="display: inline-block; ">');
219
                  }
220
                  
221
                  container.children('#edit-' + object + '-remove-button').val(Drupal.t('Upload'));
222
                  container.children('#edit-' + object + '-remove-button').attr('name', object + '_upload_button');
223
                  container.children('#edit-' + object + '-remove-button').attr('id', 'edit-' + object + '-upload-button');
224
                }
225
                }
226
                    //$("#sweaver_plugin_editor #edit-" + object).val(stripped);
227
                  }
228
              else if (value && !isEmpty(Drupal.Sweaver.properties[object]) && Drupal.Sweaver.properties[object].type == 'checkbox') // Implement the new field checkbox
229
              {
230
                if (Drupal.Sweaver.properties[object]['options'][value] == true)
231
                    $("#sweaver_plugin_editor #button-checkbox-" + object).addClass('button_active');
232
                else $("#sweaver_plugin_editor #button-checkbox-" + object).removeClass('button_active')
233
              }
234
              else if (value && !isEmpty(Drupal.Sweaver.properties[object]) && Drupal.Sweaver.properties[object].type == 'radio') // Implement the new field radio
235
                  {
236
                $("#sweaver_plugin_editor div[id^=button-radio-" + object + "-]").removeClass('button_active');
237
                $("#sweaver_plugin_editor #button-radio-" + object + '-' + value).addClass('button_active');
238
                  }
239
              else {
240
                    if (value) {
241
                  if (value.substr(-1) == '%') {
242
                    // This value is in %
243
                    // We have to check if this is a correct for this field
244
                    // If not we will convert this value into px
245
                    if (!(value in Drupal.Sweaver.properties[object].options)) {
246
                      //Get first parent width
247
                      value = $(tempObject).parent().outerWidth() * value.replace('%', '') / 100;
248
                      value = Math.round(value);
249
                    }
250
                  }
251
                  // Make the sure it is a the string.
252
                  value = value + '';
253
                      $("#sweaver_plugin_editor #edit-" + object).val(value.replace('px', ''));
254
                    }
255
                  }
256
          }
257
        });
258
      }
259
    }
260
  }
261

    
262
  Drupal.Sweaver.updateMode = true;
263
}
264

    
265
/**
266
 * Empty form values and hide unnecessary fields.
267
 */
268
Drupal.Sweaver.initForm = function() {
269

    
270
  // Hide all sliders, all groups and all containers.
271
  Drupal.Sweaver.hideOverlays();
272
  $('#sweaver-editor .sweaver-group').hide();
273
  $('#sweaver-editor .container').hide();
274

    
275
  if (!isEmpty(Drupal.Sweaver.activeElement)) {
276
    // Decide which items should be shown or hidden.
277

    
278
    var type = Drupal.Sweaver.activeElement.type;
279
    $.each(Drupal.Sweaver.properties, function(index, object){
280
      if(object.name in Drupal.Sweaver.types[type]) {
281
        $('#sweaver .form-item-' + object.name).show();
282
        // From the moment that we have an visible element in a group, we need to show that group.
283
        $('#sweaver .form-item-' + object.name).parents('.sweaver-group').show();
284
        // From the moment that we have an visible element in a container, we need to show that container.
285
        $('#sweaver .form-item-' + object.name).parents('.container').show();
286
      }
287
      else {
288
        $('#sweaver .form-item-' + object.name).hide();
289
      }
290
    });
291
  }
292
}
293

    
294
/**
295
 * Show colorPicker and hook events to it
296
 */
297
Drupal.Sweaver.addColorPicker = function() {
298
  $('#sweaver .colorSelector').each(function() {
299
    var object = $(this);
300
    var property = object.parent().attr('id');
301
    object.ColorPicker({
302
      color: '#ffffff',
303
      // Determine the current color and send it to colorpicker.
304
      onBeforeShow: function () {
305
        var current_color_object = {};
306
        var current_color_value = ($('div', this).css('background-color')).replace('rgba(', '').replace('rgb(', '').replace(')', '').split(',');
307
        if (current_color_value[0] != 'transparent') {
308
          current_color_object.r = current_color_value[0];
309
          current_color_object.g = current_color_value[1];
310
          current_color_object.b = current_color_value[2];
311
          $(this).ColorPickerSetColor(current_color_object);
312
        }
313
        else {
314
          current_color_object.r = '255';
315
          current_color_object.g = '255';
316
          current_color_object.b = '255';
317
          $(this).ColorPickerSetColor(current_color_object);
318
        }
319
      },
320
      onShow: function (colpkr) {
321
        $(colpkr).fadeIn(500);
322
        if (object.parents('.sweaver-group-content').length == 0) {
323
          Drupal.Sweaver.hideOverlays();
324
        }
325
        return false;
326
      },
327
      onHide: function (colpkr) {
328
        $(colpkr).fadeOut(500);
329
        return false;
330
      },
331
      onChange: function (hsb, hex, rgb) {
332
      var preview = hex;
333
      if (hex != 'transparent') {
334
        preview = '#'+ hex;
335
      }
336
        $('div', object).css('cssText', 'background-color:' + preview + '!important;');
337
        if (Drupal.Sweaver.updateMode) {
338
          Drupal.Sweaver.setValue(property, hex);
339
        }
340
      }
341
    });
342
  });
343
}
344

    
345
/*
346
 * Add sliders through jQuery UI
347
 */
348
Drupal.Sweaver.addSliders = function() {
349
  $("#sweaver .slider-value").each(function() {
350
    $(this).after('<div class="slider-wrapper"><div id="' + $(this).attr('id').substr(5, $(this).attr('id').length - 5) + '-slider" class="slider"></div></div>');
351
  });
352

    
353
  // Move the slider to the right position on show.
354
  $("#sweaver .slider-value").click(function() {
355
    Drupal.Sweaver.updateMode = false;
356
    $(this).siblings('.slider-wrapper').children().slider("option", "value", $(this).val());
357
    Drupal.Sweaver.updateMode = true;
358
  });
359

    
360
  $("#sweaver .slider").each(function() {
361
    id = $(this).attr('id').replace('-slider', '');
362
    var minSlider = Drupal.Sweaver.properties[id].slider_min;
363
    if (minSlider == null || minSlider == '') {
364
      minSlider = 0;
365
    }
366
    var maxSlider = Drupal.Sweaver.properties[id].slider_max;
367
    if (maxSlider == null || maxSlider == '') {
368
      maxSlider = 2000;
369
    }
370
    $(this).slider({
371
      min: minSlider,
372
      max: maxSlider,
373
      slide: function(event, ui) {
374
        id = $(this).attr("id").replace('-slider','');
375
        $('#edit-' + id).val(ui.value);
376
        if (Drupal.Sweaver.updateMode) {
377
          Drupal.Sweaver.setValue(id, ui.value);
378
        }
379
      }
380
    });
381
  });
382
  
383
  //Double clicking on a slider delete all modifications made through the editor to the property
384
  $('#sweaver .slider a').bind('dblclick', function(){
385
    property = $(this).parent().attr('id').replace('-slider', '');
386
    Drupal.Sweaver.deleteProperty(Drupal.Sweaver.activePath, property);
387
  });
388
}
389

    
390
/**
391
 * Loop through all clickable area's and bind click
392
 */
393
Drupal.Sweaver.bindClicks = function() {
394

    
395
  // Get a list of selectors to exclude.
396
  var excludes = Drupal.settings.sweaver['exclude_selectors'];
397

    
398
  // Add hover outline object.
399
  $('#sweaver-frontend').append('<div style="position: absolute; top: 0; left: 0; border: 2px dotted #ccc" id="#sweaver-hover"></div>');
400

    
401
  // Build an object with all the elements that can be hovered/clicked
402
  var tempSelectors = $('body').find('*').filter(':parents(' + excludes + '):not(' + excludes + ')');
403

    
404
  // When an element is hovered, add a class 'sweaver-hovered'.
405
  if (Drupal.settings.sweaver['preview_selector']) {
406
    tempSelectors
407
    .bind('mouseenter', function(event){
408
      // Only do something when the content area is visible.
409
      if (Drupal.Sweaver.visible()) {
410
        tempObject = $(this);
411
        object = Drupal.Sweaver.buildSweaverObject(tempObject);
412
        // Loop through the selectors to see if the current item should be selectable.
413
        if (!object.translation[0]) {
414
          $.each(tempObject.parents(), function() {
415
            tempObject = $(this);
416
            object = Drupal.Sweaver.buildSweaverObject(tempObject);
417
            if (object.translation[0]) {
418
              return false;
419
            }
420
          });
421
        }
422
        // Make sure only one item has the outline.
423
        $('.sweaver-hovered').removeClass('sweaver-hovered');
424

    
425
        // Don't add the class on elements that cover the entire screen
426
        // since that would add a, annoying horizontal scrollbar.
427
        
428
        // There is actually a bug reguarding WebKit and outerHeight/outerWidth property
429
        // In aim to make it work we have to shortly change the display to inline-block
430
        var originalDisplay = tempObject.css('display');
431
        tempObject.css('display', 'inline-block');
432
        if (tempObject.outerWidth() != $(window).width()) {
433
          tempObject.addClass('sweaver-hovered');
434
        }
435
        tempObject.css('display', originalDisplay);
436
      }
437
    })
438
    .bind('mouseleave', function(event){
439
      // Loop through the selectors to see if the current item should be selectable.
440
      if (Drupal.Sweaver.visible()) {
441
        tempObject = $(this);
442
        tempObject.removeClass('sweaver-hovered');
443

    
444
        $.each(tempObject.parents(), function() {
445
          tempObject = $(this);
446
          object = Drupal.Sweaver.buildSweaverObject(tempObject);
447
          if (object.translation[0]) {
448
            return false;
449
          }
450
        });
451
        var originalDisplay = tempObject.css('display');
452
        tempObject.css('display', 'inline-block');
453
        if (tempObject.outerWidth() != $(window).width()) {
454
          tempObject.addClass('sweaver-hovered');
455
        }
456
        tempObject.css('display', originalDisplay);
457
      }
458
    });
459
  }
460

    
461
  // When an element is clicked, add a class and build the entire path.
462
  tempSelectors
463
  .bind('click', function (event) {
464
    // Only do something when the content area is visible.
465
    if (Drupal.Sweaver.visible()) {
466

    
467
      // We need to use event.target here as we need to know if we clicked on an element that should be excluded.
468
      // If we don't do this, then we will get the parent element of the excluded element, which is not what we want.
469
      tempObject = $(event.target);
470
      
471
      Drupal.Sweaver.editSelection(tempObject, event);
472
    }
473
  });
474

    
475
  // Hide sliders and close groups when clicking outside of them.
476
  $("#sweaver").click(function() {
477
    Drupal.Sweaver.hideOverlays();
478
  });
479

    
480
  // Update css when a fake checkbox is clicked
481
  $("#sweaver_plugin_editor div[id^=button-checkbox-]").click(function(){
482
    if ($(this).hasClass('button_active'))
483
      $(this).removeClass('button_active');
484
    else $(this).addClass('button_active');
485
    
486
    if (Drupal.Sweaver.updateMode) {
487
      var status = $(this).hasClass('button_active');
488
      var property_to_update = $(this).attr('id').replace('button-checkbox-', '');
489
        
490
      $.each(Drupal.Sweaver.properties[property_to_update]['options'], function(key, value) { 
491
        if (value == status)
492
          Drupal.Sweaver.setValue(property_to_update, key);
493
      });
494
    }
495
  });
496
  
497
  // Update css when a fake radio button is clicked
498
  $("#sweaver_plugin_editor div[id^=button-radio-]").click(function(){
499
    var property_to_update = $(this).attr('name');
500
    var value = $(this).attr('id').replace('button-radio-' + property_to_update + '-', '');
501
    $("#sweaver_plugin_editor div[id^=button-radio-" + property_to_update + "-]").removeClass('button_active');
502
    $(this).addClass('button_active');
503
    
504
    if (Drupal.Sweaver.updateMode) {
505
        Drupal.Sweaver.setValue(property_to_update, value);
506
    }
507
  });
508
  
509
  //Double clicking on a radio button delete all modifications made through the editor to the property
510
  $("#sweaver_plugin_editor div[id^=button-radio-]").bind('dblclick', function(){
511
    property = $(this).attr('name');
512
    Drupal.Sweaver.deleteProperty(Drupal.Sweaver.activePath, property);
513
  });
514

    
515
  // Update css when something (that is not checkbox or radio button) is changed in the form.
516
  $("#sweaver_plugin_editor input[id^=edit-], #sweaver_plugin_editor select[id^=edit-]").live('change', function(){
517
    if (Drupal.Sweaver.updateMode) {
518
      // Is this a file input ?
519
      if ($(this).attr('name').match('^files\[[a-zA-Z0-9_-]+\]')){
520
        var name = $(this).attr('name').substr(6, $(this).attr('name').length - 7);
521
        var button = $('#' + $(this).attr('id') + '-button');
522
        button.trigger('click');
523
        button.trigger('mousedown');    
524
          
525
        // this function check every second if the image selected has been uploaded
526
        (function imageValueChecker (i) {  
527
          var fidInput = $('#sweaver_plugin_editor input[name="' + name + '[fid]"]');
528
          setTimeout(function () {  
529
          if (fidInput.val() != 0 ){
530
          // Download complete
531
          // We proceed of the css update
532
            $('#edit-' + name + '-ajax-wrapper').ajaxSuccess(function(evt, request, settings){
533
              window.location.reload();
534
            });
535
            absolute_path = fidInput.siblings('.file').children('a').attr('href');
536
            relative_path = absolute_path.replace(Drupal.settings.sweaver['base_root'], '');
537
            Drupal.Sweaver.setValue(name ,relative_path);
538
            Drupal.Sweaver.SavePosition();
539
            Drupal.Sweaver.AutoSave();
540
          }               
541
          if (fidInput.val() == 0 && --i) imageValueChecker(i);      //  decrement i and call myLoop again if i > 0
542
          }, 1000);
543
        })(15); // If 15 seconds after the beginning of the upload it is not yet finished we can assume that there has been a problem.
544
      }
545
      else {
546
        Drupal.Sweaver.setValue($(this).attr('name'), $(this).val());
547
      }
548
    }
549
  });
550
  
551
  $('#sweaver_plugin_editor .form-managed-file input[type=submit]').live('mouseover', function(){
552
    if(!$(this).hasClass('event_added')){
553
      $(this).addClass('event_added');
554
      $(this).bind('mousedown', function(){
555
        Drupal.Sweaver.setValue($(this).attr('name').replace('_remove_button', ''), 'none');
556
      });
557
    }
558
  });
559
  
560
  // Show the slider when a numeric value is entered.
561
  $("#sweaver_plugin_editor  .slider-value").click(function(event){
562
    event.stopPropagation();
563
    $slider = $(this).siblings('.slider-wrapper');
564

    
565
    if ($slider.css('visibility') == 'visible') {
566
      // Add an active class for IE position issues.
567
      $slider.parent().removeClass('active');
568
      $slider.parents('.sweaver-group').removeClass('active');
569

    
570
      // Close slider again on second click.
571
      $slider.css({'visibility' : 'hidden'});
572
    }
573
    else {
574
      // Hide all other sliders.
575
      $('#sweaver_plugin_editor .slider-wrapper').css({'visibility' : 'hidden'});
576

    
577
      // Add an active class for IE position issues.
578
      $('#sweaver_plugin_editor .form-item, #sweaver_plugin_editor .sweaver-group').removeClass('active');
579
      $slider.parent().addClass('active');
580
      $slider.parents('.sweaver-group').addClass('active');
581
      
582
      var container = $(this).parent().parent();      
583
      var top =  $slider.outerHeight();
584
      var left = -($slider.width() / 2) + ($(this).outerWidth() / 2);
585
      
586
      if ($slider.siblings('label').is(':visible')) {
587
        left += $slider.siblings('label').width();
588
      }
589
      else if (container.hasClass('side')) {
590
        left += $(this).offset().left - container.offset().left;      
591
      }
592
      
593
      // Flip the slider over the input when it is too close to the bottom of the page to be displayed
594
      if ($('#sweaver').offset().top + $('#sweaver').height() - $(this).offset().top < 100) {
595
        top = 0 - top - 5;
596
      }  
597
      
598
      $slider.css({'left' : left, 'top' : top}).css({'visibility' : 'visible'});
599
    }
600
  });
601
  
602
  // The value of an input field can be modified with arrows
603
  $("#sweaver_plugin_editor  .slider-value").keydown(function(event){
604
    var value = $(this).val();
605
    switch(event.keyCode) {
606
      case 37:
607
      case 40:
608
        value--;
609
        $(this).val(value);
610
        Drupal.Sweaver.setValue($(this).attr('name'), value);
611
        break;
612
      
613
      case 38:
614
      case 39:
615
        value++;
616
        $(this).val(value);
617
        Drupal.Sweaver.setValue($(this).attr('name'), value);
618
        break;
619
    }
620
  });
621

    
622
}
623

    
624
/**
625
 * Load an object to the editor from a selector
626
 */
627
Drupal.Sweaver.editSelection = function (tempObject, event) {
628
  clicked_object = (event == null) ? false : true;
629
  if (!tempObject.parents(Drupal.settings.sweaver['exclude_selectors']).length > 0) {
630
    if (clicked_object) {
631
      event.stopPropagation();
632
    }
633

    
634
    object = Drupal.Sweaver.buildSweaverObject(tempObject);
635
    
636
    // If the clicked object is a link, or an element in a link, prevent default behavior.
637
    $('#follow-link').hide();
638
    if (object.tag == 'a' || tempObject.parents('a').length > 0) {
639
      var position = tempObject.offset();
640
      var clickObject = tempObject;
641
      if (object.tag != 'a') {
642
        clickObject = tempObject.parents('a');
643
      }
644
      if (object.id != 'follow-link') {
645
        $('#follow-link').attr('href', clickObject.attr('href')).css({
646
          'top': position.top + clickObject.outerHeight() + 5,
647
          'left': position.left
648
        }).fadeIn();
649
        if (clicked_object) {
650
          event.preventDefault();
651
        }
652
      }
653
    }
654
    // If the clicked object is a button prevent default behavior.
655
    if ((object.tag == 'input' || object.tag == 'label') && clicked_object) {
656
      event.preventDefault();
657
    }
658

    
659
    // Don't do anything if the clicked object is the 'follow-link' link.
660
    if (object.id != 'follow-link') {
661

    
662
      // Only do something if the clicked item is found in the selectors.
663
      if (!object.translation[0]) {
664
        $.each(tempObject.parents(), function () {
665
          tempObject = $(this);
666
          object = Drupal.Sweaver.buildSweaverObject(tempObject);
667
          if (object.translation[0]) {
668
            return false;
669
          }
670
        });
671
      }
672
      
673
      // Prevent from selecting non modifiable selectors
674
      if (!object.translation[0]) {
675
        return false;
676
      }
677

    
678
      // clear the old paths.
679
      $('#sweaver_plugin_editor .sweaver-header').html('<div id="full-path" class="clearfix"></div><div id="selected-path" class="clear-block"></div>');
680

    
681
      // Reset some values.
682
      Drupal.Sweaver.path.length = 0;
683
      Drupal.Sweaver.pathIndexes.length = 0;
684
      $("#selected-path").html('<span class="path-label">' + Drupal.t('Selected item: ') + '</span><span class="path-content"></span>');
685
      $("#full-path").html('<span class="path-label">' + Drupal.t('Full path: ') + '</span><span class="path-content"></span>');
686

    
687
      // Build path with parents.
688
      Drupal.Sweaver.buildPath(tempObject);
689
      Drupal.Sweaver.updateForm();
690
      Drupal.Sweaver.updateScreen();
691
    }
692
  }
693
}
694

    
695
/**
696
 * Loop through all clickable area's and bind click
697
 */
698
Drupal.Sweaver.updateScreen = function() {
699
  if (Drupal.settings.sweaver['preview_selector']) {
700
    // Add border around selected element.
701
    var excludes = Drupal.settings.sweaver['exclude_selectors'];
702
    $('.sweaver-clicked').removeClass('sweaver-clicked');
703
    if (Drupal.Sweaver.safeActivePath && $(Drupal.Sweaver.safeActivePath).outerWidth() != $(window).width()) {
704
      $(Drupal.Sweaver.safeActivePath).filter(':parents(' + excludes + '):not(' + excludes + ')').addClass('sweaver-clicked');
705
    }
706
    else {
707
      // Hide the 'clicked' outlines.
708
      $('.sweaver-clicked').removeClass('sweaver-clicked');
709
    }
710
  }
711
}
712

    
713
/**
714
 * Store the parents of a clicked item.
715
 */
716
Drupal.Sweaver.buildPath = function(object) {
717
  var index = 0;
718

    
719
  // Collect info on currently active item.
720
  Drupal.Sweaver.activeElement = Drupal.Sweaver.buildSweaverObject(object);
721

    
722
  // Add active element to first element in the path array.
723
  Drupal.Sweaver.path[0] = Drupal.Sweaver.activeElement;
724

    
725
  // Show the currenty active path and the full path.
726
  Drupal.Sweaver.addToFullPath(index, true);
727
  Drupal.Sweaver.addToActivePathIndex(0);
728

    
729
  // Traverse all parents and save them in the path array.
730
  var i = 1;
731
  var active;
732
  object.parents().each(function() {
733

    
734
    active = false;
735
    var parent = Drupal.Sweaver.buildSweaverObject($(this));
736
    if (parent.translation[0]) {
737
      Drupal.Sweaver.path[i] = parent;
738

    
739
      // If selector is tagged as 'highlight', automatically select it.
740
      var match = '';
741
      $.each(Drupal.Sweaver.selectors, function (index, selector) {
742
        if (selector.selector == 'sweaver_all_ids' || selector.selector == 'sweaver_all_classes' || selector.selector == 'sweaver_all_tags') {
743
          return false;
744
        }
745
        if (selector.selector == '#' + parent.id || selector.selector == parent.tag) {
746
          match = selector.selector;
747
          if (selector.highlight == '1') {
748
            active = true;
749
            Drupal.Sweaver.addToActivePathIndex(i);
750
          }
751
        } else {
752
          $.each(parent.classes, function(index, aClass) {
753
            if (selector.selector == '.' + aClass) {
754
              match = selector.selector;
755
              if (selector.highlight == '1') {
756
                active = true;
757
                Drupal.Sweaver.addToActivePathIndex(i);
758
                return false;
759
              }
760
            }
761
          });
762
        }
763
        if (match != '') {
764
         return false;
765
        }
766
      });
767

    
768
      // Add all items to the full path except for the html tag.
769
      if (parent.tag != 'html') {
770
        Drupal.Sweaver.addToFullPath(i, active);
771
      }
772
      i++;
773
    }
774
  });
775
  if (i > 2) // There are always at least 2 levels
776
  {
777
    if (!(1 in Drupal.Sweaver.pathIndexes)) {
778
      Drupal.Sweaver.addToActivePathIndex(1);
779
      $('#sweaver #full-path #sid-1').addClass('active');
780
    }
781
  }
782
  Drupal.Sweaver.printActivePath();
783
}
784

    
785
/**
786
 * Add one item to the full path.
787
 */
788
Drupal.Sweaver.addToFullPath = function(index, active) {
789
  var path_separator = '&nbsp;&gt;&nbsp;';
790
  var active_class = '';
791

    
792
  // Don't show a seperator after the last item in the path.
793
  if (index == 0) {
794
    path_separator = '';
795
  }
796

    
797
  // Add an active class to the selected items.
798
  if (active == true) {
799
    active_class = ' active';
800
  }
801

    
802
  // Get the list of translated selectors.
803
  var selectorList = Drupal.Sweaver.path[index].translation;
804

    
805
  // First add the default selector.
806
  $("#full-path .path-content").prepend('<div class="selector-wrapper' + active_class + '" id="sid-' + index + '"><div class="first-selector"><a title="' + Drupal.t('Click to add this element to the selected path') + '">' + selectorList[0] + '</a></div><div class="selector-separator">' + path_separator + '</div></div>');
807

    
808
  // Next add a popup with all possible selectors.
809
  var selectors = ''
810
  for (var i=1; i < selectorList.length; i++) {
811
    tempClass = '';
812
    // Add a class active to indicate the preferred selector.
813
    if (i == 1) {
814
      tempClass += 'active ';
815
    }
816
    if (i == 1) {
817
      tempClass += 'first ';
818
    }
819
    if (i == selectorList.length - 1) {
820
      tempClass += 'last';
821
    }
822
    selectors += '<li class="' + tempClass + '"><a href="#" id="ssid-' + (i-1) + '">' + selectorList[i] + '</a></li>';
823
  }
824

    
825
  // Finally, add some pseudo-classes.
826
  var pseudoClasses = '';
827
  if (Drupal.Sweaver.path[index].tag == 'a') {
828
    pseudoClasses += '<li class="first"><a href="#">:hover</a></li>';
829
    pseudoClasses += '<li><a href="#">:visited</a></li>';
830
    pseudoClasses += '<li><a href="#">:active</a></li>';
831
    pseudoClasses += '<li class="last"><a href="#" >:link</a></li>';
832
  }
833
  else {
834
    pseudoClasses += '<li class="first last"><a href="#" class="hover">:hover</a></li>';
835
  }
836

    
837
  $("#sid-" + index).prepend('<div class="selector-popup-opener">open</div><div class="selector-popup"><ul class="selectors">' + selectors + '</ul><ul class="pseudoclasses">' + pseudoClasses + '</ul></div>');
838

    
839
  // Bind click to change the active path.
840
  $('#sid-' + index + ' .first-selector a').click(function() {
841
    $(this).parent().parent().toggleClass('active');
842
    Drupal.Sweaver.addToActivePathIndex(index);
843
    Drupal.Sweaver.printActivePath();
844
    // Reset the active element as it might have changed.
845
    Drupal.Sweaver.pathIndexes.sort(function(a,b){return a - b});
846
    Drupal.Sweaver.activeElement = Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[0]] ? Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[0]] : {} ;
847
    Drupal.Sweaver.updateForm();
848
    Drupal.Sweaver.updateScreen();
849

    
850
    // Stop the link from doing anything.
851
    return false;
852
  });
853

    
854
  // Change the active path from a popup.
855
  $('#sid-' + index + ' .selector-popup ul.selectors a').click(function() {
856
    // Store in the active object that there is a new preferred selector instead of the first one defined in the backend.
857
    var $link = $(this);
858
    var i = $link.attr('id').substr(5);
859
    Drupal.Sweaver.path[index].preferredSelector = i;
860
    Drupal.Sweaver.printActivePath();
861
    // Replace the selector in the full path.
862
    $('#sid-' + index + ' .first-selector a').html(Drupal.Sweaver.objectToReadable(Drupal.Sweaver.path[index])[0]);
863
    // Add an active class.
864
    $link.parents('.selector-popup').css({'left' : '-10000px'}).parent().removeClass('open');
865
    $link.parent().siblings('.active').removeClass('active');
866
    $link.parent().addClass('active');
867
    // Update the form.
868
    Drupal.Sweaver.updateForm();
869
    Drupal.Sweaver.updateScreen();
870
    return false;
871
  });
872

    
873
  // Add a pseudo-class from a popup.
874
  $('#sid-' + index + ' .selector-popup ul.pseudoclasses a').click(function() {
875
    var $link = $(this);
876
    // If the link was already active, deactivate it otherwhise add the active class.
877
    if (!$link.parent().hasClass('active')) {
878
            // Add the pseudo-class to the object in question.
879
            Drupal.Sweaver.path[index].pseudoClass = $(this).text();
880
            // Update the translation of the object in question.
881
            Drupal.Sweaver.path[index].translation = Drupal.Sweaver.objectToReadable(Drupal.Sweaver.path[index]);
882
            // Update the active path.
883
            Drupal.Sweaver.printActivePath();
884
            // Change the text in the full path.
885
            $('#sid-' + index + ' .first-selector a').html(Drupal.Sweaver.path[index].translation[0]);
886
            // Handle all active classes.
887
            $link.parent().siblings('.active').removeClass('active');
888
            $link.parent().addClass('active');
889
    }
890
    else {
891
      Drupal.Sweaver.path[index].pseudoClass = '';
892
      // Update the translation of the object in question.
893
      Drupal.Sweaver.path[index].translation = Drupal.Sweaver.objectToReadable(Drupal.Sweaver.path[index]);
894
      // Update the active path.
895
      Drupal.Sweaver.printActivePath();
896
      // Change the text in the full path.
897
      $('#sid-' + index + ' .first-selector a').html(Drupal.Sweaver.path[index].translation[0]);
898
      // Handle all active classes.
899
      $link.parent().removeClass('active');
900
          }
901
    // Close the popup.
902
                $link.parents('.selector-popup').css({'left' : '-10000px'}).parent().removeClass('open');
903
    // Update the form with the new path.
904
    Drupal.Sweaver.updateForm();
905
    Drupal.Sweaver.updateScreen();
906
    return false;
907
  });
908

    
909
  // Hide/show selector popups.
910
  $('#sid-' + index + ' .selector-popup-opener').click(function() {
911
    var $popup = $(this).siblings('.selector-popup');
912
    $this = $(this);
913
    if ($this.parent().hasClass('open')) {
914
      $this.parent().removeClass('open');
915
      $popup.css({'left' : '-10000px'});
916
    }
917
    else {
918
      // Hide other open selector popups.
919
      $('#sweaver .selector-wrapper.open .selector-popup').css({'left' : '-10000px'});
920
      $this.parent().addClass('open');
921
      $this.parent().siblings().removeClass('open');
922
            // Calculate the right width.
923
            var width = 0;
924
            $($popup.children('ul')).each(function() {
925
             width += $(this).outerWidth();
926
            });
927
      $popup.css({'width' : width});
928
      // See if the popup should be opened on the left or the right.
929
      var offset = $this.offset();
930
      var left = (offset.left + width) > $(window).width() ? - $popup.outerWidth() :  $this.outerWidth();
931
      $popup.hide().css({'left' : left});
932
      // Show the popup.
933
      $popup.slideDown('fast');
934
    }
935
  });
936
}
937

    
938
/**
939
 * Add an item to the active path index.
940
 * This way we can keep track of the selected items in the ful path.
941
 */
942
Drupal.Sweaver.addToActivePathIndex = function(i) {
943
  // Do not add the item when selected or remove it from Active path.
944
  var position = $.inArray(i, Drupal.Sweaver.pathIndexes);
945
  if (position < 0) {
946
    Drupal.Sweaver.pathIndexes.unshift(i);
947
  }
948
  else {
949
    // Remove from pathIndexes if necessary.
950
    for (var key in Drupal.Sweaver.pathIndexes) {
951
      if (Drupal.Sweaver.pathIndexes[key] == i) {
952
        Drupal.Sweaver.pathIndexes.splice(key, 1);
953
      }
954
    }
955
  }
956
}
957

    
958
/**
959
 * Print the active path.
960
 */
961
Drupal.Sweaver.printActivePath = function() {
962
  // Reset the previous path and add the next item to pathIndexes.
963
  $path = $("#selected-path .path-content");
964
  $path.html('');
965
  Drupal.Sweaver.activePath = '';
966
  // Since jquery cannot get a css value when a pseudo-class is in it, we have to create a version
967
  // of the active patch without the pseudo-classes.
968
  Drupal.Sweaver.safeActivePath = '';
969

    
970
  // Sort pathIndexes.
971
  Drupal.Sweaver.pathIndexes.sort(function(a,b){return a - b});
972

    
973
  // Print the selected path in human-readable language.
974

    
975
  if (Drupal.Sweaver.pathIndexes.length > 0) {
976
    for ( var i=0, len=Drupal.Sweaver.pathIndexes.length; i<len; ++i ){
977
      if (i > 0) {
978
        $path.append(' in ');
979
      }
980
      // See which translation should be used.
981
      var j = Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[i]].preferredSelector ? Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[i]].preferredSelector : 0;
982
      j++;
983
      $path.append(Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[i]].translation[j]);
984
    }
985
    // Save the currently active css path.
986
    Drupal.Sweaver.pathIndexes.reverse();
987
    for (var i=0, len=Drupal.Sweaver.pathIndexes.length; i<len; ++i){
988
      // See which translation should be used.
989
      var j = Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[i]].preferredSelector ? Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[i]].preferredSelector : 0;
990
      j++;
991
      Drupal.Sweaver.activePath += Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[i]].css[j] + Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[i]].pseudoClass + ' ';
992
      Drupal.Sweaver.safeActivePath += Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[i]].css[j] + ' ';
993
    }
994
  }
995
  else {
996
    $path.html(Drupal.t('none'));
997
  }
998
}
999

    
1000
/**
1001
 * Fill the activeElement and update the Form and ActivePath.
1002
 * Other plugins can use this function to set values on the
1003
 * style tab. To switch tabs, you can use the Drupal.Sweaver.switchTab
1004
 * function.
1005
 */
1006
Drupal.Sweaver.updateStyleTab = function(theClass, name) {
1007
  // Build the object with manipulated data.
1008
  var tempObject = Drupal.Sweaver.buildSweaverObject($('.' + theClass));
1009

    
1010
  tempObject.translation = new Array(name, name);
1011
  tempObject.classes = new Array('.' + theClass);
1012
  tempObject.css = new Array('.' + theClass, '.' + theClass);
1013

    
1014
  Drupal.Sweaver.activeElement = tempObject;
1015

    
1016
  // Build path with parents.
1017
  $('#sweaver_plugin_editor .sweaver-header').html('<div id="selected-path" class="clearfix"></div>');
1018
  Drupal.Sweaver.path[0] = new Object({'id' : Drupal.Sweaver.activeElement.id, 'class' : Drupal.Sweaver.activeElement.classes, 'pseudoClass' : '', 'tag' : Drupal.Sweaver.activeElement.tag,  'type' : Drupal.Sweaver.activeElement.type, 'translation' : Drupal.Sweaver.activeElement.translation, 'css' : Drupal.Sweaver.activeElement.css});
1019
  Drupal.Sweaver.addToFullPath(0, true);
1020
  Drupal.Sweaver.pathIndexes = new Array();
1021
  Drupal.Sweaver.addToActivePathIndex(0);
1022
  Drupal.Sweaver.printActivePath();
1023
  Drupal.Sweaver.activePath = '.' + theClass;
1024
  Drupal.Sweaver.updateForm();
1025
  Drupal.Sweaver.updateScreen();
1026
}
1027

    
1028
/**
1029
 * Store new value and update inline css.
1030
 */
1031
Drupal.Sweaver.setValue = function(property, value) {
1032
  Drupal.Sweaver.css[Drupal.Sweaver.activePath] = Drupal.Sweaver.css[Drupal.Sweaver.activePath] || {};
1033
  Drupal.Sweaver.css[Drupal.Sweaver.activePath][property] = {
1034
    'value' : value,
1035
    'hidden' : false,
1036
  };
1037
  Drupal.Sweaver.writeCss();
1038
}
1039

    
1040
/**
1041
 * Delete a property from a selector.
1042
 */
1043
Drupal.Sweaver.deleteProperty = function(key, property) {
1044
  var target = Drupal.Sweaver.css[key];
1045
  Drupal.Sweaver.css[key] = {};
1046
  for (var prop in target) {
1047
    if (prop != property) {
1048
      Drupal.Sweaver.css[key][prop] = target[prop];
1049
    }
1050
  }
1051
  Drupal.Sweaver.writeCss();
1052
  Drupal.Sweaver.updateForm();
1053
}
1054

    
1055
/**
1056
 * Translate an parent item in a human-readable name.
1057
 */
1058
Drupal.Sweaver.objectToReadable = function(object) {
1059

    
1060
  var translation = new Array();
1061
  var id_translation = new Array();
1062
  var class_translation = new Array();
1063
  var tag_translation = new Array();
1064

    
1065
  var css = new Array();
1066
  var id_css = new Array();
1067
  var class_css = new Array();
1068
  var tag_css = new Array();
1069

    
1070
  var selector = '';
1071
  var description = '';
1072
  var tempSelectors = new Array();
1073
  var pseudoClass = object.pseudoClass ? object.pseudoClass : '';
1074

    
1075
  var i = 0;
1076

    
1077
  // Traverse all selectors defined in the backend and return an array with the description.
1078
  $.each(Drupal.Sweaver.selectors, function() {
1079
    selector = this.selector;
1080
    name = this.name;
1081
    description = this.description;
1082

    
1083
    if (name == 'allids') {
1084
      if (object.id && $.inArray('#' + object.id, tempSelectors) < 0) {
1085
        id_translation[i] = 'the ' + object.id + ' region';
1086
        id_css[i] = '#' + object.id;
1087
        tempSelectors.push('#' + object.id);
1088
        i++;
1089
      }
1090
    }
1091
    else if (name == 'allclasses') {
1092
      if (object.classes && object.classes[0]) {
1093
        $.each(object.classes, function(index, tempClass) {
1094
          if ($.inArray(tempClass, Drupal.Sweaver.excludeClasses) < 0 && $.inArray('.' + tempClass, tempSelectors) < 0) {
1095
            class_translation[i] = 'all ' + tempClass;
1096
            class_css[i] = '.' + tempClass;
1097
            tempSelectors.push('.' + tempClass);
1098
            i++;
1099
          }
1100
        });
1101
      }
1102
    }
1103
    else if (name == 'alltags' && $.inArray(object.tag, tempSelectors) < 0) {
1104
      tag_translation[i] = object.tag;
1105
      tag_css[i] = object.tag;
1106
      tempSelectors.push(object.tag);
1107
      i++;
1108
    }
1109
    else {
1110
      if (selector == '#' + object.id && $.inArray('#' + object.id, tempSelectors) < 0) {
1111
        id_translation[i] = description;
1112
        id_css[i] = '#' + object.id;
1113
        tempSelectors.push('#' + object.id);
1114
        i++;
1115
      } else if (selector == object.tag && $.inArray(object.tag, tempSelectors) < 0) {
1116
        tag_translation[i] = description;
1117
        tag_css[i] = object.tag;
1118
        tempSelectors.push(object.tag);
1119
        i++;
1120
      } else {
1121
        $.each(object.classes, function(index, tempClass) {
1122
          if (selector == '.' + tempClass  && $.inArray(tempClass, Drupal.Sweaver.excludeClasses) < 0 && $.inArray('.' + tempClass, tempSelectors) < 0) {
1123
            class_translation[i] = description;
1124
            class_css[i] = '.' + tempClass;
1125
            tempSelectors.push('.' + tempClass);
1126
            i++;
1127
          }
1128
        });
1129
      }
1130
    }
1131
  });
1132

    
1133
  // Merge the translation arrays.
1134
  for (var j = 0; j < i; j++) {
1135
    var k = id_translation[j] ? id_translation[j] : class_translation[j] ? class_translation[j] : tag_translation[j];
1136
    translation[j] = Drupal.Sweaver.addPseudoClass(pseudoClass, k);
1137
  }
1138

    
1139
  // Merge the css arrays.
1140
  for (var j = 0; j < i; j++) {
1141
    var k = id_css[j] ? id_css[j] : class_css[j] ? class_css[j] : tag_css[j];
1142
    css[j] = k;
1143
  }
1144

    
1145
  // Add combinations of classes, ids and tags.
1146
  if (Drupal.settings.sweaver['combined_selectors']) {
1147
          t = i;
1148
          if (tag_translation.length > 0) {
1149
            $.each(tag_translation, function(index, tag) {
1150
              if (tag) {
1151
                            $.each(id_translation, function(index, trans) {
1152
                              if (trans) {
1153
                                translation[t] = Drupal.Sweaver.addPseudoClass(pseudoClass, tag + ' + ' + trans);
1154
                                css[t] = object.tag + id_css[index];
1155
                                t++;
1156
                              }
1157
                            });
1158
                      $.each(class_translation, function(index, trans) {
1159
                        if (trans) {
1160
                          translation[t] = Drupal.Sweaver.addPseudoClass(pseudoClass, tag + ' + ' + trans);
1161
              css[t] = object.tag + class_css[index];
1162
                          t++;
1163
                        }
1164
                      });
1165
                    }
1166
                  });
1167
          }
1168
  }
1169

    
1170
  // If a prefered selector was set in the object, return that one instead of the default first one.
1171
  index = object.preferredSelector ? object.preferredSelector : 0;
1172
  translation.splice(0, 0, translation[index]);
1173
  css.splice(0, 0, css[index]);
1174

    
1175
  object.translation = Drupal.settings.sweaver['translate_path'] ? translation : css;
1176
  object.css = css;
1177
  return translation;
1178
}
1179

    
1180
/**
1181
 * Add a pseudo class to the translation.
1182
 */
1183
Drupal.Sweaver.addPseudoClass = function(pseudoClass, original) {
1184
  if (Drupal.settings.sweaver['translate_path']) {
1185
    var translation = pseudoClass ? original + Drupal.t(' in the ' + pseudoClass + ' state') : original;
1186
  }
1187
  else {
1188
    var translation = pseudoClass ? original + pseudoClass : original;
1189
  }
1190
  return translation;
1191
}
1192

    
1193
/**
1194
 * Save current position
1195
 */
1196
Drupal.Sweaver.SavePosition = function() {
1197
  // Store the object used
1198
  // First we need to construct this path
1199
  path = '';
1200
  Drupal.Sweaver.path.reverse();
1201
  $.each(Drupal.Sweaver.path, function(index, value){
1202
    $.each(value.classes, function(i, v){
1203
      if (v == 'sweaver-hovered' || v == 'sweaver-clicked') {
1204
        value.classes.splice(i);
1205
      }
1206
    })
1207
    
1208
    if (value.tag == 'html' || value.tag == 'body') {
1209
      path += ' ' + value.tag;
1210
    }
1211
    else if (value.id != '') {
1212
      path += ' #' + value.id;
1213
    }
1214
    else if (Object.keys( value.classes ).length !== 0 && value.classes[0] != ''){
1215
      path += ' .' + value.classes[0];
1216
    }
1217
    else {
1218
      path += ' ' + value.tag;
1219
    }
1220
  });
1221
  Drupal.Sweaver.path.reverse();
1222
  Drupal.Sweaver.cookie('sweaver_active_path', path);
1223
  
1224
  // Save indexed path
1225
  indexed_path = '';
1226
  $('#sweaver_plugin_editor #full-path div[id^=sid-].active').each(function(){
1227
    id = $(this).attr('id').substr(4);
1228
    $(this).find('li.active').each(function(){
1229
      if ($(this).children().attr('id') != '') {
1230
        sub_id = $(this).children().attr('id').substr(5);
1231
      }
1232
      else {
1233
        sub_id = $(this).children().attr('class');
1234
      }
1235
      indexed_path += ' ' + id + '-' + sub_id;
1236
    });
1237
  });
1238
  Drupal.Sweaver.cookie('sweaver_indexed_path', indexed_path);
1239
  
1240
  // Store the tab used
1241
  Drupal.Sweaver.cookie('sweaver_active_vertical_tab', $('#sweaver_plugin_editor #sweaver-editor .vertical-tabs a.active').parent().attr('id'));
1242
}
1243

    
1244
/**
1245
 * Load a saved position in the editor (active path and tab)
1246
 */
1247
Drupal.Sweaver.LoadPosition = function() {
1248
  active_path = Drupal.Sweaver.cookie('sweaver_active_path');
1249
  indexed_path = Drupal.Sweaver.cookie('sweaver_indexed_path');
1250
  vertical_tab = Drupal.Sweaver.cookie('sweaver_active_vertical_tab');
1251
  
1252
  // If a configuration has been saved lets load it
1253
  if (active_path && indexed_path && vertical_tab){    
1254
    tempObject = $(active_path);
1255
    
1256
    // Load active path in the editor
1257
    Drupal.Sweaver.editSelection(tempObject);
1258
    
1259
    // Reset full path
1260
    $('#sweaver_plugin_editor #full-path div[id^=sid-]').removeClass('active');
1261
    Drupal.Sweaver.pathIndexes = [];
1262
    
1263
    // Apply indexed path
1264
    $.each(indexed_path.split(' '), function(index, value){
1265
      specific_path = value.split('-');
1266
      if (specific_path.length == 2) {
1267
        $('#sweaver_plugin_editor #full-path #sid-' + specific_path[0]).addClass('active');
1268
        Drupal.Sweaver.addToActivePathIndex(specific_path[0]);
1269
        Drupal.Sweaver.pathIndexes.sort(function(a,b){return a - b});
1270
        
1271
        if (specific_path[1].match('^[0-9]+$')) {
1272
        // Alternative Class  
1273
          Drupal.Sweaver.path[specific_path[0]].preferredSelector = specific_path[1];
1274
          
1275
          $('#sid-' + specific_path[0] + ' .first-selector a').html(Drupal.Sweaver.objectToReadable(Drupal.Sweaver.path[specific_path[0]])[0]);
1276
          
1277
          $('#sweaver_plugin_editor #full-path #sid-' + specific_path[0] + ' .selectors li').removeClass('active');
1278
          $('#sweaver_plugin_editor #full-path #sid-' + specific_path[0] + ' #ssid-' + specific_path[1]).parent().addClass('active');
1279
        }
1280
        else {
1281
        // Pseudo Class
1282
          Drupal.Sweaver.path[specific_path[0]].pseudoClass = ':' + specific_path[1];
1283
          Drupal.Sweaver.path[specific_path[0]].translation = Drupal.Sweaver.objectToReadable(Drupal.Sweaver.path[specific_path[0]]);
1284
          $('#sid-' + specific_path[0] + ' .first-selector a').html(Drupal.Sweaver.path[specific_path[0]].translation[0]);
1285
          
1286
          $('#sweaver_plugin_editor #full-path #sid-' + specific_path[0] + ' .pseudoclasses .' + specific_path[1]).parent().addClass('active');
1287
        }
1288
      }
1289
    });
1290
    Drupal.Sweaver.printActivePath();
1291
    Drupal.Sweaver.activeElement = Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[0]] ? Drupal.Sweaver.path[Drupal.Sweaver.pathIndexes[0]] : {} ;
1292
    Drupal.Sweaver.updateForm();
1293
    Drupal.Sweaver.updateScreen();
1294
    
1295
    $('#sweaver_plugin_editor #sweaver-editor #' + vertical_tab + ' a').click();
1296
    
1297
    Drupal.Sweaver.cookie('sweaver_active_path', null);
1298
    Drupal.Sweaver.cookie('sweaver_indexed_path', null);
1299
    Drupal.Sweaver.cookie('sweaver_active_vertical_tab', null);
1300
  }
1301
}
1302

    
1303

    
1304
/**
1305
 * Build a Sweaver object.
1306
 */
1307
Drupal.Sweaver.buildSweaverObject = function(object) {
1308
  var tempObject = new Object;
1309
  tempObject.id = object.attr('id');
1310
  tempObject.classes = trim(object.attr('class')).split(' ');
1311
  tempObject.pseudoClass = '';
1312
  tempObject.tag = object.get(0).tagName.toLowerCase();
1313
  tempObject.type = object.css('display');
1314

    
1315
  // Fallback to block if an unknow type is detected.
1316
  if (!(tempObject.type in Drupal.Sweaver.types)) {
1317
    tempObject.type = 'block';
1318
  }
1319

    
1320
  // Generate a human-readable name and a css selector.
1321
  Drupal.Sweaver.objectToReadable(tempObject);
1322
  return tempObject;
1323
}
1324

    
1325
/**
1326
 * Helper function to remove trailing leading and multiple spaces.
1327
 */
1328
function trim(s) {
1329
  s = s.replace(/(^\s*)|(\s*$)/gi,"");
1330
  s = s.replace(/[ ]{2,}/gi," ");
1331
  s = s.replace(/\n /,"\n");
1332
  return s;
1333
}
1334

    
1335
/**
1336
 * Hide all sliders.
1337
 */
1338
Drupal.Sweaver.hideOverlays = function() {
1339
  $('#sweaver .slider-wrapper').css({'visibility' : 'hidden'});
1340

    
1341
  // Remove all active classes from form-items and groups
1342
  $('#sweaver_plugin_editor .form-item, #sweaver_plugin_editor .sweaver-group').removeClass('active');
1343
}
1344

    
1345
/**
1346
 * Check wether the editor tab is visible.
1347
 */
1348
Drupal.Sweaver.visible = function() {
1349
  if (Drupal.Sweaver.open == 'true' && $('#sweaver_plugin_editor .sweaver-content').is(':visible')) {
1350
    return true;
1351
  }
1352
  else {
1353
    return false;
1354
  }
1355
}
1356

    
1357
/**
1358
 * Helper function to check if an object is empty.
1359
 */
1360
function isEmpty(obj) {
1361
  for(var prop in obj) {
1362
    if(obj.hasOwnProperty(prop))
1363
      return false;
1364
  }
1365
  return true;
1366
}
1367

    
1368

    
1369
/**
1370
 * Add custom expression to exclude all selectors in the sweaver bar.
1371
 */
1372
$.expr[':'].parents = function(a,i,m){
1373
  return jQuery(a).parents(m[3]).length < 1;
1374
};
1375

    
1376
})(jQuery);