FINAL suepr merge step : added all modules to this super repos
This commit is contained in:
457
sites/all/modules/contrib/admin/features/features.js
Normal file
457
sites/all/modules/contrib/admin/features/features.js
Normal file
@@ -0,0 +1,457 @@
|
||||
/**
|
||||
* jQuery.fn.sortElements
|
||||
* --------------
|
||||
* @param Function comparator:
|
||||
* Exactly the same behaviour as [1,2,3].sort(comparator)
|
||||
*
|
||||
* @param Function getSortable
|
||||
* A function that should return the element that is
|
||||
* to be sorted. The comparator will run on the
|
||||
* current collection, but you may want the actual
|
||||
* resulting sort to occur on a parent or another
|
||||
* associated element.
|
||||
*
|
||||
* E.g. $('td').sortElements(comparator, function(){
|
||||
* return this.parentNode;
|
||||
* })
|
||||
*
|
||||
* The <td>'s parent (<tr>) will be sorted instead
|
||||
* of the <td> itself.
|
||||
*
|
||||
* Credit: http://james.padolsey.com/javascript/sorting-elements-with-jquery/
|
||||
*
|
||||
*/
|
||||
jQuery.fn.sortElements = (function(){
|
||||
|
||||
var sort = [].sort;
|
||||
|
||||
return function(comparator, getSortable) {
|
||||
|
||||
getSortable = getSortable || function(){return this;};
|
||||
|
||||
var placements = this.map(function(){
|
||||
|
||||
var sortElement = getSortable.call(this),
|
||||
parentNode = sortElement.parentNode,
|
||||
|
||||
// Since the element itself will change position, we have
|
||||
// to have some way of storing its original position in
|
||||
// the DOM. The easiest way is to have a 'flag' node:
|
||||
nextSibling = parentNode.insertBefore(
|
||||
document.createTextNode(''),
|
||||
sortElement.nextSibling
|
||||
);
|
||||
|
||||
return function() {
|
||||
|
||||
if (parentNode === this) {
|
||||
throw new Error(
|
||||
"You can't sort elements if any one is a descendant of another."
|
||||
);
|
||||
}
|
||||
|
||||
// Insert before flag:
|
||||
parentNode.insertBefore(this, nextSibling);
|
||||
// Remove flag:
|
||||
parentNode.removeChild(nextSibling);
|
||||
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
return sort.call(this, comparator).each(function(i){
|
||||
placements[i].call(getSortable.call(this));
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
(function ($) {
|
||||
Drupal.behaviors.features = {
|
||||
attach: function(context, settings) {
|
||||
// Features management form
|
||||
$('table.features:not(.processed)', context).each(function() {
|
||||
$(this).addClass('processed');
|
||||
|
||||
// Check the overridden status of each feature
|
||||
Drupal.features.checkStatus();
|
||||
|
||||
// Add some nicer row hilighting when checkboxes change values
|
||||
$('input', this).bind('change', function() {
|
||||
if (!$(this).attr('checked')) {
|
||||
$(this).parents('tr').removeClass('enabled').addClass('disabled');
|
||||
}
|
||||
else {
|
||||
$(this).parents('tr').addClass('enabled').removeClass('disabled');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Export form component selector
|
||||
$('form.features-export-form select.features-select-components:not(.processed)', context).each(function() {
|
||||
$(this)
|
||||
.addClass('processed')
|
||||
.change(function() {
|
||||
var target = $(this).val();
|
||||
$('div.features-select').hide();
|
||||
$('div.features-select-' + target).show();
|
||||
return false;
|
||||
}).trigger('change');
|
||||
});
|
||||
|
||||
// Export form machine-readable JS
|
||||
$('.feature-name:not(.processed)', context).each(function() {
|
||||
$('.feature-name')
|
||||
.addClass('processed')
|
||||
.after(' <small class="feature-module-name-suffix"> </small>');
|
||||
if ($('.feature-module-name').val() === $('.feature-name').val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_') || $('.feature-module-name').val() === '') {
|
||||
$('.feature-module-name').parents('.form-item').hide();
|
||||
$('.feature-name').bind('keyup change', function() {
|
||||
var machine = $(this).val().toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/_+/g, '_');
|
||||
if (machine !== '_' && machine !== '') {
|
||||
$('.feature-module-name').val(machine);
|
||||
$('.feature-module-name-suffix').empty().append(' Machine name: ' + machine + ' [').append($('<a href="#">'+ Drupal.t('Edit') +'</a>').click(function() {
|
||||
$('.feature-module-name').parents('.form-item').show();
|
||||
$('.feature-module-name-suffix').hide();
|
||||
$('.feature-name').unbind('keyup');
|
||||
return false;
|
||||
})).append(']');
|
||||
}
|
||||
else {
|
||||
$('.feature-module-name').val(machine);
|
||||
$('.feature-module-name-suffix').text('');
|
||||
}
|
||||
});
|
||||
$('.feature-name').keyup();
|
||||
}
|
||||
});
|
||||
|
||||
//View info dialog
|
||||
var infoDialog = $('#features-info-file');
|
||||
if (infoDialog.length != 0) {
|
||||
infoDialog.dialog({
|
||||
autoOpen: false,
|
||||
modal: true,
|
||||
draggable: false,
|
||||
resizable: false,
|
||||
width: 600,
|
||||
height: 480
|
||||
});
|
||||
}
|
||||
|
||||
if ((Drupal.settings.features != undefined) && (Drupal.settings.features.info != undefined)) {
|
||||
$('#features-info-file textarea').val(Drupal.settings.features.info);
|
||||
$('#features-info-file').dialog('open');
|
||||
//To be reset by the button click ajax
|
||||
Drupal.settings.features.info = undefined;
|
||||
}
|
||||
|
||||
// mark any conflicts with a class
|
||||
if ((Drupal.settings.features != undefined) && (Drupal.settings.features.conflicts != undefined)) {
|
||||
for (var moduleName in Drupal.settings.features.conflicts) {
|
||||
moduleConflicts = Drupal.settings.features.conflicts[moduleName];
|
||||
$('#features-export-wrapper input[type=checkbox]', context).each(function() {
|
||||
if (!$(this).hasClass('features-checkall')) {
|
||||
var key = $(this).attr('name');
|
||||
var matches = key.match(/^([^\[]+)(\[.+\])?\[(.+)\]\[(.+)\]$/);
|
||||
var component = matches[1];
|
||||
var item = matches[4];
|
||||
if ((component in moduleConflicts) && (moduleConflicts[component].indexOf(item) != -1)) {
|
||||
$(this).parent().addClass('features-conflict');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function _checkAll(value) {
|
||||
if (value) {
|
||||
$('#features-export-wrapper .component-select input[type=checkbox]:visible', context).each(function() {
|
||||
var move_id = $(this).attr('id');
|
||||
$(this).click();
|
||||
$('#'+ move_id).attr('checked', 'checked');
|
||||
});
|
||||
}
|
||||
else {
|
||||
$('#features-export-wrapper .component-added input[type=checkbox]:visible', context).each(function() {
|
||||
var move_id = $(this).attr('id');
|
||||
$('#'+ move_id).removeAttr('checked');
|
||||
$(this).click();
|
||||
$('#'+ move_id).removeAttr('checked');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateComponentCountInfo(item, section) {
|
||||
console.log(section);
|
||||
switch (section) {
|
||||
case 'select':
|
||||
var parent = $(item).closest('.features-export-list').siblings('.features-export-component');
|
||||
$('.component-count', parent).text(function (index, text) {
|
||||
return +text + 1;
|
||||
}
|
||||
);
|
||||
break;
|
||||
case 'added':
|
||||
case 'detected':
|
||||
var parent = $(item).closest('.features-export-component');
|
||||
$('.component-count', parent).text(function (index, text) {
|
||||
return text - 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function moveCheckbox(item, section, value) {
|
||||
updateComponentCountInfo(item, section);
|
||||
var curParent = item;
|
||||
if ($(item).hasClass('form-type-checkbox')) {
|
||||
item = $(item).children('input[type=checkbox]');
|
||||
}
|
||||
else {
|
||||
curParent = $(item).parents('.form-type-checkbox');
|
||||
}
|
||||
var newParent = $(curParent).parents('.features-export-parent').find('.form-checkboxes.component-'+section);
|
||||
$(curParent).detach();
|
||||
$(curParent).appendTo(newParent);
|
||||
var list = ['select', 'added', 'detected', 'included'];
|
||||
for (i in list) {
|
||||
$(curParent).removeClass('component-' + list[i]);
|
||||
$(item).removeClass('component-' + list[i]);
|
||||
}
|
||||
$(curParent).addClass('component-'+section);
|
||||
$(item).addClass('component-'+section);
|
||||
if (value) {
|
||||
$(item).attr('checked', 'checked');
|
||||
}
|
||||
else {
|
||||
$(item).removeAttr('checked')
|
||||
}
|
||||
$(newParent).parent().removeClass('features-export-empty');
|
||||
|
||||
// re-sort new list of checkboxes based on labels
|
||||
$(newParent).find('label').sortElements(
|
||||
function(a, b){
|
||||
return $(a).text() > $(b).text() ? 1 : -1;
|
||||
},
|
||||
function(){
|
||||
return this.parentNode;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// provide timer for auto-refresh trigger
|
||||
var timeoutID = 0;
|
||||
var inTimeout = 0;
|
||||
function _triggerTimeout() {
|
||||
timeoutID = 0;
|
||||
_updateDetected();
|
||||
}
|
||||
function _resetTimeout() {
|
||||
inTimeout++;
|
||||
// if timeout is already active, reset it
|
||||
if (timeoutID != 0) {
|
||||
window.clearTimeout(timeoutID);
|
||||
if (inTimeout > 0) inTimeout--;
|
||||
}
|
||||
timeoutID = window.setTimeout(_triggerTimeout, 500);
|
||||
}
|
||||
|
||||
function _updateDetected() {
|
||||
var autodetect = $('#features-autodetect input[type=checkbox]');
|
||||
if ((autodetect.length > 0) && (!autodetect.is(':checked'))) return;
|
||||
// query the server for a list of components/items in the feature and update
|
||||
// the auto-detected items
|
||||
var items = []; // will contain a list of selected items exported to feature
|
||||
var components = {}; // contains object of component names that have checked items
|
||||
$('#features-export-wrapper input[type=checkbox]:checked', context).each(function() {
|
||||
if (!$(this).hasClass('features-checkall')) {
|
||||
var key = $(this).attr('name');
|
||||
var matches = key.match(/^([^\[]+)(\[.+\])?\[(.+)\]\[(.+)\]$/);
|
||||
components[matches[1]] = matches[1];
|
||||
if (!$(this).hasClass('component-detected')) {
|
||||
items.push(key);
|
||||
}
|
||||
}
|
||||
});
|
||||
var featureName = $('#edit-module-name').val();
|
||||
if (featureName == '') {
|
||||
featureName = '*';
|
||||
}
|
||||
var url = Drupal.settings.basePath + 'features/ajaxcallback/' + featureName;
|
||||
var excluded = Drupal.settings.features.excluded;
|
||||
var postData = {'items': items, 'excluded': excluded};
|
||||
jQuery.post(url, postData, function(data) {
|
||||
if (inTimeout > 0) inTimeout--;
|
||||
// if we have triggered another timeout then don't update with old results
|
||||
if (inTimeout == 0) {
|
||||
// data is an object keyed by component listing the exports of the feature
|
||||
for (var component in data) {
|
||||
var itemList = data[component];
|
||||
$('#features-export-wrapper .component-' + component + ' input[type=checkbox]', context).each(function() {
|
||||
var key = $(this).attr('value');
|
||||
// first remove any auto-detected items that are no longer in component
|
||||
if ($(this).hasClass('component-detected')) {
|
||||
if (!(key in itemList)) {
|
||||
moveCheckbox(this, 'select', false)
|
||||
}
|
||||
}
|
||||
// next, add any new auto-detected items
|
||||
else if ($(this).hasClass('component-select')) {
|
||||
if (key in itemList) {
|
||||
moveCheckbox(this, 'detected', itemList[key]);
|
||||
$(this).parent().show(); // make sure it's not hidden from filter
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// loop over all selected components and check for any that have been completely removed
|
||||
for (var component in components) {
|
||||
if ((data == null) || !(component in data)) {
|
||||
$('#features-export-wrapper .component-' + component + ' input[type=checkbox].component-detected', context).each(function() {
|
||||
moveCheckbox(this, 'select', false);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
|
||||
// Handle component selection UI
|
||||
$('#features-export-wrapper input[type=checkbox]', context).click(function() {
|
||||
_resetTimeout();
|
||||
if ($(this).hasClass('component-select')) {
|
||||
moveCheckbox(this, 'added', true);
|
||||
}
|
||||
else if ($(this).hasClass('component-included')) {
|
||||
moveCheckbox(this, 'added', false);
|
||||
}
|
||||
else if ($(this).hasClass('component-added')) {
|
||||
if ($(this).is(':checked')) {
|
||||
moveCheckbox(this, 'included', true);
|
||||
}
|
||||
else {
|
||||
moveCheckbox(this, 'select', false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle select/unselect all
|
||||
$('#features-filter .features-checkall', context).click(function() {
|
||||
if ($(this).attr('checked')) {
|
||||
_checkAll(true);
|
||||
$(this).next().html(Drupal.t('Deselect all'));
|
||||
}
|
||||
else {
|
||||
_checkAll(false);
|
||||
$(this).next().html(Drupal.t('Select all'));
|
||||
}
|
||||
_resetTimeout();
|
||||
});
|
||||
|
||||
// Handle filtering
|
||||
|
||||
// provide timer for auto-refresh trigger
|
||||
var filterTimeoutID = 0;
|
||||
var inFilterTimeout = 0;
|
||||
function _triggerFilterTimeout() {
|
||||
filterTimeoutID = 0;
|
||||
_updateFilter();
|
||||
}
|
||||
function _resetFilterTimeout() {
|
||||
inFilterTimeout++;
|
||||
// if timeout is already active, reset it
|
||||
if (filterTimeoutID != 0) {
|
||||
window.clearTimeout(filterTimeoutID);
|
||||
if (inFilterTimeout > 0) inFilterTimeout--;
|
||||
}
|
||||
filterTimeoutID = window.setTimeout(_triggerFilterTimeout, 200);
|
||||
}
|
||||
function _updateFilter() {
|
||||
var filter = $('#features-filter input').val();
|
||||
var regex = new RegExp(filter, 'i');
|
||||
// collapse fieldsets
|
||||
var newState = {};
|
||||
var currentState = {};
|
||||
$('#features-export-wrapper fieldset.features-export-component', context).each(function() {
|
||||
// expand parent fieldset
|
||||
var section = $(this).attr('id');
|
||||
currentState[section] = !($(this).hasClass('collapsed'));
|
||||
if (!(section in newState)) {
|
||||
newState[section] = false;
|
||||
}
|
||||
|
||||
$(this).find('div.component-select label').each(function() {
|
||||
if (filter == '') {
|
||||
if (currentState[section]) {
|
||||
Drupal.toggleFieldset($('#'+section));
|
||||
currentState[section] = false;
|
||||
}
|
||||
$(this).parent().show();
|
||||
}
|
||||
else if ($(this).text().match(regex)) {
|
||||
$(this).parent().show();
|
||||
newState[section] = true;
|
||||
}
|
||||
else {
|
||||
$(this).parent().hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
for (section in newState) {
|
||||
if (currentState[section] != newState[section]) {
|
||||
Drupal.toggleFieldset($('#'+section));
|
||||
}
|
||||
}
|
||||
}
|
||||
$('#features-filter input', context).bind("input", function() {
|
||||
_resetFilterTimeout();
|
||||
});
|
||||
$('#features-filter .features-filter-clear', context).click(function() {
|
||||
$('#features-filter input').val('');
|
||||
_updateFilter();
|
||||
});
|
||||
|
||||
// show the filter bar
|
||||
$('#features-filter', context).removeClass('element-invisible');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Drupal.features = {
|
||||
'checkStatus': function() {
|
||||
$('table.features tbody tr').not('.processed').filter(':first').each(function() {
|
||||
var elem = $(this);
|
||||
$(elem).addClass('processed');
|
||||
var uri = $(this).find('a.admin-check').attr('href');
|
||||
if (uri) {
|
||||
$.get(uri, [], function(data) {
|
||||
$(elem).find('.admin-loading').hide();
|
||||
switch (data.storage) {
|
||||
case 3:
|
||||
$(elem).find('.admin-rebuilding').show();
|
||||
break;
|
||||
case 2:
|
||||
$(elem).find('.admin-needs-review').show();
|
||||
break;
|
||||
case 1:
|
||||
$(elem).find('.admin-overridden').show();
|
||||
break;
|
||||
default:
|
||||
$(elem).find('.admin-default').show();
|
||||
break;
|
||||
}
|
||||
Drupal.features.checkStatus();
|
||||
}, 'json');
|
||||
}
|
||||
else {
|
||||
Drupal.features.checkStatus();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
})(jQuery);
|
||||
|
||||
|
Reference in New Issue
Block a user