cms.js 12.3 KB
// CSS Browser Selector   v0.2.3b (M@: added noscript support)
// Documentation:         http://rafael.adm.br/css_browser_selector
// License:               http://creativecommons.org/licenses/by/2.5/
// Author:                Rafael Lima (http://rafael.adm.br)
// Contributors:          http://rafael.adm.br/css_browser_selector#contributors
var css_browser_selector = function() {
  var 
    ua = navigator.userAgent.toLowerCase(),
    is = function(t){ return ua.indexOf(t) != -1; },
    h = document.getElementsByTagName('html')[0],
    b = (!(/opera|webtv/i.test(ua)) && /msie (\d)/.test(ua)) ? ((is('mac') ? 'ieMac ' : '') + 'ie ie' + RegExp.$1)
      : is('gecko/') ? 'gecko' : is('opera') ? 'opera' : is('konqueror') ? 'konqueror' : is('applewebkit/') ? 'webkit safari' : is('mozilla/') ? 'gecko' : '',
    os = (is('x11') || is('linux')) ? ' linux' : is('mac') ? ' mac' : is('win') ? ' win' : '';
  var c = b+os+' js'; 
  h.className = h.className.replace('noscript', '') + h.className?' '+c:c;
}();

// List View Functions
var ComatoseList = {
  save_node_state: true,
  state_store: 'cookie', // Only 'cookie' for now
  state_key: 'ComatoseTreeState',

  init: function() {
    var items = ComatoseList._read_state();
    items.each(function(node){
      ComatoseList.expand_node(node.replace('page_controller_', ''))
    });
  },
  
  toggle_tree_nodes : function(img, id) {
    if(/expanded/.test(img.src)) {
      $('page_list_'+ id).addClassName('collapsed');
      img.src = img.src.replace(/expanded/, 'collapsed')
      if(ComatoseList.save_node_state) {
        var items = ComatoseList._read_state();
        items = items.select(function(id){ return id != img.id; })
        ComatoseList._write_state(items);
      }
    } else {
      $('page_list_'+ id).removeClassName('collapsed');
      img.src = img.src.replace(/collapsed/, 'expanded')
      if(ComatoseList.save_node_state) {
        var items = ComatoseList._read_state();
        items.push(img.id);
        ComatoseList._write_state(items);
      }
    }
  },
  
  expand_node: function(id) {
    $('page_list_'+ id).removeClassName('collapsed');
    $('page_controller_'+ id).src = $('page_controller_'+ id).src.replace(/collapsed/, 'expanded')    
  },
  
  collapse_node: function(id) {
    $('page_list_'+ id).addClassName('collapsed');
    $('page_controller_'+ id).src = $('page_controller_'+ id).src.replace(/expanded/, 'collapsed')    
  },
  
  item_hover : function(node, state, is_delete) {
    if( state == 'over') {
      $(node).addClassName( (is_delete) ? 'hover-delete' : 'hover' );
    } else {
      $(node).removeClassName( (is_delete) ? 'hover-delete' : 'hover' );
    }
  },
  
  toggle_reorder: function(node, anc, id, reorder_text, finished_text) {
    if( $(node).hasClassName('do-reorder') ) {
      $(node).removeClassName( 'do-reorder' );
      $(anc).removeClassName('reordering');
      $(anc).innerHTML = reorder_text;
    } else {
      $(node).addClassName( 'do-reorder' );
      $(anc).addClassName('reordering');
      $(anc).innerHTML = finished_text;
      // Make sure the children are visible...
      ComatoseList.expand_node(id);
    }
  },
  
  _write_state: function(items) {
    var cookie = {}; var options = {}; var expiration = new Date();
    cookie[ ComatoseList.state_key ] = items.join(',');
    expiration.setDate(expiration.getDate()+30)
    options['expires'] = expiration;
    Cookie.write( cookie, options );
  },
  
  _read_state: function() {
    var state = Cookie.read( ComatoseList.state_key );
    return (state != "" && state != null) ? state.split(',') : [];
  }
}

// Edit Form Functions
var ComatoseEditForm = {

  default_data: {},
  last_preview: {},
  last_title_slug: '',
  mode : null,
  liquid_horiz: false, // changed from true to false by terceiro
  width_offset: 325,

  // Initialize the page...
  init : function(mode) {
    this.mode = mode;
    this.default_data = Form.serialize(document.forms[0]);
    if(mode == 'new') {
      this.last_title_slug = $('page_title').value.toSlug();
      Event.observe('page_title', 'blur', ComatoseEditForm.title_updated_aggressive);
    } else {
      Event.observe('page_title', 'blur', ComatoseEditForm.title_updated);
    }
    $('page_title').focus();
    Hide.these(
      'preview-area',
      'slug_row',
      'parent_row',
      'keywords_row',
      'filter_row',
      'created_row'
    );
    $('page_title').select();
    // Create the horizontal liquidity of the fields
    if(this.liquid_horiz) {
      xOffset = this.width_offset;
      new Layout.LiquidHoriz((xOffset + 50), 'page_title');
      new Layout.LiquidHoriz(xOffset, 'page_slug','page_keywords','page_parent','page_body');
    }
  },
  // For use when updating an existing page...
  title_updated : function() {
    slug = $('page_slug');
    if(slug.value == "") {
      title = $('page_title');
      slug.value = title.value.toSlug();
    }
  },
  // For use when creating a new page...
  title_updated_aggressive : function() {
    slug = $('page_slug');
    title = $('page_title');
    if(slug.value == "" || slug.value == this.last_title ) {
      slug.value = title.value.toSlug();
    }
    this.last_title = slug.value;
  },
  // Todo: Make the meta fields remember their visibility?
  toggle_extra_fields : function(anchor, more_label, less_label) {
    if(anchor.innerHTML == more_label) {
      Show.these(
        'slug_row',
        'keywords_row',
        'parent_row',
        'filter_row',
        'created_row'
      );
      anchor.innerHTML = less_label;
    } else {
      Hide.these(
        'slug_row',
        'keywords_row',
        'parent_row',
        'filter_row',
        'created_row'
      );
      anchor.innerHTML = more_label;
    }
  },
  // Uses server to create preview of content...
  preview_content : function(preview_url, preview_label) {
    $('preview-area').show();
    var params = Form.serialize(document.forms[0]);
    if( params != this.last_preview ) {
      $('preview-panel').innerHTML = "<span style='color:blue;'>" + preview_label + "</span>";
      new Ajax.Updater(
         'preview-panel',
         preview_url,
         { parameters: params }
      );
    }
    this.last_preview = params;
  },
  cancel : function(url, cancel_warning) {
    var current_data = Form.serialize(document.forms[0]);
    var data_changed = (this.default_data != current_data) 
    if(data_changed) {
      if( confirm(cancel_warning) ) {
        location.href = url;
      }
    } else {
      location.href = url;      
    }
    
  }
}

var Hide = {
  these : function() {
    for (var i = 0; i < arguments.length; i++) {
      try {
        $(arguments[i]).hide();
      } catch (e) {}
    }
  }
}

var Show = {
  these : function() {
    for (var i = 0; i < arguments.length; i++) {
      try {
        $(arguments[i]).show();
      } catch (e) {}
    }
  }
}

// Layout namespace
var Layout = {};

// This class allows dom objects to stretch with the browser 
// (for when a good, cross-browser, CSS approach can't be found)
Layout.LiquidBase = Class.create();
// Base class for all Liquid* layouts...
Object.extend(Layout.LiquidBase.prototype, {
  enabled: true,
  elems: [],
  offset: null,
  // Constructor is (offset, **array_of_elements)
  initialize: function() {
    args = $A(arguments)
    this.offset = args.shift();
    this.elems = args.select( function(elem){ return ($(elem) != null) } );
    if( this.elems.length > 0 ) {
      this.on_resize(); // Initial size
      Event.observe(window, 'resize', this.on_resize.bind(this) );
      Event.observe(window, 'load', this.on_resize.bind(this) );
    }
  },
  resize_in: function(timeout) {
    setTimeout( this.on_resize.bind(this), timeout );
  },
  on_resize: function() {       
    // Need to override!
    alert('Override on_resize, please!');
  }
});


// Liquid vertical layout
Layout.LiquidVert = Class.create();
Object.extend(Layout.LiquidVert.prototype, Object.extend(Layout.LiquidBase.prototype, {
  on_resize: function() {       
    if( this.offset != null && this.enabled ) {
      var new_height = ((window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - this.offset) +"px";
      this.elems.each(function(e){ $(e).style.height = new_height; })
    }
  }
}) );


// Liquid horizontal layout
Layout.LiquidHoriz = Class.create();
Object.extend(Layout.LiquidHoriz.prototype, Object.extend(Layout.LiquidBase.prototype, {
  on_resize: function() {       
    if( this.offset != null && this.enabled ) {
      var new_width = ((window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) - this.offset) +"px";
      this.elems.each( function(e){ $(e).style.width = new_width; })
    }
  }
}) );

// String Extensions... Yes, these are from Radiant! ;-)
Object.extend(String.prototype, {
  upcase: function() {
    return this.toUpperCase();
  },
  downcase: function() {
    return this.toLowerCase();
  },
  strip: function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  },
  toInteger: function() {
    return parseInt(this);
  },
  toSlug: function() {
    // M@: Modified from Radiant's version, removes multple --'s next to each other
    // This is the same RegExp as the one on the page model...
    return this.strip().downcase().replace(/[^-a-z0-9~\s\.:;+=_]/g, '').replace(/[\s\.:;=_+]+/g, '-').replace(/[\-]{2,}/g, '-');
  }
});

// Run a spinner when an AJAX request in running...
var ComatoseAJAXSpinner = {
  busy : function () {
    if($('spinner') && Ajax.activeRequestCount > 0) {
      Effect.Appear('spinner',{duration:0.5,queue:'end'});
    }
  },

  notBusy: function() {
    if($('spinner') && Ajax.activeRequestCount == 0) {
      Effect.Fade('spinner',{duration:0.5,queue:'end'});
    }
  }  
}
// Register it with Prototype...
Ajax.Responders.register({
  onCreate: ComatoseAJAXSpinner.busy, 
  onComplete: ComatoseAJAXSpinner.notBusy
});


if(!window.Cookie)
  (function (){
    // From Mephisto!
    window.Cookie = {
      version: '0.7',
      cookies: {},
      _each: function(iterator) {
        $H(this.cookies).each(iterator);
      },
  
      getAll: function() {
        this.cookies = {};
        $A(document.cookie.split('; ')).each(function(cookie) {
          var seperator = cookie.indexOf('=');
          this.cookies[cookie.substring(0, seperator)] = 
              unescape(cookie.substring(seperator + 1, cookie.length));
        }.bind(this));
        return this.cookies;
      },
  
      read: function() {
        var cookies = $A(arguments), results = [];
        this.getAll();
        cookies.each(function(name) {
          if (this.cookies[name]) results.push(this.cookies[name]);
          else results.push(null);
        }.bind(this));
        return results.length > 1 ? results : results[0];
      },
  
      write: function(cookies, options) {
        if (cookies.constructor == Object && cookies.name) cookies = [cookies];
        if (cookies.constructor == Array) {
          $A(cookies).each(function(cookie) {
            this._write(cookie.name, cookie.value, cookie.expires,
                        cookie.path, cookie.domain);
          }.bind(this));
        } else {
          options = options || {expires: false, path: '', domain: ''};
          for (name in cookies){
            this._write(name, cookies[name],
                        options.expires, options.path, options.domain);
          }
        }
      },
  
      _write: function(name, value, expires, path, domain) {
        if (name.indexOf('=') != -1) return;
        var cookieString = name + '=' + escape(value);
        if (expires) cookieString += '; expires=' + expires.toGMTString();
        if (path) cookieString += '; path=' + path;
        if (domain) cookieString += '; domain=' + domain;
        document.cookie = cookieString;
      },
  
      erase: function(cookies) {
        var cookiesToErase = {};
        $A(arguments).each(function(cookie) {
          cookiesToErase[cookie] = '';
        });
    
        this.write(cookiesToErase, {expires: (new Date((new Date()).getTime() - 1e11))});
        this.getAll();
      },
  
      eraseAll: function() {
        this.erase.apply(this, $H(this.getAll()).keys());
      }
    };

    Object.extend(Cookie, {
      get: Cookie.read,
      set: Cookie.write,
  
      add: Cookie.read,
      remove: Cookie.erase,
      removeAll: Cookie.eraseAll,
  
      wipe: Cookie.erase,
      wipeAll: Cookie.eraseAll,
      destroy: Cookie.erase,
      destroyAll: Cookie.eraseAll
    });
  })();