wp/wp-content/plugins/option-tree/assets/js/ot-admin.js
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
--- a/wp/wp-content/plugins/option-tree/assets/js/ot-admin.js	Mon Jun 08 16:11:51 2015 +0000
+++ b/wp/wp-content/plugins/option-tree/assets/js/ot-admin.js	Tue Jun 09 03:35:32 2015 +0200
@@ -14,20 +14,24 @@
       this.init_add();
       this.init_edit();
       this.init_remove();
-      this.init_edit_title()
+      this.init_edit_title();
       this.init_edit_id();
       this.init_activate_layout();
+      this.init_conditions();
       this.init_upload();
       this.init_upload_remove();
       this.init_numeric_slider();
       this.init_tabs();
       this.init_radio_image_select();
       this.init_select_wrapper();
+      this.bind_select_wrapper();
+      this.init_google_fonts();
       this.fix_upload_parent();
-      this.fix_colorpicker();
       this.fix_textarea();
       this.replicate_ajax();
       this.reset_settings();
+      this.css_editor_mode();
+      this.javascript_editor_mode();
     },
     init_hide_body: function(elm,type) {
       var css = '.option-tree-setting-body';
@@ -55,8 +59,9 @@
         $(css).removeClass('active');
       }
     },
-    init_sortable: function() {
-      $('.option-tree-sortable').each( function() {
+    init_sortable: function(scope) {
+      scope = scope || document;
+      $('.option-tree-sortable', scope).each( function() {
         if ( $(this).children('li').length ) {
           var elm = $(this);
           elm.show();
@@ -80,27 +85,31 @@
       });
     },
     init_add: function() {
-      $('.option-tree-section-add').live('click', function(e) {
+      $(document).on('click', '.option-tree-section-add', function(e) {
         e.preventDefault();
         OT_UI.add(this,'section');
       });
-      $('.option-tree-setting-add').live('click', function(e) {
+      $(document).on('click', '.option-tree-setting-add', function(e) {
         e.preventDefault();
         OT_UI.add(this,'setting');
       });
-      $('.option-tree-help-add').live('click', function(e) {
+      $(document).on('click', '.option-tree-help-add', function(e) {
         e.preventDefault();
         OT_UI.add(this,'the_contextual_help');
       });
-      $('.option-tree-choice-add').live('click', function(e) {
+      $(document).on('click', '.option-tree-choice-add', function(e) {
         e.preventDefault();
         OT_UI.add(this,'choice');
       });
-      $('.option-tree-list-item-add').live('click', function(e) {
+      $(document).on('click', '.option-tree-list-item-add', function(e) {
         e.preventDefault();
         OT_UI.add(this,'list_item');
       });
-      $('.option-tree-list-item-setting-add').live('click', function(e) {
+      $(document).on('click', '.option-tree-social-links-add', function(e) {
+        e.preventDefault();
+        OT_UI.add(this,'social_links');
+      });
+      $(document).on('click', '.option-tree-list-item-setting-add', function(e) {
         e.preventDefault();
         if ( $(this).parents('ul').parents('ul').hasClass('ui-sortable') ) {
           alert(option_tree.setting_limit);
@@ -110,7 +119,7 @@
       });
     },
     init_edit: function() {
-      $('.option-tree-setting-edit').live('click', function(e) {
+      $(document).on('click', '.option-tree-setting-edit', function(e) {
         e.preventDefault();
         if ( $(this).parents().hasClass('option-tree-setting-body') ) {
           OT_UI.init_remove_active($(this),'child');
@@ -124,7 +133,7 @@
       });
     },
     init_remove: function() {
-      $('.option-tree-setting-remove').live('click', function(event) {
+      $(document).on('click', '.option-tree-setting-remove', function(event) {
         event.preventDefault();
         if ( $(this).parents('li').hasClass('ui-state-disabled') ) {
           alert(option_tree.remove_no);
@@ -142,23 +151,30 @@
       });
     },
     init_edit_title: function() {
-      $('.option-tree-setting-title').live('keyup', function() {
+      $(document).on('keyup', '.option-tree-setting-title', function() {
         OT_UI.edit_title(this);
       });
+      // Automatically fill option IDs with clean versions of their respective option labels
+      $(document).on('blur', '.option-tree-setting-title', function() {
+        var optionId = $(this).parents('.option-tree-setting-body').find('[type="text"][name$="id]"]')
+        if ( optionId.val() === '' ) {
+          optionId.val($(this).val().replace(/[^a-z0-9]/gi,'_').toLowerCase());
+        }
+      });
     },
     init_edit_id: function() {
-      $('.section-id').live('keyup', function(){
+      $(document).on('keyup', '.section-id', function(){
         OT_UI.update_id(this);
       });
     },
     init_activate_layout: function() {
-      $('.option-tree-layout-activate').live('click', function() { 
+      $(document).on('click', '.option-tree-layout-activate', function() { 
         var active = $(this).parents('.option-tree-setting').find('.open').text();
         $('.option-tree-layout-activate').removeClass('active');
         $(this).toggleClass('active');
         $('.active-layout-input').attr({'value':active});
       });
-      $('#option-tree-options-layouts-form select').live('change', function() {
+      $(document).on('change', '#option-tree-options-layouts-form select', function() {
         var agree = confirm(option_tree.activate_layout_agree);
         if (agree) {
           $('#option-tree-options-layouts-form').submit();
@@ -189,6 +205,9 @@
       } else if ( type == 'list_item_setting' ) {
         list = $(elm).parent().children('ul');
         list_class = 'list-sub-setting';
+      } else if ( type == 'social_links' ) {
+        list = $(elm).parent().children('ul');
+        list_class = 'list-sub-setting';
       } else {
         list = $(elm).parent().find('ul:first');
         list_class = ( type == 'section' ) ? 'list-section' : 'list-setting';
@@ -200,7 +219,7 @@
       if ( this.processing === false ) {
         this.processing = true;
         var count = parseInt(list.children('li').length);
-        if ( type == 'list_item' ) {
+        if ( type == 'list_item' || type == 'social_links' ) {
           list.find('li input.option-tree-setting-title', self).each(function(){
             var setting = $(this).attr('name'),
                 regex = /\[([0-9]+)\]/,
@@ -232,18 +251,18 @@
               OT_UI.init_remove_active();
               OT_UI.init_hide_body();
             }
-            list.append('<li class="ui-state-default ' + list_class + '">' + data.responseText + '</li>');
+            var listItem = $('<li class="ui-state-default ' + list_class + '">' + data.responseText + '</li>');
+            list.append(listItem);
             list.children().last().find('.option-tree-setting-edit').toggleClass('active');
             list.children().last().find('.option-tree-setting-body').toggle();
             list.children().last().find('.option-tree-setting-title').focus();
             if ( type != 'the_contextual_help' ) {
               OT_UI.update_ids(list);
             }
-            setTimeout( function() {
-              OT_UI.init_sortable();
-              OT_UI.init_select_wrapper();
-              OT_UI.init_numeric_slider();
-            }, 500);
+            OT_UI.init_sortable(listItem);
+            OT_UI.init_select_wrapper(listItem);
+            OT_UI.init_numeric_slider(listItem);
+            OT_UI.parse_condition();
             self.processing = false;
           }
         });
@@ -288,11 +307,122 @@
         last_section = section;
       });
     },
+    condition_objects: function() {
+      return 'select, input[type="radio"]:checked, input[type="text"], input[type="hidden"], input.ot-numeric-slider-hidden-input';
+    },
+    match_conditions: function(condition) {
+      var match;
+      var regex = /(.+?):(is|not|contains|less_than|less_than_or_equal_to|greater_than|greater_than_or_equal_to)\((.*?)\),?/g;
+      var conditions = [];
+
+      while( match = regex.exec( condition ) ) {
+        conditions.push({
+          'check': match[1], 
+          'rule':  match[2], 
+          'value': match[3] || ''
+        });
+      }
+
+      return conditions;
+    },
+    parse_condition: function() {
+      $( '.format-settings[id^="setting_"][data-condition]' ).each(function() {
+
+        var passed;
+        var conditions = OT_UI.match_conditions( $( this ).data( 'condition' ) );
+        var operator = ( $( this ).data( 'operator' ) || 'and' ).toLowerCase();
+
+        $.each( conditions, function( index, condition ) {
+
+          var target   = $( '#setting_' + condition.check );
+          var targetEl = !! target.length && target.find( OT_UI.condition_objects() ).first();
+
+          if ( ! target.length || ( ! targetEl.length && condition.value.toString() != '' ) ) {
+            return;
+          }
+
+          var v1 = targetEl.length ? targetEl.val().toString() : '';
+          var v2 = condition.value.toString();
+          var result;
+
+          switch ( condition.rule ) {
+            case 'less_than':
+              result = ( parseInt( v1 ) < parseInt( v2 ) );
+              break;
+            case 'less_than_or_equal_to':
+              result = ( parseInt( v1 ) <= parseInt( v2 ) );
+              break;
+            case 'greater_than':
+              result = ( parseInt( v1 ) > parseInt( v2 ) );
+              break;
+            case 'greater_than_or_equal_to':
+              result = ( parseInt( v1 ) >= parseInt( v2 ) );
+              break;
+            case 'contains':
+              result = ( v1.indexOf(v2) !== -1 ? true : false );
+              break; 
+            case 'is':
+              result = ( v1 == v2 );
+              break;
+            case 'not':
+              result = ( v1 != v2 );
+              break;
+          }
+
+          if ( 'undefined' == typeof passed ) {
+            passed = result;
+          }
+
+          switch ( operator ) {
+            case 'or':
+              passed = ( passed || result );
+              break;
+            case 'and':
+            default:
+              passed = ( passed && result );
+              break;
+          }
+          
+        });
+
+        if ( passed ) {
+          $(this).animate({opacity: 'show' , height: 'show'}, 200);
+        } else {
+          $(this).animate({opacity: 'hide' , height: 'hide'}, 200);
+        }
+        
+        delete passed;
+
+      });
+    },
+    init_conditions: function() {
+      var delay = (function() {
+        var timer = 0;
+        return function(callback, ms) {
+          clearTimeout(timer);
+          timer = setTimeout(callback, ms);
+        };
+      })();
+
+      $('.format-settings[id^="setting_"]').on( 'change.conditionals, keyup.conditionals', OT_UI.condition_objects(), function(e) {
+        if (e.type === 'keyup') {
+          // handle keyup event only once every 500ms
+          delay(function() {
+            OT_UI.parse_condition();
+          }, 500);
+        } else {
+          OT_UI.parse_condition();
+        }
+        OT_UI.load_editors();
+      });
+      OT_UI.parse_condition();
+    },
     init_upload: function() {
       $(document).on('click', '.ot_upload_media', function() {
-        var field_id    = $(this).parent('.option-tree-ui-upload-parent').find('input').attr('id'),
-            post_id     = $(this).attr('rel'),
-            btnContent  = '';
+        var field_id            = $(this).parent('.option-tree-ui-upload-parent').find('input').attr('id'),
+            post_id             = $(this).attr('rel'),
+            save_attachment_id  = $('#'+field_id).hasClass('ot-upload-attachment-id'),
+            btnContent          = '';
         if ( window.wp && wp.media ) {
           window.ot_media_frame = window.ot_media_frame || new wp.media.view.MediaFrame.Select({
             title: $(this).attr('title'),
@@ -303,14 +433,15 @@
           });
           window.ot_media_frame.on('select', function() {
             var attachment = window.ot_media_frame.state().get('selection').first(), 
-                href = attachment.attributes.url, 
+                href = attachment.attributes.url,
+                attachment_id = attachment.attributes.id,
                 mime = attachment.attributes.mime,
                 regex = /^image\/(?:jpe?g|png|gif|x-icon)$/i;
             if ( mime.match(regex) ) {
               btnContent += '<div class="option-tree-ui-image-wrap"><img src="'+href+'" alt="" /></div>';
             }
-            btnContent += '<a href="javascript:(void);" class="option-tree-ui-remove-media option-tree-ui-button red light" title="'+option_tree.remove_media_text+'"><span class="icon trash-can">'+option_tree.remove_media_text+'</span></a>';
-            $('#'+field_id).val(href);
+            btnContent += '<a href="javascript:(void);" class="option-tree-ui-remove-media option-tree-ui-button button button-secondary light" title="'+option_tree.remove_media_text+'"><span class="icon ot-icon-minus-circle"></span>'+option_tree.remove_media_text+'</a>';
+            $('#'+field_id).val( ( save_attachment_id ? attachment_id : href ) );
             $('#'+field_id+'_media').remove();
             $('#'+field_id).parent().parent('div').append('<div class="option-tree-ui-media-wrap" id="'+field_id+'_media" />');
             $('#'+field_id+'_media').append(btnContent).slideDown();
@@ -338,7 +469,7 @@
             if (href.match(image) && OT_UI.url_exists(href)) {
               btnContent += '<div class="option-tree-ui-image-wrap"><img src="'+href+'" alt="" /></div>';
             }
-            btnContent += '<a href="javascript:(void);" class="option-tree-ui-remove-media option-tree-ui-button red light" title="'+option_tree.remove_media_text+'"><span class="icon trash-can">'+option_tree.remove_media_text+'</span></a>';
+            btnContent += '<a href="javascript:(void);" class="option-tree-ui-remove-media option-tree-ui-button button button-secondary light" title="'+option_tree.remove_media_text+'"><span class="icon ot-icon-minus-circle"></span>'+option_tree.remove_media_text+'</a>';
             $('#'+field_id).val(href);
             $('#'+field_id+'_media').remove();
             $('#'+field_id).parent().parent('div').append('<div class="option-tree-ui-media-wrap" id="'+field_id+'_media" />');
@@ -353,7 +484,7 @@
       });
     },
     init_upload_remove: function() {
-      $('.option-tree-ui-remove-media').live('click', function(event) {
+      $(document).on('click', '.option-tree-ui-remove-media', function(event) {
         event.preventDefault();
         var agree = confirm(option_tree.remove_agree);
         if (agree) {
@@ -366,9 +497,12 @@
     init_upload_fix: function(elm) {
       var id  = $(elm).attr('id'),
           val = $(elm).val(),
-          img = $(elm).parent().next('option-tree-ui-media-wrap').find('img'),
+          img = $(elm).parent().next('.option-tree-ui-media-wrap').find('img'),
           src = img.attr('src'),
           btnContent = '';
+      if ( val == src ) {
+        return;
+      }
       if ( val != src ) {
         img.attr('src', val);
       }
@@ -377,7 +511,7 @@
         if (val.match(image)) {
           btnContent += '<div class="option-tree-ui-image-wrap"><img src="'+val+'" alt="" /></div>';
         }
-        btnContent += '<a href="javascript:(void);" class="option-tree-ui-remove-media option-tree-ui-button red light" title="'+option_tree.remove_media_text+'"><span class="icon trash-can">'+option_tree.remove_media_text+'</span></a>';
+        btnContent += '<a href="javascript:(void);" class="option-tree-ui-remove-media option-tree-ui-button button button-secondary light" title="'+option_tree.remove_media_text+'"><span class="icon ot-icon-minus-circle">'+option_tree.remove_media_text+'</span></a>';
         $('#'+id).val(val);
         $('#'+id+'_media').remove();
         $('#'+id).parent().parent('div').append('<div class="option-tree-ui-media-wrap" id="'+id+'_media" />');
@@ -386,8 +520,9 @@
         $(elm).parent().next('.option-tree-ui-media-wrap').remove();
       }
     },
-    init_numeric_slider: function() {
-      $(".ot-numeric-slider-wrap").each(function() {
+    init_numeric_slider: function(scope) {
+      scope = scope || document;
+      $(".ot-numeric-slider-wrap", scope).each(function() {
         var hidden = $(".ot-numeric-slider-hidden-input", this),
             value  = hidden.val(),
             helper = $(".ot-numeric-slider-helper-input", this);
@@ -401,7 +536,13 @@
           step: hidden.data("step"),
           value: value, 
           slide: function(event, ui) {
-            hidden.add(helper).val(ui.value);
+            hidden.add(helper).val(ui.value).trigger('change');
+          },
+          create: function() {
+            hidden.val($(this).slider('value'));
+          },
+          change: function() {
+            OT_UI.parse_condition();
           }
         });
       });
@@ -430,47 +571,118 @@
       });
     },
     init_radio_image_select: function() {
-      $('.option-tree-ui-radio-image').live('click', function() {
+      $(document).on('click', '.option-tree-ui-radio-image', function() {
         $(this).closest('.type-radio-image').find('.option-tree-ui-radio-image').removeClass('option-tree-ui-radio-image-selected');
         $(this).toggleClass('option-tree-ui-radio-image-selected');
-        $(this).parent().find('.option-tree-ui-radio').attr('checked', true);
+        $(this).parent().find('.option-tree-ui-radio').prop('checked', true).trigger('change');
       });
     },
-    init_select_wrapper: function() {
-      $('.option-tree-ui-select').each(function () {
+    init_select_wrapper: function(scope) {
+      scope = scope || document;
+      $('.option-tree-ui-select', scope).each(function () {
         if ( ! $(this).parent().hasClass('select-wrapper') ) {
           $(this).wrap('<div class="select-wrapper" />');
           $(this).parent('.select-wrapper').prepend('<span>' + $(this).find('option:selected').text() + '</span>');
         }
       });
-      $('.option-tree-ui-select').live('change', function () {
+    },
+    bind_select_wrapper: function() {
+      $(document).on('change', '.option-tree-ui-select', function () {
         $(this).prev('span').replaceWith('<span>' + $(this).find('option:selected').text() + '</span>');
       });
-      $('.option-tree-ui-select').bind($.browser.msie ? 'click' : 'change', function(event) {
-        $(this).prev('span').replaceWith('<span>' + $(this).find('option:selected').text() + '</span>');
+    },
+    init_google_fonts: function() {
+      var update_items = function(input, items, element) {
+        var itemsUI = input.closest('.type-google-font-group').find(element);
+        if ( itemsUI.length ) {
+          itemsUI.empty();
+          itemsUI.append($.map(items, function(item) {
+            var input = document.createElement('input'),
+                label = document.createElement('label');
+            input.type = 'checkbox';
+            input.id = ( itemsUI.data('field-id-prefix') || '' ) + item;
+            input.name =  ( itemsUI.data('field-name') || '' ) + '[]';
+            input.value =  item;
+            label.innerHTML = item;
+            $( label ).attr( 'for', input.id );
+            return $( document.createElement('p') ).addClass('checkbox-wrap').append([input, label]);
+          }));
+        }
+      };
+      $(document).on('change', '.option-tree-google-font-family select', function() {
+        var input = $(this);
+        $.ajax({
+          url: option_tree.ajax,
+          type: 'POST',
+          dataType: 'json',
+          data: {
+            action: 'ot_google_font',
+            family: input.val(), 
+            field_id: input.attr('id')
+          }
+        }).done(function(response) {
+          if ( response.hasOwnProperty('variants') ) {
+            update_items( input, response.variants, '.option-tree-google-font-variants' );
+          }
+          if ( response.hasOwnProperty('subsets') ) {
+            update_items( input, response.subsets, '.option-tree-google-font-subsets' );
+          }
+        });
+      });
+      $('.js-add-google-font').on('click', function (event) {
+        var $group = $(this).parent('.format-setting-inner').find('.type-google-font-group'),
+            $el_clone = $(this).prev('.type-google-font-group-clone'),
+            $clone = $el_clone.clone(true),
+            $count = $group.length ? $group.length : 0;
+        $clone.attr('class', 'type-google-font-group');
+        var replacer = function(index, elm) { 
+          return elm.replace('%key%', $count);
+        }
+        $('select', $clone).each( function() {
+          $(this).attr('id', replacer ).attr('name', replacer );
+        });
+        $('.option-tree-google-font-variants', $clone).each( function() {
+          $(this).attr('data-field-id-prefix', replacer ).attr('data-field-name', replacer );
+        });
+        $('.option-tree-google-font-subsets', $clone).each( function() {
+          $(this).attr('data-field-id-prefix', replacer ).attr('data-field-name', replacer );
+        });
+        $el_clone.before($clone)
+        event.preventDefault()
+      });
+      $('.js-remove-google-font').on('click', function (event) {
+        $(this).parents('.type-google-font-group').remove();
+        event.preventDefault();
       });
     },
     bind_colorpicker: function(field_id) {
-      $('#'+field_id).ColorPicker({
-        onSubmit: function(hsb, hex, rgb) {
-          $('#'+field_id).val('#'+hex);
-        },
-        onBeforeShow: function () {
-          $(this).ColorPickerSetColor(this.value);
-          return false;
-        },
-        onChange: function (hsb, hex, rgb) {
-          var bc = $.inArray(hex, [ 'FFFFFF', 'FFF', 'ffffff', 'fff' ]) != -1 ? 'ccc' : hex;
-          $('#cp_'+field_id).css({'backgroundColor':'#'+hex,'borderColor':'#'+bc});
-          $('#cp_'+field_id).prev('input').attr('value', '#'+hex);
+      $('#'+field_id).wpColorPicker({
+        change: function() {
+          OT_UI.parse_condition();
+        }, 
+        clear: function() {
+          OT_UI.parse_condition();
         }
-      })  
-      .bind('keyup', function(){
-        $(this).ColorPickerSetColor(this.value);
+      });
+    },
+    bind_date_picker: function(field_id, date_format) {
+      $('#'+field_id).datepicker({
+        showOtherMonths: true,
+        showButtonPanel: true,
+        currentText: option_tree.date_current,
+        closeText: option_tree.date_close,
+        dateFormat: date_format
+      });
+    },
+    bind_date_time_picker: function(field_id, date_format) {
+      $('#'+field_id).datetimepicker({
+        showOtherMonths: true,
+        closeText: option_tree.date_close,
+        dateFormat: date_format
       });
     },
     fix_upload_parent: function() {
-      $('.option-tree-ui-upload-input').live('focus blur', function(){
+      $('.option-tree-ui-upload-input').not('.ot-upload-attachment-id').on('focus blur', function(){
         $(this).parent('.option-tree-ui-upload-parent').toggleClass('focus');
         OT_UI.init_upload_fix(this);
       });
@@ -479,19 +691,6 @@
       $(e).parent().parent().find('.option-tree-ui-upload-input').attr('value','');
       $(e).parent('.option-tree-ui-media-wrap').remove();
     },
-    fix_colorpicker: function() {
-      $('.cp_input').live('blur', function() {
-        $('.cp_input').each( function(index, el) {
-          var val = $(el).val();
-          var reg = /^[A-Fa-f0-9]{6}$/;
-          if( reg.test(val) && val != '' ) { 
-            $(el).attr('value', '#'+val)
-          } else if ( val == '' ) {
-            $(this).next('.cp_box').css({'background':'#f1f1f1','border-color':'#ccc'});
-          }
-        });
-      });
-    },
     fix_textarea: function() {
       $('.wp-editor-area').focus( function(){
         $(this).parent('div').css({borderColor:'#bbb'});
@@ -511,7 +710,7 @@
       }, 3000 );
     },
     reset_settings: function() {
-      $(".reset-settings").live("click", function(event){
+      $(document).on("click", ".reset-settings", function(event){
         var agree = confirm(option_tree.reset_agree);
         if (agree) {
           return true;
@@ -521,7 +720,50 @@
         event.preventDefault();
       });
     },
+    css_editor_mode: function() {
+      $('.ot-css-editor').each(function() {
+        var editor = ace.edit($(this).attr('id'));
+        var this_textarea = $('#textarea_' + $(this).attr('id'));
+        editor.setTheme("ace/theme/chrome");
+        editor.getSession().setMode("ace/mode/css");
+        editor.setShowPrintMargin( false );
+    
+        editor.getSession().setValue(this_textarea.val());
+        editor.getSession().on('change', function(){
+          this_textarea.val(editor.getSession().getValue());
+        });
+        this_textarea.on('change', function(){
+          editor.getSession().setValue(this_textarea.val());
+        });
+      });
+    },
+    javascript_editor_mode: function() {
+      $('.ot-javascript-editor').each(function() {
+        var editor = ace.edit($(this).attr('id'));
+        var this_textarea = $('#textarea_' + $(this).attr('id'));
+        editor.setTheme("ace/theme/chrome");
+        editor.getSession().setMode("ace/mode/javascript");
+        editor.setShowPrintMargin( false );
+    
+        editor.getSession().setValue(this_textarea.val());
+        editor.getSession().on('change', function(){
+          this_textarea.val(editor.getSession().getValue());
+        });
+        this_textarea.on('change', function(){
+          editor.getSession().setValue(this_textarea.val());
+        });
+      });
+    },
+    load_editors: function() {
+      OT_UI.css_editor_mode();
+      OT_UI.javascript_editor_mode();
+    },
     url_exists: function(url) {
+      var link = document.createElement('a')
+      link.href = url
+      if ( link.hostname != window.location.hostname ) {
+        return true; // Stop the code from checking across domains.
+      }
       var http = new XMLHttpRequest();
       http.open('HEAD', url, false);
       http.send();
@@ -536,4 +778,515 @@
   $(document).ready( function() {
     OT_UI.init();
   });
-})(jQuery);
\ No newline at end of file
+})(jQuery);
+
+/* Gallery */
+!function ($) {
+  
+  ot_gallery = {
+      
+    frame: function (elm) {
+      
+      var selection = this.select(elm)
+      
+      this._frame = wp.media({
+        id:         'ot-gallery-frame'
+      , frame:      'post'
+      , state:      'gallery-edit'
+      , title:      wp.media.view.l10n.editGalleryTitle
+      , editing:    true
+      , multiple:   true
+      , selection:  selection
+      })
+      
+      this._frame.on('update', function () {
+        var controller = ot_gallery._frame.states.get('gallery-edit')
+          , library = controller.get('library')
+          , ids = library.pluck('id')
+          , parent = $(elm).parents('.format-setting-inner')
+          , input = parent.children('.ot-gallery-value')
+          , shortcode = wp.media.gallery.shortcode( selection ).string().replace(/\"/g,"'")
+        
+        input.attr('value', ids)
+                        
+        if ( parent.children('.ot-gallery-list').length <= 0 )
+          input.after('<ul class="ot-gallery-list" />')
+        
+        $.ajax({
+          type: 'POST',
+          url: ajaxurl,
+          dataType: 'html',
+          data: {
+            action: 'gallery_update'
+          , ids: ids
+          },
+          success: function(res) {
+            parent.children('.ot-gallery-list').html(res);
+            if ( input.hasClass('ot-gallery-shortcode') ) {
+              input.val(shortcode);
+            }
+            if ( $(elm).parent().children('.ot-gallery-delete').length <= 0 ) {
+              $(elm).parent().append('<a href="#" class="option-tree-ui-button button button-secondary hug-left ot-gallery-delete">' + option_tree.delete + '</a>');
+            }
+            $(elm).text(option_tree.edit);
+            OT_UI.parse_condition();
+          }
+        })
+      })
+        
+      return this._frame
+      
+    }
+      
+  , select: function (elm) {
+      var input = $(elm).parents('.format-setting-inner').children('.ot-gallery-value')
+        , ids = input.attr('value')
+        , _shortcode = input.hasClass('ot-gallery-shortcode') ? ids : '[gallery ids=\'' + ids + '\]'
+        , shortcode = wp.shortcode.next('gallery', ( ids ? _shortcode : wp.media.view.settings.ot_gallery.shortcode ) )
+        , defaultPostId = wp.media.gallery.defaults.id
+        , attachments
+        , selection
+        
+      // Bail if we didn't match the shortcode or all of the content.
+      if ( ! shortcode )
+        return
+      
+      // Ignore the rest of the match object.
+      shortcode = shortcode.shortcode
+      
+      if ( _.isUndefined( shortcode.get('id') ) && ! _.isUndefined( defaultPostId ) )
+        shortcode.set( 'id', defaultPostId )
+      
+      if ( _.isUndefined( shortcode.get('ids') ) && ! input.hasClass('ot-gallery-shortcode') && ids )
+        shortcode.set( 'ids', ids )
+      
+      if ( _.isUndefined( shortcode.get('ids') ) )
+        shortcode.set( 'ids', '0' )
+      
+      attachments = wp.media.gallery.attachments( shortcode )
+
+      selection = new wp.media.model.Selection( attachments.models, {
+        props:    attachments.props.toJSON()
+      , multiple: true
+      })
+      
+      selection.gallery = attachments.gallery
+    
+      // Fetch the query's attachments, and then break ties from the query to allow for sorting.
+      selection.more().done( function () {
+        selection.props.set({ query: false })
+        selection.unmirror()
+        selection.props.unset('orderby')
+      })
+      
+      return selection
+      
+    }
+    
+  , open: function (elm) {
+      
+      ot_gallery.frame(elm).open()
+      
+    }
+  
+  , remove: function (elm) {
+      
+      if ( confirm( option_tree.confirm ) ) {
+        
+        $(elm).parents('.format-setting-inner').children('.ot-gallery-value').attr('value', '');
+        $(elm).parents('.format-setting-inner').children('.ot-gallery-list').remove();
+        $(elm).next('.ot-gallery-edit').text( option_tree.create );
+        $(elm).remove();
+        OT_UI.parse_condition();
+        
+      }
+
+    }
+  
+  }
+
+  // Gallery delete
+  $(document).on('click.ot_gallery.data-api', '.ot-gallery-delete', function (e) {
+    e.preventDefault()
+    ot_gallery.remove($(this))
+  })
+  
+  // Gallery edit
+  $(document).on('click.ot_gallery.data-api', '.ot-gallery-edit', function (e) {
+    e.preventDefault()
+    ot_gallery.open($(this))
+  })
+  
+}(window.jQuery);
+
+/*!
+ * Adds metabox tabs
+ */
+!function ($) {
+
+  $(document).on('ready', function () {
+    
+    // Loop over the metaboxes
+    $('.ot-metabox-wrapper').each( function() {
+    
+      // Only if there is a tab option
+      if ( $(this).find('.type-tab').length ) {
+        
+        // Add .ot-metabox-panels
+        $(this).find('.type-tab').parents('.ot-metabox-wrapper').wrapInner('<div class="ot-metabox-panels" />')
+        
+        // Wrapp with .ot-metabox-tabs & add .ot-metabox-nav before .ot-metabox-panels
+        $(this).find('.ot-metabox-panels').wrap('<div class="ot-metabox-tabs" />').before('<ul class="ot-metabox-nav" />')
+        
+        // Loop over settings and build the tabs nav
+        $(this).find('.format-settings').each( function() {
+      
+          if ( $(this).find('.type-tab').length > 0 ) {
+            var title = $(this).find('.type-tab').prev().find('label').text()
+              , id = $(this).attr('id')
+  
+            // Add a class, hide & append nav item 
+            $(this).addClass('is-panel').hide()
+            $(this).parents('.ot-metabox-panels').prev('.ot-metabox-nav').append('<li><a href="#' + id + '">' + title + '</a></li>')
+            
+          }
+          
+        })
+        
+        // Loop over the panels and wrap and ID them.
+        $(this).find('.is-panel').each( function() {
+          var id = $(this).attr('id')
+          
+          $(this).add( $(this).nextUntil('.is-panel') ).wrapAll('<div id="' + id + '" class="tab-content" />')
+          
+        })
+        
+        // Create the tabs
+        $(this).find('.ot-metabox-tabs').tabs({
+          activate: function( event, ui ) {
+            var parent = $(this).outerHeight(),
+                child = $(this).find('.ot-metabox-panels').outerHeight() + 8,
+                minHeight = parent - 34
+            if ( $(this).find('.ot-metabox-panels').css('padding') == '12px' && child < parent ) {
+              $(this).find('.ot-metabox-panels').css({ minHeight: minHeight })
+            }
+            OT_UI.load_editors();
+          }
+        })
+        
+        // Move the orphaned settings to the top
+        $(this).find('.ot-metabox-panels > .format-settings').prependTo($(this))
+        
+        // Remove a bunch of classes to stop style conflicts.
+        $(this).find('.ot-metabox-tabs').removeClass('ui-widget ui-widget-content ui-corner-all')
+        $(this).find('.ot-metabox-nav').removeClass('ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all')
+        $(this).find('.ot-metabox-nav li').removeClass('ui-state-default ui-corner-top ui-tabs-active ui-tabs-active')
+        $(this).find('.ot-metabox-nav li').on('mouseenter mouseleave', function() { $(this).removeClass('ui-state-hover') })
+
+      }
+    
+    })
+     
+  })
+  
+}(window.jQuery);
+
+/*!
+ * Adds theme option tabs
+ */
+!function ($) {
+
+  $(document).on('ready', function () {
+    
+    // Loop over the theme options
+    $('#option-tree-settings-api .inside').each( function() {
+    
+      // Only if there is a tab option
+      if ( $(this).find('.type-tab').length ) {
+        
+        // Add .ot-theme-option-panels
+        $(this).find('.type-tab').parents('.inside').wrapInner('<div class="ot-theme-option-panels" />')
+        
+        // Wrap with .ot-theme-option-tabs & add .ot-theme-option-nav before .ot-theme-option-panels
+        $(this).find('.ot-theme-option-panels').wrap('<div class="ot-theme-option-tabs" />').before('<ul class="ot-theme-option-nav" />')
+        
+        // Loop over settings and build the tabs nav
+        $(this).find('.format-settings').each( function() {
+      
+          if ( $(this).find('.type-tab').length > 0 ) {
+            var title = $(this).find('.type-tab').prev().find('.label').text()
+              , id = $(this).attr('id')
+  
+            // Add a class, hide & append nav item 
+            $(this).addClass('is-panel').hide()
+            $(this).parents('.ot-theme-option-panels').prev('.ot-theme-option-nav').append('<li><a href="#' + id + '">' + title + '</a></li>')
+            
+          } else {
+          
+          }
+          
+        })
+        
+        // Loop over the panels and wrap and ID them.
+        $(this).find('.is-panel').each( function() {
+          var id = $(this).attr('id')
+          
+          $(this).add( $(this).nextUntil('.is-panel') ).wrapAll('<div id="' + id + '" class="tab-content" />')
+          
+        })
+        
+        // Create the tabs
+        $(this).find('.ot-theme-option-tabs').tabs({
+          activate: function( event, ui ) {
+            OT_UI.load_editors();
+          }
+        })
+        
+        // Move the orphaned settings to the top
+        $(this).find('.ot-theme-option-panels > .format-settings').prependTo($(this).find('.ot-theme-option-tabs'))
+      
+      }
+    
+    })
+     
+  })
+  
+}(window.jQuery);
+
+/*!
+ * Fixes the state of metabox radio buttons after a Drag & Drop event.
+ */
+!function ($) {
+  
+  $(document).on('ready', function () {
+
+    // detect mousedown and store all checked radio buttons
+    $('.hndle').on('mousedown', function () {
+      
+      // get parent element of .hndle selected. 
+      // We only need to monitor radios insde the object that is being moved.
+      var parent_id = $(this).closest('div').attr('id')
+      
+      // set live event listener for mouse up on the content .wrap 
+      // then give the dragged div time to settle before firing the reclick function
+      $('.wrap').on('mouseup', function () {
+        
+        var ot_checked_radios = {}
+        
+        // loop over all checked radio buttons inside of parent element
+        $('#' + parent_id + ' input[type="radio"]').each( function () {
+          
+          // stores checked radio buttons
+          if ( $(this).is(':checked') ) {
+            
+            ot_checked_radios[$(this).attr('name')] = $(this).val()
+          
+          }
+          
+          // write to the object
+          $(document).data('ot_checked_radios', ot_checked_radios)
+          
+        })
+        
+        // restore all checked radio buttons 
+        setTimeout( function () {
+      
+          // get object of checked radio button names and values
+          var checked = $(document).data('ot_checked_radios')
+          
+          // step thru each object element and trigger a click on it's corresponding radio button
+          for ( key in checked ) {
+            
+            $('input[name="' + key + '"]').filter('[value="' + checked[key] + '"]').trigger('click')
+            
+          }
+          
+          $('.wrap').unbind('mouseup')
+          
+        }, 50 )
+      
+      })
+      
+    })
+  
+  })
+  
+}(window.jQuery);
+
+/*!
+ * Adds opacity to the default colorpicker
+ *
+ * Derivative work of the Codestar WP Color Picker.
+ */
+;(function ( $, window, document, undefined ) {
+  'use strict';
+
+  // adding alpha support for Automattic Color.js toString function.
+  if( typeof Color.fn.toString !== undefined ) {
+
+    Color.fn.toString = function () {
+
+      // check for alpha
+      if ( this._alpha < 1 ) {
+        return this.toCSS('rgba', this._alpha).replace(/\s+/g, '');
+      }
+
+      var hex = parseInt( this._color, 10 ).toString( 16 );
+
+      if ( this.error ) { return ''; }
+
+      // maybe left pad it
+      if ( hex.length < 6 ) {
+        for (var i = 6 - hex.length - 1; i >= 0; i--) {
+          hex = '0' + hex;
+        }
+      }
+
+      return '#' + hex;
+
+    };
+
+  }
+
+  $.ot_ParseColorValue = function( val ) {
+
+    var value = val.replace(/\s+/g, ''),
+        alpha = ( value.indexOf('rgba') !== -1 ) ? parseFloat( value.replace(/^.*,(.+)\)/, '$1') * 100 ) : 100,
+        rgba  = ( alpha < 100 ) ? true : false;
+
+    return { value: value, alpha: alpha, rgba: rgba };
+
+  };
+
+  $.fn.ot_wpColorPicker = function() {
+
+    return this.each(function() {
+
+      var $this = $(this);
+
+      // check for rgba enabled/disable
+      if( $this.data('rgba') !== false ) {
+
+        // parse value
+        var picker = $.ot_ParseColorValue( $this.val() );
+
+        // wpColorPicker core
+        $this.wpColorPicker({
+
+          // wpColorPicker: change
+          change: function( event, ui ) {
+
+            // update checkerboard background color
+            $this.closest('.wp-picker-container').find('.option-tree-opacity-slider-offset').css('background-color', ui.color.toString());
+            $this.trigger('keyup');
+
+          },
+
+          // wpColorPicker: create
+          create: function( event, ui ) {
+
+            // set variables for alpha slider
+            var a8cIris       = $this.data('a8cIris'),
+                $container    = $this.closest('.wp-picker-container'),
+
+                // appending alpha wrapper
+                $alpha_wrap   = $('<div class="option-tree-opacity-wrap">' +
+                                  '<div class="option-tree-opacity-slider"></div>' +
+                                  '<div class="option-tree-opacity-slider-offset"></div>' +
+                                  '<div class="option-tree-opacity-text"></div>' +
+                                  '</div>').appendTo( $container.find('.wp-picker-holder') ),
+
+                $alpha_slider = $alpha_wrap.find('.option-tree-opacity-slider'),
+                $alpha_text   = $alpha_wrap.find('.option-tree-opacity-text'),
+                $alpha_offset = $alpha_wrap.find('.option-tree-opacity-slider-offset');
+
+            // alpha slider
+            $alpha_slider.slider({
+
+              // slider: slide
+              slide: function( event, ui ) {
+
+                var slide_value = parseFloat( ui.value / 100 );
+
+                // update iris data alpha && wpColorPicker color option && alpha text
+                a8cIris._color._alpha = slide_value;
+                $this.wpColorPicker( 'color', a8cIris._color.toString() );
+                $alpha_text.text( ( slide_value < 1 ? slide_value : '' ) );
+
+              },
+
+              // slider: create
+              create: function() {
+
+                var slide_value = parseFloat( picker.alpha / 100 ),
+                    alpha_text_value = slide_value < 1 ? slide_value : '';
+
+                // update alpha text && checkerboard background color
+                $alpha_text.text(alpha_text_value);
+                $alpha_offset.css('background-color', picker.value);
+
+                // wpColorPicker clear button for update iris data alpha && alpha text && slider color option
+                $container.on('click', '.wp-picker-clear', function() {
+
+                  a8cIris._color._alpha = 1;
+                  $alpha_text.text('');
+                  $alpha_slider.slider('option', 'value', 100).trigger('slide');
+
+                });
+
+                // wpColorPicker default button for update iris data alpha && alpha text && slider color option
+                $container.on('click', '.wp-picker-default', function() {
+
+                  var default_picker = $.ot_ParseColorValue( $this.data('default-color') ),
+                      default_value  = parseFloat( default_picker.alpha / 100 ),
+                      default_text   = default_value < 1 ? default_value : '';
+
+                  a8cIris._color._alpha = default_value;
+                  $alpha_text.text(default_text);
+                  $alpha_slider.slider('option', 'value', default_picker.alpha).trigger('slide');
+
+                });
+
+                // show alpha wrapper on click color picker button
+                $container.on('click', '.wp-color-result', function() {
+                  $alpha_wrap.toggle();
+                });
+
+                // hide alpha wrapper on click body
+                $('body').on( 'click.wpcolorpicker', function() {
+                  $alpha_wrap.hide();
+                });
+
+              },
+
+              // slider: options
+              value: picker.alpha,
+              step: 1,
+              min: 1,
+              max: 100
+
+            });
+          }
+
+        });
+
+      } else {
+
+        // wpColorPicker default picker
+        $this.wpColorPicker({
+          change: function() {
+            $this.trigger('keyup');
+          }
+        });
+
+      }
+
+    });
+
+  };
+
+  $(document).ready( function(){
+    $('.hide-color-picker.ot-colorpicker-opacity').ot_wpColorPicker();
+  });
+
+})( jQuery, window, document );
\ No newline at end of file