Файл: contao-3.5.8/assets/contao/js/core-uncompressed.js
Строк: 2427
<?php
/**
* Contao Open Source CMS
*
* Copyright (c) 2005-2016 Leo Feyer
*
* @license LGPL-3.0+
*/
/**
* Provide methods to handle Ajax requests.
*
* @author Leo Feyer <https://github.com/leofeyer>
*/
var AjaxRequest =
{
/**
* The theme path
* @member {string}
*/
themePath: Contao.script_url + 'system/themes/' + Contao.theme + '/images/',
/**
* Toggle the navigation menu
*
* @param {object} el The DOM element
* @param {string} id The ID of the menu item
*
* @returns {boolean}
*/
toggleNavigation: function(el, id) {
el.blur();
var item = $(id),
image = $(el).getFirst('img');
if (item) {
if (item.getStyle('display') == 'none') {
item.setStyle('display', 'inline');
image.src = AjaxRequest.themePath + 'modMinus.gif';
$(el).store('tip:title', Contao.lang.collapse);
new Request.Contao().post({'action':'toggleNavigation', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
} else {
item.setStyle('display', 'none');
image.src = AjaxRequest.themePath + 'modPlus.gif';
$(el).store('tip:title', Contao.lang.expand);
new Request.Contao().post({'action':'toggleNavigation', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token});
}
return false;
}
new Request.Contao({
evalScripts: true,
onRequest: AjaxRequest.displayBox(Contao.lang.loading + ' …'),
onSuccess: function(txt) {
var li = new Element('li', {
'id': id,
'class': 'tl_parent',
'html': txt,
'styles': {
'display': 'inline'
}
}).inject($(el).getParent('li'), 'after');
// Update the referer ID
li.getElements('a').each(function(el) {
el.href = el.href.replace(/&ref=[a-f0-9]+/, '&ref=' + Contao.referer_id);
});
$(el).store('tip:title', Contao.lang.collapse);
image.src = AjaxRequest.themePath + 'modMinus.gif';
AjaxRequest.hideBox();
// HOOK
window.fireEvent('ajax_change');
}
}).post({'action':'loadNavigation', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
return false;
},
/**
* Toggle the site structure tree
*
* @param {object} el The DOM lement
* @param {string} id The ID of the target element
* @param {int} level The indentation level
* @param {int} mode The insert mode
*
* @returns {boolean}
*/
toggleStructure: function (el, id, level, mode) {
el.blur();
var item = $(id),
image = $(el).getFirst('img');
if (item) {
if (item.getStyle('display') == 'none') {
item.setStyle('display', 'inline');
image.src = AjaxRequest.themePath + 'folMinus.gif';
$(el).store('tip:title', Contao.lang.collapse);
new Request.Contao({field:el}).post({'action':'toggleStructure', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
} else {
item.setStyle('display', 'none');
image.src = AjaxRequest.themePath + 'folPlus.gif';
$(el).store('tip:title', Contao.lang.expand);
new Request.Contao({field:el}).post({'action':'toggleStructure', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token});
}
return false;
}
new Request.Contao({
field: el,
evalScripts: true,
onRequest: AjaxRequest.displayBox(Contao.lang.loading + ' …'),
onSuccess: function(txt) {
var li = new Element('li', {
'id': id,
'class': 'parent',
'styles': {
'display': 'inline'
}
});
new Element('ul', {
'class': 'level_' + level,
'html': txt
}).inject(li, 'bottom');
if (mode == 5) {
li.inject($(el).getParent('li'), 'after');
} else {
var folder = false,
parent = $(el).getParent('li'),
next;
while (typeOf(parent) == 'element' && (next = parent.getNext('li'))) {
parent = next;
if (parent.hasClass('tl_folder')) {
folder = true;
break;
}
}
if (folder) {
li.inject(parent, 'before');
} else {
li.inject(parent, 'after');
}
}
// Update the referer ID
li.getElements('a').each(function(el) {
el.href = el.href.replace(/&ref=[a-f0-9]+/, '&ref=' + Contao.referer_id);
});
$(el).store('tip:title', Contao.lang.collapse);
image.src = AjaxRequest.themePath + 'folMinus.gif';
window.fireEvent('structure');
AjaxRequest.hideBox();
// HOOK
window.fireEvent('ajax_change');
}
}).post({'action':'loadStructure', 'id':id, 'level':level, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
return false;
},
/**
* Toggle the file manager tree
*
* @param {object} el The DOM element
* @param {string} id The ID of the target element
* @param {string} folder The folder's path
* @param {int} level The indentation level
*
* @returns {boolean}
*/
toggleFileManager: function (el, id, folder, level) {
el.blur();
var item = $(id),
image = $(el).getFirst('img');
if (item) {
if (item.getStyle('display') == 'none') {
item.setStyle('display', 'inline');
image.src = AjaxRequest.themePath + 'folMinus.gif';
$(el).store('tip:title', Contao.lang.collapse);
new Request.Contao({field:el}).post({'action':'toggleFileManager', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
} else {
item.setStyle('display', 'none');
image.src = AjaxRequest.themePath + 'folPlus.gif';
$(el).store('tip:title', Contao.lang.expand);
new Request.Contao({field:el}).post({'action':'toggleFileManager', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token});
}
return false;
}
new Request.Contao({
field: el,
evalScripts: true,
onRequest: AjaxRequest.displayBox(Contao.lang.loading + ' …'),
onSuccess: function(txt) {
var li = new Element('li', {
'id': id,
'class': 'parent',
'styles': {
'display': 'inline'
}
});
new Element('ul', {
'class': 'level_' + level,
'html': txt
}).inject(li, 'bottom');
li.inject($(el).getParent('li'), 'after');
// Update the referer ID
li.getElements('a').each(function(el) {
el.href = el.href.replace(/&ref=[a-f0-9]+/, '&ref=' + Contao.referer_id);
});
$(el).store('tip:title', Contao.lang.collapse);
image.src = AjaxRequest.themePath + 'folMinus.gif';
AjaxRequest.hideBox();
// HOOK
window.fireEvent('ajax_change');
}
}).post({'action':'loadFileManager', 'id':id, 'level':level, 'folder':folder, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
return false;
},
/**
* Toggle the page tree input field
*
* @param {object} el The DOM element
* @param {string} id The ID of the target element
* @param {string} field The field name
* @param {string} name The Ajax field name
* @param {int} level The indentation level
*
* @returns {boolean}
*/
togglePagetree: function (el, id, field, name, level) {
el.blur();
Backend.getScrollOffset();
var item = $(id),
image = $(el).getFirst('img');
if (item) {
if (item.getStyle('display') == 'none') {
item.setStyle('display', 'inline');
image.src = AjaxRequest.themePath + 'folMinus.gif';
$(el).store('tip:title', Contao.lang.collapse);
new Request.Contao({field:el}).post({'action':'togglePagetree', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
} else {
item.setStyle('display', 'none');
image.src = AjaxRequest.themePath + 'folPlus.gif';
$(el).store('tip:title', Contao.lang.expand);
new Request.Contao({field:el}).post({'action':'togglePagetree', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token});
}
return false;
}
new Request.Contao({
field: el,
evalScripts: true,
onRequest: AjaxRequest.displayBox(Contao.lang.loading + ' …'),
onSuccess: function(txt) {
var li = new Element('li', {
'id': id,
'class': 'parent',
'styles': {
'display': 'inline'
}
});
new Element('ul', {
'class': 'level_' + level,
'html': txt
}).inject(li, 'bottom');
li.inject($(el).getParent('li'), 'after');
// Update the referer ID
li.getElements('a').each(function(el) {
el.href = el.href.replace(/&ref=[a-f0-9]+/, '&ref=' + Contao.referer_id);
});
$(el).store('tip:title', Contao.lang.collapse);
image.src = AjaxRequest.themePath + 'folMinus.gif';
AjaxRequest.hideBox();
// HOOK
window.fireEvent('ajax_change');
}
}).post({'action':'loadPagetree', 'id':id, 'level':level, 'field':field, 'name':name, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
return false;
},
/**
* Toggle the file tree input field
*
* @param {object} el The DOM element
* @param {string} id The ID of the target element
* @param {string} folder The folder name
* @param {string} field The field name
* @param {string} name The Ajax field name
* @param {int} level The indentation level
*
* @returns {boolean}
*/
toggleFiletree: function (el, id, folder, field, name, level) {
el.blur();
Backend.getScrollOffset();
var item = $(id),
image = $(el).getFirst('img');
if (item) {
if (item.getStyle('display') == 'none') {
item.setStyle('display', 'inline');
image.src = AjaxRequest.themePath + 'folMinus.gif';
$(el).store('tip:title', Contao.lang.collapse);
new Request.Contao({field:el}).post({'action':'toggleFiletree', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
} else {
item.setStyle('display', 'none');
image.src = AjaxRequest.themePath + 'folPlus.gif';
$(el).store('tip:title', Contao.lang.expand);
new Request.Contao({field:el}).post({'action':'toggleFiletree', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token});
}
return false;
}
new Request.Contao({
field: el,
evalScripts: true,
onRequest: AjaxRequest.displayBox(Contao.lang.loading + ' …'),
onSuccess: function(txt) {
var li = new Element('li', {
'id': id,
'class': 'parent',
'styles': {
'display': 'inline'
}
});
new Element('ul', {
'class': 'level_' + level,
'html': txt
}).inject(li, 'bottom');
li.inject($(el).getParent('li'), 'after');
// Update the referer ID
li.getElements('a').each(function(el) {
el.href = el.href.replace(/&ref=[a-f0-9]+/, '&ref=' + Contao.referer_id);
});
$(el).store('tip:title', Contao.lang.collapse);
image.src = AjaxRequest.themePath + 'folMinus.gif';
AjaxRequest.hideBox();
// HOOK
window.fireEvent('ajax_change');
}
}).post({'action':'loadFiletree', 'id':id, 'folder':folder, 'level':level, 'field':field, 'name':name, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
return false;
},
/**
* Toggle subpalettes in edit mode
*
* @param {object} el The DOM element
* @param {string} id The ID of the target element
* @param {string} field The field name
*/
toggleSubpalette: function (el, id, field) {
el.blur();
var item = $(id);
if (item) {
if (!el.value) {
el.value = 1;
el.checked = 'checked';
item.setStyle('display', 'block');
new Request.Contao({field:el}).post({'action':'toggleSubpalette', 'id':id, 'field':field, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
} else {
el.value = '';
el.checked = '';
item.setStyle('display', 'none');
new Request.Contao({field:el}).post({'action':'toggleSubpalette', 'id':id, 'field':field, 'state':0, 'REQUEST_TOKEN':Contao.request_token});
}
return;
}
new Request.Contao({
field: el,
evalScripts: false,
onRequest: AjaxRequest.displayBox(Contao.lang.loading + ' …'),
onSuccess: function(txt, json) {
var div = new Element('div', {
'id': id,
'html': txt,
'styles': {
'display': 'block'
}
}).inject($(el).getParent('div').getParent('div'), 'after');
// Execute scripts after the DOM has been updated
if (json.javascript) {
// Use Asset.javascript() instead of document.write() to load a
// JavaScript file and re-execude the code after it has been loaded
document.write = function(str) {
var src = '';
str.replace(/<script src="([^"]+)"/i, function(all, match){
src = match;
});
src && Asset.javascript(src, {
onLoad: function() {
Browser.exec(json.javascript);
}
});
};
Browser.exec(json.javascript);
}
el.value = 1;
el.checked = 'checked';
// Update the referer ID
div.getElements('a').each(function(el) {
el.href = el.href.replace(/&ref=[a-f0-9]+/, '&ref=' + Contao.referer_id);
});
AjaxRequest.hideBox();
// HOOK
window.fireEvent('subpalette'); // Backwards compatibility
window.fireEvent('ajax_change');
}
}).post({'action':'toggleSubpalette', 'id':id, 'field':field, 'load':1, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
},
/**
* Toggle the visibility of an element
*
* @param {object} el The DOM element
* @param {string} id The ID of the target element
* @param {string} table The table name
*
* @returns {boolean}
*/
toggleVisibility: function(el, id, table) {
el.blur();
var img = null,
image = $(el).getFirst('img'),
published = (image.get('data-state') == 1),
div = el.getParent('div'),
index, next, icon, icond, pa;
// Backwards compatibility
if (image.get('data-state') === null) {
published = (image.src.indexOf('invisible') == -1);
console.warn('Using a visibility toggle without a "data-state" attribute is deprecated. Please adjust your Contao DCA file.');
}
// Find the icon depending on the view (tree view, list view, parent view)
if (div.hasClass('tl_right')) {
img = div.getPrevious('div').getElement('img');
} else if (div.hasClass('tl_listing_container')) {
img = el.getParent('td').getPrevious('td').getFirst('div.list_icon');
if (img === null) { // comments
img = el.getParent('td').getPrevious('td').getElement('div.cte_type');
}
if (img === null) { // showColumns
img = el.getParent('tr').getFirst('td').getElement('div.list_icon_new');
}
} else if (next = div.getNext('div')) {
if (next.hasClass('cte_type')) {
img = next;
}
if (img === null) { // newsletter recipients
img = next.getFirst('div.list_icon');
}
}
// Change the icon
if (img !== null) {
// Tree view
if (img.nodeName.toLowerCase() == 'img') {
if (img.getParent('ul.tl_listing').hasClass('tl_tree_xtnd')) {
icon = img.get('data-icon');
icond = img.get('data-icon-disabled');
// Backwards compatibility
if (icon === null) {
icon = img.src.replace(/(.*)/([a-z0-9]+)_?.(gif|png|jpe?g|svg)$/, '$1/$2.$3');
console.warn('Using a row icon without a "data-icon" attribute is deprecated. Please adjust your Contao DCA file.');
}
if (icond === null) {
icond = img.src.replace(/(.*)/([a-z0-9]+)_?.(gif|png|jpe?g|svg)$/, '$1/$2_.$3');
console.warn('Using a row icon without a "data-icon-disabled" attribute is deprecated. Please adjust your Contao DCA file.');
}
// Prepend the theme path
if (icon.indexOf('/') == -1) {
icon = AjaxRequest.themePath + icon;
}
if (icond.indexOf('/') == -1) {
icond = AjaxRequest.themePath + icond;
}
img.src = !published ? icon : icond;
} else {
pa = img.getParent('a');
if (pa.href.indexOf('do=feRedirect') == -1) {
if (next = pa.getNext('a')) {
img = next.getFirst('img');
} else {
img = new Element('img'); // no icons used (see #2286)
}
}
icon = img.get('data-icon');
icond = img.get('data-icon-disabled');
// Backwards compatibility
if (icon === null) {
index = img.src.replace(/.*_([0-9]).(gif|png|jpe?g|svg)/, '$1');
icon = img.src.replace(/_[0-9].(gif|png|jpe?g|svg)/, ((index.toInt() == 1) ? '' : '_' + (index.toInt() - 1)) + '.$1').split(/[\/]/).pop();
console.warn('Using a row icon without a "data-icon" attribute is deprecated. Please adjust your Contao DCA file.');
}
if (icond === null) {
index = img.src.replace(/.*_([0-9]).(gif|png|jpe?g|svg)/, '$1');
icond = img.src.replace(/(_[0-9])?.(gif|png|jpe?g|svg)/, ((index == img.src) ? '_1' : '_' + (index.toInt() + 1)) + '.$2').split(/[\/]/).pop();
console.warn('Using a row icon without a "data-icon-disabled" attribute is deprecated. Please adjust your Contao DCA file.');
}
// Prepend the theme path
if (icon.indexOf('/') == -1) {
icon = AjaxRequest.themePath + icon;
}
if (icond.indexOf('/') == -1) {
icond = AjaxRequest.themePath + icond;
}
img.src = !published ? icon : icond;
}
}
// Parent view
else if (img.hasClass('cte_type')) {
if (!published) {
img.addClass('published');
img.removeClass('unpublished');
} else {
img.addClass('unpublished');
img.removeClass('published');
}
}
// List view
else {
icon = img.get('data-icon');
icond = img.get('data-icon-disabled');
// Backwards compatibility
if (icon === null) {
icon = img.getStyle('background-image').replace(/(.*)/([a-z0-9]+)_?.(gif|png|jpe?g|svg));?$/, '$1/$2.$2');
console.warn('Using a row icon without a "data-icon" attribute is deprecated. Please adjust your Contao DCA file.');
}
if (icond === null) {
icond = img.getStyle('background-image').replace(/(.*)/([a-z0-9]+)_?.(gif|png|jpe?g|svg));?$/, '$1/$2_.$3');
console.warn('Using a row icon without a "data-icon-disabled" attribute is deprecated. Please adjust your Contao DCA file.');
}
// Prepend the theme path
if (icon.indexOf('/') == -1) {
icon = AjaxRequest.themePath + icon;
}
if (icond.indexOf('/') == -1) {
icond = AjaxRequest.themePath + icond;
}
img.setStyle('background-image', 'url(' + (!published ? icon : icond) + ')');
}
}
// Mark disabled format definitions
if (table == 'tl_style') {
div.getParent('div').getElement('pre').toggleClass('disabled');
}
// Send request
if (!published) {
image.src = AjaxRequest.themePath + 'visible.gif';
image.set('data-state', 1);
new Request.Contao({'url':window.location.href, 'followRedirects':false}).get({'tid':id, 'state':1, 'rt':Contao.request_token});
} else {
image.src = AjaxRequest.themePath + 'invisible.gif';
image.set('data-state', 0);
new Request.Contao({'url':window.location.href, 'followRedirects':false}).get({'tid':id, 'state':0, 'rt':Contao.request_token});
}
return false;
},
/**
* Feature/unfeature an element
*
* @param {object} el The DOM element
* @param {string} id The ID of the target element
*
* @returns {boolean}
*/
toggleFeatured: function(el, id) {
el.blur();
var image = $(el).getFirst('img'),
featured = (image.get('data-state') == 1);
// Backwards compatibility
if (image.get('data-state') === null) {
featured = (image.src.indexOf('featured_') == -1);
console.warn('Using a featured toggle without a "data-state" attribute is deprecated. Please adjust your Contao DCA file.');
}
// Send the request
if (!featured) {
image.src = AjaxRequest.themePath + 'featured.gif';
image.set('data-state', 1);
new Request.Contao().post({'action':'toggleFeatured', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
} else {
image.src = AjaxRequest.themePath + 'featured_.gif';
image.set('data-state', 0);
new Request.Contao().post({'action':'toggleFeatured', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token});
}
return false;
},
/**
* Toggle the visibility of a fieldset
*
* @param {object} el The DOM element
* @param {string} id The ID of the target element
* @param {string} table The table name
*
* @returns {boolean}
*/
toggleFieldset: function(el, id, table) {
el.blur();
var fs = $('pal_' + id);
if (fs.hasClass('collapsed')) {
fs.removeClass('collapsed');
new Request.Contao().post({'action':'toggleFieldset', 'id':id, 'table':table, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
} else {
fs.addClass('collapsed');
new Request.Contao().post({'action':'toggleFieldset', 'id':id, 'table':table, 'state':0, 'REQUEST_TOKEN':Contao.request_token});
}
return false;
},
/**
* Toggle a group of a multi-checkbox field
*
* @param {object} el The DOM element
* @param {string} id The ID of the target element
*
* @returns {boolean}
*/
toggleCheckboxGroup: function(el, id) {
el.blur();
var item = $(id),
image = $(el).getFirst('img');
if (item) {
if (item.getStyle('display') != 'block') {
item.setStyle('display', 'block');
image.src = AjaxRequest.themePath + 'folMinus.gif';
new Request.Contao().post({'action':'toggleCheckboxGroup', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token});
} else {
item.setStyle('display', 'none');
image.src = AjaxRequest.themePath + 'folPlus.gif';
new Request.Contao().post({'action':'toggleCheckboxGroup', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token});
}
return true;
}
return false;
},
/**
* Store the Live Update ID
*
* @param {object} el The DOM element
* @param {string} id The ID of the input field
*/
liveUpdate: function(el, id) {
var uid = $(id);
if (!uid) return;
new Request.Contao({
onRequest: $('lu_message').set('html', '<p class="tl_info">Connecting to the Live Update server</p>'),
onSuccess: function(txt, json) {
if (txt) {
$('lu_message').set('html', json.content);
} else {
$(el).submit();
}
}
}).post({'action':'liveUpdate', 'id':uid.value, 'REQUEST_TOKEN':Contao.request_token});
},
/**
* Display the "loading data" message
*
* @param {string} message The message text
*/
displayBox: function(message) {
var box = $('tl_ajaxBox'),
overlay = $('tl_ajaxOverlay'),
scroll = window.getScroll();
if (overlay === null) {
overlay = new Element('div', {
'id': 'tl_ajaxOverlay'
}).inject($(document.body), 'bottom');
}
overlay.set({
'styles': {
'display': 'block',
'top': scroll.y + 'px'
}
});
if (box === null) {
box = new Element('div', {
'id': 'tl_ajaxBox'
}).inject($(document.body), 'bottom');
}
box.set({
'html': message,
'styles': {
'display': 'block',
'top': (scroll.y + 100) + 'px'
}
})
},
/**
* Hide the "loading data" message
*/
hideBox: function() {
var box = $('tl_ajaxBox'),
overlay = $('tl_ajaxOverlay');
if (overlay) {
overlay.setStyle('display', 'none');
}
if (box) {
box.setStyle('display', 'none');
}
}
};
/**
* Provide methods to handle back end tasks.
*
* @author Leo Feyer <https://github.com/leofeyer>
*/
var Backend =
{
/**
* The current ID
* @member {(string|null)}
*/
currentId: null,
/**
* The x mouse position
* @member {int}
*/
xMousePosition: 0,
/**
* The Y mouse position
* @member {int}
*/
yMousePosition: 0,
/**
* The popup window
* @member {object}
*/
popupWindow: null,
/**
* The theme path
* @member {string}
*/
themePath: Contao.script_url + 'system/themes/' + Contao.theme + '/images/',
/**
* Get the current mouse position
*
* @param {object} event The event object
*/
getMousePosition: function(event) {
Backend.xMousePosition = event.client.x;
Backend.yMousePosition = event.client.y;
},
/**
* Open a new window
*
* @param {object} el The DOM element
* @param {int} width The width in pixels
* @param {int} height The height in pixels
*
* @deprecated Use Backend.openModalWindow() instead
*/
openWindow: function(el, width, height) {
el.blur();
width = Browser.ie ? (width + 40) : (width + 17);
height = Browser.ie ? (height + 30) : (height + 17);
Backend.popupWindow = window.open(el.href, '', 'width=' + width + ',height=' + height + ',modal=yes,left=100,top=50,location=no,menubar=no,resizable=yes,scrollbars=yes,status=no,toolbar=no');
},
/**
* Open a modal window
*
* @param {int} width The width in pixels
* @param {string} title The window's title
* @param {string} content The window's content
*/
openModalWindow: function(width, title, content) {
new SimpleModal({
'width': width,
'hideFooter': true,
'draggable': false,
'overlayOpacity': .5,
'onShow': function() { document.body.setStyle('overflow', 'hidden'); },
'onHide': function() { document.body.setStyle('overflow', 'auto'); }
}).show({
'title': title,
'contents': content
});
},
/**
* Open an image in a modal window
*
* @param {object} options An optional options object
*/
openModalImage: function(options) {
var opt = options || {};
var M = new SimpleModal({
'width': opt.width,
'hideFooter': true,
'draggable': false,
'overlayOpacity': .5,
'onShow': function() { document.body.setStyle('overflow', 'hidden'); },
'onHide': function() { document.body.setStyle('overflow', 'auto'); }
});
M.show({
'title': opt.title,
'contents': '<img src="' + opt.url + '" alt="">'
});
},
/**
* Open an iframe in a modal window
*
* @param {object} options An optional options object
*/
openModalIframe: function(options) {
var opt = options || {};
var max = (window.getSize().y-180).toInt();
if (!opt.height || opt.height > max) opt.height = max;
var M = new SimpleModal({
'width': opt.width,
'hideFooter': true,
'draggable': false,
'overlayOpacity': .5,
'onShow': function() { document.body.setStyle('overflow', 'hidden'); },
'onHide': function() { document.body.setStyle('overflow', 'auto'); }
});
M.show({
'title': opt.title,
'contents': '<iframe src="' + opt.url + '" width="100%" height="' + opt.height + '" frameborder="0"></iframe>'
});
},
/**
* Open a selector page in a modal window
*
* @param {object} options An optional options object
*/
openModalSelector: function(options) {
var opt = options || {},
max = (window.getSize().y-180).toInt();
if (!opt.height || opt.height > max) opt.height = max;
var M = new SimpleModal({
'width': opt.width,
'btn_ok': Contao.lang.close,
'draggable': false,
'overlayOpacity': .5,
'onShow': function() { document.body.setStyle('overflow', 'hidden'); },
'onHide': function() { document.body.setStyle('overflow', 'auto'); }
});
M.addButton(Contao.lang.close, 'btn', function() {
this.hide();
});
M.addButton(Contao.lang.apply, 'btn primary', function() {
var frm = window.frames['simple-modal-iframe'],
val = [], inp, field, i;
if (frm === undefined) {
alert('Could not find the SimpleModal frame');
return;
}
if (frm.document.location.href.indexOf('contao/main.php') != -1) {
alert(Contao.lang.picker);
return; // see #5704
}
inp = frm.document.getElementById('tl_select').getElementsByTagName('input');
for (i=0; i<inp.length; i++) {
if (!inp[i].checked || inp[i].id.match(/^check_all_/)) continue;
if (!inp[i].id.match(/^reset_/)) val.push(inp[i].get('value'));
}
if (opt.tag) {
$(opt.tag).value = val.join(',');
if (frm.document.location.href.indexOf('contao/page.php') != -1) {
$(opt.tag).value = '{{link_url::' + $(opt.tag).value + '}}';
}
opt.self.set('href', opt.self.get('href').replace(/&value=[^&]*/, '&value=' + val.join(',')));
} else {
field = $('ctrl_' + opt.id);
field.value = val.join("t");
var act = (frm.document.location.href.indexOf('contao/page.php') != -1) ? 'reloadPagetree' : 'reloadFiletree';
new Request.Contao({
field: field,
evalScripts: false,
onRequest: AjaxRequest.displayBox(Contao.lang.loading + ' …'),
onSuccess: function(txt, json) {
$('ctrl_' + opt.id).getParent('div').set('html', json.content);
json.javascript && Browser.exec(json.javascript);
AjaxRequest.hideBox();
window.fireEvent('ajax_change');
}
}).post({'action':act, 'name':opt.id, 'value':field.value, 'REQUEST_TOKEN':Contao.request_token});
}
this.hide();
});
M.show({
'title': opt.title,
'contents': '<iframe src="' + opt.url + '" name="simple-modal-iframe" width="100%" height="' + opt.height + '" frameborder="0"></iframe>',
'model': 'modal'
});
},
/**
* Open a TinyMCE file browser in a modal window
*
* @param {string} field_name The field name
* @param {object} url An URI object
* @param {string} type The picker type
* @param {object} win The window object
*/
openModalBrowser: function(field_name, url, type, win) {
var file = 'file.php',
swtch = (type == 'file' ? '&switch=1' : ''),
isLink = (url.indexOf('{{link_url::') != -1);
if (type == 'file' && (url == '' || isLink)) {
file = 'page.php';
}
if (isLink) {
url = url.replace(/^{{link_url::([0-9]+)}}$/, '$1');
}
var M = new SimpleModal({
'width': 768,
'btn_ok': Contao.lang.close,
'draggable': false,
'overlayOpacity': .5,
'onShow': function() { document.body.setStyle('overflow', 'hidden'); },
'onHide': function() { document.body.setStyle('overflow', 'auto'); }
});
M.addButton(Contao.lang.close, 'btn', function() {
this.hide();
});
M.addButton(Contao.lang.apply, 'btn primary', function() {
var frm = window.frames['simple-modal-iframe'],
val, inp, i;
if (frm === undefined) {
alert('Could not find the SimpleModal frame');
return;
}
inp = frm.document.getElementById('tl_select').getElementsByTagName('input');
for (i=0; i<inp.length; i++) {
if (inp[i].checked && !inp[i].id.match(/^reset_/)) {
val = inp[i].get('value');
break;
}
}
if (!isNaN(val)) {
val = '{{link_url::' + val + '}}';
}
win.document.getElementById(field_name).value = val;
this.hide();
});
M.show({
'title': win.document.getElement('div.mce-title').get('text'),
'contents': '<iframe src="contao/' + file + '?table=tl_content&field=singleSRC&value=' + encodeURIComponent(url) + swtch + '" name="simple-modal-iframe" width="100%" height="' + (window.getSize().y-180).toInt() + '" frameborder="0"></iframe>',
'model': 'modal'
});
},
/**
* Get the current scroll offset and store it in a cookie
*/
getScrollOffset: function() {
document.cookie = "BE_PAGE_OFFSET=" + window.getScroll().y + "; path=" + (Contao.path || '/');
},
/**
* Automatically submit a form
*
* @param {object} el The DOM element
*/
autoSubmit: function(el) {
Backend.getScrollOffset();
var hidden = new Element('input', {
'type': 'hidden',
'name': 'SUBMIT_TYPE',
'value': 'auto'
});
var form = $(el) || el;
hidden.inject(form, 'bottom');
form.submit();
},
/**
* Scroll the window to a certain vertical position
*
* @param {int} offset The offset to scroll to
*/
vScrollTo: function(offset) {
window.addEvent('load', function() {
window.scrollTo(null, parseInt(offset));
});
},
/**
* Limit the height of the preview pane
*/
limitPreviewHeight: function() {
var hgt = 0;
$$('div.limit_height').each(function(div) {
var toggler, size, style;
if (hgt === 0) {
hgt = div.className.replace(/[^0-9]*/, '').toInt();
}
// Return if there is no height value
if (!hgt) return;
toggler = new Element('img', {
'class': 'limit_toggler',
'alt': '',
'title': Contao.lang.expand,
'width': 20,
'height': 24,
'data-state': 0
});
size = div.getCoordinates();
new Tips.Contao(toggler, {
offset: {x:0, y:30}
});
div.setStyle('height', hgt);
// Disable the function if the preview height is below the max-height
if (size.height <= hgt) {
toggler.src = Backend.themePath + 'expand_.gif';
toggler.inject(div, 'after');
return;
}
toggler.src = Backend.themePath + 'expand.gif';
toggler.setStyle('cursor', 'pointer');
toggler.addEvent('click', function() {
style = this.getPrevious('div').getStyle('height').toInt();
toggler.getPrevious('div').setStyle('height', ((style > hgt) ? hgt : ''));
if (toggler.get('data-state') == 0) {
toggler.src = Backend.themePath + 'collapse.gif';
toggler.set('data-state', 1);
toggler.store('tip:title', Contao.lang.collapse);
} else {
toggler.src = Backend.themePath + 'expand.gif';
toggler.set('data-state', 0);
toggler.store('tip:title', Contao.lang.expand);
}
});
toggler.inject(div, 'after');
});
},
/**
* Toggle checkboxes
*
* @param {object} el The DOM element
* @param {string} [id] The ID of the target element
*/
toggleCheckboxes: function(el, id) {
var items = $$('input'),
status = $(el).checked ? 'checked' : '';
for (var i=0; i<items.length; i++) {
if (items[i].type.toLowerCase() != 'checkbox') {
continue;
}
if (id && items[i].id.substr(0, id.length) != id) {
continue;
}
items[i].checked = status;
}
},
/**
* Toggle a checkbox group
*
* @param {object} el The DOM element
* @param {string} id The ID of the target element
*/
toggleCheckboxGroup: function(el, id) {
var cls = $(el).className,
status = $(el).checked ? 'checked' : '';
if (cls == 'tl_checkbox') {
var cbx = $(id) ? $$('#' + id + ' .tl_checkbox') : $(el).getParent('fieldset').getElements('.tl_checkbox');
cbx.each(function(checkbox) {
checkbox.checked = status;
});
} else if (cls == 'tl_tree_checkbox') {
$$('#' + id + ' .parent .tl_tree_checkbox').each(function(checkbox) {
checkbox.checked = status;
});
}
Backend.getScrollOffset();
},
/**
* Toggle checkbox elements
*
* @param {string} el The DOM element
* @param {string} cls The CSS class name
*/
toggleCheckboxElements: function(el, cls) {
var status = $(el).checked ? 'checked' : '';
$$('.' + cls).each(function(checkbox) {
if (checkbox.hasClass('tl_checkbox')) {
checkbox.checked = status;
}
});
Backend.getScrollOffset();
},
/**
* Toggle the line wrapping mode of a textarea
*
* @param {string} id The ID of the target element
*/
toggleWrap: function(id) {
var textarea = $(id),
status = (textarea.getProperty('wrap') == 'off') ? 'soft' : 'off';
textarea.setProperty('wrap', status);
},
/**
* Toggle the synchronization results
*/
toggleUnchanged: function() {
$$('#result-list .tl_confirm').each(function(el) {
el.toggleClass('hidden');
});
},
/**
* Toggle the opacity of the paste buttons
*
* @deprecated Not required anymore
*/
blink: function() {},
/**
* Initialize the mootools color picker
*
* @returns {boolean}
*
* @deprecated Not required anymore
*/
addColorPicker: function() {
return true;
},
/**
* Open the page picker wizard in a modal window
*
* @param {string} id The ID of the target element
*
* @deprecated Use Backend.openModalIframe() instead
*/
pickPage: function(id) {
var width = 320,
height = 112;
Backend.currentId = id;
Backend.ppValue = $(id).value;
Backend.getScrollOffset();
window.open($$('base')[0].href + 'contao/page.php?value=' + Backend.ppValue, '', 'width=' + width + ',height=' + height + ',modal=yes,left=' + (Backend.xMousePosition ? (Backend.xMousePosition-(width/2)) : 200) + ',top=' + (Backend.yMousePosition ? (Backend.yMousePosition-(height/2)+80) : 100) + ',location=no,menubar=no,resizable=yes,scrollbars=no,status=no,toolbar=no');
},
/**
* Open the file picker wizard in a modal window
*
* @param {string} id The ID of the target element
* @param {string} filter The filter value
*
* @deprecated Use Backend.openModalIframe() instead
*/
pickFile: function(id, filter) {
var width = 320,
height = 112;
Backend.currentId = id;
Backend.ppValue = $(id).value;
Backend.getScrollOffset();
window.open($$('base')[0].href + 'contao/file.php?value=' + Backend.ppValue + '&filter=' + filter, '', 'width=' + width + ',height=' + height + ',modal=yes,left=' + (Backend.xMousePosition ? (Backend.xMousePosition-(width/2)) : 200) + ',top=' + (Backend.yMousePosition ? (Backend.yMousePosition-(height/2)+80) : 100) + ',location=no,menubar=no,resizable=yes,scrollbars=no,status=no,toolbar=no');
},
/**
* Collapse all palettes
*/
collapsePalettes: function() {
$$('fieldset.hide').each(function(el) {
el.addClass('collapsed');
});
$$('label.error, label.mandatory').each(function(el) {
var fs = el.getParent('fieldset');
fs && fs.removeClass('collapsed');
});
},
/**
* Add the interactive help
*/
addInteractiveHelp: function() {
new Tips.Contao('p.tl_tip', {
offset: {x:9, y:21},
text: function(e) {
return e.get('html');
}
});
// Links and input elements
['a[title]', 'input[title]'].each(function(el) {
new Tips.Contao($$(el).filter(function(i) {
return i.title != '';
}), {
offset: {x:0, y:26}
});
});
// Images
$$('img[title]').filter(function(i) {
return i.title != '';
}).each(function(el) {
new Tips.Contao(el, {
offset: {x:0, y:((el.get('class') == 'gimage') ? 60 : 30)}
});
});
},
/**
* Make parent view items sortable
*
* @param {object} ul The DOM element
*
* @author Joe Ray Gregory
* @author Martin Auswöger
*/
makeParentViewSortable: function(ul) {
var ds = new Scroller(document.getElement('body'), {
onChange: function(x, y) {
this.element.scrollTo(this.element.getScroll().x, y);
}
});
var list = new Sortables(ul, {
constrain: true,
opacity: 0.6,
onStart: function() {
ds.start();
},
onComplete: function() {
ds.stop();
},
onSort: function(el) {
var ul = el.getParent('ul'),
wrapLevel = 0;
if (!ul) return;
ul.getChildren('li').each(function(el) {
var div = el.getFirst('div');
if (!div) return;
if (div.hasClass('wrapper_stop') && wrapLevel > 0) {
wrapLevel--;
}
div.className = div.className.replace(/(^|s)indent[^s]*/g, '');
if (wrapLevel > 0) {
div.addClass('indent').addClass('indent_' + wrapLevel);
}
if (div.hasClass('wrapper_start')) {
wrapLevel++;
}
});
},
handle: '.drag-handle'
});
list.active = false;
list.addEvent('start', function() {
list.active = true;
});
list.addEvent('complete', function(el) {
if (!list.active) return;
var id, pid, req, href;
if (el.getPrevious('li')) {
id = el.get('id').replace(/li_/, '');
pid = el.getPrevious('li').get('id').replace(/li_/, '');
req = window.location.search.replace(/id=[0-9]*/, 'id=' + id) + '&act=cut&mode=1&pid=' + pid;
href = window.location.href.replace(/?.*$/, '');
new Request.Contao({'url':href+req, 'followRedirects':false}).get();
} else if (el.getParent('ul')) {
id = el.get('id').replace(/li_/, '');
pid = el.getParent('ul').get('id').replace(/ul_/, '');
req = window.location.search.replace(/id=[0-9]*/, 'id=' + id) + '&act=cut&mode=2&pid=' + pid;
href = window.location.href.replace(/?.*$/, '');
new Request.Contao({'url':href+req, 'followRedirects':false}).get();
}
});
},
/**
* Make multiSRC items sortable
*
* @param {string} id The ID of the target element
* @param {string} oid The DOM element
*/
makeMultiSrcSortable: function(id, oid) {
var list = new Sortables($(id), {
constrain: true,
opacity: 0.6
}).addEvent('complete', function() {
var els = [],
lis = $(id).getChildren('li'),
i;
for (i=0; i<lis.length; i++) {
els.push(lis[i].get('data-id'));
}
$(oid).value = els.join(',');
});
list.fireEvent('complete'); // Initial sorting
},
/**
* Make the wizards sortable
*/
makeWizardsSortable: function() {
$$('.tl_listwizard').each(function(el) {
new Sortables(el, {
constrain: true,
opacity: 0.6,
handle: '.drag-handle'
});
});
$$('.tl_tablewizard').each(function(el) {
var els = el.getElement('.sortable');
new Sortables(els, {
constrain: true,
opacity: 0.6,
handle: '.drag-handle',
onComplete: function() {
Backend.tableWizardResort(els);
}
});
});
$$('.tl_modulewizard').each(function(el) {
new Sortables(el.getElement('.sortable'), {
constrain: true,
opacity: 0.6,
handle: '.drag-handle'
});
});
$$('.tl_optionwizard').each(function(el) {
new Sortables(el.getElement('.sortable'), {
constrain: true,
opacity: 0.6,
handle: '.drag-handle'
});
});
$$('.tl_checkbox_wizard').each(function(el) {
var els = el.getElement('.sortable');
if (els.hasClass('sortable-done')) return;
new Sortables(els, {
constrain: true,
opacity: 0.6,
handle: '.drag-handle'
});
els.addClass('sortable-done');
});
},
/**
* List wizard
*
* @param {object} el The DOM element
* @param {string} command The command name
* @param {string} id The ID of the target element
*/
listWizard: function(el, command, id) {
var list = $(id),
parent = $(el).getParent('li'),
items = list.getChildren(),
tabindex = list.get('data-tabindex'),
input, previous, next, rows, i;
Backend.getScrollOffset();
switch (command) {
case 'copy':
var clone = parent.clone(true).inject(parent, 'before');
if (input = parent.getFirst('input')) {
clone.getFirst('input').value = input.value;
}
break;
case 'up':
if (previous = parent.getPrevious('li')) {
parent.inject(previous, 'before');
} else {
parent.inject(list, 'bottom');
}
break;
case 'down':
if (next = parent.getNext('li')) {
parent.inject(next, 'after');
} else {
parent.inject(list.getFirst('li'), 'before');
}
break;
case 'delete':
if (items.length > 1) {
parent.destroy();
} else {
parent.getFirst('input').set('value', '');
}
break;
}
rows = list.getChildren();
for (i=0; i<rows.length; i++) {
if (input = rows[i].getFirst('input[type="text"]')) {
input.set('tabindex', tabindex++);
}
}
new Sortables(list, {
constrain: true,
opacity: 0.6,
handle: '.drag-handle'
});
},
/**
* Table wizard
*
* @param {object} el The DOM element
* @param {string} command The command name
* @param {string} id The ID of the target element
*/
tableWizard: function(el, command, id) {
var table = $(id),
tbody = table.getElement('tbody'),
rows = tbody.getChildren(),
parentTd = $(el).getParent('td'),
parentTr = parentTd.getParent('tr'),
headTr = table.getElement('thead').getFirst('tr'),
cols = parentTr.getChildren(),
index = 0,
textarea, previous, next, current, i;
for (i=0; i<cols.length; i++) {
if (cols[i] == parentTd) {
break;
}
index++;
}
Backend.getScrollOffset();
switch (command) {
case 'rcopy':
var tr = new Element('tr');
for (i=0; i<cols.length; i++) {
next = cols[i].clone(true).inject(tr, 'bottom');
if (textarea = cols[i].getFirst('textarea')) {
next.getFirst('textarea').value = textarea.value;
}
}
tr.inject(parentTr, 'after');
break;
case 'rup':
if (previous = parentTr.getPrevious('tr')) {
parentTr.inject(previous, 'before');
} else {
parentTr.inject(tbody, 'bottom')
}
break;
case 'rdown':
if (next = parentTr.getNext('tr')) {
parentTr.inject(next, 'after');
} else {
parentTr.inject(tbody, 'top');
}
break;
case 'rdelete':
if (rows.length > 1) {
parentTr.destroy();
} else {
parentTr.getElements('textarea').set('text', '');
}
break;
case 'ccopy':
for (i=0; i<rows.length; i++) {
current = rows[i].getChildren()[index];
next = current.clone(true).inject(current, 'after');
if (textarea = current.getFirst('textarea')) {
next.getFirst('textarea').value = textarea.value;
}
}
headTr.getFirst('td').clone(true).inject(headTr.getLast('td'), 'before');
break;
case 'cmovel':
if (index > 0) {
for (i=0; i<rows.length; i++) {
current = rows[i].getChildren()[index];
current.inject(current.getPrevious(), 'before');
}
} else {
for (i=0; i<rows.length; i++) {
current = rows[i].getChildren()[index];
current.inject(rows[i].getLast(), 'before');
}
}
break;
case 'cmover':
if (index < (cols.length - 2)) {
for (i=0; i<rows.length; i++) {
current = rows[i].getChildren()[index];
current.inject(current.getNext(), 'after');
}
} else {
for (i=0; i<rows.length; i++) {
current = rows[i].getChildren()[index];
current.inject(rows[i].getFirst(), 'before');
}
}
break;
case 'cdelete':
if (cols.length > 2) {
for (i=0; i<rows.length; i++) {
rows[i].getChildren()[index].destroy();
}
headTr.getFirst('td').destroy();
} else {
for (i=0; i<rows.length; i++) {
rows[i].getElements('textarea').set('text', '');
}
}
break;
}
Backend.tableWizardResort(tbody);
new Sortables(tbody, {
constrain: true,
opacity: 0.6,
handle: '.drag-handle',
onComplete: function() {
Backend.tableWizardResort(tbody);
}
});
Backend.tableWizardResize();
},
/**
* Resort the table wizard fields
*
* @param {object} tbody The DOM element
*/
tableWizardResort: function(tbody) {
var rows = tbody.getChildren(),
tabindex = tbody.get('data-tabindex'),
textarea, childs, i, j;
for (i=0; i<rows.length; i++) {
childs = rows[i].getChildren();
for (j=0; j<childs.length; j++) {
if (textarea = childs[j].getFirst('textarea')) {
textarea.set('tabindex', tabindex++);
textarea.name = textarea.name.replace(/[[0-9]+][[0-9]+]/g, '[' + i + '][' + j + ']')
}
}
}
},
/**
* Resize the table wizard fields on focus
*
* @param {float} [factor] The resize factor
*/
tableWizardResize: function(factor) {
var size = Cookie.read('BE_CELL_SIZE');
if (size === null && factor === null) return;
if (factor !== null) {
size = '';
$$('.tl_tablewizard textarea').each(function(el) {
el.setStyle('width', (el.getStyle('width').toInt() * factor).round().limit(142, 284));
el.setStyle('height', (el.getStyle('height').toInt() * factor).round().limit(66, 132));
if (size == '') {
size = el.getStyle('width') + '|' + el.getStyle('height');
}
});
Cookie.write('BE_CELL_SIZE', size, { path: Contao.path });
} else if (size !== null) {
var chunks = size.split('|');
$$('.tl_tablewizard textarea').each(function(el) {
el.setStyle('width', chunks[0]);
el.setStyle('height', chunks[1]);
});
}
},
/**
* Module wizard
*
* @param {object} el The DOM element
* @param {string} command The command name
* @param {string} id The ID of the target element
*/
moduleWizard: function(el, command, id) {
var table = $(id),
tbody = table.getElement('tbody'),
parent = $(el).getParent('tr'),
rows = tbody.getChildren(),
tabindex = tbody.get('data-tabindex'),
input, select, childs, a, i, j;
Backend.getScrollOffset();
switch (command) {
case 'copy':
var tr = new Element('tr');
childs = parent.getChildren();
for (i=0; i<childs.length; i++) {
var next = childs[i].clone(true).inject(tr, 'bottom');
if (select = childs[i].getFirst('select')) {
next.getFirst('select').value = select.value;
}
}
tr.inject(parent, 'after');
tr.getElement('.chzn-container').destroy();
tr.getElement('.tl_select_column').destroy();
new Chosen(tr.getElement('select.tl_select'));
Stylect.convertSelects();
Backend.convertEnableModules();
break;
case 'up':
if (tr = parent.getPrevious('tr')) {
parent.inject(tr, 'before');
} else {
parent.inject(tbody, 'bottom');
}
break;
case 'down':
if (tr = parent.getNext('tr')) {
parent.inject(tr, 'after');
} else {
parent.inject(tbody, 'top');
}
break;
case 'delete':
if (rows.length > 1) {
parent.destroy();
}
break;
}
rows = tbody.getChildren();
for (i=0; i<rows.length; i++) {
childs = rows[i].getChildren();
for (j=0; j<childs.length; j++) {
if (a = childs[j].getFirst('a.chzn-single')) {
a.set('tabindex', tabindex++);
}
if (select = childs[j].getFirst('select')) {
select.name = select.name.replace(/[[0-9]+]/g, '[' + i + ']');
}
if (input = childs[j].getFirst('input[type="checkbox"]')) {
input.set('tabindex', tabindex++);
input.name = input.name.replace(/[[0-9]+]/g, '[' + i + ']');
}
}
}
new Sortables(tbody, {
constrain: true,
opacity: 0.6,
handle: '.drag-handle'
});
},
/**
* Options wizard
*
* @param {object} el The DOM element
* @param {string} command The command name
* @param {string} id The ID of the target element
*/
optionsWizard: function(el, command, id) {
var table = $(id),
tbody = table.getElement('tbody'),
parent = $(el).getParent('tr'),
rows = tbody.getChildren(),
tabindex = tbody.get('data-tabindex'),
input, childs, i, j;
Backend.getScrollOffset();
switch (command) {
case 'copy':
var tr = new Element('tr');
childs = parent.getChildren();
for (i=0; i<childs.length; i++) {
var next = childs[i].clone(true).inject(tr, 'bottom');
if (input = childs[i].getFirst('input')) {
next.getFirst('input').value = input.value;
if (input.type == 'checkbox') {
next.getFirst('input').checked = input.checked ? 'checked' : '';
}
}
}
tr.inject(parent, 'after');
break;
case 'up':
if (tr = parent.getPrevious('tr')) {
parent.inject(tr, 'before');
} else {
parent.inject(tbody, 'bottom');
}
break;
case 'down':
if (tr = parent.getNext('tr')) {
parent.inject(tr, 'after');
} else {
parent.inject(tbody, 'top');
}
break;
case 'delete':
if (rows.length > 1) {
parent.destroy();
}
break;
}
rows = tbody.getChildren();
for (i=0; i<rows.length; i++) {
childs = rows[i].getChildren();
for (j=0; j<childs.length; j++) {
if (input = childs[j].getFirst('input')) {
input.set('tabindex', tabindex++);
input.name = input.name.replace(/[[0-9]+]/g, '[' + i + ']');
if (input.type == 'checkbox') {
input.id = input.name.replace(/[[0-9]+]/g, '').replace(/[/g, '_').replace(/]/g, '') + '_' + i;
input.getNext('label').set('for', input.id);
}
}
}
}
new Sortables(tbody, {
constrain: true,
opacity: 0.6,
handle: '.drag-handle'
});
},
/**
* Key/value wizard
*
* @param {object} el The DOM element
* @param {string} command The command name
* @param {string} id The ID of the target element
*/
keyValueWizard: function(el, command, id) {
var table = $(id),
tbody = table.getElement('tbody'),
parent = $(el).getParent('tr'),
rows = tbody.getChildren(),
tabindex = tbody.get('data-tabindex'),
input, childs, i, j;
Backend.getScrollOffset();
switch (command) {
case 'copy':
var tr = new Element('tr');
childs = parent.getChildren();
for (i=0; i<childs.length; i++) {
var next = childs[i].clone(true).inject(tr, 'bottom');
if (input = childs[i].getFirst('input')) {
next.getFirst().value = input.value;
}
}
tr.inject(parent, 'after');
break;
case 'up':
if (tr = parent.getPrevious('tr')) {
parent.inject(tr, 'before');
} else {
parent.inject(tbody, 'bottom');
}
break;
case 'down':
if (tr = parent.getNext('tr')) {
parent.inject(tr, 'after');
} else {
parent.inject(tbody, 'top');
}
break;
case 'delete':
if (rows.length > 1) {
parent.destroy();
}
break;
}
rows = tbody.getChildren();
for (i=0; i<rows.length; i++) {
childs = rows[i].getChildren();
for (j=0; j<childs.length; j++) {
if (input = childs[j].getFirst('input')) {
input.set('tabindex', tabindex++);
input.name = input.name.replace(/[[0-9]+]/g, '[' + i + ']')
}
}
}
new Sortables(tbody, {
constrain: true,
opacity: 0.6,
handle: '.drag-handle'
});
},
/**
* Checkbox wizard
*
* @param {object} el The DOM element
* @param {string} command The command name
* @param {string} id The ID of the target element
*/
checkboxWizard: function(el, command, id) {
var container = $(id).getElement('.sortable'),
parent = $(el).getParent('span'), span;
Backend.getScrollOffset();
switch (command) {
case 'up':
if ((span = parent.getPrevious('span'))) {
parent.inject(span, 'before');
} else {
parent.inject(container, 'bottom');
}
break;
case 'down':
if (span = parent.getNext('span')) {
parent.inject(span, 'after');
} else {
parent.inject(container, 'top');
}
break;
}
},
/**
* Meta wizard
*
* @param {object} el The select element
* @param {string} ul The DOM element
*/
metaWizard: function(el, ul) {
var opt = el.getParent('div').getElement('select');
if (opt.value == '') {
return; // No language given
}
var li = $(ul).getLast('li').clone(),
span = li.getElement('span'),
img = span.getElement('img');
// Update the data-language attribute
li.setProperty('data-language', opt.value);
// Update the language text
span.set('text', opt.options[opt.selectedIndex].text + ' ');
img.inject(span, 'bottom');
// Update the name, label and ID attributes
li.getElements('input').each(function(inp) {
inp.value = '';
inp.name = inp.name.replace(/[[a-z]{2}(_[A-Z]{2})?]/, '[' + opt.value + ']');
var lbl = inp.getPrevious('label'),
i = parseInt(lbl.get('for').replace(/ctrl_[^_]+_/, ''));
lbl.set('for', lbl.get('for').replace(i, i+1));
inp.id = lbl.get('for');
});
// Update the class name
li.className = (li.className == 'even') ? 'odd' : 'even';
li.inject($(ul), 'bottom');
// Disable the "add language" button
el.getParent('div').getElement('input[type="button"]').setProperty('disabled', true);
// Disable the option and update chosen
opt.options[opt.selectedIndex].setProperty('disabled', true);
opt.value = '';
opt.fireEvent('liszt:updated');
},
/**
* Remove a meta entry
*
* @param {object} el The DOM element
*/
metaDelete: function(el) {
var li = el.getParent('li'),
opt = el.getParent('div').getElement('select');
// Empty the last element instead of removing it (see #4858)
if (li.getPrevious() === null && li.getNext() === null) {
li.getElements('input').each(function(input) {
input.value = '';
});
} else {
// Enable the option and update chosen
opt.getElement('option[value=' + li.getProperty('data-language') + ']').removeProperty('disabled');
li.destroy();
opt.fireEvent('liszt:updated');
}
},
/**
* Toggle the "add language" button
*
* @param {object} el The DOM element
*/
toggleAddLanguageButton: function(el) {
var inp = el.getParent('div').getElement('input[type="button"]');
if (el.value != '') {
inp.removeProperty('disabled');
} else {
inp.setProperty('disabled', true);
}
},
/**
* Update the "edit module" links in the module wizard
*
* @param {object} el The DOM element
*/
updateModuleLink: function(el) {
var td = el.getParent('tr').getLast('td'),
a = td.getElement('a.module_link');
a.href = a.href.replace(/id=[0-9]+/, 'id=' + el.value);
if (el.value > 0) {
td.getElement('a.module_link').setStyle('display', 'inline');
td.getElement('img.module_image').setStyle('display', 'none');
} else {
td.getElement('a.module_link').setStyle('display', 'none');
td.getElement('img.module_image').setStyle('display', 'inline');
}
},
/**
* Convert the "enable module" checkboxes
*/
convertEnableModules: function() {
$$('img.mw_enable').filter(function(el) {
return !el.hasEvent('click');
}).each(function(el) {
el.addEvent('click', function() {
Backend.getScrollOffset();
var cbx = el.getNext('input');
if (cbx.checked) {
cbx.checked = '';
el.src = Backend.themePath + 'invisible.gif';
} else {
cbx.checked = 'checked';
el.src = Backend.themePath + 'visible.gif';
}
});
});
},
/**
* Update the fields of the imageSize widget upon change
*/
enableImageSizeWidgets: function() {
$$('.tl_image_size').each(function(el) {
var select = el.getElement('select'),
widthInput = el.getChildren('input')[0],
heightInput = el.getChildren('input')[1],
update = function() {
if (select.get('value') === '' || select.get('value').toInt().toString() === select.get('value')) {
widthInput.readOnly = true;
heightInput.readOnly = true;
var dimensions = $(select.getSelected()[0]).get('text');
dimensions = dimensions.split('(').length > 1
? dimensions.split('(').getLast().split(')')[0].split('x')
: ['', ''];
widthInput.set('value', '').set('placeholder', dimensions[0] * 1 || '');
heightInput.set('value', '').set('placeholder', dimensions[1] * 1 || '');
}
else {
widthInput.set('placeholder', '');
heightInput.set('placeholder', '');
widthInput.readOnly = false;
heightInput.readOnly = false;
}
}
;
update();
select.addEvent('change', update);
select.addEvent('keyup', update);
});
},
/**
* Allow to toggle checkboxes or radio buttons by clicking a row
*
* @author Kamil Kuzminski
*/
enableToggleSelect: function() {
var container = $('tl_select'),
checkboxes = [], start, thisIndex, startIndex, status, from, to,
shiftToggle = function(el) {
thisIndex = checkboxes.indexOf(el);
startIndex = checkboxes.indexOf(start);
from = Math.min(thisIndex, startIndex);
to = Math.max(thisIndex, startIndex);
status = checkboxes[startIndex].checked ? true : false;
for (from; from<=to; from++) {
checkboxes[from].checked = status;
}
};
if (container) {
checkboxes = container.getElements('input[type="checkbox"]');
}
// Row click
$$('.toggle_select').each(function(el) {
el.addEvent('click', function(e) {
var input = $(el).getElement('input[type="checkbox"],input[type="radio"]');
if (!input) {
return;
}
// Radio buttons
if (input.type == 'radio') {
if (!input.checked) {
input.checked = 'checked';
}
return;
}
// Checkboxes
if (e.shift && start) {
shiftToggle(input);
} else {
input.checked = input.checked ? '' : 'checked';
if (input.get('onclick') == 'Backend.toggleCheckboxes(this)') {
Backend.toggleCheckboxes(input); // see #6399
}
}
start = input;
});
});
// Checkbox click
checkboxes.each(function(el) {
el.addEvent('click', function(e) {
if (e.shift && start) {
shiftToggle(this);
}
start = this;
});
});
},
/**
* Allow to mark the important part of an image
*
* @param {object} el The DOM element
*/
editPreviewWizard: function(el) {
el = $(el);
var imageElement = el.getElement('img'),
inputElements = {},
isDrawing = false,
originalWidth = el.get('data-original-width'),
originalHeight = el.get('data-original-height'),
partElement, startPos,
getScale = function() {
return imageElement.getComputedSize().width / originalWidth;
},
updateImage = function() {
var scale = getScale(),
imageSize = imageElement.getComputedSize();
partElement.setStyles({
top: imageSize.computedTop + (inputElements.y.get('value') * scale).round() + 'px',
left: imageSize.computedLeft + (inputElements.x.get('value') * scale).round() + 'px',
width: (inputElements.width.get('value') * scale).round() + 'px',
height: (inputElements.height.get('value') * scale).round() + 'px'
});
if (!inputElements.width.get('value').toInt() || !inputElements.height.get('value').toInt()) {
partElement.setStyle('display', 'none');
} else {
partElement.setStyle('display', '');
}
},
updateValues = function() {
var scale = getScale(),
styles = partElement.getStyles('top', 'left', 'width', 'height'),
imageSize = imageElement.getComputedSize(),
values = {
x: Math.max(0, Math.min(originalWidth, (styles.left.toFloat() - imageSize.computedLeft) / scale)).round(),
y: Math.max(0, Math.min(originalHeight, (styles.top.toFloat() - imageSize.computedTop) / scale)).round()
};
values.width = Math.min(originalWidth - values.x, styles.width.toFloat() / scale).round();
values.height = Math.min(originalHeight - values.y, styles.height.toFloat() / scale).round();
if (!values.width || !values.height) {
values.x = values.y = values.width = values.height = '';
partElement.setStyle('display', 'none');
} else {
partElement.setStyle('display', '');
}
Object.each(values, function(value, key) {
inputElements[key].set('value', value);
});
},
start = function(event) {
event.preventDefault();
if (isDrawing) {
return;
}
isDrawing = true;
startPos = {
x: event.page.x - el.getPosition().x - imageElement.getComputedSize().computedLeft,
y: event.page.y - el.getPosition().y - imageElement.getComputedSize().computedTop
};
move(event);
},
move = function(event) {
if (!isDrawing) {
return;
}
event.preventDefault();
var imageSize = imageElement.getComputedSize();
var rect = {
x: [
Math.max(0, Math.min(imageSize.width, startPos.x)),
Math.max(0, Math.min(imageSize.width, event.page.x - el.getPosition().x - imageSize.computedLeft))
],
y: [
Math.max(0, Math.min(imageSize.height, startPos.y)),
Math.max(0, Math.min(imageSize.height, event.page.y - el.getPosition().y - imageSize.computedTop))
]
};
partElement.setStyles({
top: Math.min(rect.y[0], rect.y[1]) + imageSize.computedTop + 'px',
left: Math.min(rect.x[0], rect.x[1]) + imageSize.computedLeft + 'px',
width: Math.abs(rect.x[0] - rect.x[1]) + 'px',
height: Math.abs(rect.y[0] - rect.y[1]) + 'px'
});
updateValues();
},
stop = function(event) {
move(event);
isDrawing = false;
},
init = function() {
el.getParent().getElements('input[name^="importantPart"]').each(function(input) {
['x', 'y', 'width', 'height'].each(function(key) {
if (input.get('name').substr(13, key.length) === key.capitalize()) {
inputElements[key] = input = $(input);
}
});
});
if (Object.getLength(inputElements) !== 4) {
return;
}
Object.each(inputElements, function(input) {
input.getParent().setStyle('display', 'none');
});
el.addClass('tl_edit_preview_enabled');
partElement = new Element('div', {
'class': 'tl_edit_preview_important_part'
}).inject(el);
updateImage();
imageElement.addEvent('load', updateImage);
el.addEvents({
mousedown: start,
touchstart: start
});
$(document.documentElement).addEvents({
mousemove: move,
touchmove: move,
mouseup: stop,
touchend: stop,
touchcancel: stop,
resize: updateImage
});
}
;
window.addEvent('domready', init);
}
};
// Track the mousedown event
document.addEvent('mousedown', function(event) {
Backend.getMousePosition(event);
});
// Initialize the back end script
window.addEvent('domready', function() {
$(document.body).addClass('js');
// Mark touch devices (see #5563)
if (Browser.Features.Touch) {
$(document.body).addClass('touch');
}
Backend.collapsePalettes();
Backend.addInteractiveHelp();
Backend.convertEnableModules();
Backend.makeWizardsSortable();
Backend.enableImageSizeWidgets();
Backend.enableToggleSelect();
// Chosen
if (Elements.chosen != undefined) {
$$('select.tl_chosen').chosen();
}
// Remove line wraps from textareas
$$('textarea.monospace').each(function(el) {
Backend.toggleWrap(el);
});
});
// Limit the height of the preview fields
window.addEvent('load', function() {
Backend.limitPreviewHeight();
});
// Re-apply certain changes upon ajax_change
window.addEvent('ajax_change', function() {
Backend.addInteractiveHelp();
Backend.makeWizardsSortable();
Backend.enableImageSizeWidgets();
Backend.enableToggleSelect();
// Chosen
if (Elements.chosen != undefined) {
$$('select.tl_chosen').filter(function(el) {
return el.getStyle('display') != 'none';
}).chosen();
}
});
?>