FINAL suepr merge step : added all modules to this super repos

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-19 16:46:59 +02:00
7585 changed files with 1723356 additions and 18 deletions

View File

@@ -0,0 +1,126 @@
/**
* @file
*
* CTools flexible AJAX responder object.
*/
(function ($) {
Drupal.CTools = Drupal.CTools || {};
Drupal.CTools.AJAX = Drupal.CTools.AJAX || {};
/**
* Grab the response from the server and store it.
*
* @todo restore the warm cache functionality
*/
Drupal.CTools.AJAX.warmCache = function () {
// Store this expression for a minor speed improvement.
$this = $(this);
var old_url = $this.attr('href');
// If we are currently fetching, or if we have fetched this already which is
// ideal for things like pagers, where the previous page might already have
// been seen in the cache.
if ($this.hasClass('ctools-fetching') || Drupal.CTools.AJAX.commandCache[old_url]) {
return false;
}
// Grab all the links that match this url and add the fetching class.
// This allows the caching system to grab each url once and only once
// instead of grabbing the url once per <a>.
var $objects = $('a[href="' + old_url + '"]')
$objects.addClass('ctools-fetching');
try {
url = old_url.replace(/\/nojs(\/|$)/g, '/ajax$1');
$.ajax({
type: "POST",
url: url,
data: { 'js': 1, 'ctools_ajax': 1},
global: true,
success: function (data) {
Drupal.CTools.AJAX.commandCache[old_url] = data;
$objects.addClass('ctools-cache-warmed').trigger('ctools-cache-warm', [data]);
},
complete: function() {
$objects.removeClass('ctools-fetching');
},
dataType: 'json'
});
}
catch (err) {
$objects.removeClass('ctools-fetching');
return false;
}
return false;
};
/**
* Cachable click handler to fetch the commands out of the cache or from url.
*/
Drupal.CTools.AJAX.clickAJAXCacheLink = function () {
$this = $(this);
if ($this.hasClass('ctools-fetching')) {
$this.bind('ctools-cache-warm', function (event, data) {
Drupal.CTools.AJAX.respond(data);
});
return false;
}
else {
if ($this.hasClass('ctools-cache-warmed') && Drupal.CTools.AJAX.commandCache[$this.attr('href')]) {
Drupal.CTools.AJAX.respond(Drupal.CTools.AJAX.commandCache[$this.attr('href')]);
return false;
}
else {
return Drupal.CTools.AJAX.clickAJAXLink.apply(this);
}
}
};
/**
* Find a URL for an AJAX button.
*
* The URL for this gadget will be composed of the values of items by
* taking the ID of this item and adding -url and looking for that
* class. They need to be in the form in order since we will
* concat them all together using '/'.
*/
Drupal.CTools.AJAX.findURL = function(item) {
var url = '';
var url_class = '.' + $(item).attr('id') + '-url';
$(url_class).each(
function() {
var $this = $(this);
if (url && $this.val()) {
url += '/';
}
url += $this.val();
});
return url;
};
// Hide these in a ready to ensure that Drupal.ajax is set up first.
$(function() {
Drupal.ajax.prototype.commands.attr = function(ajax, data, status) {
$(data.selector).attr(data.name, data.value);
};
Drupal.ajax.prototype.commands.redirect = function(ajax, data, status) {
if (data.delay > 0) {
setTimeout(function () {
location.href = data.url;
}, data.delay);
}
else {
location.href = data.url;
}
};
Drupal.ajax.prototype.commands.reload = function(ajax, data, status) {
location.reload();
};
Drupal.ajax.prototype.commands.submit = function(ajax, data, status) {
$(data.selector).submit();
}
});
})(jQuery);

View File

@@ -0,0 +1,100 @@
(function($){
/**
* To make a form auto submit, all you have to do is 3 things:
*
* ctools_add_js('auto-submit');
*
* On gadgets you want to auto-submit when changed, add the ctools-auto-submit
* class. With FAPI, add:
* @code
* '#attributes' => array('class' => array('ctools-auto-submit')),
* @endcode
*
* If you want to have auto-submit for every form element,
* add the ctools-auto-submit-full-form to the form. With FAPI, add:
* @code
* '#attributes' => array('class' => array('ctools-auto-submit-full-form')),
* @endcode
*
* If you want to exclude a field from the ctool-auto-submit-full-form auto submission,
* add the class ctools-auto-submit-exclude to the form element. With FAPI, add:
* @code
* '#attributes' => array('class' => array('ctools-auto-submit-exclude')),
* @endcode
*
* Finally, you have to identify which button you want clicked for autosubmit.
* The behavior of this button will be honored if it's ajaxy or not:
* @code
* '#attributes' => array('class' => array('ctools-use-ajax', 'ctools-auto-submit-click')),
* @endcode
*
* Currently only 'select', 'radio', 'checkbox' and 'textfield' types are supported. We probably
* could use additional support for HTML5 input types.
*/
Drupal.behaviors.CToolsAutoSubmit = {
attach: function(context) {
// 'this' references the form element
function triggerSubmit (e) {
var $this = $(this);
if (!$this.hasClass('ctools-ajaxing')) {
$this.find('.ctools-auto-submit-click').click();
}
}
// the change event bubbles so we only need to bind it to the outer form
$('form.ctools-auto-submit-full-form', context)
.add('.ctools-auto-submit', context)
.filter('form, select, input:not(:text, :submit)')
.once('ctools-auto-submit')
.change(function (e) {
// don't trigger on text change for full-form
if ($(e.target).is(':not(:text, :submit, .ctools-auto-submit-exclude)')) {
triggerSubmit.call(e.target.form);
}
});
// e.keyCode: key
var discardKeyCode = [
16, // shift
17, // ctrl
18, // alt
20, // caps lock
33, // page up
34, // page down
35, // end
36, // home
37, // left arrow
38, // up arrow
39, // right arrow
40, // down arrow
9, // tab
13, // enter
27 // esc
];
// Don't wait for change event on textfields
$('.ctools-auto-submit-full-form input:text, input:text.ctools-auto-submit', context)
.filter(':not(.ctools-auto-submit-exclude)')
.once('ctools-auto-submit', function () {
// each textinput element has his own timeout
var timeoutID = 0;
$(this)
.bind('keydown keyup', function (e) {
if ($.inArray(e.keyCode, discardKeyCode) === -1) {
timeoutID && clearTimeout(timeoutID);
}
})
.keyup(function(e) {
if ($.inArray(e.keyCode, discardKeyCode) === -1) {
timeoutID = setTimeout($.proxy(triggerSubmit, this.form), 500);
}
})
.bind('change', function (e) {
if ($.inArray(e.keyCode, discardKeyCode) === -1) {
timeoutID = setTimeout($.proxy(triggerSubmit, this.form), 500);
}
});
});
}
}
})(jQuery);

View File

@@ -0,0 +1,240 @@
/**
* @file
* Javascript required for a simple collapsible div.
*
* Creating a collapsible div with this doesn't take too much. There are
* three classes necessary:
*
* - ctools-collapsible-container: This is the overall container that will be
* collapsible. This must be a div.
* - ctools-collapsible-handle: This is the title area, and is what will be
* visible when it is collapsed. This can be any block element, such as div
* or h2.
* - ctools-collapsible-content: This is the ocntent area and will only be
* visible when expanded. This must be a div.
*
* Adding 'ctools-collapsible-remember' to the container class will cause the
* state of the container to be stored in a cookie, and remembered from page
* load to page load. This will only work if the container has a unique ID, so
* very carefully add IDs to your containers.
*
* If the class 'ctools-no-container' is placed on the container, the container
* will be the handle. The content will be found by appending '-content' to the
* id of the handle. The ctools-collapsible-handle and
* ctools-collapsible-content classes will not be required in that case, and no
* restrictions on what of data the container is are placed. Like
* ctools-collapsible-remember this requires an id to eist.
*
* The content will be 'open' unless the container class has 'ctools-collapsed'
* as a class, which will cause the container to draw collapsed.
*/
(function ($) {
// All CTools tools begin with this if they need to use the CTools namespace.
if (!Drupal.CTools) {
Drupal.CTools = {};
}
/**
* Object to store state.
*
* This object will remember the state of collapsible containers. The first
* time a state is requested, it will check the cookie and set up the variable.
* If a state has been changed, when the window is unloaded the state will be
* saved.
*/
Drupal.CTools.Collapsible = {
state: {},
stateLoaded: false,
stateChanged: false,
cookieString: 'ctools-collapsible-state=',
/**
* Get the current collapsed state of a container.
*
* If set to 1, the container is open. If set to -1, the container is
* collapsed. If unset the state is unknown, and the default state should
* be used.
*/
getState: function (id) {
if (!this.stateLoaded) {
this.loadCookie();
}
return this.state[id];
},
/**
* Set the collapsed state of a container for subsequent page loads.
*
* Set the state to 1 for open, -1 for collapsed.
*/
setState: function (id, state) {
if (!this.stateLoaded) {
this.loadCookie();
}
this.state[id] = state;
if (!this.stateChanged) {
this.stateChanged = true;
$(window).unload(this.unload);
}
},
/**
* Check the cookie and load the state variable.
*/
loadCookie: function () {
// If there is a previous instance of this cookie
if (document.cookie.length > 0) {
// Get the number of characters that have the list of values
// from our string index.
offset = document.cookie.indexOf(this.cookieString);
// If its positive, there is a list!
if (offset != -1) {
offset += this.cookieString.length;
var end = document.cookie.indexOf(';', offset);
if (end == -1) {
end = document.cookie.length;
}
// Get a list of all values that are saved on our string
var cookie = unescape(document.cookie.substring(offset, end));
if (cookie != '') {
var cookieList = cookie.split(',');
for (var i = 0; i < cookieList.length; i++) {
var info = cookieList[i].split(':');
this.state[info[0]] = info[1];
}
}
}
}
this.stateLoaded = true;
},
/**
* Turn the state variable into a string and store it in the cookie.
*/
storeCookie: function () {
var cookie = '';
// Get a list of IDs, saparated by comma
for (i in this.state) {
if (cookie != '') {
cookie += ',';
}
cookie += i + ':' + this.state[i];
}
// Save this values on the cookie
document.cookie = this.cookieString + escape(cookie) + ';path=/';
},
/**
* Respond to the unload event by storing the current state.
*/
unload: function() {
Drupal.CTools.Collapsible.storeCookie();
}
};
// Set up an array for callbacks.
Drupal.CTools.CollapsibleCallbacks = [];
Drupal.CTools.CollapsibleCallbacksAfterToggle = [];
/**
* Bind collapsible behavior to a given container.
*/
Drupal.CTools.bindCollapsible = function () {
var $container = $(this);
// Allow the specification of the 'no container' class, which means the
// handle and the container can be completely independent.
if ($container.hasClass('ctools-no-container') && $container.attr('id')) {
// In this case, the container *is* the handle and the content is found
// by adding '-content' to the id. Obviously, an id is required.
var handle = $container;
var content = $('#' + $container.attr('id') + '-content');
}
else {
var handle = $container.children('.ctools-collapsible-handle');
var content = $container.children('div.ctools-collapsible-content');
}
if (content.length) {
// Create the toggle item and place it in front of the toggle.
var toggle = $('<span class="ctools-toggle"></span>');
handle.before(toggle);
// If the remember class is set, check to see if we have a remembered
// state stored.
if ($container.hasClass('ctools-collapsible-remember') && $container.attr('id')) {
var state = Drupal.CTools.Collapsible.getState($container.attr('id'));
if (state == 1) {
$container.removeClass('ctools-collapsed');
}
else if (state == -1) {
$container.addClass('ctools-collapsed');
}
}
// If we should start collapsed, do so:
if ($container.hasClass('ctools-collapsed')) {
toggle.toggleClass('ctools-toggle-collapsed');
content.hide();
}
var afterToggle = function () {
if (Drupal.CTools.CollapsibleCallbacksAfterToggle) {
for (i in Drupal.CTools.CollapsibleCallbacksAfterToggle) {
Drupal.CTools.CollapsibleCallbacksAfterToggle[i]($container, handle, content, toggle);
}
}
}
var clickMe = function () {
if (Drupal.CTools.CollapsibleCallbacks) {
for (i in Drupal.CTools.CollapsibleCallbacks) {
Drupal.CTools.CollapsibleCallbacks[i]($container, handle, content, toggle);
}
}
// If the container is a table element slideToggle does not do what
// we want, so use toggle() instead.
if ($container.is('table')) {
content.toggle(0, afterToggle);
}
else {
content.slideToggle(100, afterToggle);
}
toggle.toggleClass('ctools-toggle-collapsed');
// If we're supposed to remember the state of this class, do so.
if ($container.hasClass('ctools-collapsible-remember') && $container.attr('id')) {
var state = toggle.hasClass('ctools-toggle-collapsed') ? -1 : 1;
Drupal.CTools.Collapsible.setState($container.attr('id'), state);
}
return false;
}
// Let both the toggle and the handle be clickable.
toggle.click(clickMe);
handle.click(clickMe);
}
};
/**
* Support Drupal's 'behaviors' system for binding.
*/
Drupal.behaviors.CToolsCollapsible = {
attach: function(context) {
$('.ctools-collapsible-container', context).once('ctools-collapsible', Drupal.CTools.bindCollapsible);
}
}
})(jQuery);

View File

@@ -0,0 +1,231 @@
/**
* @file
* Provides dependent visibility for form items in CTools' ajax forms.
*
* To your $form item definition add:
* - '#process' => array('ctools_process_dependency'),
* - '#dependency' => array('id-of-form-item' => array(list, of, values, that,
* make, this, item, show),
*
* Special considerations:
* - Radios are harder. Because Drupal doesn't give radio groups individual IDs,
* use 'radio:name-of-radio'.
*
* - Checkboxes don't have their own id, so you need to add one in a div
* around the checkboxes via #prefix and #suffix. You actually need to add TWO
* divs because it's the parent that gets hidden. Also be sure to retain the
* 'expand_checkboxes' in the #process array, because the CTools process will
* override it.
*/
(function ($) {
Drupal.CTools = Drupal.CTools || {};
Drupal.CTools.dependent = {};
Drupal.CTools.dependent.bindings = {};
Drupal.CTools.dependent.activeBindings = {};
Drupal.CTools.dependent.activeTriggers = [];
Drupal.CTools.dependent.inArray = function(array, search_term) {
var i = array.length;
while (i--) {
if (array[i] == search_term) {
return true;
}
}
return false;
}
Drupal.CTools.dependent.autoAttach = function() {
// Clear active bindings and triggers.
for (i in Drupal.CTools.dependent.activeTriggers) {
$(Drupal.CTools.dependent.activeTriggers[i]).unbind('change');
}
Drupal.CTools.dependent.activeTriggers = [];
Drupal.CTools.dependent.activeBindings = {};
Drupal.CTools.dependent.bindings = {};
if (!Drupal.settings.CTools) {
return;
}
// Iterate through all relationships
for (id in Drupal.settings.CTools.dependent) {
// Test to make sure the id even exists; this helps clean up multiple
// AJAX calls with multiple forms.
// Drupal.CTools.dependent.activeBindings[id] is a boolean,
// whether the binding is active or not. Defaults to no.
Drupal.CTools.dependent.activeBindings[id] = 0;
// Iterate through all possible values
for(bind_id in Drupal.settings.CTools.dependent[id].values) {
// This creates a backward relationship. The bind_id is the ID
// of the element which needs to change in order for the id to hide or become shown.
// The id is the ID of the item which will be conditionally hidden or shown.
// Here we're setting the bindings for the bind
// id to be an empty array if it doesn't already have bindings to it
if (!Drupal.CTools.dependent.bindings[bind_id]) {
Drupal.CTools.dependent.bindings[bind_id] = [];
}
// Add this ID
Drupal.CTools.dependent.bindings[bind_id].push(id);
// Big long if statement.
// Drupal.settings.CTools.dependent[id].values[bind_id] holds the possible values
if (bind_id.substring(0, 6) == 'radio:') {
var trigger_id = "input[name='" + bind_id.substring(6) + "']";
}
else {
var trigger_id = '#' + bind_id;
}
Drupal.CTools.dependent.activeTriggers.push(trigger_id);
if ($(trigger_id).attr('type') == 'checkbox') {
$(trigger_id).siblings('label').addClass('hidden-options');
}
var getValue = function(item, trigger) {
if ($(trigger).size() == 0) {
return null;
}
if (item.substring(0, 6) == 'radio:') {
var val = $(trigger + ':checked').val();
}
else {
switch ($(trigger).attr('type')) {
case 'checkbox':
var val = $(trigger).attr('checked') ? true : false;
if (val) {
$(trigger).siblings('label').removeClass('hidden-options').addClass('expanded-options');
}
else {
$(trigger).siblings('label').removeClass('expanded-options').addClass('hidden-options');
}
break;
default:
var val = $(trigger).val();
}
}
return val;
}
var setChangeTrigger = function(trigger_id, bind_id) {
// Triggered when change() is clicked.
var changeTrigger = function() {
var val = getValue(bind_id, trigger_id);
if (val == null) {
return;
}
for (i in Drupal.CTools.dependent.bindings[bind_id]) {
var id = Drupal.CTools.dependent.bindings[bind_id][i];
// Fix numerous errors
if (typeof id != 'string') {
continue;
}
// This bit had to be rewritten a bit because two properties on the
// same set caused the counter to go up and up and up.
if (!Drupal.CTools.dependent.activeBindings[id]) {
Drupal.CTools.dependent.activeBindings[id] = {};
}
if (val != null && Drupal.CTools.dependent.inArray(Drupal.settings.CTools.dependent[id].values[bind_id], val)) {
Drupal.CTools.dependent.activeBindings[id][bind_id] = 'bind';
}
else {
delete Drupal.CTools.dependent.activeBindings[id][bind_id];
}
var len = 0;
for (i in Drupal.CTools.dependent.activeBindings[id]) {
len++;
}
var object = $('#' + id + '-wrapper');
if (!object.size()) {
// Some elements can't use the parent() method or they can
// damage things. They are guaranteed to have wrappers but
// only if dependent.inc provided them. This check prevents
// problems when multiple AJAX calls cause settings to build
// up.
var $original = $('#' + id);
if ($original.is('fieldset') || $original.is('textarea')) {
continue;
}
object = $('#' + id).parent();
}
if (Drupal.settings.CTools.dependent[id].type == 'disable') {
if (Drupal.settings.CTools.dependent[id].num <= len) {
// Show if the element if criteria is matched
object.attr('disabled', false);
object.addClass('dependent-options');
object.children().attr('disabled', false);
}
else {
// Otherwise hide. Use css rather than hide() because hide()
// does not work if the item is already hidden, for example,
// in a collapsed fieldset.
object.attr('disabled', true);
object.children().attr('disabled', true);
}
}
else {
if (Drupal.settings.CTools.dependent[id].num <= len) {
// Show if the element if criteria is matched
object.show(0);
object.addClass('dependent-options');
}
else {
// Otherwise hide. Use css rather than hide() because hide()
// does not work if the item is already hidden, for example,
// in a collapsed fieldset.
object.css('display', 'none');
}
}
}
}
$(trigger_id).change(function() {
// Trigger the internal change function
// the attr('id') is used because closures are more confusing
changeTrigger(trigger_id, bind_id);
});
// Trigger initial reaction
changeTrigger(trigger_id, bind_id);
}
setChangeTrigger(trigger_id, bind_id);
}
}
}
Drupal.behaviors.CToolsDependent = {
attach: function (context) {
Drupal.CTools.dependent.autoAttach();
// Really large sets of fields are too slow with the above method, so this
// is a sort of hacked one that's faster but much less flexible.
$("select.ctools-master-dependent")
.once('ctools-dependent')
.change(function() {
var val = $(this).val();
if (val == 'all') {
$('.ctools-dependent-all').show(0);
}
else {
$('.ctools-dependent-all').hide(0);
$('.ctools-dependent-' + val).show(0);
}
})
.trigger('change');
}
}
})(jQuery);

View File

@@ -0,0 +1,94 @@
/**
* @file
* Implement a simple, clickable dropbutton menu.
*
* See dropbutton.theme.inc for primary documentation.
*
* The javascript relies on four classes:
* - The dropbutton must be fully contained in a div with the class
* ctools-dropbutton. It must also contain the class ctools-no-js
* which will be immediately removed by the javascript; this allows for
* graceful degradation.
* - The trigger that opens the dropbutton must be an a tag wit hthe class
* ctools-dropbutton-link. The href should just be '#' as this will never
* be allowed to complete.
* - The part of the dropbutton that will appear when the link is clicked must
* be a div with class ctools-dropbutton-container.
* - Finally, ctools-dropbutton-hover will be placed on any link that is being
* hovered over, so that the browser can restyle the links.
*
* This tool isn't meant to replace click-tips or anything, it is specifically
* meant to work well presenting menus.
*/
(function ($) {
Drupal.behaviors.CToolsDropbutton = {
attach: function() {
// Process buttons. All dropbuttons are buttons.
$('.ctools-button')
.once('ctools-button')
.removeClass('ctools-no-js');
// Process dropbuttons. Not all buttons are dropbuttons.
$('.ctools-dropbutton').once('ctools-dropbutton', function() {
var $dropbutton = $(this);
var $button = $('.ctools-content', $dropbutton);
var $secondaryActions = $('li', $button).not(':first');
var $twisty = $(".ctools-link", $dropbutton);
var open = false;
var hovering = false;
var timerID = 0;
var toggle = function(close) {
// if it's open or we're told to close it, close it.
if (open || close) {
// If we're just toggling it, close it immediately.
if (!close) {
open = false;
$secondaryActions.slideUp(100);
$dropbutton.removeClass('open');
}
else {
// If we were told to close it, wait half a second to make
// sure that's what the user wanted.
// Clear any previous timer we were using.
if (timerID) {
clearTimeout(timerID);
}
timerID = setTimeout(function() {
if (!hovering) {
open = false;
$secondaryActions.slideUp(100);
$dropbutton.removeClass('open');
}}, 500);
}
}
else {
// open it.
open = true;
$secondaryActions.animate({height: "show", opacity: "show"}, 100);
$dropbutton.addClass('open');
}
}
// Hide the secondary actions initially.
$secondaryActions.hide();
$twisty.click(function() {
toggle();
return false;
});
$dropbutton.hover(
function() {
hovering = true;
}, // hover in
function() { // hover out
hovering = false;
toggle(true);
return false;
}
);
});
}
}
})(jQuery);

View File

@@ -0,0 +1,87 @@
/**
* @file
* Implement a simple, clickable dropdown menu.
*
* See dropdown.theme.inc for primary documentation.
*
* The javascript relies on four classes:
* - The dropdown must be fully contained in a div with the class
* ctools-dropdown. It must also contain the class ctools-dropdown-no-js
* which will be immediately removed by the javascript; this allows for
* graceful degradation.
* - The trigger that opens the dropdown must be an a tag wit hthe class
* ctools-dropdown-link. The href should just be '#' as this will never
* be allowed to complete.
* - The part of the dropdown that will appear when the link is clicked must
* be a div with class ctools-dropdown-container.
* - Finally, ctools-dropdown-hover will be placed on any link that is being
* hovered over, so that the browser can restyle the links.
*
* This tool isn't meant to replace click-tips or anything, it is specifically
* meant to work well presenting menus.
*/
(function ($) {
Drupal.behaviors.CToolsDropdown = {
attach: function() {
$('div.ctools-dropdown').once('ctools-dropdown', function() {
var $dropdown = $(this);
var open = false;
var hovering = false;
var timerID = 0;
$dropdown.removeClass('ctools-dropdown-no-js');
var toggle = function(close) {
// if it's open or we're told to close it, close it.
if (open || close) {
// If we're just toggling it, close it immediately.
if (!close) {
open = false;
$("div.ctools-dropdown-container", $dropdown).slideUp(100);
}
else {
// If we were told to close it, wait half a second to make
// sure that's what the user wanted.
// Clear any previous timer we were using.
if (timerID) {
clearTimeout(timerID);
}
timerID = setTimeout(function() {
if (!hovering) {
open = false;
$("div.ctools-dropdown-container", $dropdown).slideUp(100);
}
}, 500);
}
}
else {
// open it.
open = true;
$("div.ctools-dropdown-container", $dropdown)
.animate({height: "show", opacity: "show"}, 100);
}
}
$("a.ctools-dropdown-link", $dropdown).click(function() {
toggle();
return false;
});
$dropdown.hover(
function() {
hovering = true;
}, // hover in
function() { // hover out
hovering = false;
toggle(true);
return false;
});
// @todo -- just use CSS for this noise.
$("div.ctools-dropdown-container a").hover(
function() { $(this).addClass('ctools-dropdown-hover'); },
function() { $(this).removeClass('ctools-dropdown-hover'); }
);
});
}
}
})(jQuery);

View File

@@ -0,0 +1,42 @@
(function($) {
Drupal.behaviors.CToolsJumpMenu = {
attach: function(context) {
$('.ctools-jump-menu-hide')
.once('ctools-jump-menu')
.hide();
$('.ctools-jump-menu-change')
.once('ctools-jump-menu')
.change(function() {
var loc = $(this).val();
var urlArray = loc.split('::');
if (urlArray[1]) {
location.href = urlArray[1];
}
else {
location.href = loc;
}
return false;
});
$('.ctools-jump-menu-button')
.once('ctools-jump-menu')
.click(function() {
// Instead of submitting the form, just perform the redirect.
// Find our sibling value.
var $select = $(this).parents('form').find('.ctools-jump-menu-select');
var loc = $select.val();
var urlArray = loc.split('::');
if (urlArray[1]) {
location.href = urlArray[1];
}
else {
location.href = loc;
}
return false;
});
}
}
})(jQuery);

View File

@@ -0,0 +1,538 @@
/**
* @file
*
* Implement a modal form.
*
* @see modal.inc for documentation.
*
* This javascript relies on the CTools ajax responder.
*/
(function ($) {
// Make sure our objects are defined.
Drupal.CTools = Drupal.CTools || {};
Drupal.CTools.Modal = Drupal.CTools.Modal || {};
/**
* Display the modal
*
* @todo -- document the settings.
*/
Drupal.CTools.Modal.show = function(choice) {
var opts = {};
if (choice && typeof choice == 'string' && Drupal.settings[choice]) {
// This notation guarantees we are actually copying it.
$.extend(true, opts, Drupal.settings[choice]);
}
else if (choice) {
$.extend(true, opts, choice);
}
var defaults = {
modalTheme: 'CToolsModalDialog',
throbberTheme: 'CToolsModalThrobber',
animation: 'show',
animationSpeed: 'fast',
modalSize: {
type: 'scale',
width: .8,
height: .8,
addWidth: 0,
addHeight: 0,
// How much to remove from the inner content to make space for the
// theming.
contentRight: 25,
contentBottom: 45
},
modalOptions: {
opacity: .55,
background: '#fff'
}
};
var settings = {};
$.extend(true, settings, defaults, Drupal.settings.CToolsModal, opts);
if (Drupal.CTools.Modal.currentSettings && Drupal.CTools.Modal.currentSettings != settings) {
Drupal.CTools.Modal.modal.remove();
Drupal.CTools.Modal.modal = null;
}
Drupal.CTools.Modal.currentSettings = settings;
var resize = function(e) {
// When creating the modal, it actually exists only in a theoretical
// place that is not in the DOM. But once the modal exists, it is in the
// DOM so the context must be set appropriately.
var context = e ? document : Drupal.CTools.Modal.modal;
if (Drupal.CTools.Modal.currentSettings.modalSize.type == 'scale') {
var width = $(window).width() * Drupal.CTools.Modal.currentSettings.modalSize.width;
var height = $(window).height() * Drupal.CTools.Modal.currentSettings.modalSize.height;
}
else {
var width = Drupal.CTools.Modal.currentSettings.modalSize.width;
var height = Drupal.CTools.Modal.currentSettings.modalSize.height;
}
// Use the additionol pixels for creating the width and height.
$('div.ctools-modal-content', context).css({
'width': width + Drupal.CTools.Modal.currentSettings.modalSize.addWidth + 'px',
'height': height + Drupal.CTools.Modal.currentSettings.modalSize.addHeight + 'px'
});
$('div.ctools-modal-content .modal-content', context).css({
'width': (width - Drupal.CTools.Modal.currentSettings.modalSize.contentRight) + 'px',
'height': (height - Drupal.CTools.Modal.currentSettings.modalSize.contentBottom) + 'px'
});
}
if (!Drupal.CTools.Modal.modal) {
Drupal.CTools.Modal.modal = $(Drupal.theme(settings.modalTheme));
if (settings.modalSize.type == 'scale') {
$(window).bind('resize', resize);
}
}
resize();
$('span.modal-title', Drupal.CTools.Modal.modal).html(Drupal.CTools.Modal.currentSettings.loadingText);
Drupal.CTools.Modal.modalContent(Drupal.CTools.Modal.modal, settings.modalOptions, settings.animation, settings.animationSpeed);
$('#modalContent .modal-content').html(Drupal.theme(settings.throbberTheme));
};
/**
* Hide the modal
*/
Drupal.CTools.Modal.dismiss = function() {
if (Drupal.CTools.Modal.modal) {
Drupal.CTools.Modal.unmodalContent(Drupal.CTools.Modal.modal);
}
};
/**
* Provide the HTML to create the modal dialog.
*/
Drupal.theme.prototype.CToolsModalDialog = function () {
var html = ''
html += ' <div id="ctools-modal">'
html += ' <div class="ctools-modal-content">' // panels-modal-content
html += ' <div class="modal-header">';
html += ' <a class="close" href="#">';
html += Drupal.CTools.Modal.currentSettings.closeText + Drupal.CTools.Modal.currentSettings.closeImage;
html += ' </a>';
html += ' <span id="modal-title" class="modal-title">&nbsp;</span>';
html += ' </div>';
html += ' <div id="modal-content" class="modal-content">';
html += ' </div>';
html += ' </div>';
html += ' </div>';
return html;
}
/**
* Provide the HTML to create the throbber.
*/
Drupal.theme.prototype.CToolsModalThrobber = function () {
var html = '';
html += ' <div id="modal-throbber">';
html += ' <div class="modal-throbber-wrapper">';
html += Drupal.CTools.Modal.currentSettings.throbber;
html += ' </div>';
html += ' </div>';
return html;
};
/**
* Figure out what settings string to use to display a modal.
*/
Drupal.CTools.Modal.getSettings = function (object) {
var match = $(object).attr('class').match(/ctools-modal-(\S+)/);
if (match) {
return match[1];
}
}
/**
* Click function for modals that can be cached.
*/
Drupal.CTools.Modal.clickAjaxCacheLink = function () {
Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this));
return Drupal.CTools.AJAX.clickAJAXCacheLink.apply(this);
};
/**
* Handler to prepare the modal for the response
*/
Drupal.CTools.Modal.clickAjaxLink = function () {
Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(this));
return false;
};
/**
* Submit responder to do an AJAX submit on all modal forms.
*/
Drupal.CTools.Modal.submitAjaxForm = function(e) {
var $form = $(this);
var url = $form.attr('action');
setTimeout(function() { Drupal.CTools.AJAX.ajaxSubmit($form, url); }, 1);
return false;
}
/**
* Bind links that will open modals to the appropriate function.
*/
Drupal.behaviors.ZZCToolsModal = {
attach: function(context) {
// Bind links
// Note that doing so in this order means that the two classes can be
// used together safely.
/*
* @todo remimplement the warm caching feature
$('a.ctools-use-modal-cache', context).once('ctools-use-modal', function() {
$(this).click(Drupal.CTools.Modal.clickAjaxCacheLink);
Drupal.CTools.AJAX.warmCache.apply(this);
});
*/
$('area.ctools-use-modal, a.ctools-use-modal', context).once('ctools-use-modal', function() {
var $this = $(this);
$this.click(Drupal.CTools.Modal.clickAjaxLink);
// Create a drupal ajax object
var element_settings = {};
if ($this.attr('href')) {
element_settings.url = $this.attr('href');
element_settings.event = 'click';
element_settings.progress = { type: 'throbber' };
}
var base = $this.attr('href');
Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
});
// Bind buttons
$('input.ctools-use-modal, button.ctools-use-modal', context).once('ctools-use-modal', function() {
var $this = $(this);
$this.click(Drupal.CTools.Modal.clickAjaxLink);
var button = this;
var element_settings = {};
// AJAX submits specified in this manner automatically submit to the
// normal form action.
element_settings.url = Drupal.CTools.Modal.findURL(this);
element_settings.event = 'click';
var base = $this.attr('id');
Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
// Make sure changes to settings are reflected in the URL.
$('.' + $(button).attr('id') + '-url').change(function() {
Drupal.ajax[base].options.url = Drupal.CTools.Modal.findURL(button);
});
});
// Bind our custom event to the form submit
$('#modal-content form', context).once('ctools-use-modal', function() {
var $this = $(this);
var element_settings = {};
element_settings.url = $this.attr('action');
element_settings.event = 'submit';
element_settings.progress = { 'type': 'throbber' }
var base = $this.attr('id');
Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
Drupal.ajax[base].form = $this;
$('input[type=submit], button', this).click(function(event) {
Drupal.ajax[base].element = this;
this.form.clk = this;
// An empty event means we were triggered via .click() and
// in jquery 1.4 this won't trigger a submit.
if (event.bubbles == undefined) {
$(this.form).trigger('submit');
return false;
}
});
});
// Bind a click handler to allow elements with the 'ctools-close-modal'
// class to close the modal.
$('.ctools-close-modal', context).once('ctools-close-modal')
.click(function() {
Drupal.CTools.Modal.dismiss();
return false;
});
}
};
// The following are implementations of AJAX responder commands.
/**
* AJAX responder command to place HTML within the modal.
*/
Drupal.CTools.Modal.modal_display = function(ajax, response, status) {
if ($('#modalContent').length == 0) {
Drupal.CTools.Modal.show(Drupal.CTools.Modal.getSettings(ajax.element));
}
$('#modal-title').html(response.title);
// Simulate an actual page load by scrolling to the top after adding the
// content. This is helpful for allowing users to see error messages at the
// top of a form, etc.
$('#modal-content').html(response.output).scrollTop(0);
Drupal.attachBehaviors();
}
/**
* AJAX responder command to dismiss the modal.
*/
Drupal.CTools.Modal.modal_dismiss = function(command) {
Drupal.CTools.Modal.dismiss();
$('link.ctools-temporary-css').remove();
}
/**
* Display loading
*/
//Drupal.CTools.AJAX.commands.modal_loading = function(command) {
Drupal.CTools.Modal.modal_loading = function(command) {
Drupal.CTools.Modal.modal_display({
output: Drupal.theme(Drupal.CTools.Modal.currentSettings.throbberTheme),
title: Drupal.CTools.Modal.currentSettings.loadingText
});
}
/**
* Find a URL for an AJAX button.
*
* The URL for this gadget will be composed of the values of items by
* taking the ID of this item and adding -url and looking for that
* class. They need to be in the form in order since we will
* concat them all together using '/'.
*/
Drupal.CTools.Modal.findURL = function(item) {
var url = '';
var url_class = '.' + $(item).attr('id') + '-url';
$(url_class).each(
function() {
var $this = $(this);
if (url && $this.val()) {
url += '/';
}
url += $this.val();
});
return url;
};
/**
* modalContent
* @param content string to display in the content box
* @param css obj of css attributes
* @param animation (fadeIn, slideDown, show)
* @param speed (valid animation speeds slow, medium, fast or # in ms)
*/
Drupal.CTools.Modal.modalContent = function(content, css, animation, speed) {
// If our animation isn't set, make it just show/pop
if (!animation) {
animation = 'show';
}
else {
// If our animation isn't "fadeIn" or "slideDown" then it always is show
if (animation != 'fadeIn' && animation != 'slideDown') {
animation = 'show';
}
}
if (!speed) {
speed = 'fast';
}
// Build our base attributes and allow them to be overriden
css = jQuery.extend({
position: 'absolute',
left: '0px',
margin: '0px',
background: '#000',
opacity: '.55'
}, css);
// Add opacity handling for IE.
css.filter = 'alpha(opacity=' + (100 * css.opacity) + ')';
content.hide();
// if we already ahve a modalContent, remove it
if ( $('#modalBackdrop')) $('#modalBackdrop').remove();
if ( $('#modalContent')) $('#modalContent').remove();
// position code lifted from http://www.quirksmode.org/viewport/compatibility.html
if (self.pageYOffset) { // all except Explorer
var wt = self.pageYOffset;
} else if (document.documentElement && document.documentElement.scrollTop) { // Explorer 6 Strict
var wt = document.documentElement.scrollTop;
} else if (document.body) { // all other Explorers
var wt = document.body.scrollTop;
}
// Get our dimensions
// Get the docHeight and (ugly hack) add 50 pixels to make sure we dont have a *visible* border below our div
var docHeight = $(document).height() + 50;
var docWidth = $(document).width();
var winHeight = $(window).height();
var winWidth = $(window).width();
if( docHeight < winHeight ) docHeight = winHeight;
// Create our divs
$('body').append('<div id="modalBackdrop" style="z-index: 1000; display: none;"></div><div id="modalContent" style="z-index: 1001; position: absolute;">' + $(content).html() + '</div>');
// Keyboard and focus event handler ensures focus stays on modal elements only
modalEventHandler = function( event ) {
target = null;
if ( event ) { //Mozilla
target = event.target;
} else { //IE
event = window.event;
target = event.srcElement;
}
var parents = $(target).parents().get();
for (var i = 0; i < parents.length; ++i) {
var position = $(parents[i]).css('position');
if (position == 'absolute' || position == 'fixed') {
return true;
}
}
if( $(target).filter('*:visible').parents('#modalContent').size()) {
// allow the event only if target is a visible child node of #modalContent
return true;
}
if ( $('#modalContent')) $('#modalContent').get(0).focus();
return false;
};
$('body').bind( 'focus', modalEventHandler );
$('body').bind( 'keypress', modalEventHandler );
// Create our content div, get the dimensions, and hide it
var modalContent = $('#modalContent').css('top','-1000px');
var mdcTop = wt + ( winHeight / 2 ) - ( modalContent.outerHeight() / 2);
var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2);
$('#modalBackdrop').css(css).css('top', 0).css('height', docHeight + 'px').css('width', docWidth + 'px').show();
modalContent.css({top: mdcTop + 'px', left: mdcLeft + 'px'}).hide()[animation](speed);
// Bind a click for closing the modalContent
modalContentClose = function(){close(); return false;};
$('.close').bind('click', modalContentClose);
// Bind a keypress on escape for closing the modalContent
modalEventEscapeCloseHandler = function(event) {
if (event.keyCode == 27) {
close();
return false;
}
};
$(document).bind('keydown', modalEventEscapeCloseHandler);
// Close the open modal content and backdrop
function close() {
// Unbind the events
$(window).unbind('resize', modalContentResize);
$('body').unbind( 'focus', modalEventHandler);
$('body').unbind( 'keypress', modalEventHandler );
$('.close').unbind('click', modalContentClose);
$('body').unbind('keypress', modalEventEscapeCloseHandler);
$(document).trigger('CToolsDetachBehaviors', $('#modalContent'));
// Set our animation parameters and use them
if ( animation == 'fadeIn' ) animation = 'fadeOut';
if ( animation == 'slideDown' ) animation = 'slideUp';
if ( animation == 'show' ) animation = 'hide';
// Close the content
modalContent.hide()[animation](speed);
// Remove the content
$('#modalContent').remove();
$('#modalBackdrop').remove();
};
// Move and resize the modalBackdrop and modalContent on resize of the window
modalContentResize = function(){
// Get our heights
var docHeight = $(document).height();
var docWidth = $(document).width();
var winHeight = $(window).height();
var winWidth = $(window).width();
if( docHeight < winHeight ) docHeight = winHeight;
// Get where we should move content to
var modalContent = $('#modalContent');
var mdcTop = ( winHeight / 2 ) - ( modalContent.outerHeight() / 2);
var mdcLeft = ( winWidth / 2 ) - ( modalContent.outerWidth() / 2);
// Apply the changes
$('#modalBackdrop').css('height', docHeight + 'px').css('width', docWidth + 'px').show();
modalContent.css('top', mdcTop + 'px').css('left', mdcLeft + 'px').show();
};
$(window).bind('resize', modalContentResize);
$('#modalContent').focus();
};
/**
* unmodalContent
* @param content (The jQuery object to remove)
* @param animation (fadeOut, slideUp, show)
* @param speed (valid animation speeds slow, medium, fast or # in ms)
*/
Drupal.CTools.Modal.unmodalContent = function(content, animation, speed)
{
// If our animation isn't set, make it just show/pop
if (!animation) { var animation = 'show'; } else {
// If our animation isn't "fade" then it always is show
if (( animation != 'fadeOut' ) && ( animation != 'slideUp')) animation = 'show';
}
// Set a speed if we dont have one
if ( !speed ) var speed = 'fast';
// Unbind the events we bound
$(window).unbind('resize', modalContentResize);
$('body').unbind('focus', modalEventHandler);
$('body').unbind('keypress', modalEventHandler);
$('.close').unbind('click', modalContentClose);
$(document).trigger('CToolsDetachBehaviors', $('#modalContent'));
// jQuery magic loop through the instances and run the animations or removal.
content.each(function(){
if ( animation == 'fade' ) {
$('#modalContent').fadeOut(speed, function() {
$('#modalBackdrop').fadeOut(speed, function() {
$(this).remove();
});
$(this).remove();
});
} else {
if ( animation == 'slide' ) {
$('#modalContent').slideUp(speed,function() {
$('#modalBackdrop').slideUp(speed, function() {
$(this).remove();
});
$(this).remove();
});
} else {
$('#modalContent').remove();
$('#modalBackdrop').remove();
}
}
});
};
$(function() {
Drupal.ajax.prototype.commands.modal_display = Drupal.CTools.Modal.modal_display;
Drupal.ajax.prototype.commands.modal_dismiss = Drupal.CTools.Modal.modal_dismiss;
});
})(jQuery);

View File

@@ -0,0 +1,220 @@
(function ($) {
Drupal.CTools = Drupal.CTools || {};
Drupal.CTools.Stylizer = {};
Drupal.CTools.Stylizer.addFarbtastic = function(context) {
// This behavior attaches by ID, so is only valid once on a page.
if ($('ctools_stylizer_color_scheme_form .color-form.Stylizer-processed').size()) {
return;
}
var form = $('.color-form', context);
var inputs = [];
var hooks = [];
var locks = [];
var focused = null;
// Add Farbtastic
$(form).prepend('<div id="placeholder"></div>').addClass('color-processed');
var farb = $.farbtastic('#placeholder');
// Decode reference colors to HSL
/*var reference = Drupal.settings.Stylizer.reference.clone();
for (i in reference) {
reference[i] = farb.RGBToHSL(farb.unpack(reference[i]));
} */
// Set up colorscheme selector
$('#edit-scheme', form).change(function () {
var colors = this.options[this.selectedIndex].value;
if (colors != '') {
colors = colors.split(',');
for (i in colors) {
callback(inputs[i], colors[i], false, true);
}
}
});
/**
* Shift a given color, using a reference pair (ref in HSL).
*
* This algorithm ensures relative ordering on the saturation and luminance
* axes is preserved, and performs a simple hue shift.
*
* It is also symmetrical. If: shift_color(c, a, b) == d,
* then shift_color(d, b, a) == c.
*/
function shift_color(given, ref1, ref2) {
// Convert to HSL
given = farb.RGBToHSL(farb.unpack(given));
// Hue: apply delta
given[0] += ref2[0] - ref1[0];
// Saturation: interpolate
if (ref1[1] == 0 || ref2[1] == 0) {
given[1] = ref2[1];
}
else {
var d = ref1[1] / ref2[1];
if (d > 1) {
given[1] /= d;
}
else {
given[1] = 1 - (1 - given[1]) * d;
}
}
// Luminance: interpolate
if (ref1[2] == 0 || ref2[2] == 0) {
given[2] = ref2[2];
}
else {
var d = ref1[2] / ref2[2];
if (d > 1) {
given[2] /= d;
}
else {
given[2] = 1 - (1 - given[2]) * d;
}
}
return farb.pack(farb.HSLToRGB(given));
}
/**
* Callback for Farbtastic when a new color is chosen.
*/
function callback(input, color, propagate, colorscheme) {
// Set background/foreground color
$(input).css({
backgroundColor: color,
'color': farb.RGBToHSL(farb.unpack(color))[2] > 0.5 ? '#000' : '#fff'
});
// Change input value
if (input.value && input.value != color) {
input.value = color;
// Update locked values
if (propagate) {
var i = input.i;
for (j = i + 1; ; ++j) {
if (!locks[j - 1] || $(locks[j - 1]).is('.unlocked')) break;
var matched = shift_color(color, reference[input.key], reference[inputs[j].key]);
callback(inputs[j], matched, false);
}
for (j = i - 1; ; --j) {
if (!locks[j] || $(locks[j]).is('.unlocked')) break;
var matched = shift_color(color, reference[input.key], reference[inputs[j].key]);
callback(inputs[j], matched, false);
}
}
// Reset colorscheme selector
if (!colorscheme) {
resetScheme();
}
}
}
/**
* Reset the color scheme selector.
*/
function resetScheme() {
$('#edit-scheme', form).each(function () {
this.selectedIndex = this.options.length - 1;
});
}
// Focus the Farbtastic on a particular field.
function focus() {
var input = this;
// Remove old bindings
focused && $(focused).unbind('keyup', farb.updateValue)
.unbind('keyup', resetScheme)
.parent().removeClass('item-selected');
// Add new bindings
focused = this;
farb.linkTo(function (color) { callback(input, color, true, false); });
farb.setColor(this.value);
$(focused).keyup(farb.updateValue).keyup(resetScheme)
.parent().addClass('item-selected');
}
// Initialize color fields
$('#palette input.form-text', form)
.each(function () {
// Extract palette field name
this.key = this.id.substring(13);
// Link to color picker temporarily to initialize.
farb.linkTo(function () {}).setColor('#000').linkTo(this);
// Add lock
var i = inputs.length;
if (inputs.length) {
var lock = $('<div class="lock"></div>').toggle(
function () {
$(this).addClass('unlocked');
$(hooks[i - 1]).attr('class',
locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook up' : 'hook'
);
$(hooks[i]).attr('class',
locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook down' : 'hook'
);
},
function () {
$(this).removeClass('unlocked');
$(hooks[i - 1]).attr('class',
locks[i - 2] && $(locks[i - 2]).is(':not(.unlocked)') ? 'hook both' : 'hook down'
);
$(hooks[i]).attr('class',
locks[i] && $(locks[i]).is(':not(.unlocked)') ? 'hook both' : 'hook up'
);
}
);
$(this).after(lock);
locks.push(lock);
};
// Add hook
var $this = $(this);
var hook = $('<div class="hook"></div>');
$this.after(hook);
hooks.push(hook);
$this.parent().find('.lock').click();
this.i = i;
inputs.push(this);
})
.focus(focus);
$('#palette label', form);
// Focus first color
focus.call(inputs[0]);
};
Drupal.behaviors.CToolsColorSettings = {
attach: function() {
$('.ctools-stylizer-color-edit:not(.ctools-color-processed)')
.addClass('ctools-color-processed')
.each(function() {
Drupal.CTools.Stylizer.addFarbtastic('#' + $(this).attr('id'));
});
$('div.form-item div.ctools-style-icon:not(.ctools-color-processed)')
.addClass('ctools-color-processed')
.click(function() {
$widget = $('input', $(this).parent());
// Toggle if a checkbox, turn on if a radio.
$widget.attr('checked', !$widget.attr('checked') || $widget.is('input[type=radio]'));
});
}
}
})(jQuery);