BUG Fix baseurl in IE missing leading /

Reformat LeftAndMain.js to new indentation standard
This commit is contained in:
Damian Mooyman 2016-04-22 17:21:14 +12:00 committed by Ingo Schommer
parent 47e2ac9885
commit 9a4b93a058
3 changed files with 2528 additions and 2522 deletions

View File

@ -1,1138 +1,1141 @@
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define('ss.LeftAndMain', ['jQuery', 'lib/Router', 'lib/Config'], factory);
} else if (typeof exports !== "undefined") {
factory(require('jQuery'), require('lib/Router'), require('lib/Config'));
} else {
var mod = {
exports: {}
};
factory(global.jQuery, global.Router, global.Config);
global.ssLeftAndMain = mod.exports;
}
if (typeof define === "function" && define.amd) {
define('ss.LeftAndMain', ['jQuery', 'lib/Router', 'lib/Config'], factory);
} else if (typeof exports !== "undefined") {
factory(require('jQuery'), require('lib/Router'), require('lib/Config'));
} else {
var mod = {
exports: {}
};
factory(global.jQuery, global.Router, global.Config);
global.ssLeftAndMain = mod.exports;
}
})(this, function (_jQuery, _Router, _Config) {
'use strict';
var _jQuery2 = _interopRequireDefault(_jQuery);
var _Router2 = _interopRequireDefault(_Router);
var _Config2 = _interopRequireDefault(_Config);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
var windowWidth, windowHeight;
_jQuery2.default.noConflict();
window.ss = window.ss || {};
window.ss.router = _Router2.default;
window.ss.debounce = function (func, wait, immediate) {
var timeout, context, args;
var later = function later() {
timeout = null;
if (!immediate) func.apply(context, args);
};
return function () {
var callNow = immediate && !timeout;
context = this;
args = arguments;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
};
function getUrlPath(url) {
var anchor = document.createElement('a');
anchor.href = url;
return anchor.pathname;
}
(0, _jQuery2.default)(window).bind('resize.leftandmain', function (e) {
(0, _jQuery2.default)('.cms-container').trigger('windowresize');
});
_jQuery2.default.entwine.warningLevel = _jQuery2.default.entwine.WARN_LEVEL_BESTPRACTISE;
_jQuery2.default.entwine('ss', function ($) {
$(window).on("message", function (e) {
var target,
event = e.originalEvent,
data = _typeof(event.data) === 'object' ? event.data : JSON.parse(event.data);
if ($.path.parseUrl(window.location.href).domain !== $.path.parseUrl(event.origin).domain) return;
target = typeof data.target === 'undefined' ? $(window) : $(data.target);
switch (data.type) {
case 'event':
target.trigger(data.event, data.data);
break;
case 'callback':
target[data.callback].call(target, data.data);
break;
}
});
var positionLoadingSpinner = function positionLoadingSpinner() {
var offset = 120;
var spinner = $('.ss-loading-screen .loading-animation');
var top = ($(window).height() - spinner.height()) / 2;
spinner.css('top', top + offset);
spinner.show();
};
var applyChosen = function applyChosen(el) {
if (el.is(':visible')) {
el.addClass('has-chosen').chosen({
allow_single_deselect: true,
disable_search_threshold: 20,
display_disabled_options: true
});
} else {
setTimeout(function () {
el.show();
applyChosen(el);
}, 500);
}
};
var isSameUrl = function isSameUrl(url1, url2) {
var baseUrl = $('base').attr('href');
url1 = $.path.isAbsoluteUrl(url1) ? url1 : $.path.makeUrlAbsolute(url1, baseUrl), url2 = $.path.isAbsoluteUrl(url2) ? url2 : $.path.makeUrlAbsolute(url2, baseUrl);
var url1parts = $.path.parseUrl(url1),
url2parts = $.path.parseUrl(url2);
return url1parts.pathname.replace(/\/*$/, '') == url2parts.pathname.replace(/\/*$/, '') && url1parts.search == url2parts.search;
};
var ajaxCompleteEvent = window.ss.debounce(function () {
$(window).trigger('ajaxComplete');
}, 1000, true);
$(window).bind('resize', positionLoadingSpinner).trigger('resize');
$(document).ajaxComplete(function (e, xhr, settings) {
var origUrl,
url = xhr.getResponseHeader('X-ControllerURL'),
destUrl = settings.url,
msg = xhr.getResponseHeader('X-Status') !== null ? xhr.getResponseHeader('X-Status') : xhr.statusText,
msgType = xhr.status < 200 || xhr.status > 399 ? 'bad' : 'good',
ignoredMessages = ['OK'];
if (window.history.state) {
origUrl = window.history.state.path;
} else {
origUrl = document.URL;
}
if (url !== null && (!isSameUrl(origUrl, url) || !isSameUrl(destUrl, url))) {
_Router2.default.show(url, {
id: new Date().getTime() + String(Math.random()).replace(/\D/g, ''),
pjax: xhr.getResponseHeader('X-Pjax') ? xhr.getResponseHeader('X-Pjax') : settings.headers['X-Pjax']
});
}
if (xhr.getResponseHeader('X-Reauthenticate')) {
$('.cms-container').showLoginDialog();
return;
}
if (xhr.status !== 0 && msg && $.inArray(msg, ignoredMessages)) {
statusMessage(decodeURIComponent(msg), msgType);
}
ajaxCompleteEvent(this);
});
$('.cms-container').entwine({
StateChangeXHR: null,
FragmentXHR: {},
StateChangeCount: 0,
LayoutOptions: {
minContentWidth: 940,
minPreviewWidth: 400,
mode: 'content'
},
onadd: function onadd() {
var self = this,
basePath = getUrlPath($('base')[0].href);
basePath = basePath.replace(/\/$/, '');
_Router2.default.base(basePath);
_Config2.default.getTopLevelRoutes().forEach(function (route) {
(0, _Router2.default)('/' + route + '(/*?)?', function (ctx, next) {
if (document.readyState !== 'complete') {
return next();
}
self.handleStateChange(null, ctx.state).done(next);
});
});
_Router2.default.start();
if ($.browser.msie && parseInt($.browser.version, 10) < 8) {
$('.ss-loading-screen').append('<p class="ss-loading-incompat-warning"><span class="notice">' + 'Your browser is not compatible with the CMS interface. Please use Internet Explorer 8+, Google Chrome or Mozilla Firefox.' + '</span></p>').css('z-index', $('.ss-loading-screen').css('z-index') + 1);
$('.loading-animation').remove();
this._super();
return;
}
this.redraw();
$('.ss-loading-screen').hide();
$('body').removeClass('loading');
$(window).unbind('resize', positionLoadingSpinner);
this.restoreTabState();
this._super();
},
fromWindow: {
onstatechange: function onstatechange(event, historyState) {
this.handleStateChange(event, historyState);
}
},
'onwindowresize': function onwindowresize() {
this.redraw();
},
'from .cms-panel': {
ontoggle: function ontoggle() {
this.redraw();
}
},
'from .cms-container': {
onaftersubmitform: function onaftersubmitform() {
this.redraw();
}
},
'from .cms-menu-list li a': {
onclick: function onclick(e) {
var href = $(e.target).attr('href');
if (e.which > 1 || href == this._tabStateUrl()) return;
this.splitViewMode();
}
},
updateLayoutOptions: function updateLayoutOptions(newSpec) {
var spec = this.getLayoutOptions();
var dirty = false;
for (var k in newSpec) {
if (spec[k] !== newSpec[k]) {
spec[k] = newSpec[k];
dirty = true;
}
}
'use strict';
var _jQuery2 = _interopRequireDefault(_jQuery);
var _Router2 = _interopRequireDefault(_Router);
var _Config2 = _interopRequireDefault(_Config);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
var windowWidth, windowHeight;
_jQuery2.default.noConflict();
window.ss = window.ss || {};
window.ss.router = _Router2.default;
window.ss.debounce = function (func, wait, immediate) {
var timeout, context, args;
var later = function later() {
timeout = null;
if (!immediate) func.apply(context, args);
};
return function () {
var callNow = immediate && !timeout;
context = this;
args = arguments;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
};
function getUrlPath(url) {
var anchor = document.createElement('a');
anchor.href = url;
return anchor.pathname;
}
(0, _jQuery2.default)(window).bind('resize.leftandmain', function (e) {
(0, _jQuery2.default)('.cms-container').trigger('windowresize');
});
_jQuery2.default.entwine.warningLevel = _jQuery2.default.entwine.WARN_LEVEL_BESTPRACTISE;
_jQuery2.default.entwine('ss', function ($) {
$(window).on("message", function (e) {
var target,
event = e.originalEvent,
data = _typeof(event.data) === 'object' ? event.data : JSON.parse(event.data);
if ($.path.parseUrl(window.location.href).domain !== $.path.parseUrl(event.origin).domain) return;
target = typeof data.target === 'undefined' ? $(window) : $(data.target);
switch (data.type) {
case 'event':
target.trigger(data.event, data.data);
break;
case 'callback':
target[data.callback].call(target, data.data);
break;
}
});
var positionLoadingSpinner = function positionLoadingSpinner() {
var offset = 120;
var spinner = $('.ss-loading-screen .loading-animation');
var top = ($(window).height() - spinner.height()) / 2;
spinner.css('top', top + offset);
spinner.show();
};
var applyChosen = function applyChosen(el) {
if (el.is(':visible')) {
el.addClass('has-chosen').chosen({
allow_single_deselect: true,
disable_search_threshold: 20,
display_disabled_options: true
});
} else {
setTimeout(function () {
el.show();
applyChosen(el);
}, 500);
}
};
var isSameUrl = function isSameUrl(url1, url2) {
var baseUrl = $('base').attr('href');
url1 = $.path.isAbsoluteUrl(url1) ? url1 : $.path.makeUrlAbsolute(url1, baseUrl), url2 = $.path.isAbsoluteUrl(url2) ? url2 : $.path.makeUrlAbsolute(url2, baseUrl);
var url1parts = $.path.parseUrl(url1),
url2parts = $.path.parseUrl(url2);
return url1parts.pathname.replace(/\/*$/, '') == url2parts.pathname.replace(/\/*$/, '') && url1parts.search == url2parts.search;
};
var ajaxCompleteEvent = window.ss.debounce(function () {
$(window).trigger('ajaxComplete');
}, 1000, true);
$(window).bind('resize', positionLoadingSpinner).trigger('resize');
$(document).ajaxComplete(function (e, xhr, settings) {
var origUrl,
url = xhr.getResponseHeader('X-ControllerURL'),
destUrl = settings.url,
msg = xhr.getResponseHeader('X-Status') !== null ? xhr.getResponseHeader('X-Status') : xhr.statusText,
msgType = xhr.status < 200 || xhr.status > 399 ? 'bad' : 'good',
ignoredMessages = ['OK'];
if (window.history.state) {
origUrl = window.history.state.path;
} else {
origUrl = document.URL;
}
if (url !== null && (!isSameUrl(origUrl, url) || !isSameUrl(destUrl, url))) {
_Router2.default.show(url, {
id: new Date().getTime() + String(Math.random()).replace(/\D/g, ''),
pjax: xhr.getResponseHeader('X-Pjax') ? xhr.getResponseHeader('X-Pjax') : settings.headers['X-Pjax']
});
}
if (xhr.getResponseHeader('X-Reauthenticate')) {
$('.cms-container').showLoginDialog();
return;
}
if (xhr.status !== 0 && msg && $.inArray(msg, ignoredMessages)) {
statusMessage(decodeURIComponent(msg), msgType);
}
ajaxCompleteEvent(this);
});
$('.cms-container').entwine({
StateChangeXHR: null,
FragmentXHR: {},
StateChangeCount: 0,
LayoutOptions: {
minContentWidth: 940,
minPreviewWidth: 400,
mode: 'content'
},
onadd: function onadd() {
var self = this,
basePath = getUrlPath($('base')[0].href);
basePath = basePath.replace(/\/$/, '');
if (basePath.match(/^[^\/]/)) {
basePath = '/' + basePath;
}
_Router2.default.base(basePath);
_Config2.default.getTopLevelRoutes().forEach(function (route) {
(0, _Router2.default)('/' + route + '(/*?)?', function (ctx, next) {
if (document.readyState !== 'complete') {
return next();
}
self.handleStateChange(null, ctx.state).done(next);
});
});
_Router2.default.start();
if ($.browser.msie && parseInt($.browser.version, 10) < 8) {
$('.ss-loading-screen').append('<p class="ss-loading-incompat-warning"><span class="notice">' + 'Your browser is not compatible with the CMS interface. Please use Internet Explorer 8+, Google Chrome or Mozilla Firefox.' + '</span></p>').css('z-index', $('.ss-loading-screen').css('z-index') + 1);
$('.loading-animation').remove();
this._super();
return;
}
this.redraw();
$('.ss-loading-screen').hide();
$('body').removeClass('loading');
$(window).unbind('resize', positionLoadingSpinner);
this.restoreTabState();
this._super();
},
fromWindow: {
onstatechange: function onstatechange(event, historyState) {
this.handleStateChange(event, historyState);
}
},
'onwindowresize': function onwindowresize() {
this.redraw();
},
'from .cms-panel': {
ontoggle: function ontoggle() {
this.redraw();
}
},
'from .cms-container': {
onaftersubmitform: function onaftersubmitform() {
this.redraw();
}
},
'from .cms-menu-list li a': {
onclick: function onclick(e) {
var href = $(e.target).attr('href');
if (e.which > 1 || href == this._tabStateUrl()) return;
this.splitViewMode();
}
},
updateLayoutOptions: function updateLayoutOptions(newSpec) {
var spec = this.getLayoutOptions();
var dirty = false;
for (var k in newSpec) {
if (spec[k] !== newSpec[k]) {
spec[k] = newSpec[k];
dirty = true;
}
}
if (dirty) this.redraw();
},
if (dirty) this.redraw();
},
splitViewMode: function splitViewMode() {
this.updateLayoutOptions({
mode: 'split'
});
},
splitViewMode: function splitViewMode() {
this.updateLayoutOptions({
mode: 'split'
});
},
contentViewMode: function contentViewMode() {
this.updateLayoutOptions({
mode: 'content'
});
},
contentViewMode: function contentViewMode() {
this.updateLayoutOptions({
mode: 'content'
});
},
previewMode: function previewMode() {
this.updateLayoutOptions({
mode: 'preview'
});
},
previewMode: function previewMode() {
this.updateLayoutOptions({
mode: 'preview'
});
},
RedrawSuppression: false,
RedrawSuppression: false,
redraw: function redraw() {
if (this.getRedrawSuppression()) return;
if (window.debug) console.log('redraw', this.attr('class'), this.get(0));
redraw: function redraw() {
if (this.getRedrawSuppression()) return;
this.data('jlayout', jLayout.threeColumnCompressor({
menu: this.children('.cms-menu'),
content: this.children('.cms-content'),
preview: this.children('.cms-preview')
}, this.getLayoutOptions()));
if (window.debug) console.log('redraw', this.attr('class'), this.get(0));
this.layout();
this.data('jlayout', jLayout.threeColumnCompressor({
menu: this.children('.cms-menu'),
content: this.children('.cms-content'),
preview: this.children('.cms-preview')
}, this.getLayoutOptions()));
this.find('.cms-panel-layout').redraw();
this.find('.cms-content-fields[data-layout-type]').redraw();
this.find('.cms-edit-form[data-layout-type]').redraw();
this.find('.cms-preview').redraw();
this.find('.cms-content').redraw();
},
this.layout();
checkCanNavigate: function checkCanNavigate(selectors) {
var contentEls = this._findFragments(selectors || ['Content']),
trackedEls = contentEls.find(':data(changetracker)').add(contentEls.filter(':data(changetracker)')),
safe = true;
this.find('.cms-panel-layout').redraw();
this.find('.cms-content-fields[data-layout-type]').redraw();
this.find('.cms-edit-form[data-layout-type]').redraw();
this.find('.cms-preview').redraw();
this.find('.cms-content').redraw();
},
if (!trackedEls.length) {
return true;
}
checkCanNavigate: function checkCanNavigate(selectors) {
var contentEls = this._findFragments(selectors || ['Content']),
trackedEls = contentEls.find(':data(changetracker)').add(contentEls.filter(':data(changetracker)')),
safe = true;
trackedEls.each(function () {
if (!$(this).confirmUnsavedChanges()) {
safe = false;
}
});
if (!trackedEls.length) {
return true;
}
return safe;
},
trackedEls.each(function () {
if (!$(this).confirmUnsavedChanges()) {
safe = false;
}
});
loadPanel: function loadPanel(url) {
var title = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];
var data = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
var forceReload = arguments[3];
var forceReferer = arguments.length <= 4 || arguments[4] === undefined ? window.history.state.path : arguments[4];
return safe;
},
if (!this.checkCanNavigate(data.pjax ? data.pjax.split(',') : ['Content'])) {
return;
}
loadPanel: function loadPanel(url) {
var title = arguments.length <= 1 || arguments[1] === undefined ? '' : arguments[1];
var data = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
var forceReload = arguments[3];
var forceReferer = arguments.length <= 4 || arguments[4] === undefined ? window.history.state.path : arguments[4];
this.saveTabState();
if (!this.checkCanNavigate(data.pjax ? data.pjax.split(',') : ['Content'])) {
return;
}
data.__forceReferer = forceReferer;
this.saveTabState();
if (forceReload) {
data.__forceReload = Math.random();
}
data.__forceReferer = forceReferer;
_Router2.default.show(url, data);
},
if (forceReload) {
data.__forceReload = Math.random();
}
reloadCurrentPanel: function reloadCurrentPanel() {
this.loadPanel(window.history.state.path, null, null, true);
},
_Router2.default.show(url, data);
},
submitForm: function submitForm(form, button, callback, ajaxOptions) {
var self = this;
reloadCurrentPanel: function reloadCurrentPanel() {
this.loadPanel(window.history.state.path, null, null, true);
},
if (!button) button = this.find('.Actions :submit[name=action_save]');
submitForm: function submitForm(form, button, callback, ajaxOptions) {
var self = this;
if (!button) button = this.find('.Actions :submit:first');
if (!button) button = this.find('.Actions :submit[name=action_save]');
form.trigger('beforesubmitform');
this.trigger('submitform', { form: form, button: button });
if (!button) button = this.find('.Actions :submit:first');
$(button).addClass('loading');
form.trigger('beforesubmitform');
this.trigger('submitform', { form: form, button: button });
var validationResult = form.validate();
if (typeof validationResult !== 'undefined' && !validationResult) {
statusMessage("Validation failed.", "bad");
$(button).addClass('loading');
$(button).removeClass('loading');
var validationResult = form.validate();
if (typeof validationResult !== 'undefined' && !validationResult) {
statusMessage("Validation failed.", "bad");
return false;
}
$(button).removeClass('loading');
var formData = form.serializeArray();
return false;
}
formData.push({ name: $(button).attr('name'), value: '1' });
var formData = form.serializeArray();
formData.push({ name: 'BackURL', value: window.history.state.path.replace(/\/$/, '') });
formData.push({ name: $(button).attr('name'), value: '1' });
this.saveTabState();
formData.push({ name: 'BackURL', value: window.history.state.path.replace(/\/$/, '') });
jQuery.ajax(jQuery.extend({
headers: { "X-Pjax": "CurrentForm,Breadcrumbs" },
url: form.attr('action'),
data: formData,
type: 'POST',
complete: function complete() {
$(button).removeClass('loading');
},
success: function success(data, status, xhr) {
form.removeClass('changed');
if (callback) callback(data, status, xhr);
this.saveTabState();
var newContentEls = self.handleAjaxResponse(data, status, xhr);
if (!newContentEls) return;
jQuery.ajax(jQuery.extend({
headers: { "X-Pjax": "CurrentForm,Breadcrumbs" },
url: form.attr('action'),
data: formData,
type: 'POST',
complete: function complete() {
$(button).removeClass('loading');
},
success: function success(data, status, xhr) {
form.removeClass('changed');
if (callback) callback(data, status, xhr);
newContentEls.filter('form').trigger('aftersubmitform', { status: status, xhr: xhr, formData: formData });
}
}, ajaxOptions));
var newContentEls = self.handleAjaxResponse(data, status, xhr);
if (!newContentEls) return;
return false;
},
newContentEls.filter('form').trigger('aftersubmitform', { status: status, xhr: xhr, formData: formData });
}
}, ajaxOptions));
LastState: null,
return false;
},
PauseState: false,
LastState: null,
handleStateChange: function handleStateChange(event) {
var historyState = arguments.length <= 1 || arguments[1] === undefined ? window.history.state : arguments[1];
PauseState: false,
if (this.getPauseState()) {
return;
}
handleStateChange: function handleStateChange(event) {
var historyState = arguments.length <= 1 || arguments[1] === undefined ? window.history.state : arguments[1];
if (this.getStateChangeXHR()) {
this.getStateChangeXHR().abort();
}
if (this.getPauseState()) {
return;
}
var self = this,
fragments = historyState.pjax || 'Content',
headers = {},
fragmentsArr = fragments.split(','),
contentEls = this._findFragments(fragmentsArr);
if (this.getStateChangeXHR()) {
this.getStateChangeXHR().abort();
}
this.setStateChangeCount(this.getStateChangeCount() + 1);
var self = this,
fragments = historyState.pjax || 'Content',
headers = {},
fragmentsArr = fragments.split(','),
contentEls = this._findFragments(fragmentsArr);
if (!this.checkCanNavigate()) {
var lastState = this.getLastState();
this.setStateChangeCount(this.getStateChangeCount() + 1);
this.setPauseState(true);
if (!this.checkCanNavigate()) {
var lastState = this.getLastState();
if (lastState !== null) {
_Router2.default.show(lastState.url);
} else {
_Router2.default.back();
}
this.setPauseState(true);
this.setPauseState(false);
if (lastState !== null) {
_Router2.default.show(lastState.url);
} else {
_Router2.default.back();
}
return;
}
this.setPauseState(false);
this.setLastState(historyState);
return;
}
if (contentEls.length < fragmentsArr.length) {
fragments = 'Content', fragmentsArr = ['Content'];
contentEls = this._findFragments(fragmentsArr);
}
this.setLastState(historyState);
this.trigger('beforestatechange', { state: historyState, element: contentEls });
if (contentEls.length < fragmentsArr.length) {
fragments = 'Content', fragmentsArr = ['Content'];
contentEls = this._findFragments(fragmentsArr);
}
headers['X-Pjax'] = fragments;
this.trigger('beforestatechange', { state: historyState, element: contentEls });
if (typeof historyState.__forceReferer !== 'undefined') {
var url = historyState.__forceReferer;
headers['X-Pjax'] = fragments;
try {
url = decodeURI(url);
} catch (e) {} finally {
headers['X-Backurl'] = encodeURI(url);
}
}
if (typeof historyState.__forceReferer !== 'undefined') {
var url = historyState.__forceReferer;
contentEls.addClass('loading');
try {
url = decodeURI(url);
} catch (e) {} finally {
headers['X-Backurl'] = encodeURI(url);
}
}
var promise = $.ajax({
headers: headers,
url: historyState.path
}).done(function (data, status, xhr) {
var els = self.handleAjaxResponse(data, status, xhr, historyState);
self.trigger('afterstatechange', { data: data, status: status, xhr: xhr, element: els, state: historyState });
}).always(function () {
self.setStateChangeXHR(null);
contentEls.addClass('loading');
contentEls.removeClass('loading');
});
var promise = $.ajax({
headers: headers,
url: historyState.path
}).done(function (data, status, xhr) {
var els = self.handleAjaxResponse(data, status, xhr, historyState);
self.trigger('afterstatechange', { data: data, status: status, xhr: xhr, element: els, state: historyState });
}).always(function () {
self.setStateChangeXHR(null);
this.setStateChangeXHR(promise);
contentEls.removeClass('loading');
});
return promise;
},
loadFragment: function loadFragment(url, pjaxFragments) {
var self = this,
xhr,
headers = {},
baseUrl = $('base').attr('href'),
fragmentXHR = this.getFragmentXHR();
this.setStateChangeXHR(promise);
if (typeof fragmentXHR[pjaxFragments] !== 'undefined' && fragmentXHR[pjaxFragments] !== null) {
fragmentXHR[pjaxFragments].abort();
fragmentXHR[pjaxFragments] = null;
}
return promise;
},
loadFragment: function loadFragment(url, pjaxFragments) {
var self = this,
xhr,
headers = {},
baseUrl = $('base').attr('href'),
fragmentXHR = this.getFragmentXHR();
url = $.path.isAbsoluteUrl(url) ? url : $.path.makeUrlAbsolute(url, baseUrl);
headers['X-Pjax'] = pjaxFragments;
if (typeof fragmentXHR[pjaxFragments] !== 'undefined' && fragmentXHR[pjaxFragments] !== null) {
fragmentXHR[pjaxFragments].abort();
fragmentXHR[pjaxFragments] = null;
}
url = $.path.isAbsoluteUrl(url) ? url : $.path.makeUrlAbsolute(url, baseUrl);
headers['X-Pjax'] = pjaxFragments;
xhr = $.ajax({
headers: headers,
url: url,
success: function success(data, status, xhr) {
var elements = self.handleAjaxResponse(data, status, xhr, null);
self.trigger('afterloadfragment', { data: data, status: status, xhr: xhr, elements: elements });
},
error: function error(xhr, status, _error) {
self.trigger('loadfragmenterror', { xhr: xhr, status: status, error: _error });
},
complete: function complete() {
var fragmentXHR = self.getFragmentXHR();
if (typeof fragmentXHR[pjaxFragments] !== 'undefined' && fragmentXHR[pjaxFragments] !== null) {
fragmentXHR[pjaxFragments] = null;
}
}
});
fragmentXHR[pjaxFragments] = xhr;
return xhr;
},
handleAjaxResponse: function handleAjaxResponse(data, status, xhr, state) {
var self = this,
url,
selectedTabs,
guessFragment,
fragment,
$data;
if (xhr.getResponseHeader('X-Reload') && xhr.getResponseHeader('X-ControllerURL')) {
var baseUrl = $('base').attr('href'),
rawURL = xhr.getResponseHeader('X-ControllerURL'),
url = $.path.isAbsoluteUrl(rawURL) ? rawURL : $.path.makeUrlAbsolute(rawURL, baseUrl);
document.location.href = url;
return;
}
if (!data) return;
var title = xhr.getResponseHeader('X-Title');
if (title) document.title = decodeURIComponent(title.replace(/\+/g, ' '));
var newFragments = {},
newContentEls;
if (xhr.getResponseHeader('Content-Type').match(/^((text)|(application))\/json[ \t]*;?/i)) {
newFragments = data;
} else {
fragment = document.createDocumentFragment();
jQuery.clean([data], document, fragment, []);
$data = $(jQuery.merge([], fragment.childNodes));
guessFragment = 'Content';
if ($data.is('form') && !$data.is('[data-pjax-fragment~=Content]')) guessFragment = 'CurrentForm';
newFragments[guessFragment] = $data;
}
this.setRedrawSuppression(true);
try {
$.each(newFragments, function (newFragment, html) {
var contentEl = $('[data-pjax-fragment]').filter(function () {
return $.inArray(newFragment, $(this).data('pjaxFragment').split(' ')) != -1;
}),
newContentEl = $(html);
if (newContentEls) newContentEls.add(newContentEl);else newContentEls = newContentEl;
if (newContentEl.find('.cms-container').length) {
throw 'Content loaded via ajax is not allowed to contain tags matching the ".cms-container" selector to avoid infinite loops';
}
var origStyle = contentEl.attr('style');
var origParent = contentEl.parent();
var origParentLayoutApplied = typeof origParent.data('jlayout') !== 'undefined';
var layoutClasses = ['east', 'west', 'center', 'north', 'south', 'column-hidden'];
var elemClasses = contentEl.attr('class');
var origLayoutClasses = [];
if (elemClasses) {
origLayoutClasses = $.grep(elemClasses.split(' '), function (val) {
return $.inArray(val, layoutClasses) >= 0;
});
}
newContentEl.removeClass(layoutClasses.join(' ')).addClass(origLayoutClasses.join(' '));
if (origStyle) newContentEl.attr('style', origStyle);
var styles = newContentEl.find('style').detach();
if (styles.length) $(document).find('head').append(styles);
contentEl.replaceWith(newContentEl);
if (!origParent.is('.cms-container') && origParentLayoutApplied) {
origParent.layout();
}
});
var newForm = newContentEls.filter('form');
if (newForm.hasClass('cms-tabset')) newForm.removeClass('cms-tabset').addClass('cms-tabset');
} finally {
this.setRedrawSuppression(false);
}
this.redraw();
this.restoreTabState(state && typeof state.tabState !== 'undefined' ? state.tabState : null);
return newContentEls;
},
_findFragments: function _findFragments(fragments) {
return $('[data-pjax-fragment]').filter(function () {
var i,
nodeFragments = $(this).data('pjaxFragment').split(' ');
for (i in fragments) {
if ($.inArray(fragments[i], nodeFragments) != -1) return true;
}
return false;
});
},
refresh: function refresh() {
$(window).trigger('statechange');
$(this).redraw();
},
saveTabState: function saveTabState() {
if (typeof window.sessionStorage == "undefined" || window.sessionStorage === null) return;
var selectedTabs = [],
url = this._tabStateUrl();
this.find('.cms-tabset,.ss-tabset').each(function (i, el) {
var id = $(el).attr('id');
if (!id) return;
if (!$(el).data('tabs')) return;
if ($(el).data('ignoreTabState') || $(el).getIgnoreTabState()) return;
selectedTabs.push({ id: id, selected: $(el).tabs('option', 'selected') });
});
if (selectedTabs) {
var tabsUrl = 'tabs-' + url;
try {
window.sessionStorage.setItem(tabsUrl, JSON.stringify(selectedTabs));
} catch (err) {
if (err.code === DOMException.QUOTA_EXCEEDED_ERR && window.sessionStorage.length === 0) {
return;
} else {
throw err;
}
}
}
},
restoreTabState: function restoreTabState(overrideStates) {
var self = this,
url = this._tabStateUrl(),
hasSessionStorage = typeof window.sessionStorage !== "undefined" && window.sessionStorage,
sessionData = hasSessionStorage ? window.sessionStorage.getItem('tabs-' + url) : null,
sessionStates = sessionData ? JSON.parse(sessionData) : false;
this.find('.cms-tabset, .ss-tabset').each(function () {
var index,
tabset = $(this),
tabsetId = tabset.attr('id'),
tab,
forcedTab = tabset.find('.ss-tabs-force-active');
if (!tabset.data('tabs')) {
return;
}
tabset.tabs('refresh');
if (forcedTab.length) {
index = forcedTab.index();
} else if (overrideStates && overrideStates[tabsetId]) {
tab = tabset.find(overrideStates[tabsetId].tabSelector);
if (tab.length) {
index = tab.index();
}
} else if (sessionStates) {
$.each(sessionStates, function (i, sessionState) {
if (tabset.is('#' + sessionState.id)) {
index = sessionState.selected;
}
});
}
if (index !== null) {
tabset.tabs('option', 'active', index);
self.trigger('tabstaterestored');
}
});
},
clearTabState: function clearTabState(url) {
if (typeof window.sessionStorage == "undefined") return;
var s = window.sessionStorage;
if (url) {
s.removeItem('tabs-' + url);
} else {
for (var i = 0; i < s.length; i++) {
if (s.key(i).match(/^tabs-/)) s.removeItem(s.key(i));
}
}
},
clearCurrentTabState: function clearCurrentTabState() {
this.clearTabState(this._tabStateUrl());
},
_tabStateUrl: function _tabStateUrl() {
return window.history.state.path.replace(/\?.*/, '').replace(/#.*/, '').replace($('base').attr('href'), '');
},
showLoginDialog: function showLoginDialog() {
var tempid = $('body').data('member-tempid'),
dialog = $('.leftandmain-logindialog'),
url = 'CMSSecurity/login';
if (dialog.length) dialog.remove();
url = $.path.addSearchParams(url, {
'tempid': tempid,
'BackURL': window.location.href
});
dialog = $('<div class="leftandmain-logindialog"></div>');
dialog.attr('id', new Date().getTime());
dialog.data('url', url);
$('body').append(dialog);
}
});
$('.leftandmain-logindialog').entwine({
onmatch: function onmatch() {
this._super();
this.ssdialog({
iframeUrl: this.data('url'),
dialogClass: "leftandmain-logindialog-dialog",
autoOpen: true,
minWidth: 500,
maxWidth: 500,
minHeight: 370,
maxHeight: 400,
closeOnEscape: false,
open: function open() {
$('.ui-widget-overlay').addClass('leftandmain-logindialog-overlay');
},
close: function close() {
$('.ui-widget-overlay').removeClass('leftandmain-logindialog-overlay');
}
});
},
onunmatch: function onunmatch() {
this._super();
},
open: function open() {
this.ssdialog('open');
},
close: function close() {
this.ssdialog('close');
},
toggle: function toggle(bool) {
if (this.is(':visible')) this.close();else this.open();
},
reauthenticate: function reauthenticate(data) {
if (typeof data.SecurityID !== 'undefined') {
$(':input[name=SecurityID]').val(data.SecurityID);
}
if (typeof data.TempID !== 'undefined') {
$('body').data('member-tempid', data.TempID);
}
this.close();
}
});
$('form.loading,.cms-content.loading,.cms-content-fields.loading,.cms-content-view.loading').entwine({
onmatch: function onmatch() {
this.append('<div class="cms-content-loading-overlay ui-widget-overlay-light"></div><div class="cms-content-loading-spinner"></div>');
this._super();
},
onunmatch: function onunmatch() {
this.find('.cms-content-loading-overlay,.cms-content-loading-spinner').remove();
this._super();
}
});
$('.cms input[type="submit"], .cms button, .cms input[type="reset"], .cms .ss-ui-button').entwine({
onadd: function onadd() {
this.addClass('ss-ui-button');
if (!this.data('button')) this.button();
this._super();
},
onremove: function onremove() {
if (this.data('button')) this.button('destroy');
this._super();
}
});
$('.cms .cms-panel-link').entwine({
onclick: function onclick(e) {
if ($(this).hasClass('external-link')) {
e.stopPropagation();
return;
}
var href = this.attr('href'),
url = href && !href.match(/^#/) ? href : this.data('href'),
data = { pjax: this.data('pjaxTarget') };
$('.cms-container').loadPanel(url, null, data);
e.preventDefault();
}
});
$('.cms .ss-ui-button-ajax').entwine({
onclick: function onclick(e) {
$(this).removeClass('ui-button-text-only');
$(this).addClass('ss-ui-button-loading ui-button-text-icons');
var loading = $(this).find(".ss-ui-loading-icon");
if (loading.length < 1) {
loading = $("<span></span>").addClass('ss-ui-loading-icon ui-button-icon-primary ui-icon');
$(this).prepend(loading);
}
loading.show();
var href = this.attr('href'),
url = href ? href : this.data('href');
jQuery.ajax({
url: url,
complete: function complete(xmlhttp, status) {
var msg = xmlhttp.getResponseHeader('X-Status') ? xmlhttp.getResponseHeader('X-Status') : xmlhttp.responseText;
try {
if (typeof msg != "undefined" && msg !== null) eval(msg);
} catch (e) {}
loading.hide();
$(".cms-container").refresh();
$(this).removeClass('ss-ui-button-loading ui-button-text-icons');
$(this).addClass('ui-button-text-only');
},
dataType: 'html'
});
e.preventDefault();
}
});
$('.cms .ss-ui-dialog-link').entwine({
UUID: null,
onmatch: function onmatch() {
this._super();
this.setUUID(new Date().getTime());
},
onunmatch: function onunmatch() {
this._super();
},
onclick: function onclick() {
this._super();
var self = this,
id = 'ss-ui-dialog-' + this.getUUID();
var dialog = $('#' + id);
if (!dialog.length) {
dialog = $('<div class="ss-ui-dialog" id="' + id + '" />');
$('body').append(dialog);
}
var extraClass = this.data('popupclass') ? this.data('popupclass') : '';
dialog.ssdialog({ iframeUrl: this.attr('href'), autoOpen: true, dialogExtraClass: extraClass });
return false;
}
});
$('.cms-content .Actions').entwine({
onmatch: function onmatch() {
this.find('.ss-ui-button').click(function () {
var form = this.form;
if (form) {
form.clickedButton = this;
setTimeout(function () {
form.clickedButton = null;
}, 10);
}
});
this.redraw();
this._super();
},
onunmatch: function onunmatch() {
this._super();
},
redraw: function redraw() {
if (window.debug) console.log('redraw', this.attr('class'), this.get(0));
this.contents().filter(function () {
return this.nodeType == 3 && !/\S/.test(this.nodeValue);
}).remove();
this.find('.ss-ui-button').each(function () {
if (!$(this).data('button')) $(this).button();
});
this.find('.ss-ui-buttonset').buttonset();
}
});
$('.cms .field.date input.text').entwine({
onmatch: function onmatch() {
var holder = $(this).parents('.field.date:first'),
config = holder.data();
if (!config.showcalendar) {
this._super();
return;
}
config.showOn = 'button';
if (config.locale && $.datepicker.regional[config.locale]) {
config = $.extend(config, $.datepicker.regional[config.locale], {});
}
$(this).datepicker(config);
this._super();
},
onunmatch: function onunmatch() {
this._super();
}
});
$('.cms .field.dropdown select, .cms .field select[multiple], .fieldholder-small select.dropdown').entwine({
onmatch: function onmatch() {
if (this.is('.no-chosen')) {
this._super();
return;
}
if (!this.data('placeholder')) this.data('placeholder', ' ');
this.removeClass('has-chosen').chosen("destroy");
this.siblings('.chosen-container').remove();
applyChosen(this);
this._super();
},
onunmatch: function onunmatch() {
this._super();
}
});
$(".cms-panel-layout").entwine({
redraw: function redraw() {
if (window.debug) console.log('redraw', this.attr('class'), this.get(0));
}
});
$('.cms .ss-gridfield').entwine({
showDetailView: function showDetailView(url) {
var params = window.location.search.replace(/^\?/, '');
if (params) url = $.path.addSearchParams(url, params);
$('.cms-container').loadPanel(url);
}
});
$('.cms-search-form').entwine({
onsubmit: function onsubmit(e) {
var nonEmptyInputs, url;
nonEmptyInputs = this.find(':input:not(:submit)').filter(function () {
var vals = $.grep($(this).fieldValue(), function (val) {
return val;
});
return vals.length;
});
url = this.attr('action');
if (nonEmptyInputs.length) {
url = $.path.addSearchParams(url, nonEmptyInputs.serialize().replace('+', '%20'));
}
var container = this.closest('.cms-container');
container.find('.cms-edit-form').tabs('select', 0);
container.loadPanel(url, "", {}, true);
return false;
}
});
$(".cms-search-form button[type=reset], .cms-search-form input[type=reset]").entwine({
onclick: function onclick(e) {
e.preventDefault();
var form = $(this).parents('form');
form.clearForm();
form.find(".dropdown select").prop('selectedIndex', 0).trigger("chosen:updated");
form.submit();
}
});
window._panelDeferredCache = {};
$('.cms-panel-deferred').entwine({
onadd: function onadd() {
this._super();
this.redraw();
},
onremove: function onremove() {
if (window.debug) console.log('saving', this.data('url'), this);
if (!this.data('deferredNoCache')) window._panelDeferredCache[this.data('url')] = this.html();
this._super();
},
redraw: function redraw() {
if (window.debug) console.log('redraw', this.attr('class'), this.get(0));
var self = this,
url = this.data('url');
if (!url) throw 'Elements of class .cms-panel-deferred need a "data-url" attribute';
this._super();
if (!this.children().length) {
if (!this.data('deferredNoCache') && typeof window._panelDeferredCache[url] !== 'undefined') {
this.html(window._panelDeferredCache[url]);
} else {
this.addClass('loading');
$.ajax({
url: url,
complete: function complete() {
self.removeClass('loading');
},
success: function success(data, status, xhr) {
self.html(data);
}
});
}
}
}
});
$('.cms-tabset').entwine({
onadd: function onadd() {
this.redrawTabs();
this._super();
},
onremove: function onremove() {
if (this.data('tabs')) this.tabs('destroy');
this._super();
},
redrawTabs: function redrawTabs() {
this.rewriteHashlinks();
var id = this.attr('id'),
activeTab = this.find('ul:first .ui-tabs-active');
if (!this.data('uiTabs')) this.tabs({
active: activeTab.index() != -1 ? activeTab.index() : 0,
beforeLoad: function beforeLoad(e, ui) {
return false;
},
activate: function activate(e, ui) {
var actions = $(this).closest('form').find('.Actions');
if ($(ui.newTab).closest('li').hasClass('readonly')) {
actions.fadeOut();
} else {
actions.show();
}
}
});
},
rewriteHashlinks: function rewriteHashlinks() {
$(this).find('ul a').each(function () {
if (!$(this).attr('href')) return;
var matches = $(this).attr('href').match(/#.*/);
if (!matches) return;
$(this).attr('href', document.location.href.replace(/#.*/, '') + matches[0]);
});
}
});
$('#filters-button').entwine({
onmatch: function onmatch() {
this._super();
this.data('collapsed', true);
this.data('animating', false);
},
onunmatch: function onunmatch() {
this._super();
},
showHide: function showHide() {
var self = this,
$filters = $('.cms-content-filters').first(),
collapsed = this.data('collapsed');
if (this.data('animating')) {
return;
}
this.toggleClass('active');
this.data('animating', true);
$filters[collapsed ? 'slideDown' : 'slideUp']({
complete: function complete() {
self.data('collapsed', !collapsed);
self.data('animating', false);
}
});
},
onclick: function onclick() {
this.showHide();
}
});
});
var statusMessage = function statusMessage(text, type) {
text = jQuery('<div/>').text(text).html();
jQuery.noticeAdd({ text: text, type: type, stayTime: 5000, inEffect: { left: '0', opacity: 'show' } });
};
var errorMessage = function errorMessage(text) {
jQuery.noticeAdd({ text: text, type: 'error', stayTime: 5000, inEffect: { left: '0', opacity: 'show' } });
};
xhr = $.ajax({
headers: headers,
url: url,
success: function success(data, status, xhr) {
var elements = self.handleAjaxResponse(data, status, xhr, null);
self.trigger('afterloadfragment', { data: data, status: status, xhr: xhr, elements: elements });
},
error: function error(xhr, status, _error) {
self.trigger('loadfragmenterror', { xhr: xhr, status: status, error: _error });
},
complete: function complete() {
var fragmentXHR = self.getFragmentXHR();
if (typeof fragmentXHR[pjaxFragments] !== 'undefined' && fragmentXHR[pjaxFragments] !== null) {
fragmentXHR[pjaxFragments] = null;
}
}
});
fragmentXHR[pjaxFragments] = xhr;
return xhr;
},
handleAjaxResponse: function handleAjaxResponse(data, status, xhr, state) {
var self = this,
url,
selectedTabs,
guessFragment,
fragment,
$data;
if (xhr.getResponseHeader('X-Reload') && xhr.getResponseHeader('X-ControllerURL')) {
var baseUrl = $('base').attr('href'),
rawURL = xhr.getResponseHeader('X-ControllerURL'),
url = $.path.isAbsoluteUrl(rawURL) ? rawURL : $.path.makeUrlAbsolute(rawURL, baseUrl);
document.location.href = url;
return;
}
if (!data) return;
var title = xhr.getResponseHeader('X-Title');
if (title) document.title = decodeURIComponent(title.replace(/\+/g, ' '));
var newFragments = {},
newContentEls;
if (xhr.getResponseHeader('Content-Type').match(/^((text)|(application))\/json[ \t]*;?/i)) {
newFragments = data;
} else {
fragment = document.createDocumentFragment();
jQuery.clean([data], document, fragment, []);
$data = $(jQuery.merge([], fragment.childNodes));
guessFragment = 'Content';
if ($data.is('form') && !$data.is('[data-pjax-fragment~=Content]')) guessFragment = 'CurrentForm';
newFragments[guessFragment] = $data;
}
this.setRedrawSuppression(true);
try {
$.each(newFragments, function (newFragment, html) {
var contentEl = $('[data-pjax-fragment]').filter(function () {
return $.inArray(newFragment, $(this).data('pjaxFragment').split(' ')) != -1;
}),
newContentEl = $(html);
if (newContentEls) newContentEls.add(newContentEl);else newContentEls = newContentEl;
if (newContentEl.find('.cms-container').length) {
throw 'Content loaded via ajax is not allowed to contain tags matching the ".cms-container" selector to avoid infinite loops';
}
var origStyle = contentEl.attr('style');
var origParent = contentEl.parent();
var origParentLayoutApplied = typeof origParent.data('jlayout') !== 'undefined';
var layoutClasses = ['east', 'west', 'center', 'north', 'south', 'column-hidden'];
var elemClasses = contentEl.attr('class');
var origLayoutClasses = [];
if (elemClasses) {
origLayoutClasses = $.grep(elemClasses.split(' '), function (val) {
return $.inArray(val, layoutClasses) >= 0;
});
}
newContentEl.removeClass(layoutClasses.join(' ')).addClass(origLayoutClasses.join(' '));
if (origStyle) newContentEl.attr('style', origStyle);
var styles = newContentEl.find('style').detach();
if (styles.length) $(document).find('head').append(styles);
contentEl.replaceWith(newContentEl);
if (!origParent.is('.cms-container') && origParentLayoutApplied) {
origParent.layout();
}
});
var newForm = newContentEls.filter('form');
if (newForm.hasClass('cms-tabset')) newForm.removeClass('cms-tabset').addClass('cms-tabset');
} finally {
this.setRedrawSuppression(false);
}
this.redraw();
this.restoreTabState(state && typeof state.tabState !== 'undefined' ? state.tabState : null);
return newContentEls;
},
_findFragments: function _findFragments(fragments) {
return $('[data-pjax-fragment]').filter(function () {
var i,
nodeFragments = $(this).data('pjaxFragment').split(' ');
for (i in fragments) {
if ($.inArray(fragments[i], nodeFragments) != -1) return true;
}
return false;
});
},
refresh: function refresh() {
$(window).trigger('statechange');
$(this).redraw();
},
saveTabState: function saveTabState() {
if (typeof window.sessionStorage == "undefined" || window.sessionStorage === null) return;
var selectedTabs = [],
url = this._tabStateUrl();
this.find('.cms-tabset,.ss-tabset').each(function (i, el) {
var id = $(el).attr('id');
if (!id) return;
if (!$(el).data('tabs')) return;
if ($(el).data('ignoreTabState') || $(el).getIgnoreTabState()) return;
selectedTabs.push({ id: id, selected: $(el).tabs('option', 'selected') });
});
if (selectedTabs) {
var tabsUrl = 'tabs-' + url;
try {
window.sessionStorage.setItem(tabsUrl, JSON.stringify(selectedTabs));
} catch (err) {
if (err.code === DOMException.QUOTA_EXCEEDED_ERR && window.sessionStorage.length === 0) {
return;
} else {
throw err;
}
}
}
},
restoreTabState: function restoreTabState(overrideStates) {
var self = this,
url = this._tabStateUrl(),
hasSessionStorage = typeof window.sessionStorage !== "undefined" && window.sessionStorage,
sessionData = hasSessionStorage ? window.sessionStorage.getItem('tabs-' + url) : null,
sessionStates = sessionData ? JSON.parse(sessionData) : false;
this.find('.cms-tabset, .ss-tabset').each(function () {
var index,
tabset = $(this),
tabsetId = tabset.attr('id'),
tab,
forcedTab = tabset.find('.ss-tabs-force-active');
if (!tabset.data('tabs')) {
return;
}
tabset.tabs('refresh');
if (forcedTab.length) {
index = forcedTab.index();
} else if (overrideStates && overrideStates[tabsetId]) {
tab = tabset.find(overrideStates[tabsetId].tabSelector);
if (tab.length) {
index = tab.index();
}
} else if (sessionStates) {
$.each(sessionStates, function (i, sessionState) {
if (tabset.is('#' + sessionState.id)) {
index = sessionState.selected;
}
});
}
if (index !== null) {
tabset.tabs('option', 'active', index);
self.trigger('tabstaterestored');
}
});
},
clearTabState: function clearTabState(url) {
if (typeof window.sessionStorage == "undefined") return;
var s = window.sessionStorage;
if (url) {
s.removeItem('tabs-' + url);
} else {
for (var i = 0; i < s.length; i++) {
if (s.key(i).match(/^tabs-/)) s.removeItem(s.key(i));
}
}
},
clearCurrentTabState: function clearCurrentTabState() {
this.clearTabState(this._tabStateUrl());
},
_tabStateUrl: function _tabStateUrl() {
return window.history.state.path.replace(/\?.*/, '').replace(/#.*/, '').replace($('base').attr('href'), '');
},
showLoginDialog: function showLoginDialog() {
var tempid = $('body').data('member-tempid'),
dialog = $('.leftandmain-logindialog'),
url = 'CMSSecurity/login';
if (dialog.length) dialog.remove();
url = $.path.addSearchParams(url, {
'tempid': tempid,
'BackURL': window.location.href
});
dialog = $('<div class="leftandmain-logindialog"></div>');
dialog.attr('id', new Date().getTime());
dialog.data('url', url);
$('body').append(dialog);
}
});
$('.leftandmain-logindialog').entwine({
onmatch: function onmatch() {
this._super();
this.ssdialog({
iframeUrl: this.data('url'),
dialogClass: "leftandmain-logindialog-dialog",
autoOpen: true,
minWidth: 500,
maxWidth: 500,
minHeight: 370,
maxHeight: 400,
closeOnEscape: false,
open: function open() {
$('.ui-widget-overlay').addClass('leftandmain-logindialog-overlay');
},
close: function close() {
$('.ui-widget-overlay').removeClass('leftandmain-logindialog-overlay');
}
});
},
onunmatch: function onunmatch() {
this._super();
},
open: function open() {
this.ssdialog('open');
},
close: function close() {
this.ssdialog('close');
},
toggle: function toggle(bool) {
if (this.is(':visible')) this.close();else this.open();
},
reauthenticate: function reauthenticate(data) {
if (typeof data.SecurityID !== 'undefined') {
$(':input[name=SecurityID]').val(data.SecurityID);
}
if (typeof data.TempID !== 'undefined') {
$('body').data('member-tempid', data.TempID);
}
this.close();
}
});
$('form.loading,.cms-content.loading,.cms-content-fields.loading,.cms-content-view.loading').entwine({
onmatch: function onmatch() {
this.append('<div class="cms-content-loading-overlay ui-widget-overlay-light"></div><div class="cms-content-loading-spinner"></div>');
this._super();
},
onunmatch: function onunmatch() {
this.find('.cms-content-loading-overlay,.cms-content-loading-spinner').remove();
this._super();
}
});
$('.cms input[type="submit"], .cms button, .cms input[type="reset"], .cms .ss-ui-button').entwine({
onadd: function onadd() {
this.addClass('ss-ui-button');
if (!this.data('button')) this.button();
this._super();
},
onremove: function onremove() {
if (this.data('button')) this.button('destroy');
this._super();
}
});
$('.cms .cms-panel-link').entwine({
onclick: function onclick(e) {
if ($(this).hasClass('external-link')) {
e.stopPropagation();
return;
}
var href = this.attr('href'),
url = href && !href.match(/^#/) ? href : this.data('href'),
data = { pjax: this.data('pjaxTarget') };
$('.cms-container').loadPanel(url, null, data);
e.preventDefault();
}
});
$('.cms .ss-ui-button-ajax').entwine({
onclick: function onclick(e) {
$(this).removeClass('ui-button-text-only');
$(this).addClass('ss-ui-button-loading ui-button-text-icons');
var loading = $(this).find(".ss-ui-loading-icon");
if (loading.length < 1) {
loading = $("<span></span>").addClass('ss-ui-loading-icon ui-button-icon-primary ui-icon');
$(this).prepend(loading);
}
loading.show();
var href = this.attr('href'),
url = href ? href : this.data('href');
jQuery.ajax({
url: url,
complete: function complete(xmlhttp, status) {
var msg = xmlhttp.getResponseHeader('X-Status') ? xmlhttp.getResponseHeader('X-Status') : xmlhttp.responseText;
try {
if (typeof msg != "undefined" && msg !== null) eval(msg);
} catch (e) {}
loading.hide();
$(".cms-container").refresh();
$(this).removeClass('ss-ui-button-loading ui-button-text-icons');
$(this).addClass('ui-button-text-only');
},
dataType: 'html'
});
e.preventDefault();
}
});
$('.cms .ss-ui-dialog-link').entwine({
UUID: null,
onmatch: function onmatch() {
this._super();
this.setUUID(new Date().getTime());
},
onunmatch: function onunmatch() {
this._super();
},
onclick: function onclick() {
this._super();
var self = this,
id = 'ss-ui-dialog-' + this.getUUID();
var dialog = $('#' + id);
if (!dialog.length) {
dialog = $('<div class="ss-ui-dialog" id="' + id + '" />');
$('body').append(dialog);
}
var extraClass = this.data('popupclass') ? this.data('popupclass') : '';
dialog.ssdialog({ iframeUrl: this.attr('href'), autoOpen: true, dialogExtraClass: extraClass });
return false;
}
});
$('.cms-content .Actions').entwine({
onmatch: function onmatch() {
this.find('.ss-ui-button').click(function () {
var form = this.form;
if (form) {
form.clickedButton = this;
setTimeout(function () {
form.clickedButton = null;
}, 10);
}
});
this.redraw();
this._super();
},
onunmatch: function onunmatch() {
this._super();
},
redraw: function redraw() {
if (window.debug) console.log('redraw', this.attr('class'), this.get(0));
this.contents().filter(function () {
return this.nodeType == 3 && !/\S/.test(this.nodeValue);
}).remove();
this.find('.ss-ui-button').each(function () {
if (!$(this).data('button')) $(this).button();
});
this.find('.ss-ui-buttonset').buttonset();
}
});
$('.cms .field.date input.text').entwine({
onmatch: function onmatch() {
var holder = $(this).parents('.field.date:first'),
config = holder.data();
if (!config.showcalendar) {
this._super();
return;
}
config.showOn = 'button';
if (config.locale && $.datepicker.regional[config.locale]) {
config = $.extend(config, $.datepicker.regional[config.locale], {});
}
$(this).datepicker(config);
this._super();
},
onunmatch: function onunmatch() {
this._super();
}
});
$('.cms .field.dropdown select, .cms .field select[multiple], .fieldholder-small select.dropdown').entwine({
onmatch: function onmatch() {
if (this.is('.no-chosen')) {
this._super();
return;
}
if (!this.data('placeholder')) this.data('placeholder', ' ');
this.removeClass('has-chosen').chosen("destroy");
this.siblings('.chosen-container').remove();
applyChosen(this);
this._super();
},
onunmatch: function onunmatch() {
this._super();
}
});
$(".cms-panel-layout").entwine({
redraw: function redraw() {
if (window.debug) console.log('redraw', this.attr('class'), this.get(0));
}
});
$('.cms .ss-gridfield').entwine({
showDetailView: function showDetailView(url) {
var params = window.location.search.replace(/^\?/, '');
if (params) url = $.path.addSearchParams(url, params);
$('.cms-container').loadPanel(url);
}
});
$('.cms-search-form').entwine({
onsubmit: function onsubmit(e) {
var nonEmptyInputs, url;
nonEmptyInputs = this.find(':input:not(:submit)').filter(function () {
var vals = $.grep($(this).fieldValue(), function (val) {
return val;
});
return vals.length;
});
url = this.attr('action');
if (nonEmptyInputs.length) {
url = $.path.addSearchParams(url, nonEmptyInputs.serialize().replace('+', '%20'));
}
var container = this.closest('.cms-container');
container.find('.cms-edit-form').tabs('select', 0);
container.loadPanel(url, "", {}, true);
return false;
}
});
$(".cms-search-form button[type=reset], .cms-search-form input[type=reset]").entwine({
onclick: function onclick(e) {
e.preventDefault();
var form = $(this).parents('form');
form.clearForm();
form.find(".dropdown select").prop('selectedIndex', 0).trigger("chosen:updated");
form.submit();
}
});
window._panelDeferredCache = {};
$('.cms-panel-deferred').entwine({
onadd: function onadd() {
this._super();
this.redraw();
},
onremove: function onremove() {
if (window.debug) console.log('saving', this.data('url'), this);
if (!this.data('deferredNoCache')) window._panelDeferredCache[this.data('url')] = this.html();
this._super();
},
redraw: function redraw() {
if (window.debug) console.log('redraw', this.attr('class'), this.get(0));
var self = this,
url = this.data('url');
if (!url) throw 'Elements of class .cms-panel-deferred need a "data-url" attribute';
this._super();
if (!this.children().length) {
if (!this.data('deferredNoCache') && typeof window._panelDeferredCache[url] !== 'undefined') {
this.html(window._panelDeferredCache[url]);
} else {
this.addClass('loading');
$.ajax({
url: url,
complete: function complete() {
self.removeClass('loading');
},
success: function success(data, status, xhr) {
self.html(data);
}
});
}
}
}
});
$('.cms-tabset').entwine({
onadd: function onadd() {
this.redrawTabs();
this._super();
},
onremove: function onremove() {
if (this.data('tabs')) this.tabs('destroy');
this._super();
},
redrawTabs: function redrawTabs() {
this.rewriteHashlinks();
var id = this.attr('id'),
activeTab = this.find('ul:first .ui-tabs-active');
if (!this.data('uiTabs')) this.tabs({
active: activeTab.index() != -1 ? activeTab.index() : 0,
beforeLoad: function beforeLoad(e, ui) {
return false;
},
activate: function activate(e, ui) {
var actions = $(this).closest('form').find('.Actions');
if ($(ui.newTab).closest('li').hasClass('readonly')) {
actions.fadeOut();
} else {
actions.show();
}
}
});
},
rewriteHashlinks: function rewriteHashlinks() {
$(this).find('ul a').each(function () {
if (!$(this).attr('href')) return;
var matches = $(this).attr('href').match(/#.*/);
if (!matches) return;
$(this).attr('href', document.location.href.replace(/#.*/, '') + matches[0]);
});
}
});
$('#filters-button').entwine({
onmatch: function onmatch() {
this._super();
this.data('collapsed', true);
this.data('animating', false);
},
onunmatch: function onunmatch() {
this._super();
},
showHide: function showHide() {
var self = this,
$filters = $('.cms-content-filters').first(),
collapsed = this.data('collapsed');
if (this.data('animating')) {
return;
}
this.toggleClass('active');
this.data('animating', true);
$filters[collapsed ? 'slideDown' : 'slideUp']({
complete: function complete() {
self.data('collapsed', !collapsed);
self.data('animating', false);
}
});
},
onclick: function onclick() {
this.showHide();
}
});
});
var statusMessage = function statusMessage(text, type) {
text = jQuery('<div/>').text(text).html();
jQuery.noticeAdd({ text: text, type: type, stayTime: 5000, inEffect: { left: '0', opacity: 'show' } });
};
var errorMessage = function errorMessage(text) {
jQuery.noticeAdd({ text: text, type: 'error', stayTime: 5000, inEffect: { left: '0', opacity: 'show' } });
};
});

View File

@ -1,4 +1,4 @@
!function e(t,n,i){function s(o,r){if(!n[o]){if(!t[o]){var l="function"==typeof require&&require;if(!r&&l)return l(o,!0);if(a)return a(o,!0);var d=new Error("Cannot find module '"+o+"'");throw d.code="MODULE_NOT_FOUND",d}var c=n[o]={exports:{}};t[o][0].call(c.exports,function(e){var n=t[o][1][e];return s(n?n:e)},c,c.exports,e,t,n,i)}return n[o].exports}for(var a="function"==typeof require&&require,o=0;o<i.length;o++)s(i[o]);return s}({1:[function(e,t,n){"use strict";e("../legacy/LeftAndMain.Layout.js"),e("../legacy/LeftAndMain.js"),e("../legacy/LeftAndMain.ActionTabSet.js"),e("../legacy/LeftAndMain.Panel.js"),e("../legacy/LeftAndMain.Tree.js"),e("../legacy/LeftAndMain.Content.js"),e("../legacy/LeftAndMain.EditForm.js"),e("../legacy/LeftAndMain.Menu.js"),e("../legacy/LeftAndMain.Preview.js"),e("../legacy/LeftAndMain.BatchActions.js"),e("../legacy/LeftAndMain.FieldHelp.js"),e("../legacy/LeftAndMain.FieldDescriptionToggle.js"),e("../legacy/LeftAndMain.TreeDropdownField.js")},{"../legacy/LeftAndMain.ActionTabSet.js":2,"../legacy/LeftAndMain.BatchActions.js":3,"../legacy/LeftAndMain.Content.js":4,"../legacy/LeftAndMain.EditForm.js":5,"../legacy/LeftAndMain.FieldDescriptionToggle.js":6,"../legacy/LeftAndMain.FieldHelp.js":7,"../legacy/LeftAndMain.Layout.js":8,"../legacy/LeftAndMain.Menu.js":9,"../legacy/LeftAndMain.Panel.js":10,"../legacy/LeftAndMain.Preview.js":11,"../legacy/LeftAndMain.Tree.js":12,"../legacy/LeftAndMain.TreeDropdownField.js":13,"../legacy/LeftAndMain.js":14}],2:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss",function(e){e(".ss-tabset.ss-ui-action-tabset").entwine({IgnoreTabState:!0,onadd:function(){this._super(),this.tabs({collapsible:!0,active:!1})},onremove:function(){var t=e(".cms-container").find("iframe");t.each(function(t,n){try{e(n).contents().off("click.ss-ui-action-tabset")}catch(i){console.warn("Unable to access iframe, possible https mis-match")}}),e(document).off("click.ss-ui-action-tabset"),this._super()},ontabsbeforeactivate:function(e,t){this.riseUp(e,t)},onclick:function(e,t){this.attachCloseHandler(e,t)},attachCloseHandler:function(t,n){var i,s=this,a=e(".cms-container").find("iframe");i=function(t){var n,a;n=e(t.target).closest(".ss-ui-action-tabset .ui-tabs-panel"),e(t.target).closest(s).length||n.length||(s.tabs("option","active",!1),a=e(".cms-container").find("iframe"),a.each(function(t,n){e(n).contents().off("click.ss-ui-action-tabset",i)}),e(document).off("click.ss-ui-action-tabset",i))},e(document).on("click.ss-ui-action-tabset",i),a.length>0&&a.each(function(t,n){e(n).contents().on("click.ss-ui-action-tabset",i)})},riseUp:function(t,n){var i,s,a,o,r,l,d,c,u;return i=e(this).find(".ui-tabs-panel").outerHeight(),s=e(this).find(".ui-tabs-nav").outerHeight(),a=e(window).height()+e(document).scrollTop()-s,o=e(this).find(".ui-tabs-nav").offset().top,r=n.newPanel,l=n.newTab,o+i>=a&&o-i>0?(this.addClass("rise-up"),null!==l.position()&&(d=-r.outerHeight(),c=r.parents(".south"),c&&(u=l.offset().top-c.offset().top,d-=u),e(r).css("top",d+"px"))):(this.removeClass("rise-up"),null!==l.position()&&e(r).css("top","0px")),!1}}),e(".cms-content-actions .ss-tabset.ss-ui-action-tabset").entwine({ontabsbeforeactivate:function(t,n){this._super(t,n),e(n.newPanel).length>0&&e(n.newPanel).css("left",n.newTab.position().left+"px")}}),e(".cms-actions-row.ss-tabset.ss-ui-action-tabset").entwine({ontabsbeforeactivate:function(t,n){this._super(t,n),e(this).closest(".ss-ui-action-tabset").removeClass("tabset-open tabset-open-last")}}),e(".cms-content-fields .ss-tabset.ss-ui-action-tabset").entwine({ontabsbeforeactivate:function(t,n){this._super(t,n),e(n.newPanel).length>0&&(e(n.newTab).hasClass("last")?(e(n.newPanel).css({left:"auto",right:"0px"}),e(n.newPanel).parent().addClass("tabset-open-last")):(e(n.newPanel).css("left",n.newTab.position().left+"px"),e(n.newTab).hasClass("first")&&(e(n.newPanel).css("left","0px"),e(n.newPanel).parent().addClass("tabset-open"))))}}),e(".cms-tree-view-sidebar .cms-actions-row.ss-tabset.ss-ui-action-tabset").entwine({"from .ui-tabs-nav li":{onhover:function(t){e(t.target).parent().find("li .active").removeClass("active"),e(t.target).find("a").addClass("active")}},ontabsbeforeactivate:function(t,n){this._super(t,n),e(n.newPanel).css({left:"auto",right:"auto"}),e(n.newPanel).length>0&&e(n.newPanel).parent().addClass("tabset-open")}})})},{jQuery:"jQuery"}],3:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s),o=e("i18n"),r=i(o);a["default"].entwine("ss.tree",function(e){e("#Form_BatchActionsForm").entwine({Actions:[],getTree:function(){return e(".cms-tree")},fromTree:{oncheck_node:function(e,t){this.serializeFromTree()},onuncheck_node:function(e,t){this.serializeFromTree()}},registerDefault:function(){this.register("admin/pages/batchactions/publish",function(e){var t=confirm(r["default"].inject(r["default"]._t("CMSMAIN.BATCH_PUBLISH_PROMPT","You have {num} page(s) selected.\n\nDo you really want to publish?"),{num:e.length}));return t?e:!1}),this.register("admin/pages/batchactions/unpublish",function(e){var t=confirm(r["default"].inject(r["default"]._t("CMSMAIN.BATCH_UNPUBLISH_PROMPT","You have {num} page(s) selected.\n\nDo you really want to unpublish"),{num:e.length}));return t?e:!1}),this.register("admin/pages/batchactions/delete",function(e){var t=confirm(r["default"].inject(r["default"]._t("CMSMAIN.BATCH_DELETE_PROMPT","You have {num} page(s) selected.\n\nDo you really want to delete?"),{num:e.length}));return t?e:!1}),this.register("admin/pages/batchactions/archive",function(e){var t=confirm(r["default"].inject(r["default"]._t("CMSMAIN.BATCH_ARCHIVE_PROMPT","You have {num} page(s) selected.\n\nAre you sure you want to archive these pages?\n\nThese pages and all of their children pages will be unpublished and sent to the archive."),{num:e.length}));return t?e:!1}),this.register("admin/pages/batchactions/restore",function(e){var t=confirm(r["default"].inject(r["default"]._t("CMSMAIN.BATCH_RESTORE_PROMPT","You have {num} page(s) selected.\n\nDo you really want to restore to stage?\n\nChildren of archived pages will be restored to the root level, unless those pages are also being restored."),{num:e.length}));return t?e:!1}),this.register("admin/pages/batchactions/deletefromlive",function(e){var t=confirm(r["default"].inject(r["default"]._t("CMSMAIN.BATCH_DELETELIVE_PROMPT","You have {num} page(s) selected.\n\nDo you really want to delete these pages from live?"),{num:e.length}));return t?e:!1})},onadd:function(){this.registerDefault(),this._super()},register:function(e,t){this.trigger("register",{type:e,callback:t});var n=this.getActions();n[e]=t,this.setActions(n)},unregister:function(e){this.trigger("unregister",{type:e});var t=this.getActions();t[e]&&delete t[e],this.setActions(t)},refreshSelected:function(t){var n=this,i=this.getTree(),s=this.getIDs(),a=[],o=e(".cms-content-batchactions-button"),r=this.find(":input[name=Action]").val();null==t&&(t=i);for(var l in s)e(e(i).getNodeByID(l)).addClass("selected").attr("selected","selected");if(!r||-1==r||!o.hasClass("active"))return void e(t).find("li").each(function(){e(this).setEnabled(!0)});e(t).find("li").each(function(){a.push(e(this).data("id")),e(this).addClass("treeloading").setEnabled(!1)});var d=e.path.parseUrl(r),c=d.hrefNoSearch+"/applicablepages/";c=e.path.addSearchParams(c,d.search),c=e.path.addSearchParams(c,{csvIDs:a.join(",")}),jQuery.getJSON(c,function(i){jQuery(t).find("li").each(function(){e(this).removeClass("treeloading");var t=e(this).data("id");0==t||e.inArray(t,i)>=0?e(this).setEnabled(!0):(e(this).removeClass("selected").setEnabled(!1),e(this).prop("selected",!1))}),n.serializeFromTree()})},serializeFromTree:function(){var e=this.getTree(),t=e.getSelectedIDs();return this.setIDs(t),!0},setIDs:function(e){this.find(":input[name=csvIDs]").val(e?e.join(","):null)},getIDs:function(){var e=this.find(":input[name=csvIDs]").val();return e?e.split(","):[]},onsubmit:function(t){var n=this,i=this.getIDs(),s=this.getTree(),a=this.getActions();if(!i||!i.length)return alert(r["default"]._t("CMSMAIN.SELECTONEPAGE","Please select at least one page")),t.preventDefault(),!1;var o=this.find(":input[name=Action]").val();if(a[o]&&(i=this.getActions()[o].apply(this,[i])),!i||!i.length)return t.preventDefault(),!1;this.setIDs(i),s.find("li").removeClass("failed");var l=this.find(":submit:first");return l.addClass("loading"),jQuery.ajax({url:o,type:"POST",data:this.serializeArray(),complete:function(e,t){l.removeClass("loading"),s.jstree("refresh",-1),n.setIDs([]),n.find(":input[name=Action]").val("").change();var i=e.getResponseHeader("X-Status");i&&statusMessage(decodeURIComponent(i),"success"==t?"good":"bad")},success:function(t,n){var i,a;if(t.modified){var o=[];for(i in t.modified)a=s.getNodeByID(i),s.jstree("set_text",a,t.modified[i].TreeTitle),o.push(a);e(o).effect("highlight")}if(t.deleted)for(i in t.deleted)a=s.getNodeByID(i),a.length&&s.jstree("delete_node",a);if(t.error)for(i in t.error)a=s.getNodeByID(i),e(a).addClass("failed")},dataType:"json"}),t.preventDefault(),!1}}),e(".cms-content-batchactions-button").entwine({onmatch:function(){this._super(),this.updateTree()},onunmatch:function(){this._super()},onclick:function(e){this.updateTree()},updateTree:function(){var t=e(".cms-tree"),n=e("#Form_BatchActionsForm");this._super(),this.data("active")?(t.addClass("multiple"),t.removeClass("draggable"),n.serializeFromTree()):(t.removeClass("multiple"),t.addClass("draggable")),e("#Form_BatchActionsForm").refreshSelected()}}),e("#Form_BatchActionsForm select[name=Action]").entwine({onchange:function(t){var n=e(t.target.form),i=n.find(":submit"),s=e(t.target).val();s&&-1!=s?i.removeAttr("disabled").button("refresh"):i.attr("disabled","disabled").button("refresh"),e("#Form_BatchActionsForm").refreshSelected(),this.trigger("chosen:updated"),this._super(t)}})})},{i18n:"i18n",jQuery:"jQuery"}],4:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss",function(e){e(".cms-content").entwine({onadd:function(){this.find(".cms-tabset").redrawTabs(),this._super()},redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0)),this.add(this.find(".cms-tabset")).redrawTabs(),this.find(".cms-content-header").redraw(),this.find(".cms-content-actions").redraw()}}),e(".cms-content .cms-tree").entwine({onadd:function(){var t=this;this._super(),this.bind("select_node.jstree",function(n,i){var s=i.rslt.obj,a=t.find(":input[name=ID]").val(),o=i.args[2],r=e(".cms-container");if(!o)return!1;if(e(s).hasClass("disabled"))return!1;if(e(s).data("id")!=a){var l=e(s).find("a:first").attr("href");l&&"#"!=l?(l=l.split("?")[0],t.jstree("deselect_all"),t.jstree("uncheck_all"),e.path.isExternal(e(s).find("a:first"))&&(l=l=e.path.makeUrlAbsolute(l,e("base").attr("href"))),document.location.search&&(l=e.path.addSearchParams(l,document.location.search.replace(/^\?/,""))),r.loadPanel(l)):t.removeForm()}})}}),e(".cms-content .cms-content-fields").entwine({redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0))}}),e(".cms-content .cms-content-header, .cms-content .cms-content-actions").entwine({redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0)),this.height("auto"),this.height(this.innerHeight()-this.css("padding-top")-this.css("padding-bottom"))}})})},{jQuery:"jQuery"}],5:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s),o=e("i18n"),r=i(o);window.onbeforeunload=function(e){var t=(0,a["default"])(".cms-edit-form");return t.trigger("beforesubmitform"),t.is(".changed")&&!t.is(".discardchanges")?r["default"]._t("LeftAndMain.CONFIRMUNSAVEDSHORT"):void 0},a["default"].entwine("ss",function(e){e(".cms-edit-form").entwine({PlaceholderHtml:"",ChangeTrackerOptions:{ignoreFieldSelector:".no-change-track, .ss-upload :input, .cms-navigator :input"},onadd:function(){this.attr("autocomplete","off"),this._setupChangeTracker();for(var t in{action:!0,method:!0,enctype:!0,name:!0}){var n=this.find(":input[name=_form_"+t+"]");n&&(this.attr(t,n.val()),n.remove())}if(this.hasClass("validationerror")){var i=this.find(".message.validation, .message.required").first().closest(".tab");e(".cms-container").clearCurrentTabState(),i.closest(".ss-tabset").tabs("option","active",i.index(".tab"))}this._super()},onremove:function(){this.changetracker("destroy"),this._super()},onmatch:function(){this._super()},onunmatch:function(){this._super()},redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0)),this.add(this.find(".cms-tabset")).redrawTabs(),this.find(".cms-content-header").redraw()},_setupChangeTracker:function(){this.changetracker(this.getChangeTrackerOptions())},confirmUnsavedChanges:function(){if(this.trigger("beforesubmitform"),!this.is(".changed")||this.is(".discardchanges"))return!0;var e=confirm(r["default"]._t("LeftAndMain.CONFIRMUNSAVED"));return e&&this.addClass("discardchanges"),e},onsubmit:function(e,t){return"_blank"!=this.prop("target")?(t&&this.closest(".cms-container").submitForm(this,t),!1):void 0},validate:function(){var e=!0;return this.trigger("validate",{isValid:e}),e},"from .htmleditor":{oneditorinit:function(t){var n=this,i=e(t.target).closest(".field.htmleditor"),s=i.find("textarea.htmleditor").getEditor().getInstance();s.onClick.add(function(e){n.saveFieldFocus(i.attr("id"))})}},"from .cms-edit-form :input:not(:submit)":{onclick:function(t){this.saveFieldFocus(e(t.target).attr("id"))},onfocus:function(t){this.saveFieldFocus(e(t.target).attr("id"))}},"from .cms-edit-form .treedropdown *":{onfocusin:function(t){var n=e(t.target).closest(".field.treedropdown");this.saveFieldFocus(n.attr("id"))}},"from .cms-edit-form .dropdown .chosen-container a":{onfocusin:function(t){var n=e(t.target).closest(".field.dropdown");this.saveFieldFocus(n.attr("id"))}},"from .cms-container":{ontabstaterestored:function(e){this.restoreFieldFocus()}},saveFieldFocus:function(t){if("undefined"!=typeof window.sessionStorage&&null!==window.sessionStorage){var n=e(this).attr("id"),i=[];if(i.push({id:n,selected:t}),i)try{window.sessionStorage.setItem(n,JSON.stringify(i))}catch(s){if(s.code===DOMException.QUOTA_EXCEEDED_ERR&&0===window.sessionStorage.length)return;throw s}}},restoreFieldFocus:function(){if("undefined"!=typeof window.sessionStorage&&null!==window.sessionStorage){var t,n,i,s,a,o=this,r="undefined"!=typeof window.sessionStorage&&window.sessionStorage,l=r?window.sessionStorage.getItem(this.attr("id")):null,d=l?JSON.parse(l):!1,c=0!==this.find(".ss-tabset").length;if(r&&d.length>0){if(e.each(d,function(n,i){o.is("#"+i.id)&&(t=e("#"+i.selected))}),e(t).length<1)return void this.focusFirstInput();if(n=e(t).closest(".ss-tabset").find(".ui-tabs-nav .ui-tabs-active .ui-tabs-anchor").attr("id"),i="tab-"+e(t).closest(".ss-tabset .ui-tabs-panel").attr("id"),c&&i!==n)return;s=e(t).closest(".togglecomposite"),s.length>0&&s.accordion("activate",s.find(".ui-accordion-header")),a=e(t).position().top,e(t).is(":visible")||(t="#"+e(t).closest(".field").attr("id"),a=e(t).position().top),e(t).focus(),a>e(window).height()/2&&o.find(".cms-content-fields").scrollTop(a)}else this.focusFirstInput()}},focusFirstInput:function(){this.find(':input:not(:submit)[data-skip-autofocus!="true"]').filter(":visible:first").focus()}}),e(".cms-edit-form .Actions input.action[type=submit], .cms-edit-form .Actions button.action").entwine({onclick:function(e){return this.hasClass("gridfield-button-delete")&&!confirm(r["default"]._t("TABLEFIELD.DELETECONFIRMMESSAGE"))?(e.preventDefault(),!1):(this.is(":disabled")||this.parents("form").trigger("submit",[this]),e.preventDefault(),!1)}}),e(".cms-edit-form .Actions input.action[type=submit].ss-ui-action-cancel, .cms-edit-form .Actions button.action.ss-ui-action-cancel").entwine({onclick:function(e){window.history.length>1?window.history.back():this.parents("form").trigger("submit",[this]),e.preventDefault()}}),e(".cms-edit-form .ss-tabset").entwine({onmatch:function(){if(!this.hasClass("ss-ui-action-tabset")){var e=this.find("> ul:first");1==e.children("li").length&&e.hide().parent().addClass("ss-tabset-tabshidden")}this._super()},onunmatch:function(){this._super()}})})},{i18n:"i18n",jQuery:"jQuery"}],6:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss",function(e){e(".cms-description-toggle").entwine({onadd:function(){var e=!1,t=this.prop("id").substr(0,this.prop("id").indexOf("_Holder")),n=this.find(".cms-description-trigger"),i=this.find(".description");this.hasClass("description-toggle-enabled")||(0===n.length&&(n=this.find(".middleColumn").first().after('<label class="right" for="'+t+'"><a class="cms-description-trigger" href="javascript:void(0)"><span class="btn-icon-information"></span></a></label>').next()),this.addClass("description-toggle-enabled"),n.on("click",function(){i[e?"hide":"show"](),e=!e}),i.hide())}})})},{jQuery:"jQuery"}],7:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss",function(e){e(".cms .field.cms-description-tooltip").entwine({onmatch:function(){this._super();var e=this.find(".description");e.length&&(this.attr("title",e.text()).tooltip({content:e.html()}),e.remove())}}),e(".cms .field.cms-description-tooltip :input").entwine({onfocusin:function(e){this.closest(".field").tooltip("open")},onfocusout:function(e){this.closest(".field").tooltip("close")}})})},{jQuery:"jQuery"}],8:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].fn.layout.defaults.resize=!1,jLayout="undefined"==typeof jLayout?{}:jLayout,jLayout.threeColumnCompressor=function(e,t){function n(e){var t=e+"Size";return function(e){var n=s[t](),i=o[t](),a=r[t](),l=e.insets();return width=n.width+i.width+a.width,height=Math.max(n.height,i.height,a.height),{width:l.left+l.right+width,height:l.top+l.bottom+height}}}if("undefined"==typeof e.menu||"undefined"==typeof e.content||"undefined"==typeof e.preview)throw'Spec is invalid. Please provide "menu", "content" and "preview" elements.';if("undefined"==typeof t.minContentWidth||"undefined"==typeof t.minPreviewWidth||"undefined"==typeof t.mode)throw'Spec is invalid. Please provide "minContentWidth", "minPreviewWidth", "mode"';if("split"!==t.mode&&"content"!==t.mode&&"preview"!==t.mode)throw'Spec is invalid. "mode" should be either "split", "content" or "preview"';var i={options:t},s=a["default"].jLayoutWrap(e.menu),o=a["default"].jLayoutWrap(e.content),r=a["default"].jLayoutWrap(e.preview);return i.layout=function(n){var i=n.bounds(),a=n.insets(),l=a.top,d=i.height-a.bottom,c=a.left,u=i.width-a.right,h=e.menu.width(),f=0,p=0;"preview"===this.options.mode?(f=0,p=u-c-h):"content"===this.options.mode?(f=u-c-h,p=0):(f=(u-c-h)/2,p=u-c-(h+f),f<this.options.minContentWidth?(f=this.options.minContentWidth,p=u-c-(h+f)):p<this.options.minPreviewWidth&&(p=this.options.minPreviewWidth,f=u-c-(h+p)),(f<this.options.minContentWidth||p<this.options.minPreviewWidth)&&(f=u-c-h,p=0));var m={content:e.content.hasClass("column-hidden"),preview:e.preview.hasClass("column-hidden")},g={content:0===f,preview:0===p};return e.content.toggleClass("column-hidden",g.content),e.preview.toggleClass("column-hidden",g.preview),s.bounds({x:c,y:l,height:d-l,width:h}),s.doLayout(),c+=h,o.bounds({x:c,y:l,height:d-l,width:f}),g.content||o.doLayout(),c+=f,r.bounds({x:c,y:l,height:d-l,width:p}),g.preview||r.doLayout(),g.content!==m.content&&e.content.trigger("columnvisibilitychanged"),g.preview!==m.preview&&e.preview.trigger("columnvisibilitychanged"),f+p<t.minContentWidth+t.minPreviewWidth?e.preview.trigger("disable"):e.preview.trigger("enable"),n},i.preferred=n("preferred"),i.minimum=n("minimum"),i.maximum=n("maximum"),i}},{jQuery:"jQuery"}],9:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss",function(e){e(".cms-panel.cms-menu").entwine({togglePanel:function(t,n,i){e(".cms-menu-list").children("li").each(function(){t?e(this).children("ul").each(function(){e(this).removeClass("collapsed-flyout"),e(this).data("collapse")&&(e(this).removeData("collapse"),e(this).addClass("collapse"))}):e(this).children("ul").each(function(){e(this).addClass("collapsed-flyout"),e(this).hasClass("collapse"),e(this).removeClass("collapse"),e(this).data("collapse",!0)})}),this.toggleFlyoutState(t),this._super(t,n,i)},toggleFlyoutState:function(t){if(t)e(".collapsed").find("li").show(),e(".cms-menu-list").find(".child-flyout-indicator").hide();else{e(".collapsed-flyout").find("li").each(function(){e(this).hide()});var n=e(".cms-menu-list ul.collapsed-flyout").parent();0===n.children(".child-flyout-indicator").length&&n.append('<span class="child-flyout-indicator"></span>').fadeIn(),n.children(".child-flyout-indicator").fadeIn()}},siteTreePresent:function(){return e("#cms-content-tools-CMSMain").length>0},getPersistedStickyState:function(){var t,n;return void 0!==e.cookie&&(n=e.cookie("cms-menu-sticky"),void 0!==n&&null!==n&&(t="true"===n)),t},setPersistedStickyState:function(t){void 0!==e.cookie&&e.cookie("cms-menu-sticky",t,{path:"/",expires:31})},getEvaluatedCollapsedState:function(){var t,n=this.getPersistedCollapsedState(),i=e(".cms-menu").getPersistedStickyState(),s=this.siteTreePresent();return t=void 0===n?s:n!==s&&i?n:s},onadd:function(){var t=this;setTimeout(function(){t.togglePanel(!t.getEvaluatedCollapsedState(),!1,!1)},0),e(window).on("ajaxComplete",function(e){setTimeout(function(){t.togglePanel(!t.getEvaluatedCollapsedState(),!1,!1)},0)}),this._super()}}),e(".cms-menu-list").entwine({onmatch:function(){this.find("li.current").select(),this.updateItems(),this._super()},onunmatch:function(){this._super()},updateMenuFromResponse:function(e){var t=e.getResponseHeader("X-Controller");if(t){var n=this.find("li#Menu-"+t.replace(/\\/g,"-").replace(/[^a-zA-Z0-9\-_:.]+/,""));n.hasClass("current")||n.select()}this.updateItems()},"from .cms-container":{onafterstatechange:function(e,t){this.updateMenuFromResponse(t.xhr)},onaftersubmitform:function(e,t){this.updateMenuFromResponse(t.xhr)}},"from .cms-edit-form":{onrelodeditform:function(e,t){this.updateMenuFromResponse(t.xmlhttp)}},getContainingPanel:function(){return this.closest(".cms-panel")},fromContainingPanel:{ontoggle:function(t){this.toggleClass("collapsed",e(t.target).hasClass("collapsed")),e(".cms-container").trigger("windowresize"),this.hasClass("collapsed")&&this.find("li.children.opened").removeClass("opened"),this.hasClass("collapsed")||e(".toggle-children.opened").closest("li").addClass("opened")}},updateItems:function(){var t=this.find("#Menu-CMSMain");t[t.is(".current")?"show":"hide"]();var n=e(".cms-content input[name=ID]").val();n&&this.find("li").each(function(){e.isFunction(e(this).setRecordID)&&e(this).setRecordID(n)})}}),e(".cms-menu-list li").entwine({toggleFlyout:function(t){var n=e(this);if(n.children("ul").first().hasClass("collapsed-flyout"))if(t){if(!n.children("ul").first().children("li").first().hasClass("clone")){var i=n.clone();i.addClass("clone").css({}),i.children("ul").first().remove(),i.find("span").not(".text").remove(),i.find("a").first().unbind("click"),n.children("ul").prepend(i)}e(".collapsed-flyout").show(),n.addClass("opened"),n.children("ul").find("li").fadeIn("fast")}else i&&i.remove(),e(".collapsed-flyout").hide(),n.removeClass("opened"),n.find("toggle-children").removeClass("opened"),n.children("ul").find("li").hide()}}),e(".cms-menu-list li").hoverIntent(function(){e(this).toggleFlyout(!0)},function(){e(this).toggleFlyout(!1)}),e(".cms-menu-list .toggle").entwine({onclick:function(t){t.preventDefault(),e(this).toogleFlyout(!0)}}),e(".cms-menu-list li").entwine({onmatch:function(){this.find("ul").length&&this.find("a:first").append('<span class="toggle-children"><span class="toggle-children-icon"></span></span>'),this._super()},onunmatch:function(){this._super()},toggle:function(){this[this.hasClass("opened")?"close":"open"]()},open:function(){var e=this.getMenuItem();e&&e.open(),this.find("li.clone")&&this.find("li.clone").remove(),this.addClass("opened").find("ul").show(),this.find(".toggle-children").addClass("opened")},close:function(){this.removeClass("opened").find("ul").hide(),this.find(".toggle-children").removeClass("opened")},select:function(){var e=this.getMenuItem();if(this.addClass("current").open(),this.siblings().removeClass("current").close(),this.siblings().find("li").removeClass("current"),e){var t=e.siblings();e.addClass("current"),t.removeClass("current").close(),t.find("li").removeClass("current").close()}this.getMenu().updateItems(),this.trigger("select")}}),e(".cms-menu-list *").entwine({getMenu:function(){return this.parents(".cms-menu-list:first")}}),e(".cms-menu-list li *").entwine({getMenuItem:function(){return this.parents("li:first")}}),e(".cms-menu-list li a").entwine({onclick:function(t){var n=e.path.isExternal(this.attr("href"));if(!(t.which>1||n)&&"_blank"!=this.attr("target")){t.preventDefault();var i=this.getMenuItem(),s=this.attr("href");n||(s=e("base").attr("href")+s);var a=i.find("li");if(a.length)a.first().find("a").click();else if(!e(".cms-container").loadPanel(s))return!1;i.select()}}}),e(".cms-menu-list li .toggle-children").entwine({onclick:function(e){var t=this.closest("li");return t.toggle(),!1}}),e(".cms .profile-link").entwine({onclick:function(){return e(".cms-container").loadPanel(this.attr("href")),e(".cms-menu-list li").removeClass("current").close(),!1}}),e(".cms-menu .sticky-toggle").entwine({onadd:function(){var t=!!e(".cms-menu").getPersistedStickyState();this.toggleCSS(t),this.toggleIndicator(t),this._super()},toggleCSS:function(e){this[e?"addClass":"removeClass"]("active")},toggleIndicator:function(e){this.next(".sticky-status-indicator").text(e?"fixed":"auto")},onclick:function(){var e=this.closest(".cms-menu"),t=e.getPersistedCollapsedState(),n=e.getPersistedStickyState(),i=void 0===n?!this.hasClass("active"):!n;void 0===t?e.setPersistedCollapsedState(e.hasClass("collapsed")):void 0!==t&&i===!1&&e.clearPersistedCollapsedState(),e.setPersistedStickyState(i),this.toggleCSS(i),this.toggleIndicator(i),this._super()}})})},{jQuery:"jQuery"}],10:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss",function(e){e.entwine.warningLevel=e.entwine.WARN_LEVEL_BESTPRACTISE,e(".cms-panel").entwine({WidthExpanded:null,WidthCollapsed:null,canSetCookie:function(){return void 0!==e.cookie&&void 0!==this.attr("id")},getPersistedCollapsedState:function(){var t,n;return this.canSetCookie()&&(n=e.cookie("cms-panel-collapsed-"+this.attr("id")),void 0!==n&&null!==n&&(t="true"===n)),t},setPersistedCollapsedState:function(t){this.canSetCookie()&&e.cookie("cms-panel-collapsed-"+this.attr("id"),t,{path:"/",expires:31})},clearPersistedCollapsedState:function(){this.canSetCookie()&&e.cookie("cms-panel-collapsed-"+this.attr("id"),"",{path:"/",expires:-1})},getInitialCollapsedState:function(){var e=this.getPersistedCollapsedState();return void 0===e&&(e=this.hasClass("collapsed")),e},onadd:function(){var t,n;if(!this.find(".cms-panel-content").length)throw new Exception('Content panel for ".cms-panel" not found');this.find(".cms-panel-toggle").length||(n=e("<div class='cms-panel-toggle south'></div>").append('<a class="toggle-expand" href="#"><span>&raquo;</span></a>').append('<a class="toggle-collapse" href="#"><span>&laquo;</span></a>'),this.append(n)),this.setWidthExpanded(this.find(".cms-panel-content").innerWidth()),t=this.find(".cms-panel-content-collapsed"),this.setWidthCollapsed(t.length?t.innerWidth():this.find(".toggle-expand").innerWidth()),this.togglePanel(!this.getInitialCollapsedState(),!0,!1),this._super()},togglePanel:function(e,t,n){var i,s;t||(this.trigger("beforetoggle.sspanel",e),this.trigger(e?"beforeexpand":"beforecollapse")),this.toggleClass("collapsed",!e),i=e?this.getWidthExpanded():this.getWidthCollapsed(),this.width(i),s=this.find(".cms-panel-content-collapsed"),s.length&&(this.find(".cms-panel-content")[e?"show":"hide"](),this.find(".cms-panel-content-collapsed")[e?"hide":"show"]()),n!==!1&&this.setPersistedCollapsedState(!e),this.trigger("toggle",e),this.trigger(e?"expand":"collapse")},expandPanel:function(e){(e||this.hasClass("collapsed"))&&this.togglePanel(!0)},collapsePanel:function(e){!e&&this.hasClass("collapsed")||this.togglePanel(!1)}}),e(".cms-panel.collapsed .cms-panel-toggle").entwine({onclick:function(e){this.expandPanel(),e.preventDefault()}}),e(".cms-panel *").entwine({getPanel:function(){return this.parents(".cms-panel:first")}}),e(".cms-panel .toggle-expand").entwine({onclick:function(e){e.preventDefault(),e.stopPropagation(),this.getPanel().expandPanel(),this._super(e)}}),e(".cms-panel .toggle-collapse").entwine({onclick:function(e){e.preventDefault(),e.stopPropagation(),this.getPanel().collapsePanel(),this._super(e)}}),e(".cms-content-tools.collapsed").entwine({onclick:function(e){this.expandPanel(),this._super(e)}})})},{jQuery:"jQuery"}],11:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s),o=e("i18n"),r=i(o);a["default"].entwine("ss.preview",function(e){e(".cms-preview").entwine({AllowedStates:["StageLink","LiveLink","ArchiveLink"],CurrentStateName:null,CurrentSizeName:"auto",IsPreviewEnabled:!1,DefaultMode:"split",Sizes:{auto:{width:"100%",height:"100%"},mobile:{width:"335px",height:"568px"},mobileLandscape:{width:"583px",height:"320px"},tablet:{width:"783px",height:"1024px"},tabletLandscape:{width:"1039px",height:"768px"},desktop:{width:"1024px",height:"800px"}},changeState:function(t,n){var i=this,s=this._getNavigatorStates();return n!==!1&&e.each(s,function(e,n){i.saveState("state",t)}),this.setCurrentStateName(t),this._loadCurrentState(),this.redraw(),this},changeMode:function(t,n){var i=e(".cms-container");if("split"==t)i.entwine(".ss").splitViewMode(),this.setIsPreviewEnabled(!0),this._loadCurrentState();else if("content"==t)i.entwine(".ss").contentViewMode(),this.setIsPreviewEnabled(!1);else{if("preview"!=t)throw"Invalid mode: "+t;i.entwine(".ss").previewMode(),this.setIsPreviewEnabled(!0),this._loadCurrentState()}return n!==!1&&this.saveState("mode",t),this.redraw(),this},changeSize:function(e){var t=this.getSizes();return this.setCurrentSizeName(e),this.removeClass("auto desktop tablet mobile").addClass(e),this.find(".preview-device-outer").width(t[e].width).height(t[e].height),this.find(".preview-device-inner").width(t[e].width),this.saveState("size",e),this.redraw(),this},redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0));var t=this.getCurrentStateName();t&&this.find(".cms-preview-states").changeVisibleState(t);var n=e(".cms-container").entwine(".ss").getLayoutOptions();n&&e(".preview-mode-selector").changeVisibleMode(n.mode);var i=this.getCurrentSizeName();return i&&this.find(".preview-size-selector").changeVisibleSize(this.getCurrentSizeName()),this},saveState:function(e,t){this._supportsLocalStorage()&&window.localStorage.setItem("cms-preview-state-"+e,t)},loadState:function(e){return this._supportsLocalStorage()?window.localStorage.getItem("cms-preview-state-"+e):void 0},disablePreview:function(){return this.setPendingURL(null),this._loadUrl("about:blank"),this._block(),this.changeMode("content",!1),this.setIsPreviewEnabled(!1),this},enablePreview:function(){return this.getIsPreviewEnabled()||(this.setIsPreviewEnabled(!0),e.browser.msie&&e.browser.version.slice(0,3)<=7?this.changeMode("content"):this.changeMode(this.getDefaultMode(),!1)),this},getOrAppendFontFixStyleElement:function(){var t=e("#FontFixStyleElement");return t.length||(t=e('<style type="text/css" id="FontFixStyleElement" disabled="disabled">:before,:after{content:none !important}</style>').appendTo("head")),
t},onadd:function(){var t=this,n=(this.parent(),this.find("iframe"));n.addClass("center"),n.bind("load",function(){t._adjustIframeForPreview(),t._loadCurrentPage(),e(this).removeClass("loading")}),e.browser.msie&&8===parseInt(e.browser.version,10)&&n.bind("readystatechange",function(e){"interactive"==n[0].readyState&&(t.getOrAppendFontFixStyleElement().removeAttr("disabled"),setTimeout(function(){t.getOrAppendFontFixStyleElement().attr("disabled","disabled")},0))}),this.append('<div class="cms-preview-overlay ui-widget-overlay-light"></div>'),this.find(".cms-preview-overlay").hide(),this.disablePreview(),this._super()},_supportsLocalStorage:function(){var e,t,n=new Date;try{return(e=window.localStorage).setItem(n,n),t=e.getItem(n)==n,e.removeItem(n),t&&e}catch(i){console.warn("localStorge is not available due to current browser / system settings.")}},onenable:function(){var t=e(".preview-mode-selector");t.removeClass("split-disabled"),t.find(".disabled-tooltip").hide()},ondisable:function(){var t=e(".preview-mode-selector");t.addClass("split-disabled"),t.find(".disabled-tooltip").show()},_block:function(){return this.addClass("blocked"),this.find(".cms-preview-overlay").show(),this},_unblock:function(){return this.removeClass("blocked"),this.find(".cms-preview-overlay").hide(),this},_initialiseFromContent:function(){var t,n;return e(".cms-previewable").length?(t=this.loadState("mode"),n=this.loadState("size"),this._moveNavigator(),t&&"content"==t||(this.enablePreview(),this._loadCurrentState()),this.redraw(),t&&this.changeMode(t),n&&this.changeSize(n)):this.disablePreview(),this},"from .cms-container":{onafterstatechange:function(e,t){t.xhr.getResponseHeader("X-ControllerURL")||this._initialiseFromContent()}},PendingURL:null,oncolumnvisibilitychanged:function(){var e=this.getPendingURL();e&&!this.is(".column-hidden")&&(this.setPendingURL(null),this._loadUrl(e),this._unblock())},"from .cms-container .cms-edit-form":{onaftersubmitform:function(){this._initialiseFromContent()}},_loadUrl:function(e){return this.find("iframe").addClass("loading").attr("src",e),this},_getNavigatorStates:function(){var t=e.map(this.getAllowedStates(),function(t){var n=e(".cms-preview-states .state-name[data-name="+t+"]");return n.length?{name:t,url:n.attr("data-link"),active:n.is(":radio")?n.is(":checked"):n.is(":selected")}:null});return t},_loadCurrentState:function(){if(!this.getIsPreviewEnabled())return this;var t=this._getNavigatorStates(),n=this.getCurrentStateName(),i=null;t&&(i=e.grep(t,function(e,t){return n===e.name||!n&&e.active}));var s=null;return i[0]?s=i[0].url:t.length?(this.setCurrentStateName(t[0].name),s=t[0].url):this.setCurrentStateName(null),s+=(-1===s.indexOf("?")?"?":"&")+"CMSPreview=1",this.is(".column-hidden")?(this.setPendingURL(s),this._loadUrl("about:blank"),this._block()):(this.setPendingURL(null),s?(this._loadUrl(s),this._unblock()):this._block()),this},_moveNavigator:function(){var t=e(".cms-preview .cms-preview-controls"),n=e(".cms-edit-form .cms-navigator");n.length&&t.length?t.html(e(".cms-edit-form .cms-navigator").detach()):this._block()},_loadCurrentPage:function(){if(this.getIsPreviewEnabled()){var t;e(".cms-container");try{t=this.find("iframe")[0].contentDocument}catch(n){console.warn("Unable to access iframe, possible https mis-match")}if(t){var i=e(t).find("meta[name=x-page-id]").attr("content"),s=e(t).find("meta[name=x-cms-edit-link]").attr("content"),a=e(".cms-content");i&&a.find(":input[name=ID]").val()!=i&&e(".cms-container").entwine(".ss").loadPanel(s)}}},_adjustIframeForPreview:function(){var e,t=this.find("iframe")[0];if(t){try{e=t.contentDocument}catch(n){console.warn("Unable to access iframe, possible https mis-match")}if(e){for(var i=e.getElementsByTagName("A"),s=0;s<i.length;s++){var a=i[s].getAttribute("href");a&&a.match(/^http:\/\//)&&i[s].setAttribute("target","_blank")}var o=e.getElementById("SilverStripeNavigator");o&&(o.style.display="none");var r=e.getElementById("SilverStripeNavigatorMessage");r&&(r.style.display="none"),this.trigger("afterIframeAdjustedForPreview",[e])}}}}),e(".cms-edit-form").entwine({onadd:function(){this._super(),e(".cms-preview")._initialiseFromContent()}}),e(".cms-preview-states").entwine({changeVisibleState:function(e){this.find('input[data-name="'+e+'"]').prop("checked",!0)}}),e(".cms-preview-states .state-name").entwine({onclick:function(t){this.parent().find(".active").removeClass("active"),this.next("label").addClass("active");var n=e(this).attr("data-name");e(".cms-preview").changeState(n)}}),e(".preview-mode-selector").entwine({changeVisibleMode:function(e){this.find("select").val(e).trigger("chosen:updated")._addIcon()}}),e(".preview-mode-selector select").entwine({onchange:function(t){this._super(t),t.preventDefault();var n=e(this).val();e(".cms-preview").changeMode(n)}}),e(".cms-preview.column-hidden").entwine({onmatch:function(){e("#preview-mode-dropdown-in-content").show(),e(".cms-preview .result-selected").hasClass("font-icon-columns")&&statusMessage(r["default"]._t("LeftAndMain.DISABLESPLITVIEW","Screen too small to show site preview in split mode"),"error"),this._super()},onunmatch:function(){e("#preview-mode-dropdown-in-content").hide(),this._super()}}),e("#preview-mode-dropdown-in-content").entwine({onmatch:function(){e(".cms-preview").is(".column-hidden")?this.show():this.hide(),this._super()},onunmatch:function(){this._super()}}),e(".preview-size-selector").entwine({changeVisibleSize:function(e){this.find("select").val(e).trigger("chosen:updated")._addIcon()}}),e(".preview-size-selector select").entwine({onchange:function(t){t.preventDefault();var n=e(this).val();e(".cms-preview").changeSize(n)}}),e(".preview-selector select.preview-dropdown").entwine({"onchosen:ready":function(){this._super(),this._addIcon()},_addIcon:function(){var e=this.find(":selected"),t=e.attr("data-icon"),n=this.parent().find(".chosen-container a.chosen-single"),i=n.attr("data-icon");return"undefined"!=typeof i&&n.removeClass(i),n.addClass(t),n.attr("data-icon",t),this}}),e(".preview-mode-selector .chosen-drop li:last-child").entwine({onmatch:function(){e(".preview-mode-selector").hasClass("split-disabled")?this.parent().append('<div class="disabled-tooltip"></div>'):this.parent().append('<div class="disabled-tooltip" style="display: none;"></div>')}}),e(".preview-device-outer").entwine({onclick:function(){this.toggleClass("rotate")}})})},{i18n:"i18n",jQuery:"jQuery"}],12:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss.tree",function(e){e(".cms-tree").entwine({Hints:null,IsUpdatingTree:!1,IsLoaded:!1,onadd:function(){if(this._super(),!e.isNumeric(this.data("jstree_instance_id"))){var t=this.attr("data-hints");t&&this.setHints(e.parseJSON(t));var n=this;this.jstree(this.getTreeConfig()).bind("loaded.jstree",function(t,i){n.setIsLoaded(!0),i.inst._set_settings({html_data:{ajax:{url:n.data("urlTree"),data:function(t){var i=n.data("searchparams")||[];return i=e.grep(i,function(e,t){return"ID"!=e.name&&"value"!=e.name}),i.push({name:"ID",value:e(t).data("id")?e(t).data("id"):0}),i.push({name:"ajax",value:1}),i}}}}),n.updateFromEditForm(),n.css("visibility","visible"),i.inst.hide_checkboxes()}).bind("before.jstree",function(t,i){if("start_drag"==i.func&&(!n.hasClass("draggable")||n.hasClass("multiselect")))return t.stopImmediatePropagation(),!1;if(e.inArray(i.func,["check_node","uncheck_node"])){var s=e(i.args[0]).parents("li:first"),a=s.find("li:not(.disabled)");if(s.hasClass("disabled")&&0==a)return t.stopImmediatePropagation(),!1}}).bind("move_node.jstree",function(t,i){if(!n.getIsUpdatingTree()){var s=i.rslt.o,a=i.rslt.np,o=(i.inst._get_parent(s),e(a).data("id")||0),r=e(s).data("id"),l=e.map(e(s).siblings().andSelf(),function(t){return e(t).data("id")});e.ajax({url:n.data("urlSavetreenode"),type:"POST",data:{ID:r,ParentID:o,SiblingIDs:l},success:function(){e(".cms-edit-form :input[name=ID]").val()==r&&e(".cms-edit-form :input[name=ParentID]").val(o),n.updateNodesFromServer([r])},statusCode:{403:function(){e.jstree.rollback(i.rlbk)}}})}}).bind("select_node.jstree check_node.jstree uncheck_node.jstree",function(t,n){e(document).triggerHandler(t,n)})}},onremove:function(){this.jstree("destroy"),this._super()},"from .cms-container":{onafterstatechange:function(e){this.updateFromEditForm()}},"from .cms-container form":{onaftersubmitform:function(t){var n=e(".cms-edit-form :input[name=ID]").val();this.updateNodesFromServer([n])}},getTreeConfig:function(){var t=this;return{core:{initially_open:["record-0"],animation:0,html_titles:!0},html_data:{},ui:{select_limit:1,initially_select:[this.find(".current").attr("id")]},crrm:{move:{check_move:function(n){var i=e(n.o),s=e(n.np),a=n.ot.get_container()[0]==n.np[0],o=i.getClassname(),r=s.getClassname(),l=t.getHints(),d=[],c=r?r:"Root",u=l&&"undefined"!=typeof l[c]?l[c]:null;u&&i.attr("class").match(/VirtualPage-([^\s]*)/)&&(o=RegExp.$1),u&&(d="undefined"!=typeof u.disallowedChildren?u.disallowedChildren:[]);var h=!(0===i.data("id")||i.hasClass("status-archived")||a&&"inside"!=n.p||s.hasClass("nochildren")||d.length&&-1!=e.inArray(o,d));return h}}},dnd:{drop_target:!1,drag_target:!1},checkbox:{two_state:!0},themes:{theme:"apple",url:e("body").data("frameworkpath")+"/thirdparty/jstree/themes/apple/style.css"},plugins:["html_data","ui","dnd","crrm","themes","checkbox"]}},search:function(e,t){e?this.data("searchparams",e):this.removeData("searchparams"),this.jstree("refresh",-1,t)},getNodeByID:function(e){return this.find("*[data-id="+e+"]")},createNode:function(t,n,i){var s=this,a=void 0!==n.ParentID?s.getNodeByID(n.ParentID):!1,o=e(t),r={data:""};o.hasClass("jstree-open")?r.state="open":o.hasClass("jstree-closed")&&(r.state="closed"),this.jstree("create_node",a.length?a:-1,"last",r,function(e){for(var t=e.attr("class"),n=0;n<o[0].attributes.length;n++){var s=o[0].attributes[n];e.attr(s.name,s.value)}e.addClass(t).html(o.html()),i(e)})},updateNode:function(t,n,i){var s=e(n),a=t.attr("class"),o=i.NextID?this.getNodeByID(i.NextID):!1,r=i.PrevID?this.getNodeByID(i.PrevID):!1,l=i.ParentID?this.getNodeByID(i.ParentID):!1;e.each(["id","style","class","data-pagetype"],function(e,n){t.attr(n,s.attr(n))}),a=a.replace(/status-[^\s]*/,"");var d=t.children("ul").detach();t.addClass(a).html(s.html()).append(d),o&&o.length?this.jstree("move_node",t,o,"before"):r&&r.length?this.jstree("move_node",t,r,"after"):this.jstree("move_node",t,l.length?l:-1)},updateFromEditForm:function(){var t,n=e(".cms-edit-form :input[name=ID]").val();n?(t=this.getNodeByID(n),t.length?(this.jstree("deselect_all"),this.jstree("select_node",t)):this.updateNodesFromServer([n])):this.jstree("deselect_all")},updateNodesFromServer:function(t){if(!this.getIsUpdatingTree()&&this.getIsLoaded()){var n=this,i=!1;this.setIsUpdatingTree(!0),n.jstree("save_selected");var s=function(e){n.getNodeByID(e.data("id")).not(e).remove(),n.jstree("deselect_all"),n.jstree("select_node",e)};n.jstree("open_node",this.getNodeByID(0)),n.jstree("save_opened"),n.jstree("save_selected"),e.ajax({url:e.path.addSearchParams(this.data("urlUpdatetreenodes"),"ids="+t.join(",")),dataType:"json",success:function(t,a){e.each(t,function(e,t){var a=n.getNodeByID(e);return t?void(a.length?(n.updateNode(a,t.html,t),setTimeout(function(){s(a)},500)):(i=!0,t.ParentID&&!n.find("li[data-id="+t.ParentID+"]").length?n.jstree("load_node",-1,function(){newNode=n.find("li[data-id="+e+"]"),s(newNode)}):n.createNode(t.html,t,function(e){s(e)}))):void n.jstree("delete_node",a)}),i||(n.jstree("deselect_all"),n.jstree("reselect"),n.jstree("reopen"))},complete:function(){n.setIsUpdatingTree(!1)}})}}}),e(".cms-tree.multiple").entwine({onmatch:function(){this._super(),this.jstree("show_checkboxes")},onunmatch:function(){this._super(),this.jstree("uncheck_all"),this.jstree("hide_checkboxes")},getSelectedIDs:function(){return e(this).jstree("get_checked").not(".disabled").map(function(){return e(this).data("id")}).get()}}),e(".cms-tree li").entwine({setEnabled:function(e){this.toggleClass("disabled",!e)},getClassname:function(){var e=this.attr("class").match(/class-([^\s]*)/i);return e?e[1]:""},getID:function(){return this.data("id")}})})},{jQuery:"jQuery"}],13:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss",function(e){e(".TreeDropdownField").entwine({"from .cms-container form":{onaftersubmitform:function(e){this.find(".tree-holder").empty(),this._super()}}})})},{jQuery:"jQuery"}],14:[function(require,module,exports){"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function getUrlPath(e){var t=document.createElement("a");return t.href=e,t.pathname}var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e},_jQuery=require("jQuery"),_jQuery2=_interopRequireDefault(_jQuery),_Router=require("lib/Router"),_Router2=_interopRequireDefault(_Router),_Config=require("lib/Config"),_Config2=_interopRequireDefault(_Config),windowWidth,windowHeight;_jQuery2["default"].noConflict(),window.ss=window.ss||{},window.ss.router=_Router2["default"],window.ss.debounce=function(e,t,n){var i,s,a,o=function(){i=null,n||e.apply(s,a)};return function(){var r=n&&!i;s=this,a=arguments,clearTimeout(i),i=setTimeout(o,t),r&&e.apply(s,a)}},(0,_jQuery2["default"])(window).bind("resize.leftandmain",function(e){(0,_jQuery2["default"])(".cms-container").trigger("windowresize")}),_jQuery2["default"].entwine.warningLevel=_jQuery2["default"].entwine.WARN_LEVEL_BESTPRACTISE,_jQuery2["default"].entwine("ss",function($){$(window).on("message",function(e){var t,n=e.originalEvent,i="object"===_typeof(n.data)?n.data:JSON.parse(n.data);if($.path.parseUrl(window.location.href).domain===$.path.parseUrl(n.origin).domain)switch(t=$("undefined"==typeof i.target?window:i.target),i.type){case"event":t.trigger(i.event,i.data);break;case"callback":t[i.callback].call(t,i.data)}});var positionLoadingSpinner=function(){var e=120,t=$(".ss-loading-screen .loading-animation"),n=($(window).height()-t.height())/2;t.css("top",n+e),t.show()},applyChosen=function e(t){t.is(":visible")?t.addClass("has-chosen").chosen({allow_single_deselect:!0,disable_search_threshold:20,display_disabled_options:!0}):setTimeout(function(){t.show(),e(t)},500)},isSameUrl=function(e,t){var n=$("base").attr("href");e=$.path.isAbsoluteUrl(e)?e:$.path.makeUrlAbsolute(e,n),t=$.path.isAbsoluteUrl(t)?t:$.path.makeUrlAbsolute(t,n);var i=$.path.parseUrl(e),s=$.path.parseUrl(t);return i.pathname.replace(/\/*$/,"")==s.pathname.replace(/\/*$/,"")&&i.search==s.search},ajaxCompleteEvent=window.ss.debounce(function(){$(window).trigger("ajaxComplete")},1e3,!0);$(window).bind("resize",positionLoadingSpinner).trigger("resize"),$(document).ajaxComplete(function(e,t,n){var i,s=t.getResponseHeader("X-ControllerURL"),a=n.url,o=null!==t.getResponseHeader("X-Status")?t.getResponseHeader("X-Status"):t.statusText,r=t.status<200||t.status>399?"bad":"good",l=["OK"];return i=window.history.state?window.history.state.path:document.URL,null===s||isSameUrl(i,s)&&isSameUrl(a,s)||_Router2["default"].show(s,{id:(new Date).getTime()+String(Math.random()).replace(/\D/g,""),pjax:t.getResponseHeader("X-Pjax")?t.getResponseHeader("X-Pjax"):n.headers["X-Pjax"]}),t.getResponseHeader("X-Reauthenticate")?void $(".cms-container").showLoginDialog():(0!==t.status&&o&&$.inArray(o,l)&&statusMessage(decodeURIComponent(o),r),void ajaxCompleteEvent(this))}),$(".cms-container").entwine({StateChangeXHR:null,FragmentXHR:{},StateChangeCount:0,LayoutOptions:{minContentWidth:940,minPreviewWidth:400,mode:"content"},onadd:function(){var e=this,t=getUrlPath($("base")[0].href);return t=t.replace(/\/$/,""),_Router2["default"].base(t),_Config2["default"].getTopLevelRoutes().forEach(function(t){(0,_Router2["default"])("/"+t+"(/*?)?",function(t,n){return"complete"!==document.readyState?n():void e.handleStateChange(null,t.state).done(n)})}),_Router2["default"].start(),$.browser.msie&&parseInt($.browser.version,10)<8?($(".ss-loading-screen").append('<p class="ss-loading-incompat-warning"><span class="notice">Your browser is not compatible with the CMS interface. Please use Internet Explorer 8+, Google Chrome or Mozilla Firefox.</span></p>').css("z-index",$(".ss-loading-screen").css("z-index")+1),$(".loading-animation").remove(),void this._super()):(this.redraw(),$(".ss-loading-screen").hide(),$("body").removeClass("loading"),$(window).unbind("resize",positionLoadingSpinner),this.restoreTabState(),void this._super())},fromWindow:{onstatechange:function(e,t){this.handleStateChange(e,t)}},onwindowresize:function(){this.redraw()},"from .cms-panel":{ontoggle:function(){this.redraw()}},"from .cms-container":{onaftersubmitform:function(){this.redraw()}},"from .cms-menu-list li a":{onclick:function(e){var t=$(e.target).attr("href");e.which>1||t==this._tabStateUrl()||this.splitViewMode()}},updateLayoutOptions:function(e){var t=this.getLayoutOptions(),n=!1;for(var i in e)t[i]!==e[i]&&(t[i]=e[i],n=!0);n&&this.redraw()},splitViewMode:function(){this.updateLayoutOptions({mode:"split"})},contentViewMode:function(){this.updateLayoutOptions({mode:"content"})},previewMode:function(){this.updateLayoutOptions({mode:"preview"})},RedrawSuppression:!1,redraw:function(){this.getRedrawSuppression()||(window.debug&&console.log("redraw",this.attr("class"),this.get(0)),this.data("jlayout",jLayout.threeColumnCompressor({menu:this.children(".cms-menu"),content:this.children(".cms-content"),preview:this.children(".cms-preview")},this.getLayoutOptions())),this.layout(),this.find(".cms-panel-layout").redraw(),this.find(".cms-content-fields[data-layout-type]").redraw(),this.find(".cms-edit-form[data-layout-type]").redraw(),this.find(".cms-preview").redraw(),this.find(".cms-content").redraw())},checkCanNavigate:function(e){var t=this._findFragments(e||["Content"]),n=t.find(":data(changetracker)").add(t.filter(":data(changetracker)")),i=!0;return n.length?(n.each(function(){$(this).confirmUnsavedChanges()||(i=!1)}),i):!0},loadPanel:function(e){var t=(arguments.length<=1||void 0===arguments[1]?"":arguments[1],arguments.length<=2||void 0===arguments[2]?{}:arguments[2]),n=arguments[3],i=arguments.length<=4||void 0===arguments[4]?window.history.state.path:arguments[4];this.checkCanNavigate(t.pjax?t.pjax.split(","):["Content"])&&(this.saveTabState(),t.__forceReferer=i,n&&(t.__forceReload=Math.random()),_Router2["default"].show(e,t))},reloadCurrentPanel:function(){this.loadPanel(window.history.state.path,null,null,!0)},submitForm:function(e,t,n,i){var s=this;t||(t=this.find(".Actions :submit[name=action_save]")),t||(t=this.find(".Actions :submit:first")),e.trigger("beforesubmitform"),this.trigger("submitform",{form:e,button:t}),$(t).addClass("loading");var a=e.validate();if("undefined"!=typeof a&&!a)return statusMessage("Validation failed.","bad"),$(t).removeClass("loading"),!1;var o=e.serializeArray();return o.push({name:$(t).attr("name"),value:"1"}),o.push({name:"BackURL",value:window.history.state.path.replace(/\/$/,"")}),this.saveTabState(),jQuery.ajax(jQuery.extend({headers:{"X-Pjax":"CurrentForm,Breadcrumbs"},url:e.attr("action"),data:o,type:"POST",complete:function(){$(t).removeClass("loading")},success:function(t,i,a){e.removeClass("changed"),n&&n(t,i,a);var r=s.handleAjaxResponse(t,i,a);r&&r.filter("form").trigger("aftersubmitform",{status:i,xhr:a,formData:o})}},i)),!1},LastState:null,PauseState:!1,handleStateChange:function(e){var t=arguments.length<=1||void 0===arguments[1]?window.history.state:arguments[1];if(!this.getPauseState()){this.getStateChangeXHR()&&this.getStateChangeXHR().abort();var n=this,i=t.pjax||"Content",s={},a=i.split(","),o=this._findFragments(a);if(this.setStateChangeCount(this.getStateChangeCount()+1),!this.checkCanNavigate()){var r=this.getLastState();return this.setPauseState(!0),null!==r?_Router2["default"].show(r.url):_Router2["default"].back(),void this.setPauseState(!1)}if(this.setLastState(t),o.length<a.length&&(i="Content",a=["Content"],o=this._findFragments(a)),this.trigger("beforestatechange",{state:t,element:o}),s["X-Pjax"]=i,"undefined"!=typeof t.__forceReferer){var l=t.__forceReferer;try{l=decodeURI(l)}catch(d){}finally{s["X-Backurl"]=encodeURI(l)}}o.addClass("loading");var c=$.ajax({headers:s,url:t.path}).done(function(e,i,s){var a=n.handleAjaxResponse(e,i,s,t);n.trigger("afterstatechange",{data:e,status:i,xhr:s,element:a,state:t})}).always(function(){n.setStateChangeXHR(null),o.removeClass("loading")});return this.setStateChangeXHR(c),c}},loadFragment:function(e,t){var n,i=this,s={},a=$("base").attr("href"),o=this.getFragmentXHR();return"undefined"!=typeof o[t]&&null!==o[t]&&(o[t].abort(),o[t]=null),e=$.path.isAbsoluteUrl(e)?e:$.path.makeUrlAbsolute(e,a),s["X-Pjax"]=t,n=$.ajax({headers:s,url:e,success:function(e,t,n){var s=i.handleAjaxResponse(e,t,n,null);i.trigger("afterloadfragment",{data:e,status:t,xhr:n,elements:s})},error:function(e,t,n){i.trigger("loadfragmenterror",{xhr:e,status:t,error:n})},complete:function(){var e=i.getFragmentXHR();"undefined"!=typeof e[t]&&null!==e[t]&&(e[t]=null)}}),o[t]=n,n},handleAjaxResponse:function(e,t,n,i){var s,a,o,r;if(n.getResponseHeader("X-Reload")&&n.getResponseHeader("X-ControllerURL")){var l=$("base").attr("href"),d=n.getResponseHeader("X-ControllerURL"),s=$.path.isAbsoluteUrl(d)?d:$.path.makeUrlAbsolute(d,l);return void(document.location.href=s)}if(e){var c=n.getResponseHeader("X-Title");c&&(document.title=decodeURIComponent(c.replace(/\+/g," ")));var u,h={};n.getResponseHeader("Content-Type").match(/^((text)|(application))\/json[ \t]*;?/i)?h=e:(o=document.createDocumentFragment(),jQuery.clean([e],document,o,[]),r=$(jQuery.merge([],o.childNodes)),a="Content",r.is("form")&&!r.is("[data-pjax-fragment~=Content]")&&(a="CurrentForm"),h[a]=r),this.setRedrawSuppression(!0);try{$.each(h,function(e,t){var n=$("[data-pjax-fragment]").filter(function(){return-1!=$.inArray(e,$(this).data("pjaxFragment").split(" "))}),i=$(t);if(u?u.add(i):u=i,i.find(".cms-container").length)throw'Content loaded via ajax is not allowed to contain tags matching the ".cms-container" selector to avoid infinite loops';var s=n.attr("style"),a=n.parent(),o="undefined"!=typeof a.data("jlayout"),r=["east","west","center","north","south","column-hidden"],l=n.attr("class"),d=[];l&&(d=$.grep(l.split(" "),function(e){return $.inArray(e,r)>=0})),i.removeClass(r.join(" ")).addClass(d.join(" ")),s&&i.attr("style",s);var c=i.find("style").detach();c.length&&$(document).find("head").append(c),n.replaceWith(i),!a.is(".cms-container")&&o&&a.layout()});var f=u.filter("form");f.hasClass("cms-tabset")&&f.removeClass("cms-tabset").addClass("cms-tabset")}finally{this.setRedrawSuppression(!1)}return this.redraw(),this.restoreTabState(i&&"undefined"!=typeof i.tabState?i.tabState:null),u}},_findFragments:function(e){return $("[data-pjax-fragment]").filter(function(){var t,n=$(this).data("pjaxFragment").split(" ");for(t in e)if(-1!=$.inArray(e[t],n))return!0;return!1})},refresh:function(){$(window).trigger("statechange"),$(this).redraw()},saveTabState:function(){if("undefined"!=typeof window.sessionStorage&&null!==window.sessionStorage){var e=[],t=this._tabStateUrl();if(this.find(".cms-tabset,.ss-tabset").each(function(t,n){var i=$(n).attr("id");i&&$(n).data("tabs")&&($(n).data("ignoreTabState")||$(n).getIgnoreTabState()||e.push({id:i,selected:$(n).tabs("option","selected")}))}),e){var n="tabs-"+t;try{window.sessionStorage.setItem(n,JSON.stringify(e))}catch(i){if(i.code===DOMException.QUOTA_EXCEEDED_ERR&&0===window.sessionStorage.length)return;throw i}}}},restoreTabState:function(e){var t=this,n=this._tabStateUrl(),i="undefined"!=typeof window.sessionStorage&&window.sessionStorage,s=i?window.sessionStorage.getItem("tabs-"+n):null,a=s?JSON.parse(s):!1;this.find(".cms-tabset, .ss-tabset").each(function(){var n,i,s=$(this),o=s.attr("id"),r=s.find(".ss-tabs-force-active");s.data("tabs")&&(s.tabs("refresh"),r.length?n=r.index():e&&e[o]?(i=s.find(e[o].tabSelector),i.length&&(n=i.index())):a&&$.each(a,function(e,t){s.is("#"+t.id)&&(n=t.selected)}),null!==n&&(s.tabs("option","active",n),t.trigger("tabstaterestored")))})},clearTabState:function(e){if("undefined"!=typeof window.sessionStorage){var t=window.sessionStorage;if(e)t.removeItem("tabs-"+e);else for(var n=0;n<t.length;n++)t.key(n).match(/^tabs-/)&&t.removeItem(t.key(n))}},clearCurrentTabState:function(){this.clearTabState(this._tabStateUrl())},_tabStateUrl:function(){return window.history.state.path.replace(/\?.*/,"").replace(/#.*/,"").replace($("base").attr("href"),"")},showLoginDialog:function(){var e=$("body").data("member-tempid"),t=$(".leftandmain-logindialog"),n="CMSSecurity/login";t.length&&t.remove(),n=$.path.addSearchParams(n,{tempid:e,BackURL:window.location.href}),t=$('<div class="leftandmain-logindialog"></div>'),t.attr("id",(new Date).getTime()),t.data("url",n),$("body").append(t)}}),$(".leftandmain-logindialog").entwine({onmatch:function(){this._super(),this.ssdialog({iframeUrl:this.data("url"),dialogClass:"leftandmain-logindialog-dialog",autoOpen:!0,minWidth:500,maxWidth:500,minHeight:370,maxHeight:400,closeOnEscape:!1,open:function(){$(".ui-widget-overlay").addClass("leftandmain-logindialog-overlay")},close:function(){$(".ui-widget-overlay").removeClass("leftandmain-logindialog-overlay")}})},onunmatch:function(){this._super()},open:function(){this.ssdialog("open")},close:function(){this.ssdialog("close")},toggle:function(e){this.is(":visible")?this.close():this.open()},reauthenticate:function(e){"undefined"!=typeof e.SecurityID&&$(":input[name=SecurityID]").val(e.SecurityID),"undefined"!=typeof e.TempID&&$("body").data("member-tempid",e.TempID),this.close()}}),$("form.loading,.cms-content.loading,.cms-content-fields.loading,.cms-content-view.loading").entwine({onmatch:function(){this.append('<div class="cms-content-loading-overlay ui-widget-overlay-light"></div><div class="cms-content-loading-spinner"></div>'),this._super()},onunmatch:function(){this.find(".cms-content-loading-overlay,.cms-content-loading-spinner").remove(),this._super()}}),$('.cms input[type="submit"], .cms button, .cms input[type="reset"], .cms .ss-ui-button').entwine({onadd:function(){this.addClass("ss-ui-button"),this.data("button")||this.button(),this._super()},onremove:function(){this.data("button")&&this.button("destroy"),this._super()}}),$(".cms .cms-panel-link").entwine({onclick:function(e){if($(this).hasClass("external-link"))return void e.stopPropagation();var t=this.attr("href"),n=t&&!t.match(/^#/)?t:this.data("href"),i={pjax:this.data("pjaxTarget")};$(".cms-container").loadPanel(n,null,i),e.preventDefault()}}),$(".cms .ss-ui-button-ajax").entwine({onclick:function onclick(e){$(this).removeClass("ui-button-text-only"),$(this).addClass("ss-ui-button-loading ui-button-text-icons");var loading=$(this).find(".ss-ui-loading-icon");loading.length<1&&(loading=$("<span></span>").addClass("ss-ui-loading-icon ui-button-icon-primary ui-icon"),$(this).prepend(loading)),loading.show();var href=this.attr("href"),url=href?href:this.data("href");jQuery.ajax({url:url,complete:function complete(xmlhttp,status){var msg=xmlhttp.getResponseHeader("X-Status")?xmlhttp.getResponseHeader("X-Status"):xmlhttp.responseText;try{"undefined"!=typeof msg&&null!==msg&&eval(msg)}catch(e){}loading.hide(),$(".cms-container").refresh(),$(this).removeClass("ss-ui-button-loading ui-button-text-icons"),$(this).addClass("ui-button-text-only")},dataType:"html"}),e.preventDefault()}}),$(".cms .ss-ui-dialog-link").entwine({UUID:null,onmatch:function(){this._super(),this.setUUID((new Date).getTime())},onunmatch:function(){this._super()},onclick:function(){this._super();var e="ss-ui-dialog-"+this.getUUID(),t=$("#"+e);t.length||(t=$('<div class="ss-ui-dialog" id="'+e+'" />'),$("body").append(t));var n=this.data("popupclass")?this.data("popupclass"):"";return t.ssdialog({iframeUrl:this.attr("href"),autoOpen:!0,dialogExtraClass:n}),!1}}),$(".cms-content .Actions").entwine({onmatch:function(){this.find(".ss-ui-button").click(function(){var e=this.form;e&&(e.clickedButton=this,setTimeout(function(){e.clickedButton=null},10))}),this.redraw(),this._super()},onunmatch:function(){this._super()},redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0)),this.contents().filter(function(){return 3==this.nodeType&&!/\S/.test(this.nodeValue)}).remove(),this.find(".ss-ui-button").each(function(){$(this).data("button")||$(this).button()}),this.find(".ss-ui-buttonset").buttonset()}}),$(".cms .field.date input.text").entwine({onmatch:function(){var e=$(this).parents(".field.date:first"),t=e.data();return t.showcalendar?(t.showOn="button",t.locale&&$.datepicker.regional[t.locale]&&(t=$.extend(t,$.datepicker.regional[t.locale],{})),$(this).datepicker(t),void this._super()):void this._super()},onunmatch:function(){this._super()}}),$(".cms .field.dropdown select, .cms .field select[multiple], .fieldholder-small select.dropdown").entwine({onmatch:function(){return this.is(".no-chosen")?void this._super():(this.data("placeholder")||this.data("placeholder"," "),this.removeClass("has-chosen").chosen("destroy"),this.siblings(".chosen-container").remove(),applyChosen(this),void this._super())},onunmatch:function(){this._super()}}),$(".cms-panel-layout").entwine({redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0))}}),$(".cms .ss-gridfield").entwine({showDetailView:function(e){var t=window.location.search.replace(/^\?/,"");t&&(e=$.path.addSearchParams(e,t)),$(".cms-container").loadPanel(e)}}),$(".cms-search-form").entwine({onsubmit:function(e){var t,n;t=this.find(":input:not(:submit)").filter(function(){var e=$.grep($(this).fieldValue(),function(e){return e});return e.length}),n=this.attr("action"),t.length&&(n=$.path.addSearchParams(n,t.serialize().replace("+","%20")));var i=this.closest(".cms-container");return i.find(".cms-edit-form").tabs("select",0),i.loadPanel(n,"",{},!0),!1}}),$(".cms-search-form button[type=reset], .cms-search-form input[type=reset]").entwine({onclick:function(e){e.preventDefault();var t=$(this).parents("form");t.clearForm(),t.find(".dropdown select").prop("selectedIndex",0).trigger("chosen:updated"),t.submit()}}),window._panelDeferredCache={},$(".cms-panel-deferred").entwine({onadd:function(){this._super(),this.redraw()},onremove:function(){window.debug&&console.log("saving",this.data("url"),this),this.data("deferredNoCache")||(window._panelDeferredCache[this.data("url")]=this.html()),this._super()},redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0));var e=this,t=this.data("url");if(!t)throw'Elements of class .cms-panel-deferred need a "data-url" attribute';this._super(),this.children().length||(this.data("deferredNoCache")||"undefined"==typeof window._panelDeferredCache[t]?(this.addClass("loading"),$.ajax({url:t,complete:function(){e.removeClass("loading")},success:function(t,n,i){e.html(t)}})):this.html(window._panelDeferredCache[t]))}}),$(".cms-tabset").entwine({onadd:function(){this.redrawTabs(),this._super()},onremove:function(){this.data("tabs")&&this.tabs("destroy"),this._super()},redrawTabs:function(){this.rewriteHashlinks();var e=(this.attr("id"),this.find("ul:first .ui-tabs-active"));this.data("uiTabs")||this.tabs({active:-1!=e.index()?e.index():0,beforeLoad:function(e,t){return!1},activate:function(e,t){var n=$(this).closest("form").find(".Actions");$(t.newTab).closest("li").hasClass("readonly")?n.fadeOut():n.show()}})},rewriteHashlinks:function(){$(this).find("ul a").each(function(){if($(this).attr("href")){var e=$(this).attr("href").match(/#.*/);e&&$(this).attr("href",document.location.href.replace(/#.*/,"")+e[0])}})}}),$("#filters-button").entwine({onmatch:function(){this._super(),this.data("collapsed",!0),this.data("animating",!1);
},onunmatch:function(){this._super()},showHide:function(){var e=this,t=$(".cms-content-filters").first(),n=this.data("collapsed");this.data("animating")||(this.toggleClass("active"),this.data("animating",!0),t[n?"slideDown":"slideUp"]({complete:function(){e.data("collapsed",!n),e.data("animating",!1)}}))},onclick:function(){this.showHide()}})});var statusMessage=function(e,t){e=jQuery("<div/>").text(e).html(),jQuery.noticeAdd({text:e,type:t,stayTime:5e3,inEffect:{left:"0",opacity:"show"}})},errorMessage=function(e){jQuery.noticeAdd({text:e,type:"error",stayTime:5e3,inEffect:{left:"0",opacity:"show"}})}},{jQuery:"jQuery","lib/Config":15,"lib/Router":"lib/Router"}],15:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(){i(this,e)}return e.getSection=function(e){return window.ss.config.sections[e]},e.getTopLevelRoutes=function(){var e=[];return Object.keys(window.ss.config.sections).forEach(function(t){var n=window.ss.config.sections[t].route,i=n.match(/^admin\/[^\/]+(\/?)$/);if(i){n=n.replace(/\/$/,"");var s=-1===e.indexOf(n);s&&e.push(n)}}),e},e}();n["default"]=s},{}]},{},[1]);
t},onadd:function(){var t=this,n=(this.parent(),this.find("iframe"));n.addClass("center"),n.bind("load",function(){t._adjustIframeForPreview(),t._loadCurrentPage(),e(this).removeClass("loading")}),e.browser.msie&&8===parseInt(e.browser.version,10)&&n.bind("readystatechange",function(e){"interactive"==n[0].readyState&&(t.getOrAppendFontFixStyleElement().removeAttr("disabled"),setTimeout(function(){t.getOrAppendFontFixStyleElement().attr("disabled","disabled")},0))}),this.append('<div class="cms-preview-overlay ui-widget-overlay-light"></div>'),this.find(".cms-preview-overlay").hide(),this.disablePreview(),this._super()},_supportsLocalStorage:function(){var e,t,n=new Date;try{return(e=window.localStorage).setItem(n,n),t=e.getItem(n)==n,e.removeItem(n),t&&e}catch(i){console.warn("localStorge is not available due to current browser / system settings.")}},onenable:function(){var t=e(".preview-mode-selector");t.removeClass("split-disabled"),t.find(".disabled-tooltip").hide()},ondisable:function(){var t=e(".preview-mode-selector");t.addClass("split-disabled"),t.find(".disabled-tooltip").show()},_block:function(){return this.addClass("blocked"),this.find(".cms-preview-overlay").show(),this},_unblock:function(){return this.removeClass("blocked"),this.find(".cms-preview-overlay").hide(),this},_initialiseFromContent:function(){var t,n;return e(".cms-previewable").length?(t=this.loadState("mode"),n=this.loadState("size"),this._moveNavigator(),t&&"content"==t||(this.enablePreview(),this._loadCurrentState()),this.redraw(),t&&this.changeMode(t),n&&this.changeSize(n)):this.disablePreview(),this},"from .cms-container":{onafterstatechange:function(e,t){t.xhr.getResponseHeader("X-ControllerURL")||this._initialiseFromContent()}},PendingURL:null,oncolumnvisibilitychanged:function(){var e=this.getPendingURL();e&&!this.is(".column-hidden")&&(this.setPendingURL(null),this._loadUrl(e),this._unblock())},"from .cms-container .cms-edit-form":{onaftersubmitform:function(){this._initialiseFromContent()}},_loadUrl:function(e){return this.find("iframe").addClass("loading").attr("src",e),this},_getNavigatorStates:function(){var t=e.map(this.getAllowedStates(),function(t){var n=e(".cms-preview-states .state-name[data-name="+t+"]");return n.length?{name:t,url:n.attr("data-link"),active:n.is(":radio")?n.is(":checked"):n.is(":selected")}:null});return t},_loadCurrentState:function(){if(!this.getIsPreviewEnabled())return this;var t=this._getNavigatorStates(),n=this.getCurrentStateName(),i=null;t&&(i=e.grep(t,function(e,t){return n===e.name||!n&&e.active}));var s=null;return i[0]?s=i[0].url:t.length?(this.setCurrentStateName(t[0].name),s=t[0].url):this.setCurrentStateName(null),s+=(-1===s.indexOf("?")?"?":"&")+"CMSPreview=1",this.is(".column-hidden")?(this.setPendingURL(s),this._loadUrl("about:blank"),this._block()):(this.setPendingURL(null),s?(this._loadUrl(s),this._unblock()):this._block()),this},_moveNavigator:function(){var t=e(".cms-preview .cms-preview-controls"),n=e(".cms-edit-form .cms-navigator");n.length&&t.length?t.html(e(".cms-edit-form .cms-navigator").detach()):this._block()},_loadCurrentPage:function(){if(this.getIsPreviewEnabled()){var t;e(".cms-container");try{t=this.find("iframe")[0].contentDocument}catch(n){console.warn("Unable to access iframe, possible https mis-match")}if(t){var i=e(t).find("meta[name=x-page-id]").attr("content"),s=e(t).find("meta[name=x-cms-edit-link]").attr("content"),a=e(".cms-content");i&&a.find(":input[name=ID]").val()!=i&&e(".cms-container").entwine(".ss").loadPanel(s)}}},_adjustIframeForPreview:function(){var e,t=this.find("iframe")[0];if(t){try{e=t.contentDocument}catch(n){console.warn("Unable to access iframe, possible https mis-match")}if(e){for(var i=e.getElementsByTagName("A"),s=0;s<i.length;s++){var a=i[s].getAttribute("href");a&&a.match(/^http:\/\//)&&i[s].setAttribute("target","_blank")}var o=e.getElementById("SilverStripeNavigator");o&&(o.style.display="none");var r=e.getElementById("SilverStripeNavigatorMessage");r&&(r.style.display="none"),this.trigger("afterIframeAdjustedForPreview",[e])}}}}),e(".cms-edit-form").entwine({onadd:function(){this._super(),e(".cms-preview")._initialiseFromContent()}}),e(".cms-preview-states").entwine({changeVisibleState:function(e){this.find('input[data-name="'+e+'"]').prop("checked",!0)}}),e(".cms-preview-states .state-name").entwine({onclick:function(t){this.parent().find(".active").removeClass("active"),this.next("label").addClass("active");var n=e(this).attr("data-name");e(".cms-preview").changeState(n)}}),e(".preview-mode-selector").entwine({changeVisibleMode:function(e){this.find("select").val(e).trigger("chosen:updated")._addIcon()}}),e(".preview-mode-selector select").entwine({onchange:function(t){this._super(t),t.preventDefault();var n=e(this).val();e(".cms-preview").changeMode(n)}}),e(".cms-preview.column-hidden").entwine({onmatch:function(){e("#preview-mode-dropdown-in-content").show(),e(".cms-preview .result-selected").hasClass("font-icon-columns")&&statusMessage(r["default"]._t("LeftAndMain.DISABLESPLITVIEW","Screen too small to show site preview in split mode"),"error"),this._super()},onunmatch:function(){e("#preview-mode-dropdown-in-content").hide(),this._super()}}),e("#preview-mode-dropdown-in-content").entwine({onmatch:function(){e(".cms-preview").is(".column-hidden")?this.show():this.hide(),this._super()},onunmatch:function(){this._super()}}),e(".preview-size-selector").entwine({changeVisibleSize:function(e){this.find("select").val(e).trigger("chosen:updated")._addIcon()}}),e(".preview-size-selector select").entwine({onchange:function(t){t.preventDefault();var n=e(this).val();e(".cms-preview").changeSize(n)}}),e(".preview-selector select.preview-dropdown").entwine({"onchosen:ready":function(){this._super(),this._addIcon()},_addIcon:function(){var e=this.find(":selected"),t=e.attr("data-icon"),n=this.parent().find(".chosen-container a.chosen-single"),i=n.attr("data-icon");return"undefined"!=typeof i&&n.removeClass(i),n.addClass(t),n.attr("data-icon",t),this}}),e(".preview-mode-selector .chosen-drop li:last-child").entwine({onmatch:function(){e(".preview-mode-selector").hasClass("split-disabled")?this.parent().append('<div class="disabled-tooltip"></div>'):this.parent().append('<div class="disabled-tooltip" style="display: none;"></div>')}}),e(".preview-device-outer").entwine({onclick:function(){this.toggleClass("rotate")}})})},{i18n:"i18n",jQuery:"jQuery"}],12:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss.tree",function(e){e(".cms-tree").entwine({Hints:null,IsUpdatingTree:!1,IsLoaded:!1,onadd:function(){if(this._super(),!e.isNumeric(this.data("jstree_instance_id"))){var t=this.attr("data-hints");t&&this.setHints(e.parseJSON(t));var n=this;this.jstree(this.getTreeConfig()).bind("loaded.jstree",function(t,i){n.setIsLoaded(!0),i.inst._set_settings({html_data:{ajax:{url:n.data("urlTree"),data:function(t){var i=n.data("searchparams")||[];return i=e.grep(i,function(e,t){return"ID"!=e.name&&"value"!=e.name}),i.push({name:"ID",value:e(t).data("id")?e(t).data("id"):0}),i.push({name:"ajax",value:1}),i}}}}),n.updateFromEditForm(),n.css("visibility","visible"),i.inst.hide_checkboxes()}).bind("before.jstree",function(t,i){if("start_drag"==i.func&&(!n.hasClass("draggable")||n.hasClass("multiselect")))return t.stopImmediatePropagation(),!1;if(e.inArray(i.func,["check_node","uncheck_node"])){var s=e(i.args[0]).parents("li:first"),a=s.find("li:not(.disabled)");if(s.hasClass("disabled")&&0==a)return t.stopImmediatePropagation(),!1}}).bind("move_node.jstree",function(t,i){if(!n.getIsUpdatingTree()){var s=i.rslt.o,a=i.rslt.np,o=(i.inst._get_parent(s),e(a).data("id")||0),r=e(s).data("id"),l=e.map(e(s).siblings().andSelf(),function(t){return e(t).data("id")});e.ajax({url:n.data("urlSavetreenode"),type:"POST",data:{ID:r,ParentID:o,SiblingIDs:l},success:function(){e(".cms-edit-form :input[name=ID]").val()==r&&e(".cms-edit-form :input[name=ParentID]").val(o),n.updateNodesFromServer([r])},statusCode:{403:function(){e.jstree.rollback(i.rlbk)}}})}}).bind("select_node.jstree check_node.jstree uncheck_node.jstree",function(t,n){e(document).triggerHandler(t,n)})}},onremove:function(){this.jstree("destroy"),this._super()},"from .cms-container":{onafterstatechange:function(e){this.updateFromEditForm()}},"from .cms-container form":{onaftersubmitform:function(t){var n=e(".cms-edit-form :input[name=ID]").val();this.updateNodesFromServer([n])}},getTreeConfig:function(){var t=this;return{core:{initially_open:["record-0"],animation:0,html_titles:!0},html_data:{},ui:{select_limit:1,initially_select:[this.find(".current").attr("id")]},crrm:{move:{check_move:function(n){var i=e(n.o),s=e(n.np),a=n.ot.get_container()[0]==n.np[0],o=i.getClassname(),r=s.getClassname(),l=t.getHints(),d=[],c=r?r:"Root",u=l&&"undefined"!=typeof l[c]?l[c]:null;u&&i.attr("class").match(/VirtualPage-([^\s]*)/)&&(o=RegExp.$1),u&&(d="undefined"!=typeof u.disallowedChildren?u.disallowedChildren:[]);var h=!(0===i.data("id")||i.hasClass("status-archived")||a&&"inside"!=n.p||s.hasClass("nochildren")||d.length&&-1!=e.inArray(o,d));return h}}},dnd:{drop_target:!1,drag_target:!1},checkbox:{two_state:!0},themes:{theme:"apple",url:e("body").data("frameworkpath")+"/thirdparty/jstree/themes/apple/style.css"},plugins:["html_data","ui","dnd","crrm","themes","checkbox"]}},search:function(e,t){e?this.data("searchparams",e):this.removeData("searchparams"),this.jstree("refresh",-1,t)},getNodeByID:function(e){return this.find("*[data-id="+e+"]")},createNode:function(t,n,i){var s=this,a=void 0!==n.ParentID?s.getNodeByID(n.ParentID):!1,o=e(t),r={data:""};o.hasClass("jstree-open")?r.state="open":o.hasClass("jstree-closed")&&(r.state="closed"),this.jstree("create_node",a.length?a:-1,"last",r,function(e){for(var t=e.attr("class"),n=0;n<o[0].attributes.length;n++){var s=o[0].attributes[n];e.attr(s.name,s.value)}e.addClass(t).html(o.html()),i(e)})},updateNode:function(t,n,i){var s=e(n),a=t.attr("class"),o=i.NextID?this.getNodeByID(i.NextID):!1,r=i.PrevID?this.getNodeByID(i.PrevID):!1,l=i.ParentID?this.getNodeByID(i.ParentID):!1;e.each(["id","style","class","data-pagetype"],function(e,n){t.attr(n,s.attr(n))}),a=a.replace(/status-[^\s]*/,"");var d=t.children("ul").detach();t.addClass(a).html(s.html()).append(d),o&&o.length?this.jstree("move_node",t,o,"before"):r&&r.length?this.jstree("move_node",t,r,"after"):this.jstree("move_node",t,l.length?l:-1)},updateFromEditForm:function(){var t,n=e(".cms-edit-form :input[name=ID]").val();n?(t=this.getNodeByID(n),t.length?(this.jstree("deselect_all"),this.jstree("select_node",t)):this.updateNodesFromServer([n])):this.jstree("deselect_all")},updateNodesFromServer:function(t){if(!this.getIsUpdatingTree()&&this.getIsLoaded()){var n=this,i=!1;this.setIsUpdatingTree(!0),n.jstree("save_selected");var s=function(e){n.getNodeByID(e.data("id")).not(e).remove(),n.jstree("deselect_all"),n.jstree("select_node",e)};n.jstree("open_node",this.getNodeByID(0)),n.jstree("save_opened"),n.jstree("save_selected"),e.ajax({url:e.path.addSearchParams(this.data("urlUpdatetreenodes"),"ids="+t.join(",")),dataType:"json",success:function(t,a){e.each(t,function(e,t){var a=n.getNodeByID(e);return t?void(a.length?(n.updateNode(a,t.html,t),setTimeout(function(){s(a)},500)):(i=!0,t.ParentID&&!n.find("li[data-id="+t.ParentID+"]").length?n.jstree("load_node",-1,function(){newNode=n.find("li[data-id="+e+"]"),s(newNode)}):n.createNode(t.html,t,function(e){s(e)}))):void n.jstree("delete_node",a)}),i||(n.jstree("deselect_all"),n.jstree("reselect"),n.jstree("reopen"))},complete:function(){n.setIsUpdatingTree(!1)}})}}}),e(".cms-tree.multiple").entwine({onmatch:function(){this._super(),this.jstree("show_checkboxes")},onunmatch:function(){this._super(),this.jstree("uncheck_all"),this.jstree("hide_checkboxes")},getSelectedIDs:function(){return e(this).jstree("get_checked").not(".disabled").map(function(){return e(this).data("id")}).get()}}),e(".cms-tree li").entwine({setEnabled:function(e){this.toggleClass("disabled",!e)},getClassname:function(){var e=this.attr("class").match(/class-([^\s]*)/i);return e?e[1]:""},getID:function(){return this.data("id")}})})},{jQuery:"jQuery"}],13:[function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{"default":e}}var s=e("jQuery"),a=i(s);a["default"].entwine("ss",function(e){e(".TreeDropdownField").entwine({"from .cms-container form":{onaftersubmitform:function(e){this.find(".tree-holder").empty(),this._super()}}})})},{jQuery:"jQuery"}],14:[function(require,module,exports){"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function getUrlPath(e){var t=document.createElement("a");return t.href=e,t.pathname}var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e},_jQuery=require("jQuery"),_jQuery2=_interopRequireDefault(_jQuery),_Router=require("lib/Router"),_Router2=_interopRequireDefault(_Router),_Config=require("lib/Config"),_Config2=_interopRequireDefault(_Config),windowWidth,windowHeight;_jQuery2["default"].noConflict(),window.ss=window.ss||{},window.ss.router=_Router2["default"],window.ss.debounce=function(e,t,n){var i,s,a,o=function(){i=null,n||e.apply(s,a)};return function(){var r=n&&!i;s=this,a=arguments,clearTimeout(i),i=setTimeout(o,t),r&&e.apply(s,a)}},(0,_jQuery2["default"])(window).bind("resize.leftandmain",function(e){(0,_jQuery2["default"])(".cms-container").trigger("windowresize")}),_jQuery2["default"].entwine.warningLevel=_jQuery2["default"].entwine.WARN_LEVEL_BESTPRACTISE,_jQuery2["default"].entwine("ss",function($){$(window).on("message",function(e){var t,n=e.originalEvent,i="object"===_typeof(n.data)?n.data:JSON.parse(n.data);if($.path.parseUrl(window.location.href).domain===$.path.parseUrl(n.origin).domain)switch(t=$("undefined"==typeof i.target?window:i.target),i.type){case"event":t.trigger(i.event,i.data);break;case"callback":t[i.callback].call(t,i.data)}});var positionLoadingSpinner=function(){var e=120,t=$(".ss-loading-screen .loading-animation"),n=($(window).height()-t.height())/2;t.css("top",n+e),t.show()},applyChosen=function e(t){t.is(":visible")?t.addClass("has-chosen").chosen({allow_single_deselect:!0,disable_search_threshold:20,display_disabled_options:!0}):setTimeout(function(){t.show(),e(t)},500)},isSameUrl=function(e,t){var n=$("base").attr("href");e=$.path.isAbsoluteUrl(e)?e:$.path.makeUrlAbsolute(e,n),t=$.path.isAbsoluteUrl(t)?t:$.path.makeUrlAbsolute(t,n);var i=$.path.parseUrl(e),s=$.path.parseUrl(t);return i.pathname.replace(/\/*$/,"")==s.pathname.replace(/\/*$/,"")&&i.search==s.search},ajaxCompleteEvent=window.ss.debounce(function(){$(window).trigger("ajaxComplete")},1e3,!0);$(window).bind("resize",positionLoadingSpinner).trigger("resize"),$(document).ajaxComplete(function(e,t,n){var i,s=t.getResponseHeader("X-ControllerURL"),a=n.url,o=null!==t.getResponseHeader("X-Status")?t.getResponseHeader("X-Status"):t.statusText,r=t.status<200||t.status>399?"bad":"good",l=["OK"];return i=window.history.state?window.history.state.path:document.URL,null===s||isSameUrl(i,s)&&isSameUrl(a,s)||_Router2["default"].show(s,{id:(new Date).getTime()+String(Math.random()).replace(/\D/g,""),pjax:t.getResponseHeader("X-Pjax")?t.getResponseHeader("X-Pjax"):n.headers["X-Pjax"]}),t.getResponseHeader("X-Reauthenticate")?void $(".cms-container").showLoginDialog():(0!==t.status&&o&&$.inArray(o,l)&&statusMessage(decodeURIComponent(o),r),void ajaxCompleteEvent(this))}),$(".cms-container").entwine({StateChangeXHR:null,FragmentXHR:{},StateChangeCount:0,LayoutOptions:{minContentWidth:940,minPreviewWidth:400,mode:"content"},onadd:function(){var e=this,t=getUrlPath($("base")[0].href);return t=t.replace(/\/$/,""),t.match(/^[^\/]/)&&(t="/"+t),_Router2["default"].base(t),_Config2["default"].getTopLevelRoutes().forEach(function(t){(0,_Router2["default"])("/"+t+"(/*?)?",function(t,n){return"complete"!==document.readyState?n():void e.handleStateChange(null,t.state).done(n)})}),_Router2["default"].start(),$.browser.msie&&parseInt($.browser.version,10)<8?($(".ss-loading-screen").append('<p class="ss-loading-incompat-warning"><span class="notice">Your browser is not compatible with the CMS interface. Please use Internet Explorer 8+, Google Chrome or Mozilla Firefox.</span></p>').css("z-index",$(".ss-loading-screen").css("z-index")+1),$(".loading-animation").remove(),void this._super()):(this.redraw(),$(".ss-loading-screen").hide(),$("body").removeClass("loading"),$(window).unbind("resize",positionLoadingSpinner),this.restoreTabState(),void this._super())},fromWindow:{onstatechange:function(e,t){this.handleStateChange(e,t)}},onwindowresize:function(){this.redraw()},"from .cms-panel":{ontoggle:function(){this.redraw()}},"from .cms-container":{onaftersubmitform:function(){this.redraw()}},"from .cms-menu-list li a":{onclick:function(e){var t=$(e.target).attr("href");e.which>1||t==this._tabStateUrl()||this.splitViewMode()}},updateLayoutOptions:function(e){var t=this.getLayoutOptions(),n=!1;for(var i in e)t[i]!==e[i]&&(t[i]=e[i],n=!0);n&&this.redraw()},splitViewMode:function(){this.updateLayoutOptions({mode:"split"})},contentViewMode:function(){this.updateLayoutOptions({mode:"content"})},previewMode:function(){this.updateLayoutOptions({mode:"preview"})},RedrawSuppression:!1,redraw:function(){this.getRedrawSuppression()||(window.debug&&console.log("redraw",this.attr("class"),this.get(0)),this.data("jlayout",jLayout.threeColumnCompressor({menu:this.children(".cms-menu"),content:this.children(".cms-content"),preview:this.children(".cms-preview")},this.getLayoutOptions())),this.layout(),this.find(".cms-panel-layout").redraw(),this.find(".cms-content-fields[data-layout-type]").redraw(),this.find(".cms-edit-form[data-layout-type]").redraw(),this.find(".cms-preview").redraw(),this.find(".cms-content").redraw())},checkCanNavigate:function(e){var t=this._findFragments(e||["Content"]),n=t.find(":data(changetracker)").add(t.filter(":data(changetracker)")),i=!0;return n.length?(n.each(function(){$(this).confirmUnsavedChanges()||(i=!1)}),i):!0},loadPanel:function(e){var t=(arguments.length<=1||void 0===arguments[1]?"":arguments[1],arguments.length<=2||void 0===arguments[2]?{}:arguments[2]),n=arguments[3],i=arguments.length<=4||void 0===arguments[4]?window.history.state.path:arguments[4];this.checkCanNavigate(t.pjax?t.pjax.split(","):["Content"])&&(this.saveTabState(),t.__forceReferer=i,n&&(t.__forceReload=Math.random()),_Router2["default"].show(e,t))},reloadCurrentPanel:function(){this.loadPanel(window.history.state.path,null,null,!0)},submitForm:function(e,t,n,i){var s=this;t||(t=this.find(".Actions :submit[name=action_save]")),t||(t=this.find(".Actions :submit:first")),e.trigger("beforesubmitform"),this.trigger("submitform",{form:e,button:t}),$(t).addClass("loading");var a=e.validate();if("undefined"!=typeof a&&!a)return statusMessage("Validation failed.","bad"),$(t).removeClass("loading"),!1;var o=e.serializeArray();return o.push({name:$(t).attr("name"),value:"1"}),o.push({name:"BackURL",value:window.history.state.path.replace(/\/$/,"")}),this.saveTabState(),jQuery.ajax(jQuery.extend({headers:{"X-Pjax":"CurrentForm,Breadcrumbs"},url:e.attr("action"),data:o,type:"POST",complete:function(){$(t).removeClass("loading")},success:function(t,i,a){e.removeClass("changed"),n&&n(t,i,a);var r=s.handleAjaxResponse(t,i,a);r&&r.filter("form").trigger("aftersubmitform",{status:i,xhr:a,formData:o})}},i)),!1},LastState:null,PauseState:!1,handleStateChange:function(e){var t=arguments.length<=1||void 0===arguments[1]?window.history.state:arguments[1];if(!this.getPauseState()){this.getStateChangeXHR()&&this.getStateChangeXHR().abort();var n=this,i=t.pjax||"Content",s={},a=i.split(","),o=this._findFragments(a);if(this.setStateChangeCount(this.getStateChangeCount()+1),!this.checkCanNavigate()){var r=this.getLastState();return this.setPauseState(!0),null!==r?_Router2["default"].show(r.url):_Router2["default"].back(),void this.setPauseState(!1)}if(this.setLastState(t),o.length<a.length&&(i="Content",a=["Content"],o=this._findFragments(a)),this.trigger("beforestatechange",{state:t,element:o}),s["X-Pjax"]=i,"undefined"!=typeof t.__forceReferer){var l=t.__forceReferer;try{l=decodeURI(l)}catch(d){}finally{s["X-Backurl"]=encodeURI(l)}}o.addClass("loading");var c=$.ajax({headers:s,url:t.path}).done(function(e,i,s){var a=n.handleAjaxResponse(e,i,s,t);n.trigger("afterstatechange",{data:e,status:i,xhr:s,element:a,state:t})}).always(function(){n.setStateChangeXHR(null),o.removeClass("loading")});return this.setStateChangeXHR(c),c}},loadFragment:function(e,t){var n,i=this,s={},a=$("base").attr("href"),o=this.getFragmentXHR();return"undefined"!=typeof o[t]&&null!==o[t]&&(o[t].abort(),o[t]=null),e=$.path.isAbsoluteUrl(e)?e:$.path.makeUrlAbsolute(e,a),s["X-Pjax"]=t,n=$.ajax({headers:s,url:e,success:function(e,t,n){var s=i.handleAjaxResponse(e,t,n,null);i.trigger("afterloadfragment",{data:e,status:t,xhr:n,elements:s})},error:function(e,t,n){i.trigger("loadfragmenterror",{xhr:e,status:t,error:n})},complete:function(){var e=i.getFragmentXHR();"undefined"!=typeof e[t]&&null!==e[t]&&(e[t]=null)}}),o[t]=n,n},handleAjaxResponse:function(e,t,n,i){var s,a,o,r;if(n.getResponseHeader("X-Reload")&&n.getResponseHeader("X-ControllerURL")){var l=$("base").attr("href"),d=n.getResponseHeader("X-ControllerURL"),s=$.path.isAbsoluteUrl(d)?d:$.path.makeUrlAbsolute(d,l);return void(document.location.href=s)}if(e){var c=n.getResponseHeader("X-Title");c&&(document.title=decodeURIComponent(c.replace(/\+/g," ")));var u,h={};n.getResponseHeader("Content-Type").match(/^((text)|(application))\/json[ \t]*;?/i)?h=e:(o=document.createDocumentFragment(),jQuery.clean([e],document,o,[]),r=$(jQuery.merge([],o.childNodes)),a="Content",r.is("form")&&!r.is("[data-pjax-fragment~=Content]")&&(a="CurrentForm"),h[a]=r),this.setRedrawSuppression(!0);try{$.each(h,function(e,t){var n=$("[data-pjax-fragment]").filter(function(){return-1!=$.inArray(e,$(this).data("pjaxFragment").split(" "))}),i=$(t);if(u?u.add(i):u=i,i.find(".cms-container").length)throw'Content loaded via ajax is not allowed to contain tags matching the ".cms-container" selector to avoid infinite loops';var s=n.attr("style"),a=n.parent(),o="undefined"!=typeof a.data("jlayout"),r=["east","west","center","north","south","column-hidden"],l=n.attr("class"),d=[];l&&(d=$.grep(l.split(" "),function(e){return $.inArray(e,r)>=0})),i.removeClass(r.join(" ")).addClass(d.join(" ")),s&&i.attr("style",s);var c=i.find("style").detach();c.length&&$(document).find("head").append(c),n.replaceWith(i),!a.is(".cms-container")&&o&&a.layout()});var f=u.filter("form");f.hasClass("cms-tabset")&&f.removeClass("cms-tabset").addClass("cms-tabset")}finally{this.setRedrawSuppression(!1)}return this.redraw(),this.restoreTabState(i&&"undefined"!=typeof i.tabState?i.tabState:null),u}},_findFragments:function(e){return $("[data-pjax-fragment]").filter(function(){var t,n=$(this).data("pjaxFragment").split(" ");for(t in e)if(-1!=$.inArray(e[t],n))return!0;return!1})},refresh:function(){$(window).trigger("statechange"),$(this).redraw()},saveTabState:function(){if("undefined"!=typeof window.sessionStorage&&null!==window.sessionStorage){var e=[],t=this._tabStateUrl();if(this.find(".cms-tabset,.ss-tabset").each(function(t,n){var i=$(n).attr("id");i&&$(n).data("tabs")&&($(n).data("ignoreTabState")||$(n).getIgnoreTabState()||e.push({id:i,selected:$(n).tabs("option","selected")}))}),e){var n="tabs-"+t;try{window.sessionStorage.setItem(n,JSON.stringify(e))}catch(i){if(i.code===DOMException.QUOTA_EXCEEDED_ERR&&0===window.sessionStorage.length)return;throw i}}}},restoreTabState:function(e){var t=this,n=this._tabStateUrl(),i="undefined"!=typeof window.sessionStorage&&window.sessionStorage,s=i?window.sessionStorage.getItem("tabs-"+n):null,a=s?JSON.parse(s):!1;this.find(".cms-tabset, .ss-tabset").each(function(){var n,i,s=$(this),o=s.attr("id"),r=s.find(".ss-tabs-force-active");s.data("tabs")&&(s.tabs("refresh"),r.length?n=r.index():e&&e[o]?(i=s.find(e[o].tabSelector),i.length&&(n=i.index())):a&&$.each(a,function(e,t){s.is("#"+t.id)&&(n=t.selected)}),null!==n&&(s.tabs("option","active",n),t.trigger("tabstaterestored")))})},clearTabState:function(e){if("undefined"!=typeof window.sessionStorage){var t=window.sessionStorage;if(e)t.removeItem("tabs-"+e);else for(var n=0;n<t.length;n++)t.key(n).match(/^tabs-/)&&t.removeItem(t.key(n))}},clearCurrentTabState:function(){this.clearTabState(this._tabStateUrl())},_tabStateUrl:function(){return window.history.state.path.replace(/\?.*/,"").replace(/#.*/,"").replace($("base").attr("href"),"")},showLoginDialog:function(){var e=$("body").data("member-tempid"),t=$(".leftandmain-logindialog"),n="CMSSecurity/login";t.length&&t.remove(),n=$.path.addSearchParams(n,{tempid:e,BackURL:window.location.href}),t=$('<div class="leftandmain-logindialog"></div>'),t.attr("id",(new Date).getTime()),t.data("url",n),$("body").append(t)}}),$(".leftandmain-logindialog").entwine({onmatch:function(){this._super(),this.ssdialog({iframeUrl:this.data("url"),dialogClass:"leftandmain-logindialog-dialog",autoOpen:!0,minWidth:500,maxWidth:500,minHeight:370,maxHeight:400,closeOnEscape:!1,open:function(){$(".ui-widget-overlay").addClass("leftandmain-logindialog-overlay")},close:function(){$(".ui-widget-overlay").removeClass("leftandmain-logindialog-overlay")}})},onunmatch:function(){this._super()},open:function(){this.ssdialog("open")},close:function(){this.ssdialog("close")},toggle:function(e){this.is(":visible")?this.close():this.open()},reauthenticate:function(e){"undefined"!=typeof e.SecurityID&&$(":input[name=SecurityID]").val(e.SecurityID),"undefined"!=typeof e.TempID&&$("body").data("member-tempid",e.TempID),this.close()}}),$("form.loading,.cms-content.loading,.cms-content-fields.loading,.cms-content-view.loading").entwine({onmatch:function(){this.append('<div class="cms-content-loading-overlay ui-widget-overlay-light"></div><div class="cms-content-loading-spinner"></div>'),this._super()},onunmatch:function(){this.find(".cms-content-loading-overlay,.cms-content-loading-spinner").remove(),this._super()}}),$('.cms input[type="submit"], .cms button, .cms input[type="reset"], .cms .ss-ui-button').entwine({onadd:function(){this.addClass("ss-ui-button"),this.data("button")||this.button(),this._super()},onremove:function(){this.data("button")&&this.button("destroy"),this._super()}}),$(".cms .cms-panel-link").entwine({onclick:function(e){if($(this).hasClass("external-link"))return void e.stopPropagation();var t=this.attr("href"),n=t&&!t.match(/^#/)?t:this.data("href"),i={pjax:this.data("pjaxTarget")};$(".cms-container").loadPanel(n,null,i),e.preventDefault()}}),$(".cms .ss-ui-button-ajax").entwine({onclick:function onclick(e){$(this).removeClass("ui-button-text-only"),$(this).addClass("ss-ui-button-loading ui-button-text-icons");var loading=$(this).find(".ss-ui-loading-icon");loading.length<1&&(loading=$("<span></span>").addClass("ss-ui-loading-icon ui-button-icon-primary ui-icon"),$(this).prepend(loading)),loading.show();var href=this.attr("href"),url=href?href:this.data("href");jQuery.ajax({url:url,complete:function complete(xmlhttp,status){var msg=xmlhttp.getResponseHeader("X-Status")?xmlhttp.getResponseHeader("X-Status"):xmlhttp.responseText;try{"undefined"!=typeof msg&&null!==msg&&eval(msg)}catch(e){}loading.hide(),$(".cms-container").refresh(),$(this).removeClass("ss-ui-button-loading ui-button-text-icons"),$(this).addClass("ui-button-text-only")},dataType:"html"}),e.preventDefault()}}),$(".cms .ss-ui-dialog-link").entwine({UUID:null,onmatch:function(){this._super(),this.setUUID((new Date).getTime())},onunmatch:function(){this._super()},onclick:function(){this._super();var e="ss-ui-dialog-"+this.getUUID(),t=$("#"+e);t.length||(t=$('<div class="ss-ui-dialog" id="'+e+'" />'),$("body").append(t));var n=this.data("popupclass")?this.data("popupclass"):"";return t.ssdialog({iframeUrl:this.attr("href"),autoOpen:!0,dialogExtraClass:n}),!1}}),$(".cms-content .Actions").entwine({onmatch:function(){this.find(".ss-ui-button").click(function(){var e=this.form;e&&(e.clickedButton=this,setTimeout(function(){e.clickedButton=null},10))}),this.redraw(),this._super()},onunmatch:function(){this._super()},redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0)),this.contents().filter(function(){return 3==this.nodeType&&!/\S/.test(this.nodeValue)}).remove(),this.find(".ss-ui-button").each(function(){$(this).data("button")||$(this).button()}),this.find(".ss-ui-buttonset").buttonset()}}),$(".cms .field.date input.text").entwine({onmatch:function(){var e=$(this).parents(".field.date:first"),t=e.data();return t.showcalendar?(t.showOn="button",t.locale&&$.datepicker.regional[t.locale]&&(t=$.extend(t,$.datepicker.regional[t.locale],{})),$(this).datepicker(t),void this._super()):void this._super()},onunmatch:function(){this._super()}}),$(".cms .field.dropdown select, .cms .field select[multiple], .fieldholder-small select.dropdown").entwine({onmatch:function(){return this.is(".no-chosen")?void this._super():(this.data("placeholder")||this.data("placeholder"," "),this.removeClass("has-chosen").chosen("destroy"),this.siblings(".chosen-container").remove(),applyChosen(this),void this._super())},onunmatch:function(){this._super()}}),$(".cms-panel-layout").entwine({redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0))}}),$(".cms .ss-gridfield").entwine({showDetailView:function(e){var t=window.location.search.replace(/^\?/,"");t&&(e=$.path.addSearchParams(e,t)),$(".cms-container").loadPanel(e)}}),$(".cms-search-form").entwine({onsubmit:function(e){var t,n;t=this.find(":input:not(:submit)").filter(function(){var e=$.grep($(this).fieldValue(),function(e){return e});return e.length}),n=this.attr("action"),t.length&&(n=$.path.addSearchParams(n,t.serialize().replace("+","%20")));var i=this.closest(".cms-container");return i.find(".cms-edit-form").tabs("select",0),i.loadPanel(n,"",{},!0),!1}}),$(".cms-search-form button[type=reset], .cms-search-form input[type=reset]").entwine({onclick:function(e){e.preventDefault();var t=$(this).parents("form");t.clearForm(),t.find(".dropdown select").prop("selectedIndex",0).trigger("chosen:updated"),t.submit()}}),window._panelDeferredCache={},$(".cms-panel-deferred").entwine({onadd:function(){this._super(),this.redraw()},onremove:function(){window.debug&&console.log("saving",this.data("url"),this),this.data("deferredNoCache")||(window._panelDeferredCache[this.data("url")]=this.html()),this._super()},redraw:function(){window.debug&&console.log("redraw",this.attr("class"),this.get(0));var e=this,t=this.data("url");if(!t)throw'Elements of class .cms-panel-deferred need a "data-url" attribute';this._super(),this.children().length||(this.data("deferredNoCache")||"undefined"==typeof window._panelDeferredCache[t]?(this.addClass("loading"),$.ajax({url:t,complete:function(){e.removeClass("loading")},success:function(t,n,i){e.html(t)}})):this.html(window._panelDeferredCache[t]))}}),$(".cms-tabset").entwine({onadd:function(){this.redrawTabs(),this._super()},onremove:function(){this.data("tabs")&&this.tabs("destroy"),this._super()},redrawTabs:function(){this.rewriteHashlinks();var e=(this.attr("id"),this.find("ul:first .ui-tabs-active"));this.data("uiTabs")||this.tabs({active:-1!=e.index()?e.index():0,beforeLoad:function(e,t){return!1},activate:function(e,t){var n=$(this).closest("form").find(".Actions");$(t.newTab).closest("li").hasClass("readonly")?n.fadeOut():n.show()}})},rewriteHashlinks:function(){$(this).find("ul a").each(function(){if($(this).attr("href")){var e=$(this).attr("href").match(/#.*/);e&&$(this).attr("href",document.location.href.replace(/#.*/,"")+e[0])}})}}),$("#filters-button").entwine({onmatch:function(){this._super(),this.data("collapsed",!0),
this.data("animating",!1)},onunmatch:function(){this._super()},showHide:function(){var e=this,t=$(".cms-content-filters").first(),n=this.data("collapsed");this.data("animating")||(this.toggleClass("active"),this.data("animating",!0),t[n?"slideDown":"slideUp"]({complete:function(){e.data("collapsed",!n),e.data("animating",!1)}}))},onclick:function(){this.showHide()}})});var statusMessage=function(e,t){e=jQuery("<div/>").text(e).html(),jQuery.noticeAdd({text:e,type:t,stayTime:5e3,inEffect:{left:"0",opacity:"show"}})},errorMessage=function(e){jQuery.noticeAdd({text:e,type:"error",stayTime:5e3,inEffect:{left:"0",opacity:"show"}})}},{jQuery:"jQuery","lib/Config":15,"lib/Router":"lib/Router"}],15:[function(e,t,n){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var s=function(){function e(){i(this,e)}return e.getSection=function(e){return window.ss.config.sections[e]},e.getTopLevelRoutes=function(){var e=[];return Object.keys(window.ss.config.sections).forEach(function(t){var n=window.ss.config.sections[t].route,i=n.match(/^admin\/[^\/]+(\/?)$/);if(i){n=n.replace(/\/$/,"");var s=-1===e.indexOf(n);s&&e.push(n)}}),e},e}();n["default"]=s},{}]},{},[1]);
//# sourceMappingURL=bundle-legacy.js.map

View File

@ -21,26 +21,26 @@ window.ss.router = router;
* @desc Returns a function that will not be called until it hasn't been invoked for `wait` seconds.
*/
window.ss.debounce = function (func, wait, immediate) {
var timeout, context, args;
var timeout, context, args;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
return function() {
var callNow = immediate && !timeout;
return function() {
var callNow = immediate && !timeout;
context = this;
args = arguments;
context = this;
args = arguments;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
if (callNow) {
func.apply(context, args);
}
};
};
/**
@ -50,14 +50,14 @@ window.ss.debounce = function (func, wait, immediate) {
* @return string
*/
function getUrlPath(url) {
var anchor = document.createElement('a');
anchor.href = url;
var anchor = document.createElement('a');
anchor.href = url;
return anchor.pathname
return anchor.pathname
}
$(window).bind('resize.leftandmain', function(e) {
$('.cms-container').trigger('windowresize');
$('.cms-container').trigger('windowresize');
});
// setup jquery.entwine
@ -65,1437 +65,1440 @@ $.entwine.warningLevel = $.entwine.WARN_LEVEL_BESTPRACTISE;
$.entwine('ss', function($) {
/*
* Handle messages sent via nested iframes
* Messages should be raised via postMessage with an object with the 'type' parameter given.
* An optional 'target' and 'data' parameter can also be specified. If no target is specified
* events will be sent to the window instead.
* type should be one of:
* - 'event' - Will trigger the given event (specified by 'event') on the target
* - 'callback' - Will call the given method (specified by 'callback') on the target
*/
$(window).on("message", function(e) {
var target,
event = e.originalEvent,
data = typeof event.data === 'object' ? event.data : JSON.parse(event.data);
// Reject messages outside of the same origin
if($.path.parseUrl(window.location.href).domain !== $.path.parseUrl(event.origin).domain) return;
// Get target of this action
target = typeof(data.target) === 'undefined'
? $(window)
: $(data.target);
// Determine action
switch(data.type) {
case 'event':
target.trigger(data.event, data.data);
break;
case 'callback':
target[data.callback].call(target, data.data);
break;
}
});
/**
* Position the loading spinner animation below the ss logo
*/
var positionLoadingSpinner = function() {
var offset = 120; // offset from the ss logo
var spinner = $('.ss-loading-screen .loading-animation');
var top = ($(window).height() - spinner.height()) / 2;
spinner.css('top', top + offset);
spinner.show();
};
// apply an select element only when it is ready, ie. when it is rendered into a template
// with css applied and got a width value.
var applyChosen = function(el) {
if(el.is(':visible')) {
el.addClass('has-chosen').chosen({
allow_single_deselect: true,
disable_search_threshold: 20,
display_disabled_options: true
});
} else {
setTimeout(function() {
// Make sure it's visible before applying the ui
el.show();
applyChosen(el);
}, 500);
}
};
/**
* Compare URLs, but normalize trailing slashes in
* URL to work around routing weirdnesses in SS_HTTPRequest.
* Also normalizes relative URLs by prefixing them with the <base>.
*/
var isSameUrl = function(url1, url2) {
var baseUrl = $('base').attr('href');
url1 = $.path.isAbsoluteUrl(url1) ? url1 : $.path.makeUrlAbsolute(url1, baseUrl),
url2 = $.path.isAbsoluteUrl(url2) ? url2 : $.path.makeUrlAbsolute(url2, baseUrl);
var url1parts = $.path.parseUrl(url1), url2parts = $.path.parseUrl(url2);
return (
url1parts.pathname.replace(/\/*$/, '') == url2parts.pathname.replace(/\/*$/, '') &&
url1parts.search == url2parts.search
);
};
var ajaxCompleteEvent = window.ss.debounce(function () {
$(window).trigger('ajaxComplete');
}, 1000, true);
$(window).bind('resize', positionLoadingSpinner).trigger('resize');
// global ajax handlers
$(document).ajaxComplete(function(e, xhr, settings) {
// Simulates a redirect on an ajax response.
var origUrl,
url = xhr.getResponseHeader('X-ControllerURL'),
destUrl = settings.url,
msg = xhr.getResponseHeader('X-Status') !== null ? xhr.getResponseHeader('X-Status') : xhr.statusText, // Handle custom status message headers
msgType = (xhr.status < 200 || xhr.status > 399) ? 'bad' : 'good',
ignoredMessages = ['OK'];
if(window.history.state) {
origUrl = window.history.state.path;
} else {
origUrl = document.URL;
}
// Only redirect if controller url differs to the requested or current one
if (url !== null && (!isSameUrl(origUrl, url) || !isSameUrl(destUrl, url))) {
router.show(url, {
id: (new Date()).getTime() + String(Math.random()).replace(/\D/g,''), // Ensure that redirections are followed through by history API by handing it a unique ID
pjax: xhr.getResponseHeader('X-Pjax') ? xhr.getResponseHeader('X-Pjax') : settings.headers['X-Pjax']
});
}
// Enable reauthenticate dialog if requested
if (xhr.getResponseHeader('X-Reauthenticate')) {
$('.cms-container').showLoginDialog();
return;
}
// Show message (but ignore aborted requests)
if (xhr.status !== 0 && msg && $.inArray(msg, ignoredMessages)) {
// Decode into UTF-8, HTTP headers don't allow multibyte
statusMessage(decodeURIComponent(msg), msgType);
}
ajaxCompleteEvent(this);
});
/**
* Main LeftAndMain interface with some control panel and an edit form.
*
* Events:
* ajaxsubmit - ...
* validate - ...
* aftersubmitform - ...
*/
$('.cms-container').entwine({
/**
* Tracks current panel request.
*/
StateChangeXHR: null,
/**
* Tracks current fragment-only parallel PJAX requests.
*/
FragmentXHR: {},
StateChangeCount: 0,
/**
* Options for the threeColumnCompressor layout algorithm.
*
* See LeftAndMain.Layout.js for description of these options.
*/
LayoutOptions: {
minContentWidth: 940,
minPreviewWidth: 400,
mode: 'content'
},
/**
* Constructor: onmatch
*/
onadd: function() {
var self = this,
basePath = getUrlPath($('base')[0].href);
// Remove trailing / from base
basePath = basePath.replace(/\/$/, '');
router.base(basePath);
// Register all top level routes.
Config.getTopLevelRoutes().forEach((route) => {
router(`/${route}(/*?)?`, (ctx, next) => {
// If the page isn't ready.
if (document.readyState !== 'complete') {
return next();
}
// Load the panel then call the next route.
self.handleStateChange(null, ctx.state)
.done(next);
});
});
router.start();
// Browser detection
if($.browser.msie && parseInt($.browser.version, 10) < 8) {
$('.ss-loading-screen').append(
'<p class="ss-loading-incompat-warning"><span class="notice">' +
'Your browser is not compatible with the CMS interface. Please use Internet Explorer 8+, Google Chrome or Mozilla Firefox.' +
'</span></p>'
).css('z-index', $('.ss-loading-screen').css('z-index')+1);
$('.loading-animation').remove();
this._super();
return;
}
// Initialize layouts
this.redraw();
// Remove loading screen
$('.ss-loading-screen').hide();
$('body').removeClass('loading');
$(window).unbind('resize', positionLoadingSpinner);
this.restoreTabState();
this._super();
},
fromWindow: {
onstatechange: function(event, historyState){
this.handleStateChange(event, historyState);
}
},
'onwindowresize': function() {
this.redraw();
},
'from .cms-panel': {
ontoggle: function(){ this.redraw(); }
},
'from .cms-container': {
onaftersubmitform: function(){ this.redraw(); }
},
/**
* Ensure the user can see the requested section - restore the default view.
*/
'from .cms-menu-list li a': {
onclick: function(e) {
var href = $(e.target).attr('href');
if(e.which > 1 || href == this._tabStateUrl()) return;
this.splitViewMode();
}
},
/**
* Change the options of the threeColumnCompressor layout, and trigger layouting if needed.
* You can provide any or all options. The remaining options will not be changed.
*/
updateLayoutOptions: function(newSpec) {
var spec = this.getLayoutOptions();
var dirty = false;
for (var k in newSpec) {
if (spec[k] !== newSpec[k]) {
spec[k] = newSpec[k];
dirty = true;
}
}
if (dirty) this.redraw();
},
/**
* Enable the split view - with content on the left and preview on the right.
*/
splitViewMode: function() {
this.updateLayoutOptions({
mode: 'split'
});
},
/**
* Content only.
*/
contentViewMode: function() {
this.updateLayoutOptions({
mode: 'content'
});
},
/**
* Preview only.
*/
previewMode: function() {
this.updateLayoutOptions({
mode: 'preview'
});
},
RedrawSuppression: false,
redraw: function() {
if (this.getRedrawSuppression()) return;
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
// Reset the algorithm.
this.data('jlayout', jLayout.threeColumnCompressor(
{
menu: this.children('.cms-menu'),
content: this.children('.cms-content'),
preview: this.children('.cms-preview')
},
this.getLayoutOptions()
));
// Trigger layout algorithm once at the top. This also lays out children - we move from outside to
// inside, resizing to fit the parent.
this.layout();
// Redraw on all the children that need it
this.find('.cms-panel-layout').redraw();
this.find('.cms-content-fields[data-layout-type]').redraw();
this.find('.cms-edit-form[data-layout-type]').redraw();
this.find('.cms-preview').redraw();
this.find('.cms-content').redraw();
},
/**
* Confirm whether the current user can navigate away from this page
*
* @param {array} selectors Optional list of selectors
* @returns {boolean} True if the navigation can proceed
*/
checkCanNavigate: function(selectors) {
// Check change tracking (can't use events as we need a way to cancel the current state change)
var contentEls = this._findFragments(selectors || ['Content']),
trackedEls = contentEls
.find(':data(changetracker)')
.add(contentEls.filter(':data(changetracker)')),
safe = true;
if(!trackedEls.length) {
return true;
}
trackedEls.each(function() {
// See LeftAndMain.EditForm.js
if(!$(this).confirmUnsavedChanges()) {
safe = false;
}
});
return safe;
},
/**
* @param string url
* @param string title - New window title.
* @param object data - Any additional data passed through to `window.history.state`.
* @param boolean forceReload - Forces the replacement of the current history state, even if the URL is the same, i.e. allows reloading.
*/
loadPanel: function (url, title = '', data = {}, forceReload, forceReferer = window.history.state.path) {
// Check for unsaved changes
if (!this.checkCanNavigate(data.pjax ? data.pjax.split(',') : ['Content'])) {
return;
}
this.saveTabState();
data.__forceReferer = forceReferer;
if (forceReload) {
data.__forceReload = Math.random(); // Make sure the page reloads even if the URL is the same.
}
router.show(url, data);
},
/**
* Nice wrapper for reloading current history state.
*/
reloadCurrentPanel: function() {
this.loadPanel(window.history.state.path, null, null, true);
},
/**
* Function: submitForm
*
* Parameters:
* {DOMElement} form - The form to be submitted. Needs to be passed
* in to avoid entwine methods/context being removed through replacing the node itself.
* {DOMElement} button - The pressed button (optional)
* {Function} callback - Called in complete() handler of jQuery.ajax()
* {Object} ajaxOptions - Object literal to merge into $.ajax() call
*
* Returns:
* (boolean)
*/
submitForm: function(form, button, callback, ajaxOptions) {
var self = this;
// look for save button
if(!button) button = this.find('.Actions :submit[name=action_save]');
// default to first button if none given - simulates browser behaviour
if(!button) button = this.find('.Actions :submit:first');
form.trigger('beforesubmitform');
this.trigger('submitform', {form: form, button: button});
// set button to "submitting" state
$(button).addClass('loading');
// validate if required
var validationResult = form.validate();
if(typeof validationResult!=='undefined' && !validationResult) {
// TODO Automatically switch to the tab/position of the first error
statusMessage("Validation failed.", "bad");
$(button).removeClass('loading');
return false;
}
// get all data from the form
var formData = form.serializeArray();
// add button action
formData.push({name: $(button).attr('name'), value:'1'});
// Artificial HTTP referer, IE doesn't submit them via ajax.
// Also rewrites anchors to their page counterparts, which is important
// as automatic browser ajax response redirects seem to discard the hash/fragment.
// TODO Replaces trailing slashes added by History after locale (e.g. admin/?locale=en/)
formData.push({ name: 'BackURL', value: window.history.state.path.replace(/\/$/, '') });
// Save tab selections so we can restore them later
this.saveTabState();
// Standard Pjax behaviour is to replace the submitted form with new content.
// The returned view isn't always decided upon when the request
// is fired, so the server might decide to change it based on its own logic,
// sending back different `X-Pjax` headers and content
jQuery.ajax(jQuery.extend({
headers: {"X-Pjax" : "CurrentForm,Breadcrumbs"},
url: form.attr('action'),
data: formData,
type: 'POST',
complete: function() {
$(button).removeClass('loading');
},
success: function(data, status, xhr) {
form.removeClass('changed'); // TODO This should be using the plugin API
if(callback) callback(data, status, xhr);
var newContentEls = self.handleAjaxResponse(data, status, xhr);
if(!newContentEls) return;
newContentEls.filter('form').trigger('aftersubmitform', {status: status, xhr: xhr, formData: formData});
}
}, ajaxOptions));
return false;
},
/**
* Last html5 history state
*/
LastState: null,
/**
* Flag to pause handleStateChange
*/
PauseState: false,
/**
* Handles ajax loading of new panels through the window.history object.
* To trigger loading, pass a new URL to router.show().
* Use loadPanel() as a router.show() wrapper as it provides some additional functionality
* like global changetracking and user aborts.
*
* Due to the nature of history management, no callbacks are allowed.
* Use the 'beforestatechange' and 'afterstatechange' events instead,
* or overwrite the beforeLoad() and afterLoad() methods on the
* DOM element you're loading the new content into.
* Although you can pass data into router.show(url, data), it shouldn't contain
* DOM elements or callback closures.
*
* The passed URL should allow reconstructing important interface state
* without additional parameters, in the following use cases:
* - Explicit loading through router.show()
* - Implicit loading through browser navigation event triggered by the user (forward or back)
* - Full window refresh without ajax
* For example, a ModelAdmin search event should contain the search terms
* as URL parameters, and the result display should automatically appear
* if the URL is loaded without ajax.
*/
handleStateChange: function (event, historyState = window.history.state) {
if (this.getPauseState()) {
return;
}
// Don't allow parallel loading to avoid edge cases
if (this.getStateChangeXHR()) {
this.getStateChangeXHR().abort();
}
var self = this,
fragments = historyState.pjax || 'Content',
headers = {},
fragmentsArr = fragments.split(','),
contentEls = this._findFragments(fragmentsArr);
this.setStateChangeCount(this.getStateChangeCount() + 1);
if (!this.checkCanNavigate()) {
var lastState = this.getLastState();
// Suppress panel loading while resetting state
this.setPauseState(true);
// Restore best last state
if (lastState !== null) {
router.show(lastState.url);
} else {
router.back();
}
this.setPauseState(false);
// Abort loading of this panel
return;
}
this.setLastState(historyState);
// If any of the requested Pjax fragments don't exist in the current view,
// fetch the "Content" view instead, which is the "outermost" fragment
// that can be reloaded without reloading the whole window.
if (contentEls.length < fragmentsArr.length) {
fragments = 'Content', fragmentsArr = ['Content'];
contentEls = this._findFragments(fragmentsArr);
}
this.trigger('beforestatechange', { state: historyState, element: contentEls });
// Set Pjax headers, which can declare a preference for the returned view.
// The actually returned view isn't always decided upon when the request
// is fired, so the server might decide to change it based on its own logic.
headers['X-Pjax'] = fragments;
if (typeof historyState.__forceReferer !== 'undefined') {
// Ensure query string is properly encoded if present
let url = historyState.__forceReferer;
try {
// Prevent double-encoding by attempting to decode
url = decodeURI(url);
} catch(e) {
// URL not encoded, or was encoded incorrectly, so do nothing
} finally {
// Set our referer header to the encoded URL
headers['X-Backurl'] = encodeURI(url);
}
}
contentEls.addClass('loading');
let promise = $.ajax({
headers: headers,
url: historyState.path
})
.done((data, status, xhr) => {
var els = self.handleAjaxResponse(data, status, xhr, historyState);
self.trigger('afterstatechange', {data: data, status: status, xhr: xhr, element: els, state: historyState});
})
.always(() => {
self.setStateChangeXHR(null);
// Remove loading indication from old content els (regardless of which are replaced)
contentEls.removeClass('loading');
});
this.setStateChangeXHR(promise);
return promise;
},
/**
* ALternative to loadPanel/submitForm.
*
* Triggers a parallel-fetch of a PJAX fragment, which is a separate request to the
* state change requests. There could be any amount of these fetches going on in the background,
* and they don't register as a HTML5 history states.
*
* This is meant for updating a PJAX areas that are not complete panel/form reloads. These you'd
* normally do via submitForm or loadPanel which have a lot of automation built in.
*
* On receiving successful response, the framework will update the element tagged with appropriate
* data-pjax-fragment attribute (e.g. data-pjax-fragment="<pjax-fragment-name>"). Make sure this element
* is available.
*
* Example usage:
* $('.cms-container').loadFragment('admin/foobar/', 'FragmentName');
*
* @param url string Relative or absolute url of the controller.
* @param pjaxFragments string PJAX fragment(s), comma separated.
*/
loadFragment: function(url, pjaxFragments) {
var self = this,
xhr,
headers = {},
baseUrl = $('base').attr('href'),
fragmentXHR = this.getFragmentXHR();
// Make sure only one XHR for a specific fragment is currently in progress.
if(
typeof fragmentXHR[pjaxFragments]!=='undefined' &&
fragmentXHR[pjaxFragments]!==null
) {
fragmentXHR[pjaxFragments].abort();
fragmentXHR[pjaxFragments] = null;
}
url = $.path.isAbsoluteUrl(url) ? url : $.path.makeUrlAbsolute(url, baseUrl);
headers['X-Pjax'] = pjaxFragments;
xhr = $.ajax({
headers: headers,
url: url,
success: function(data, status, xhr) {
var elements = self.handleAjaxResponse(data, status, xhr, null);
// We are fully done now, make it possible for others to hook in here.
self.trigger('afterloadfragment', { data: data, status: status, xhr: xhr, elements: elements });
},
error: function(xhr, status, error) {
self.trigger('loadfragmenterror', { xhr: xhr, status: status, error: error });
},
complete: function() {
// Reset the current XHR in tracking object.
var fragmentXHR = self.getFragmentXHR();
if(
typeof fragmentXHR[pjaxFragments]!=='undefined' &&
fragmentXHR[pjaxFragments]!==null
) {
fragmentXHR[pjaxFragments] = null;
}
}
});
// Store the fragment request so we can abort later, should we get a duplicate request.
fragmentXHR[pjaxFragments] = xhr;
return xhr;
},
/**
* Handles ajax responses containing plain HTML, or mulitple
* PJAX fragments wrapped in JSON (see PjaxResponseNegotiator PHP class).
* Can be hooked into an ajax 'success' callback.
*
* Parameters:
* (Object) data
* (String) status
* (XMLHTTPRequest) xhr
* (Object) state The original history state which the request was initiated with
*/
handleAjaxResponse: function(data, status, xhr, state) {
var self = this, url, selectedTabs, guessFragment, fragment, $data;
// Support a full reload
if(xhr.getResponseHeader('X-Reload') && xhr.getResponseHeader('X-ControllerURL')) {
var baseUrl = $('base').attr('href'),
rawURL = xhr.getResponseHeader('X-ControllerURL'),
url = $.path.isAbsoluteUrl(rawURL) ? rawURL : $.path.makeUrlAbsolute(rawURL, baseUrl);
document.location.href = url;
return;
}
// Pseudo-redirects via X-ControllerURL might return empty data, in which
// case we'll ignore the response
if(!data) return;
// Update title
var title = xhr.getResponseHeader('X-Title');
if(title) document.title = decodeURIComponent(title.replace(/\+/g, ' '));
var newFragments = {}, newContentEls;
// If content type is text/json (ignoring charset and other parameters)
if(xhr.getResponseHeader('Content-Type').match(/^((text)|(application))\/json[ \t]*;?/i)) {
newFragments = data;
} else {
// Fall back to replacing the content fragment if HTML is returned
fragment = document.createDocumentFragment();
jQuery.clean( [ data ], document, fragment, [] );
$data = $(jQuery.merge( [], fragment.childNodes ));
// Try and guess the fragment if none is provided
// TODO: data-pjax-fragment might actually give us the fragment. For now we just check most common case
guessFragment = 'Content';
if ($data.is('form') && !$data.is('[data-pjax-fragment~=Content]')) guessFragment = 'CurrentForm';
newFragments[guessFragment] = $data;
}
this.setRedrawSuppression(true);
try {
// Replace each fragment individually
$.each(newFragments, function(newFragment, html) {
var contentEl = $('[data-pjax-fragment]').filter(function() {
return $.inArray(newFragment, $(this).data('pjaxFragment').split(' ')) != -1;
}), newContentEl = $(html);
// Add to result collection
if(newContentEls) newContentEls.add(newContentEl);
else newContentEls = newContentEl;
// Update panels
if(newContentEl.find('.cms-container').length) {
throw 'Content loaded via ajax is not allowed to contain tags matching the ".cms-container" selector to avoid infinite loops';
}
// Set loading state and store element state
var origStyle = contentEl.attr('style');
var origParent = contentEl.parent();
var origParentLayoutApplied = (typeof origParent.data('jlayout')!=='undefined');
var layoutClasses = ['east', 'west', 'center', 'north', 'south', 'column-hidden'];
var elemClasses = contentEl.attr('class');
var origLayoutClasses = [];
if(elemClasses) {
origLayoutClasses = $.grep(
elemClasses.split(' '),
function(val) { return ($.inArray(val, layoutClasses) >= 0);}
);
}
newContentEl
.removeClass(layoutClasses.join(' '))
.addClass(origLayoutClasses.join(' '));
if(origStyle) newContentEl.attr('style', origStyle);
// Allow injection of inline styles, as they're not allowed in the document body.
// Not handling this through jQuery.ondemand to avoid parsing the DOM twice.
var styles = newContentEl.find('style').detach();
if(styles.length) $(document).find('head').append(styles);
// Replace panel completely (we need to override the "layout" attribute, so can't replace the child instead)
contentEl.replaceWith(newContentEl);
// Force jlayout to rebuild internal hierarchy to point to the new elements.
// This is only necessary for elements that are at least 3 levels deep. 2nd level elements will
// be taken care of when we lay out the top level element (.cms-container).
if (!origParent.is('.cms-container') && origParentLayoutApplied) {
origParent.layout();
}
});
// Re-init tabs (in case the form tag itself is a tabset)
var newForm = newContentEls.filter('form');
if(newForm.hasClass('cms-tabset')) newForm.removeClass('cms-tabset').addClass('cms-tabset');
}
finally {
this.setRedrawSuppression(false);
}
this.redraw();
this.restoreTabState((state && typeof state.tabState !== 'undefined') ? state.tabState : null);
return newContentEls;
},
/**
*
*
* Parameters:
* - fragments {Array}
* Returns: jQuery collection
*/
_findFragments: function(fragments) {
return $('[data-pjax-fragment]').filter(function() {
// Allows for more than one fragment per node
var i, nodeFragments = $(this).data('pjaxFragment').split(' ');
for(i in fragments) {
if($.inArray(fragments[i], nodeFragments) != -1) return true;
}
return false;
});
},
/**
* Function: refresh
*
* Updates the container based on the current url
*
* Returns: void
*/
refresh: function() {
$(window).trigger('statechange');
$(this).redraw();
},
/**
* Save tab selections in order to reconstruct them later.
* Requires HTML5 sessionStorage support.
*/
saveTabState: function() {
if(typeof(window.sessionStorage)=="undefined" || window.sessionStorage === null) return;
var selectedTabs = [], url = this._tabStateUrl();
this.find('.cms-tabset,.ss-tabset').each(function(i, el) {
var id = $(el).attr('id');
if(!id) return; // we need a unique reference
if(!$(el).data('tabs')) return; // don't act on uninit'ed controls
// Allow opt-out via data element or entwine property.
if($(el).data('ignoreTabState') || $(el).getIgnoreTabState()) return;
selectedTabs.push({id:id, selected:$(el).tabs('option', 'selected')});
});
if(selectedTabs) {
var tabsUrl = 'tabs-' + url;
try {
window.sessionStorage.setItem(tabsUrl, JSON.stringify(selectedTabs));
} catch(err) {
if (err.code === DOMException.QUOTA_EXCEEDED_ERR && window.sessionStorage.length === 0) {
// If this fails we ignore the error as the only issue is that it
// does not remember the tab state.
// This is a Safari bug which happens when private browsing is enabled.
return;
} else {
throw err;
}
}
}
},
/**
* Re-select previously saved tabs.
* Requires HTML5 sessionStorage support.
*
* Parameters:
* (Object) Map of tab container selectors to tab selectors.
* Used to mark a specific tab as active regardless of the previously saved options.
*/
restoreTabState: function(overrideStates) {
var self = this, url = this._tabStateUrl(),
hasSessionStorage = (typeof(window.sessionStorage)!=="undefined" && window.sessionStorage),
sessionData = hasSessionStorage ? window.sessionStorage.getItem('tabs-' + url) : null,
sessionStates = sessionData ? JSON.parse(sessionData) : false;
this.find('.cms-tabset, .ss-tabset').each(function() {
var index, tabset = $(this), tabsetId = tabset.attr('id'), tab,
forcedTab = tabset.find('.ss-tabs-force-active');
if(!tabset.data('tabs')){
return; // don't act on uninit'ed controls
}
// The tabs may have changed, notify the widget that it should update its internal state.
tabset.tabs('refresh');
// Make sure the intended tab is selected.
if(forcedTab.length) {
index = forcedTab.index();
} else if(overrideStates && overrideStates[tabsetId]) {
tab = tabset.find(overrideStates[tabsetId].tabSelector);
if(tab.length){
index = tab.index();
}
} else if(sessionStates) {
$.each(sessionStates, function(i, sessionState) {
if(tabset.is('#' + sessionState.id)){
index = sessionState.selected;
}
});
}
if(index !== null){
tabset.tabs('option', 'active', index);
self.trigger('tabstaterestored');
}
});
},
/**
* Remove any previously saved state.
*
* Parameters:
* (String) url Optional (sanitized) URL to clear a specific state.
*/
clearTabState: function(url) {
if(typeof(window.sessionStorage)=="undefined") return;
var s = window.sessionStorage;
if(url) {
s.removeItem('tabs-' + url);
} else {
for(var i=0;i<s.length;i++) {
if(s.key(i).match(/^tabs-/)) s.removeItem(s.key(i));
}
}
},
/**
* Remove tab state for the current URL.
*/
clearCurrentTabState: function() {
this.clearTabState(this._tabStateUrl());
},
_tabStateUrl: function() {
return window.history.state.path
.replace(/\?.*/, '')
.replace(/#.*/, '')
.replace($('base').attr('href'), '');
},
showLoginDialog: function() {
var tempid = $('body').data('member-tempid'),
dialog = $('.leftandmain-logindialog'),
url = 'CMSSecurity/login';
// Force regeneration of any existing dialog
if(dialog.length) dialog.remove();
// Join url params
url = $.path.addSearchParams(url, {
'tempid': tempid,
'BackURL': window.location.href
});
// Show a placeholder for instant feedback. Will be replaced with actual
// form dialog once its loaded.
dialog = $('<div class="leftandmain-logindialog"></div>');
dialog.attr('id', new Date().getTime());
dialog.data('url', url);
$('body').append(dialog);
}
});
// Login dialog page
$('.leftandmain-logindialog').entwine({
onmatch: function() {
this._super();
// Create jQuery dialog
this.ssdialog({
iframeUrl: this.data('url'),
dialogClass: "leftandmain-logindialog-dialog",
autoOpen: true,
minWidth: 500,
maxWidth: 500,
minHeight: 370,
maxHeight: 400,
closeOnEscape: false,
open: function() {
$('.ui-widget-overlay').addClass('leftandmain-logindialog-overlay');
},
close: function() {
$('.ui-widget-overlay').removeClass('leftandmain-logindialog-overlay');
}
});
},
onunmatch: function() {
this._super();
},
open: function() {
this.ssdialog('open');
},
close: function() {
this.ssdialog('close');
},
toggle: function(bool) {
if(this.is(':visible')) this.close();
else this.open();
},
/**
* Callback activated by CMSSecurity_success.ss
*/
reauthenticate: function(data) {
// Replace all SecurityID fields with the given value
if(typeof(data.SecurityID) !== 'undefined') {
$(':input[name=SecurityID]').val(data.SecurityID);
}
// Update TempID for current user
if(typeof(data.TempID) !== 'undefined') {
$('body').data('member-tempid', data.TempID);
}
this.close();
}
});
/**
* Add loading overlay to selected regions in the CMS automatically.
* Not applied to all "*.loading" elements to avoid secondary regions
* like the breadcrumbs showing unnecessary loading status.
*/
$('form.loading,.cms-content.loading,.cms-content-fields.loading,.cms-content-view.loading').entwine({
onmatch: function() {
this.append('<div class="cms-content-loading-overlay ui-widget-overlay-light"></div><div class="cms-content-loading-spinner"></div>');
this._super();
},
onunmatch: function() {
this.find('.cms-content-loading-overlay,.cms-content-loading-spinner').remove();
this._super();
}
});
/** Make all buttons "hoverable" with jQuery theming. */
$('.cms input[type="submit"], .cms button, .cms input[type="reset"], .cms .ss-ui-button').entwine({
onadd: function() {
this.addClass('ss-ui-button');
if(!this.data('button')) this.button();
this._super();
},
onremove: function() {
if(this.data('button')) this.button('destroy');
this._super();
}
});
/**
* Loads the link's 'href' attribute into a panel via ajax,
* as opposed to triggering a full page reload.
* Little helper to avoid repetition, and make it easy to
* "opt in" to panel loading, while by default links still exhibit their default behaviour.
* The PJAX target can be specified via a 'data-pjax-target' attribute.
*/
$('.cms .cms-panel-link').entwine({
onclick: function(e) {
if($(this).hasClass('external-link')) {
e.stopPropagation();
return;
}
var href = this.attr('href'),
url = (href && !href.match(/^#/)) ? href : this.data('href'),
data = {pjax: this.data('pjaxTarget')};
$('.cms-container').loadPanel(url, null, data);
e.preventDefault();
}
});
/**
* Does an ajax loads of the link's 'href' attribute via ajax and displays any FormResponse messages from the CMS.
* Little helper to avoid repetition, and make it easy to trigger actions via a link,
* without reloading the page, changing the URL, or loading in any new panel content.
*/
$('.cms .ss-ui-button-ajax').entwine({
onclick: function(e) {
$(this).removeClass('ui-button-text-only');
$(this).addClass('ss-ui-button-loading ui-button-text-icons');
var loading = $(this).find(".ss-ui-loading-icon");
if(loading.length < 1) {
loading = $("<span></span>").addClass('ss-ui-loading-icon ui-button-icon-primary ui-icon');
$(this).prepend(loading);
}
loading.show();
var href = this.attr('href'), url = href ? href : this.data('href');
jQuery.ajax({
url: url,
// Ensure that form view is loaded (rather than whole "Content" template)
complete: function(xmlhttp, status) {
var msg = (xmlhttp.getResponseHeader('X-Status')) ? xmlhttp.getResponseHeader('X-Status') : xmlhttp.responseText;
try {
if (typeof msg != "undefined" && msg !== null) eval(msg);
}
catch(e) {}
loading.hide();
$(".cms-container").refresh();
$(this).removeClass('ss-ui-button-loading ui-button-text-icons');
$(this).addClass('ui-button-text-only');
},
dataType: 'html'
});
e.preventDefault();
}
});
/**
* Trigger dialogs with iframe based on the links href attribute (see ssui-core.js).
*/
$('.cms .ss-ui-dialog-link').entwine({
UUID: null,
onmatch: function() {
this._super();
this.setUUID(new Date().getTime());
},
onunmatch: function() {
this._super();
},
onclick: function() {
this._super();
var self = this, id = 'ss-ui-dialog-' + this.getUUID();
var dialog = $('#' + id);
if(!dialog.length) {
dialog = $('<div class="ss-ui-dialog" id="' + id + '" />');
$('body').append(dialog);
}
var extraClass = this.data('popupclass')?this.data('popupclass'):'';
dialog.ssdialog({iframeUrl: this.attr('href'), autoOpen: true, dialogExtraClass: extraClass});
return false;
}
});
/**
* Add styling to all contained buttons, and create buttonsets if required.
*/
$('.cms-content .Actions').entwine({
onmatch: function() {
this.find('.ss-ui-button').click(function() {
var form = this.form;
// forms don't natively store the button they've been triggered with
if(form) {
form.clickedButton = this;
// Reset the clicked button shortly after the onsubmit handlers
// have fired on the form
setTimeout(function() {
form.clickedButton = null;
}, 10);
}
});
this.redraw();
this._super();
},
onunmatch: function() {
this._super();
},
redraw: function() {
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
// Remove whitespace to avoid gaps with inline elements
this.contents().filter(function() {
return (this.nodeType == 3 && !/\S/.test(this.nodeValue));
}).remove();
// Init buttons if required
this.find('.ss-ui-button').each(function() {
if(!$(this).data('button')) $(this).button();
});
// Mark up buttonsets
this.find('.ss-ui-buttonset').buttonset();
}
});
/**
* Duplicates functionality in DateField.js, but due to using entwine we can match
* the DOM element on creation, rather than onclick - which allows us to decorate
* the field with a calendar icon
*/
$('.cms .field.date input.text').entwine({
onmatch: function() {
var holder = $(this).parents('.field.date:first'), config = holder.data();
if(!config.showcalendar) {
this._super();
return;
}
config.showOn = 'button';
if(config.locale && $.datepicker.regional[config.locale]) {
config = $.extend(config, $.datepicker.regional[config.locale], {});
}
$(this).datepicker(config);
// // Unfortunately jQuery UI only allows configuration of icon images, not sprites
// this.next('button').button('option', 'icons', {primary : 'ui-icon-calendar'});
this._super();
},
onunmatch: function() {
this._super();
}
});
/**
* Styled dropdown select fields via chosen. Allows things like search and optgroup
* selection support. Rather than manually adding classes to selects we want
* styled, we style everything but the ones we tell it not to.
*
* For the CMS we also need to tell the parent div that it has a select so
* we can fix the height cropping.
*/
$('.cms .field.dropdown select, .cms .field select[multiple], .fieldholder-small select.dropdown').entwine({
onmatch: function() {
if(this.is('.no-chosen')) {
this._super();
return;
}
// Explicitly disable default placeholder if no custom one is defined
if(!this.data('placeholder')) this.data('placeholder', ' ');
// We could've gotten stale classes and DOM elements from deferred cache.
this.removeClass('has-chosen').chosen("destroy");
this.siblings('.chosen-container').remove();
// Apply Chosen
applyChosen(this);
this._super();
},
onunmatch: function() {
this._super();
}
});
$(".cms-panel-layout").entwine({
redraw: function() {
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
}
});
/**
* Overload the default GridField behaviour (open a new URL in the browser)
* with the CMS-specific ajax loading.
*/
$('.cms .ss-gridfield').entwine({
showDetailView: function(url) {
// Include any GET parameters from the current URL, as the view state might depend on it.
// For example, a list prefiltered through external search criteria might be passed to GridField.
var params = window.location.search.replace(/^\?/, '');
if(params) url = $.path.addSearchParams(url, params);
$('.cms-container').loadPanel(url);
}
});
/**
* Generic search form in the CMS, often hooked up to a GridField results display.
*/
$('.cms-search-form').entwine({
onsubmit: function(e) {
// Remove empty elements and make the URL prettier
var nonEmptyInputs,
url;
nonEmptyInputs = this.find(':input:not(:submit)').filter(function() {
// Use fieldValue() from jQuery.form plugin rather than jQuery.val(),
// as it handles checkbox values more consistently
var vals = $.grep($(this).fieldValue(), function(val) { return (val);});
return (vals.length);
});
url = this.attr('action');
if(nonEmptyInputs.length) {
url = $.path.addSearchParams(
url,
// Undo jQuery's non-standard serialisation
// See https://github.com/jquery/jquery/blob/1.7.2/src/ajax.js#L797
nonEmptyInputs.serialize().replace('+', '%20')
);
}
var container = this.closest('.cms-container');
container.find('.cms-edit-form').tabs('select',0); //always switch to the first tab (list view) when searching
container.loadPanel(url, "", {}, true);
return false;
}
});
/**
* Reset button handler. IE8 does not bubble reset events to
*/
$(".cms-search-form button[type=reset], .cms-search-form input[type=reset]").entwine({
onclick: function(e) {
e.preventDefault();
var form = $(this).parents('form');
form.clearForm();
form.find(".dropdown select").prop('selectedIndex', 0).trigger("chosen:updated"); // Reset chosen.js
form.submit();
}
});
/**
* Allows to lazy load a panel, by leaving it empty
* and declaring a URL to load its content via a 'url' HTML5 data attribute.
* The loaded HTML is cached, with cache key being the 'url' attribute.
* In order for this to work consistently, we assume that the responses are stateless.
* To avoid caching, add a 'deferred-no-cache' to the node.
*/
window._panelDeferredCache = {};
$('.cms-panel-deferred').entwine({
onadd: function() {
this._super();
this.redraw();
},
onremove: function() {
if(window.debug) console.log('saving', this.data('url'), this);
// Save the HTML state at the last possible moment.
// Don't store the DOM to avoid memory leaks.
if(!this.data('deferredNoCache')) window._panelDeferredCache[this.data('url')] = this.html();
this._super();
},
redraw: function() {
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
var self = this, url = this.data('url');
if(!url) throw 'Elements of class .cms-panel-deferred need a "data-url" attribute';
this._super();
// If the node is empty, try to either load it from cache or via ajax.
if(!this.children().length) {
if(!this.data('deferredNoCache') && typeof window._panelDeferredCache[url] !== 'undefined') {
this.html(window._panelDeferredCache[url]);
} else {
this.addClass('loading');
$.ajax({
url: url,
complete: function() {
self.removeClass('loading');
},
success: function(data, status, xhr) {
self.html(data);
}
});
}
}
}
});
/**
* Lightweight wrapper around jQuery UI tabs.
* Ensures that anchor links are set properly,
* and any nested tabs are scrolled if they have
* their height explicitly set. This is important
* for forms inside the CMS layout.
*/
$('.cms-tabset').entwine({
onadd: function() {
// Can't name redraw() as it clashes with other CMS entwine classes
this.redrawTabs();
this._super();
},
onremove: function() {
if (this.data('tabs')) this.tabs('destroy');
this._super();
},
redrawTabs: function() {
this.rewriteHashlinks();
var id = this.attr('id'), activeTab = this.find('ul:first .ui-tabs-active');
if(!this.data('uiTabs')) this.tabs({
active: (activeTab.index() != -1) ? activeTab.index() : 0,
beforeLoad: function(e, ui) {
// Disable automatic ajax loading of tabs without matching DOM elements,
// determining if the current URL differs from the tab URL is too error prone.
return false;
},
activate: function(e, ui) {
// Usability: Hide actions for "readonly" tabs (which don't contain any editable fields)
var actions = $(this).closest('form').find('.Actions');
if($(ui.newTab).closest('li').hasClass('readonly')) {
actions.fadeOut();
} else {
actions.show();
}
}
});
},
/**
* Ensure hash links are prefixed with the current page URL,
* otherwise jQuery interprets them as being external.
*/
rewriteHashlinks: function() {
$(this).find('ul a').each(function() {
if (!$(this).attr('href')) return;
var matches = $(this).attr('href').match(/#.*/);
if(!matches) return;
$(this).attr('href', document.location.href.replace(/#.*/, '') + matches[0]);
});
}
});
/**
* CMS content filters
*/
$('#filters-button').entwine({
onmatch: function () {
this._super();
this.data('collapsed', true); // The current collapsed state of the element.
this.data('animating', false); // True if the element is currently animating.
},
onunmatch: function () {
this._super();
},
showHide: function () {
var self = this,
$filters = $('.cms-content-filters').first(),
collapsed = this.data('collapsed');
// Prevent the user from spamming the UI with animation requests.
if (this.data('animating')) {
return;
}
this.toggleClass('active');
this.data('animating', true);
// Slide the element down / up based on it's current collapsed state.
$filters[collapsed ? 'slideDown' : 'slideUp']({
complete: function () {
// Update the element's state.
self.data('collapsed', !collapsed);
self.data('animating', false);
}
});
},
onclick: function () {
this.showHide();
}
});
/*
* Handle messages sent via nested iframes
* Messages should be raised via postMessage with an object with the 'type' parameter given.
* An optional 'target' and 'data' parameter can also be specified. If no target is specified
* events will be sent to the window instead.
* type should be one of:
* - 'event' - Will trigger the given event (specified by 'event') on the target
* - 'callback' - Will call the given method (specified by 'callback') on the target
*/
$(window).on("message", function(e) {
var target,
event = e.originalEvent,
data = typeof event.data === 'object' ? event.data : JSON.parse(event.data);
// Reject messages outside of the same origin
if($.path.parseUrl(window.location.href).domain !== $.path.parseUrl(event.origin).domain) return;
// Get target of this action
target = typeof(data.target) === 'undefined'
? $(window)
: $(data.target);
// Determine action
switch(data.type) {
case 'event':
target.trigger(data.event, data.data);
break;
case 'callback':
target[data.callback].call(target, data.data);
break;
}
});
/**
* Position the loading spinner animation below the ss logo
*/
var positionLoadingSpinner = function() {
var offset = 120; // offset from the ss logo
var spinner = $('.ss-loading-screen .loading-animation');
var top = ($(window).height() - spinner.height()) / 2;
spinner.css('top', top + offset);
spinner.show();
};
// apply an select element only when it is ready, ie. when it is rendered into a template
// with css applied and got a width value.
var applyChosen = function(el) {
if(el.is(':visible')) {
el.addClass('has-chosen').chosen({
allow_single_deselect: true,
disable_search_threshold: 20,
display_disabled_options: true
});
} else {
setTimeout(function() {
// Make sure it's visible before applying the ui
el.show();
applyChosen(el);
}, 500);
}
};
/**
* Compare URLs, but normalize trailing slashes in
* URL to work around routing weirdnesses in SS_HTTPRequest.
* Also normalizes relative URLs by prefixing them with the <base>.
*/
var isSameUrl = function(url1, url2) {
var baseUrl = $('base').attr('href');
url1 = $.path.isAbsoluteUrl(url1) ? url1 : $.path.makeUrlAbsolute(url1, baseUrl),
url2 = $.path.isAbsoluteUrl(url2) ? url2 : $.path.makeUrlAbsolute(url2, baseUrl);
var url1parts = $.path.parseUrl(url1), url2parts = $.path.parseUrl(url2);
return (
url1parts.pathname.replace(/\/*$/, '') == url2parts.pathname.replace(/\/*$/, '') &&
url1parts.search == url2parts.search
);
};
var ajaxCompleteEvent = window.ss.debounce(function () {
$(window).trigger('ajaxComplete');
}, 1000, true);
$(window).bind('resize', positionLoadingSpinner).trigger('resize');
// global ajax handlers
$(document).ajaxComplete(function(e, xhr, settings) {
// Simulates a redirect on an ajax response.
var origUrl,
url = xhr.getResponseHeader('X-ControllerURL'),
destUrl = settings.url,
msg = xhr.getResponseHeader('X-Status') !== null ? xhr.getResponseHeader('X-Status') : xhr.statusText, // Handle custom status message headers
msgType = (xhr.status < 200 || xhr.status > 399) ? 'bad' : 'good',
ignoredMessages = ['OK'];
if(window.history.state) {
origUrl = window.history.state.path;
} else {
origUrl = document.URL;
}
// Only redirect if controller url differs to the requested or current one
if (url !== null && (!isSameUrl(origUrl, url) || !isSameUrl(destUrl, url))) {
router.show(url, {
id: (new Date()).getTime() + String(Math.random()).replace(/\D/g,''), // Ensure that redirections are followed through by history API by handing it a unique ID
pjax: xhr.getResponseHeader('X-Pjax') ? xhr.getResponseHeader('X-Pjax') : settings.headers['X-Pjax']
});
}
// Enable reauthenticate dialog if requested
if (xhr.getResponseHeader('X-Reauthenticate')) {
$('.cms-container').showLoginDialog();
return;
}
// Show message (but ignore aborted requests)
if (xhr.status !== 0 && msg && $.inArray(msg, ignoredMessages)) {
// Decode into UTF-8, HTTP headers don't allow multibyte
statusMessage(decodeURIComponent(msg), msgType);
}
ajaxCompleteEvent(this);
});
/**
* Main LeftAndMain interface with some control panel and an edit form.
*
* Events:
* ajaxsubmit - ...
* validate - ...
* aftersubmitform - ...
*/
$('.cms-container').entwine({
/**
* Tracks current panel request.
*/
StateChangeXHR: null,
/**
* Tracks current fragment-only parallel PJAX requests.
*/
FragmentXHR: {},
StateChangeCount: 0,
/**
* Options for the threeColumnCompressor layout algorithm.
*
* See LeftAndMain.Layout.js for description of these options.
*/
LayoutOptions: {
minContentWidth: 940,
minPreviewWidth: 400,
mode: 'content'
},
/**
* Constructor: onmatch
*/
onadd: function() {
var self = this,
basePath = getUrlPath($('base')[0].href);
// Cleanup baseurl
basePath = basePath.replace(/\/$/, ''); // No trailing slash
if(basePath.match(/^[^\/]/)) {
basePath = '/' + basePath; // Mandatory leading slash
}
router.base(basePath);
// Register all top level routes.
Config.getTopLevelRoutes().forEach((route) => {
router(`/${route}(/*?)?`, (ctx, next) => {
// If the page isn't ready.
if (document.readyState !== 'complete') {
return next();
}
// Load the panel then call the next route.
self.handleStateChange(null, ctx.state)
.done(next);
});
});
router.start();
// Browser detection
if($.browser.msie && parseInt($.browser.version, 10) < 8) {
$('.ss-loading-screen').append(
'<p class="ss-loading-incompat-warning"><span class="notice">' +
'Your browser is not compatible with the CMS interface. Please use Internet Explorer 8+, Google Chrome or Mozilla Firefox.' +
'</span></p>'
).css('z-index', $('.ss-loading-screen').css('z-index')+1);
$('.loading-animation').remove();
this._super();
return;
}
// Initialize layouts
this.redraw();
// Remove loading screen
$('.ss-loading-screen').hide();
$('body').removeClass('loading');
$(window).unbind('resize', positionLoadingSpinner);
this.restoreTabState();
this._super();
},
fromWindow: {
onstatechange: function(event, historyState){
this.handleStateChange(event, historyState);
}
},
'onwindowresize': function() {
this.redraw();
},
'from .cms-panel': {
ontoggle: function(){ this.redraw(); }
},
'from .cms-container': {
onaftersubmitform: function(){ this.redraw(); }
},
/**
* Ensure the user can see the requested section - restore the default view.
*/
'from .cms-menu-list li a': {
onclick: function(e) {
var href = $(e.target).attr('href');
if(e.which > 1 || href == this._tabStateUrl()) return;
this.splitViewMode();
}
},
/**
* Change the options of the threeColumnCompressor layout, and trigger layouting if needed.
* You can provide any or all options. The remaining options will not be changed.
*/
updateLayoutOptions: function(newSpec) {
var spec = this.getLayoutOptions();
var dirty = false;
for (var k in newSpec) {
if (spec[k] !== newSpec[k]) {
spec[k] = newSpec[k];
dirty = true;
}
}
if (dirty) this.redraw();
},
/**
* Enable the split view - with content on the left and preview on the right.
*/
splitViewMode: function() {
this.updateLayoutOptions({
mode: 'split'
});
},
/**
* Content only.
*/
contentViewMode: function() {
this.updateLayoutOptions({
mode: 'content'
});
},
/**
* Preview only.
*/
previewMode: function() {
this.updateLayoutOptions({
mode: 'preview'
});
},
RedrawSuppression: false,
redraw: function() {
if (this.getRedrawSuppression()) return;
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
// Reset the algorithm.
this.data('jlayout', jLayout.threeColumnCompressor(
{
menu: this.children('.cms-menu'),
content: this.children('.cms-content'),
preview: this.children('.cms-preview')
},
this.getLayoutOptions()
));
// Trigger layout algorithm once at the top. This also lays out children - we move from outside to
// inside, resizing to fit the parent.
this.layout();
// Redraw on all the children that need it
this.find('.cms-panel-layout').redraw();
this.find('.cms-content-fields[data-layout-type]').redraw();
this.find('.cms-edit-form[data-layout-type]').redraw();
this.find('.cms-preview').redraw();
this.find('.cms-content').redraw();
},
/**
* Confirm whether the current user can navigate away from this page
*
* @param {array} selectors Optional list of selectors
* @returns {boolean} True if the navigation can proceed
*/
checkCanNavigate: function(selectors) {
// Check change tracking (can't use events as we need a way to cancel the current state change)
var contentEls = this._findFragments(selectors || ['Content']),
trackedEls = contentEls
.find(':data(changetracker)')
.add(contentEls.filter(':data(changetracker)')),
safe = true;
if(!trackedEls.length) {
return true;
}
trackedEls.each(function() {
// See LeftAndMain.EditForm.js
if(!$(this).confirmUnsavedChanges()) {
safe = false;
}
});
return safe;
},
/**
* @param string url
* @param string title - New window title.
* @param object data - Any additional data passed through to `window.history.state`.
* @param boolean forceReload - Forces the replacement of the current history state, even if the URL is the same, i.e. allows reloading.
*/
loadPanel: function (url, title = '', data = {}, forceReload, forceReferer = window.history.state.path) {
// Check for unsaved changes
if (!this.checkCanNavigate(data.pjax ? data.pjax.split(',') : ['Content'])) {
return;
}
this.saveTabState();
data.__forceReferer = forceReferer;
if (forceReload) {
data.__forceReload = Math.random(); // Make sure the page reloads even if the URL is the same.
}
router.show(url, data);
},
/**
* Nice wrapper for reloading current history state.
*/
reloadCurrentPanel: function() {
this.loadPanel(window.history.state.path, null, null, true);
},
/**
* Function: submitForm
*
* Parameters:
* {DOMElement} form - The form to be submitted. Needs to be passed
* in to avoid entwine methods/context being removed through replacing the node itself.
* {DOMElement} button - The pressed button (optional)
* {Function} callback - Called in complete() handler of jQuery.ajax()
* {Object} ajaxOptions - Object literal to merge into $.ajax() call
*
* Returns:
* (boolean)
*/
submitForm: function(form, button, callback, ajaxOptions) {
var self = this;
// look for save button
if(!button) button = this.find('.Actions :submit[name=action_save]');
// default to first button if none given - simulates browser behaviour
if(!button) button = this.find('.Actions :submit:first');
form.trigger('beforesubmitform');
this.trigger('submitform', {form: form, button: button});
// set button to "submitting" state
$(button).addClass('loading');
// validate if required
var validationResult = form.validate();
if(typeof validationResult!=='undefined' && !validationResult) {
// TODO Automatically switch to the tab/position of the first error
statusMessage("Validation failed.", "bad");
$(button).removeClass('loading');
return false;
}
// get all data from the form
var formData = form.serializeArray();
// add button action
formData.push({name: $(button).attr('name'), value:'1'});
// Artificial HTTP referer, IE doesn't submit them via ajax.
// Also rewrites anchors to their page counterparts, which is important
// as automatic browser ajax response redirects seem to discard the hash/fragment.
// TODO Replaces trailing slashes added by History after locale (e.g. admin/?locale=en/)
formData.push({ name: 'BackURL', value: window.history.state.path.replace(/\/$/, '') });
// Save tab selections so we can restore them later
this.saveTabState();
// Standard Pjax behaviour is to replace the submitted form with new content.
// The returned view isn't always decided upon when the request
// is fired, so the server might decide to change it based on its own logic,
// sending back different `X-Pjax` headers and content
jQuery.ajax(jQuery.extend({
headers: {"X-Pjax" : "CurrentForm,Breadcrumbs"},
url: form.attr('action'),
data: formData,
type: 'POST',
complete: function() {
$(button).removeClass('loading');
},
success: function(data, status, xhr) {
form.removeClass('changed'); // TODO This should be using the plugin API
if(callback) callback(data, status, xhr);
var newContentEls = self.handleAjaxResponse(data, status, xhr);
if(!newContentEls) return;
newContentEls.filter('form').trigger('aftersubmitform', {status: status, xhr: xhr, formData: formData});
}
}, ajaxOptions));
return false;
},
/**
* Last html5 history state
*/
LastState: null,
/**
* Flag to pause handleStateChange
*/
PauseState: false,
/**
* Handles ajax loading of new panels through the window.history object.
* To trigger loading, pass a new URL to router.show().
* Use loadPanel() as a router.show() wrapper as it provides some additional functionality
* like global changetracking and user aborts.
*
* Due to the nature of history management, no callbacks are allowed.
* Use the 'beforestatechange' and 'afterstatechange' events instead,
* or overwrite the beforeLoad() and afterLoad() methods on the
* DOM element you're loading the new content into.
* Although you can pass data into router.show(url, data), it shouldn't contain
* DOM elements or callback closures.
*
* The passed URL should allow reconstructing important interface state
* without additional parameters, in the following use cases:
* - Explicit loading through router.show()
* - Implicit loading through browser navigation event triggered by the user (forward or back)
* - Full window refresh without ajax
* For example, a ModelAdmin search event should contain the search terms
* as URL parameters, and the result display should automatically appear
* if the URL is loaded without ajax.
*/
handleStateChange: function (event, historyState = window.history.state) {
if (this.getPauseState()) {
return;
}
// Don't allow parallel loading to avoid edge cases
if (this.getStateChangeXHR()) {
this.getStateChangeXHR().abort();
}
var self = this,
fragments = historyState.pjax || 'Content',
headers = {},
fragmentsArr = fragments.split(','),
contentEls = this._findFragments(fragmentsArr);
this.setStateChangeCount(this.getStateChangeCount() + 1);
if (!this.checkCanNavigate()) {
var lastState = this.getLastState();
// Suppress panel loading while resetting state
this.setPauseState(true);
// Restore best last state
if (lastState !== null) {
router.show(lastState.url);
} else {
router.back();
}
this.setPauseState(false);
// Abort loading of this panel
return;
}
this.setLastState(historyState);
// If any of the requested Pjax fragments don't exist in the current view,
// fetch the "Content" view instead, which is the "outermost" fragment
// that can be reloaded without reloading the whole window.
if (contentEls.length < fragmentsArr.length) {
fragments = 'Content', fragmentsArr = ['Content'];
contentEls = this._findFragments(fragmentsArr);
}
this.trigger('beforestatechange', { state: historyState, element: contentEls });
// Set Pjax headers, which can declare a preference for the returned view.
// The actually returned view isn't always decided upon when the request
// is fired, so the server might decide to change it based on its own logic.
headers['X-Pjax'] = fragments;
if (typeof historyState.__forceReferer !== 'undefined') {
// Ensure query string is properly encoded if present
let url = historyState.__forceReferer;
try {
// Prevent double-encoding by attempting to decode
url = decodeURI(url);
} catch(e) {
// URL not encoded, or was encoded incorrectly, so do nothing
} finally {
// Set our referer header to the encoded URL
headers['X-Backurl'] = encodeURI(url);
}
}
contentEls.addClass('loading');
let promise = $.ajax({
headers: headers,
url: historyState.path
})
.done((data, status, xhr) => {
var els = self.handleAjaxResponse(data, status, xhr, historyState);
self.trigger('afterstatechange', {data: data, status: status, xhr: xhr, element: els, state: historyState});
})
.always(() => {
self.setStateChangeXHR(null);
// Remove loading indication from old content els (regardless of which are replaced)
contentEls.removeClass('loading');
});
this.setStateChangeXHR(promise);
return promise;
},
/**
* ALternative to loadPanel/submitForm.
*
* Triggers a parallel-fetch of a PJAX fragment, which is a separate request to the
* state change requests. There could be any amount of these fetches going on in the background,
* and they don't register as a HTML5 history states.
*
* This is meant for updating a PJAX areas that are not complete panel/form reloads. These you'd
* normally do via submitForm or loadPanel which have a lot of automation built in.
*
* On receiving successful response, the framework will update the element tagged with appropriate
* data-pjax-fragment attribute (e.g. data-pjax-fragment="<pjax-fragment-name>"). Make sure this element
* is available.
*
* Example usage:
* $('.cms-container').loadFragment('admin/foobar/', 'FragmentName');
*
* @param url string Relative or absolute url of the controller.
* @param pjaxFragments string PJAX fragment(s), comma separated.
*/
loadFragment: function(url, pjaxFragments) {
var self = this,
xhr,
headers = {},
baseUrl = $('base').attr('href'),
fragmentXHR = this.getFragmentXHR();
// Make sure only one XHR for a specific fragment is currently in progress.
if(
typeof fragmentXHR[pjaxFragments]!=='undefined' &&
fragmentXHR[pjaxFragments]!==null
) {
fragmentXHR[pjaxFragments].abort();
fragmentXHR[pjaxFragments] = null;
}
url = $.path.isAbsoluteUrl(url) ? url : $.path.makeUrlAbsolute(url, baseUrl);
headers['X-Pjax'] = pjaxFragments;
xhr = $.ajax({
headers: headers,
url: url,
success: function(data, status, xhr) {
var elements = self.handleAjaxResponse(data, status, xhr, null);
// We are fully done now, make it possible for others to hook in here.
self.trigger('afterloadfragment', { data: data, status: status, xhr: xhr, elements: elements });
},
error: function(xhr, status, error) {
self.trigger('loadfragmenterror', { xhr: xhr, status: status, error: error });
},
complete: function() {
// Reset the current XHR in tracking object.
var fragmentXHR = self.getFragmentXHR();
if(
typeof fragmentXHR[pjaxFragments]!=='undefined' &&
fragmentXHR[pjaxFragments]!==null
) {
fragmentXHR[pjaxFragments] = null;
}
}
});
// Store the fragment request so we can abort later, should we get a duplicate request.
fragmentXHR[pjaxFragments] = xhr;
return xhr;
},
/**
* Handles ajax responses containing plain HTML, or mulitple
* PJAX fragments wrapped in JSON (see PjaxResponseNegotiator PHP class).
* Can be hooked into an ajax 'success' callback.
*
* Parameters:
* (Object) data
* (String) status
* (XMLHTTPRequest) xhr
* (Object) state The original history state which the request was initiated with
*/
handleAjaxResponse: function(data, status, xhr, state) {
var self = this, url, selectedTabs, guessFragment, fragment, $data;
// Support a full reload
if(xhr.getResponseHeader('X-Reload') && xhr.getResponseHeader('X-ControllerURL')) {
var baseUrl = $('base').attr('href'),
rawURL = xhr.getResponseHeader('X-ControllerURL'),
url = $.path.isAbsoluteUrl(rawURL) ? rawURL : $.path.makeUrlAbsolute(rawURL, baseUrl);
document.location.href = url;
return;
}
// Pseudo-redirects via X-ControllerURL might return empty data, in which
// case we'll ignore the response
if(!data) return;
// Update title
var title = xhr.getResponseHeader('X-Title');
if(title) document.title = decodeURIComponent(title.replace(/\+/g, ' '));
var newFragments = {}, newContentEls;
// If content type is text/json (ignoring charset and other parameters)
if(xhr.getResponseHeader('Content-Type').match(/^((text)|(application))\/json[ \t]*;?/i)) {
newFragments = data;
} else {
// Fall back to replacing the content fragment if HTML is returned
fragment = document.createDocumentFragment();
jQuery.clean( [ data ], document, fragment, [] );
$data = $(jQuery.merge( [], fragment.childNodes ));
// Try and guess the fragment if none is provided
// TODO: data-pjax-fragment might actually give us the fragment. For now we just check most common case
guessFragment = 'Content';
if ($data.is('form') && !$data.is('[data-pjax-fragment~=Content]')) guessFragment = 'CurrentForm';
newFragments[guessFragment] = $data;
}
this.setRedrawSuppression(true);
try {
// Replace each fragment individually
$.each(newFragments, function(newFragment, html) {
var contentEl = $('[data-pjax-fragment]').filter(function() {
return $.inArray(newFragment, $(this).data('pjaxFragment').split(' ')) != -1;
}), newContentEl = $(html);
// Add to result collection
if(newContentEls) newContentEls.add(newContentEl);
else newContentEls = newContentEl;
// Update panels
if(newContentEl.find('.cms-container').length) {
throw 'Content loaded via ajax is not allowed to contain tags matching the ".cms-container" selector to avoid infinite loops';
}
// Set loading state and store element state
var origStyle = contentEl.attr('style');
var origParent = contentEl.parent();
var origParentLayoutApplied = (typeof origParent.data('jlayout')!=='undefined');
var layoutClasses = ['east', 'west', 'center', 'north', 'south', 'column-hidden'];
var elemClasses = contentEl.attr('class');
var origLayoutClasses = [];
if(elemClasses) {
origLayoutClasses = $.grep(
elemClasses.split(' '),
function(val) { return ($.inArray(val, layoutClasses) >= 0);}
);
}
newContentEl
.removeClass(layoutClasses.join(' '))
.addClass(origLayoutClasses.join(' '));
if(origStyle) newContentEl.attr('style', origStyle);
// Allow injection of inline styles, as they're not allowed in the document body.
// Not handling this through jQuery.ondemand to avoid parsing the DOM twice.
var styles = newContentEl.find('style').detach();
if(styles.length) $(document).find('head').append(styles);
// Replace panel completely (we need to override the "layout" attribute, so can't replace the child instead)
contentEl.replaceWith(newContentEl);
// Force jlayout to rebuild internal hierarchy to point to the new elements.
// This is only necessary for elements that are at least 3 levels deep. 2nd level elements will
// be taken care of when we lay out the top level element (.cms-container).
if (!origParent.is('.cms-container') && origParentLayoutApplied) {
origParent.layout();
}
});
// Re-init tabs (in case the form tag itself is a tabset)
var newForm = newContentEls.filter('form');
if(newForm.hasClass('cms-tabset')) newForm.removeClass('cms-tabset').addClass('cms-tabset');
}
finally {
this.setRedrawSuppression(false);
}
this.redraw();
this.restoreTabState((state && typeof state.tabState !== 'undefined') ? state.tabState : null);
return newContentEls;
},
/**
*
*
* Parameters:
* - fragments {Array}
* Returns: jQuery collection
*/
_findFragments: function(fragments) {
return $('[data-pjax-fragment]').filter(function() {
// Allows for more than one fragment per node
var i, nodeFragments = $(this).data('pjaxFragment').split(' ');
for(i in fragments) {
if($.inArray(fragments[i], nodeFragments) != -1) return true;
}
return false;
});
},
/**
* Function: refresh
*
* Updates the container based on the current url
*
* Returns: void
*/
refresh: function() {
$(window).trigger('statechange');
$(this).redraw();
},
/**
* Save tab selections in order to reconstruct them later.
* Requires HTML5 sessionStorage support.
*/
saveTabState: function() {
if(typeof(window.sessionStorage)=="undefined" || window.sessionStorage === null) return;
var selectedTabs = [], url = this._tabStateUrl();
this.find('.cms-tabset,.ss-tabset').each(function(i, el) {
var id = $(el).attr('id');
if(!id) return; // we need a unique reference
if(!$(el).data('tabs')) return; // don't act on uninit'ed controls
// Allow opt-out via data element or entwine property.
if($(el).data('ignoreTabState') || $(el).getIgnoreTabState()) return;
selectedTabs.push({id:id, selected:$(el).tabs('option', 'selected')});
});
if(selectedTabs) {
var tabsUrl = 'tabs-' + url;
try {
window.sessionStorage.setItem(tabsUrl, JSON.stringify(selectedTabs));
} catch(err) {
if (err.code === DOMException.QUOTA_EXCEEDED_ERR && window.sessionStorage.length === 0) {
// If this fails we ignore the error as the only issue is that it
// does not remember the tab state.
// This is a Safari bug which happens when private browsing is enabled.
return;
} else {
throw err;
}
}
}
},
/**
* Re-select previously saved tabs.
* Requires HTML5 sessionStorage support.
*
* Parameters:
* (Object) Map of tab container selectors to tab selectors.
* Used to mark a specific tab as active regardless of the previously saved options.
*/
restoreTabState: function(overrideStates) {
var self = this, url = this._tabStateUrl(),
hasSessionStorage = (typeof(window.sessionStorage)!=="undefined" && window.sessionStorage),
sessionData = hasSessionStorage ? window.sessionStorage.getItem('tabs-' + url) : null,
sessionStates = sessionData ? JSON.parse(sessionData) : false;
this.find('.cms-tabset, .ss-tabset').each(function() {
var index, tabset = $(this), tabsetId = tabset.attr('id'), tab,
forcedTab = tabset.find('.ss-tabs-force-active');
if(!tabset.data('tabs')){
return; // don't act on uninit'ed controls
}
// The tabs may have changed, notify the widget that it should update its internal state.
tabset.tabs('refresh');
// Make sure the intended tab is selected.
if(forcedTab.length) {
index = forcedTab.index();
} else if(overrideStates && overrideStates[tabsetId]) {
tab = tabset.find(overrideStates[tabsetId].tabSelector);
if(tab.length){
index = tab.index();
}
} else if(sessionStates) {
$.each(sessionStates, function(i, sessionState) {
if(tabset.is('#' + sessionState.id)){
index = sessionState.selected;
}
});
}
if(index !== null){
tabset.tabs('option', 'active', index);
self.trigger('tabstaterestored');
}
});
},
/**
* Remove any previously saved state.
*
* Parameters:
* (String) url Optional (sanitized) URL to clear a specific state.
*/
clearTabState: function(url) {
if(typeof(window.sessionStorage)=="undefined") return;
var s = window.sessionStorage;
if(url) {
s.removeItem('tabs-' + url);
} else {
for(var i=0;i<s.length;i++) {
if(s.key(i).match(/^tabs-/)) s.removeItem(s.key(i));
}
}
},
/**
* Remove tab state for the current URL.
*/
clearCurrentTabState: function() {
this.clearTabState(this._tabStateUrl());
},
_tabStateUrl: function() {
return window.history.state.path
.replace(/\?.*/, '')
.replace(/#.*/, '')
.replace($('base').attr('href'), '');
},
showLoginDialog: function() {
var tempid = $('body').data('member-tempid'),
dialog = $('.leftandmain-logindialog'),
url = 'CMSSecurity/login';
// Force regeneration of any existing dialog
if(dialog.length) dialog.remove();
// Join url params
url = $.path.addSearchParams(url, {
'tempid': tempid,
'BackURL': window.location.href
});
// Show a placeholder for instant feedback. Will be replaced with actual
// form dialog once its loaded.
dialog = $('<div class="leftandmain-logindialog"></div>');
dialog.attr('id', new Date().getTime());
dialog.data('url', url);
$('body').append(dialog);
}
});
// Login dialog page
$('.leftandmain-logindialog').entwine({
onmatch: function() {
this._super();
// Create jQuery dialog
this.ssdialog({
iframeUrl: this.data('url'),
dialogClass: "leftandmain-logindialog-dialog",
autoOpen: true,
minWidth: 500,
maxWidth: 500,
minHeight: 370,
maxHeight: 400,
closeOnEscape: false,
open: function() {
$('.ui-widget-overlay').addClass('leftandmain-logindialog-overlay');
},
close: function() {
$('.ui-widget-overlay').removeClass('leftandmain-logindialog-overlay');
}
});
},
onunmatch: function() {
this._super();
},
open: function() {
this.ssdialog('open');
},
close: function() {
this.ssdialog('close');
},
toggle: function(bool) {
if(this.is(':visible')) this.close();
else this.open();
},
/**
* Callback activated by CMSSecurity_success.ss
*/
reauthenticate: function(data) {
// Replace all SecurityID fields with the given value
if(typeof(data.SecurityID) !== 'undefined') {
$(':input[name=SecurityID]').val(data.SecurityID);
}
// Update TempID for current user
if(typeof(data.TempID) !== 'undefined') {
$('body').data('member-tempid', data.TempID);
}
this.close();
}
});
/**
* Add loading overlay to selected regions in the CMS automatically.
* Not applied to all "*.loading" elements to avoid secondary regions
* like the breadcrumbs showing unnecessary loading status.
*/
$('form.loading,.cms-content.loading,.cms-content-fields.loading,.cms-content-view.loading').entwine({
onmatch: function() {
this.append('<div class="cms-content-loading-overlay ui-widget-overlay-light"></div><div class="cms-content-loading-spinner"></div>');
this._super();
},
onunmatch: function() {
this.find('.cms-content-loading-overlay,.cms-content-loading-spinner').remove();
this._super();
}
});
/** Make all buttons "hoverable" with jQuery theming. */
$('.cms input[type="submit"], .cms button, .cms input[type="reset"], .cms .ss-ui-button').entwine({
onadd: function() {
this.addClass('ss-ui-button');
if(!this.data('button')) this.button();
this._super();
},
onremove: function() {
if(this.data('button')) this.button('destroy');
this._super();
}
});
/**
* Loads the link's 'href' attribute into a panel via ajax,
* as opposed to triggering a full page reload.
* Little helper to avoid repetition, and make it easy to
* "opt in" to panel loading, while by default links still exhibit their default behaviour.
* The PJAX target can be specified via a 'data-pjax-target' attribute.
*/
$('.cms .cms-panel-link').entwine({
onclick: function(e) {
if($(this).hasClass('external-link')) {
e.stopPropagation();
return;
}
var href = this.attr('href'),
url = (href && !href.match(/^#/)) ? href : this.data('href'),
data = {pjax: this.data('pjaxTarget')};
$('.cms-container').loadPanel(url, null, data);
e.preventDefault();
}
});
/**
* Does an ajax loads of the link's 'href' attribute via ajax and displays any FormResponse messages from the CMS.
* Little helper to avoid repetition, and make it easy to trigger actions via a link,
* without reloading the page, changing the URL, or loading in any new panel content.
*/
$('.cms .ss-ui-button-ajax').entwine({
onclick: function(e) {
$(this).removeClass('ui-button-text-only');
$(this).addClass('ss-ui-button-loading ui-button-text-icons');
var loading = $(this).find(".ss-ui-loading-icon");
if(loading.length < 1) {
loading = $("<span></span>").addClass('ss-ui-loading-icon ui-button-icon-primary ui-icon');
$(this).prepend(loading);
}
loading.show();
var href = this.attr('href'), url = href ? href : this.data('href');
jQuery.ajax({
url: url,
// Ensure that form view is loaded (rather than whole "Content" template)
complete: function(xmlhttp, status) {
var msg = (xmlhttp.getResponseHeader('X-Status')) ? xmlhttp.getResponseHeader('X-Status') : xmlhttp.responseText;
try {
if (typeof msg != "undefined" && msg !== null) eval(msg);
}
catch(e) {}
loading.hide();
$(".cms-container").refresh();
$(this).removeClass('ss-ui-button-loading ui-button-text-icons');
$(this).addClass('ui-button-text-only');
},
dataType: 'html'
});
e.preventDefault();
}
});
/**
* Trigger dialogs with iframe based on the links href attribute (see ssui-core.js).
*/
$('.cms .ss-ui-dialog-link').entwine({
UUID: null,
onmatch: function() {
this._super();
this.setUUID(new Date().getTime());
},
onunmatch: function() {
this._super();
},
onclick: function() {
this._super();
var self = this, id = 'ss-ui-dialog-' + this.getUUID();
var dialog = $('#' + id);
if(!dialog.length) {
dialog = $('<div class="ss-ui-dialog" id="' + id + '" />');
$('body').append(dialog);
}
var extraClass = this.data('popupclass')?this.data('popupclass'):'';
dialog.ssdialog({iframeUrl: this.attr('href'), autoOpen: true, dialogExtraClass: extraClass});
return false;
}
});
/**
* Add styling to all contained buttons, and create buttonsets if required.
*/
$('.cms-content .Actions').entwine({
onmatch: function() {
this.find('.ss-ui-button').click(function() {
var form = this.form;
// forms don't natively store the button they've been triggered with
if(form) {
form.clickedButton = this;
// Reset the clicked button shortly after the onsubmit handlers
// have fired on the form
setTimeout(function() {
form.clickedButton = null;
}, 10);
}
});
this.redraw();
this._super();
},
onunmatch: function() {
this._super();
},
redraw: function() {
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
// Remove whitespace to avoid gaps with inline elements
this.contents().filter(function() {
return (this.nodeType == 3 && !/\S/.test(this.nodeValue));
}).remove();
// Init buttons if required
this.find('.ss-ui-button').each(function() {
if(!$(this).data('button')) $(this).button();
});
// Mark up buttonsets
this.find('.ss-ui-buttonset').buttonset();
}
});
/**
* Duplicates functionality in DateField.js, but due to using entwine we can match
* the DOM element on creation, rather than onclick - which allows us to decorate
* the field with a calendar icon
*/
$('.cms .field.date input.text').entwine({
onmatch: function() {
var holder = $(this).parents('.field.date:first'), config = holder.data();
if(!config.showcalendar) {
this._super();
return;
}
config.showOn = 'button';
if(config.locale && $.datepicker.regional[config.locale]) {
config = $.extend(config, $.datepicker.regional[config.locale], {});
}
$(this).datepicker(config);
// // Unfortunately jQuery UI only allows configuration of icon images, not sprites
// this.next('button').button('option', 'icons', {primary : 'ui-icon-calendar'});
this._super();
},
onunmatch: function() {
this._super();
}
});
/**
* Styled dropdown select fields via chosen. Allows things like search and optgroup
* selection support. Rather than manually adding classes to selects we want
* styled, we style everything but the ones we tell it not to.
*
* For the CMS we also need to tell the parent div that it has a select so
* we can fix the height cropping.
*/
$('.cms .field.dropdown select, .cms .field select[multiple], .fieldholder-small select.dropdown').entwine({
onmatch: function() {
if(this.is('.no-chosen')) {
this._super();
return;
}
// Explicitly disable default placeholder if no custom one is defined
if(!this.data('placeholder')) this.data('placeholder', ' ');
// We could've gotten stale classes and DOM elements from deferred cache.
this.removeClass('has-chosen').chosen("destroy");
this.siblings('.chosen-container').remove();
// Apply Chosen
applyChosen(this);
this._super();
},
onunmatch: function() {
this._super();
}
});
$(".cms-panel-layout").entwine({
redraw: function() {
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
}
});
/**
* Overload the default GridField behaviour (open a new URL in the browser)
* with the CMS-specific ajax loading.
*/
$('.cms .ss-gridfield').entwine({
showDetailView: function(url) {
// Include any GET parameters from the current URL, as the view state might depend on it.
// For example, a list prefiltered through external search criteria might be passed to GridField.
var params = window.location.search.replace(/^\?/, '');
if(params) url = $.path.addSearchParams(url, params);
$('.cms-container').loadPanel(url);
}
});
/**
* Generic search form in the CMS, often hooked up to a GridField results display.
*/
$('.cms-search-form').entwine({
onsubmit: function(e) {
// Remove empty elements and make the URL prettier
var nonEmptyInputs,
url;
nonEmptyInputs = this.find(':input:not(:submit)').filter(function() {
// Use fieldValue() from jQuery.form plugin rather than jQuery.val(),
// as it handles checkbox values more consistently
var vals = $.grep($(this).fieldValue(), function(val) { return (val);});
return (vals.length);
});
url = this.attr('action');
if(nonEmptyInputs.length) {
url = $.path.addSearchParams(
url,
// Undo jQuery's non-standard serialisation
// See https://github.com/jquery/jquery/blob/1.7.2/src/ajax.js#L797
nonEmptyInputs.serialize().replace('+', '%20')
);
}
var container = this.closest('.cms-container');
container.find('.cms-edit-form').tabs('select',0); //always switch to the first tab (list view) when searching
container.loadPanel(url, "", {}, true);
return false;
}
});
/**
* Reset button handler. IE8 does not bubble reset events to
*/
$(".cms-search-form button[type=reset], .cms-search-form input[type=reset]").entwine({
onclick: function(e) {
e.preventDefault();
var form = $(this).parents('form');
form.clearForm();
form.find(".dropdown select").prop('selectedIndex', 0).trigger("chosen:updated"); // Reset chosen.js
form.submit();
}
});
/**
* Allows to lazy load a panel, by leaving it empty
* and declaring a URL to load its content via a 'url' HTML5 data attribute.
* The loaded HTML is cached, with cache key being the 'url' attribute.
* In order for this to work consistently, we assume that the responses are stateless.
* To avoid caching, add a 'deferred-no-cache' to the node.
*/
window._panelDeferredCache = {};
$('.cms-panel-deferred').entwine({
onadd: function() {
this._super();
this.redraw();
},
onremove: function() {
if(window.debug) console.log('saving', this.data('url'), this);
// Save the HTML state at the last possible moment.
// Don't store the DOM to avoid memory leaks.
if(!this.data('deferredNoCache')) window._panelDeferredCache[this.data('url')] = this.html();
this._super();
},
redraw: function() {
if(window.debug) console.log('redraw', this.attr('class'), this.get(0));
var self = this, url = this.data('url');
if(!url) throw 'Elements of class .cms-panel-deferred need a "data-url" attribute';
this._super();
// If the node is empty, try to either load it from cache or via ajax.
if(!this.children().length) {
if(!this.data('deferredNoCache') && typeof window._panelDeferredCache[url] !== 'undefined') {
this.html(window._panelDeferredCache[url]);
} else {
this.addClass('loading');
$.ajax({
url: url,
complete: function() {
self.removeClass('loading');
},
success: function(data, status, xhr) {
self.html(data);
}
});
}
}
}
});
/**
* Lightweight wrapper around jQuery UI tabs.
* Ensures that anchor links are set properly,
* and any nested tabs are scrolled if they have
* their height explicitly set. This is important
* for forms inside the CMS layout.
*/
$('.cms-tabset').entwine({
onadd: function() {
// Can't name redraw() as it clashes with other CMS entwine classes
this.redrawTabs();
this._super();
},
onremove: function() {
if (this.data('tabs')) this.tabs('destroy');
this._super();
},
redrawTabs: function() {
this.rewriteHashlinks();
var id = this.attr('id'), activeTab = this.find('ul:first .ui-tabs-active');
if(!this.data('uiTabs')) this.tabs({
active: (activeTab.index() != -1) ? activeTab.index() : 0,
beforeLoad: function(e, ui) {
// Disable automatic ajax loading of tabs without matching DOM elements,
// determining if the current URL differs from the tab URL is too error prone.
return false;
},
activate: function(e, ui) {
// Usability: Hide actions for "readonly" tabs (which don't contain any editable fields)
var actions = $(this).closest('form').find('.Actions');
if($(ui.newTab).closest('li').hasClass('readonly')) {
actions.fadeOut();
} else {
actions.show();
}
}
});
},
/**
* Ensure hash links are prefixed with the current page URL,
* otherwise jQuery interprets them as being external.
*/
rewriteHashlinks: function() {
$(this).find('ul a').each(function() {
if (!$(this).attr('href')) return;
var matches = $(this).attr('href').match(/#.*/);
if(!matches) return;
$(this).attr('href', document.location.href.replace(/#.*/, '') + matches[0]);
});
}
});
/**
* CMS content filters
*/
$('#filters-button').entwine({
onmatch: function () {
this._super();
this.data('collapsed', true); // The current collapsed state of the element.
this.data('animating', false); // True if the element is currently animating.
},
onunmatch: function () {
this._super();
},
showHide: function () {
var self = this,
$filters = $('.cms-content-filters').first(),
collapsed = this.data('collapsed');
// Prevent the user from spamming the UI with animation requests.
if (this.data('animating')) {
return;
}
this.toggleClass('active');
this.data('animating', true);
// Slide the element down / up based on it's current collapsed state.
$filters[collapsed ? 'slideDown' : 'slideUp']({
complete: function () {
// Update the element's state.
self.data('collapsed', !collapsed);
self.data('animating', false);
}
});
},
onclick: function () {
this.showHide();
}
});
});
var statusMessage = function(text, type) {
text = jQuery('<div/>').text(text).html(); // Escape HTML entities in text
jQuery.noticeAdd({text: text, type: type, stayTime: 5000, inEffect: {left: '0', opacity: 'show'}});
text = jQuery('<div/>').text(text).html(); // Escape HTML entities in text
jQuery.noticeAdd({text: text, type: type, stayTime: 5000, inEffect: {left: '0', opacity: 'show'}});
};
var errorMessage = function(text) {
jQuery.noticeAdd({text: text, type: 'error', stayTime: 5000, inEffect: {left: '0', opacity: 'show'}});
jQuery.noticeAdd({text: text, type: 'error', stayTime: 5000, inEffect: {left: '0', opacity: 'show'}});
};