mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
Merge pull request #1375 from open-sausages/pulls/4.0/module-loader
Implement RFC-7 JavaScript module loader in CMS
This commit is contained in:
commit
c9cf833ad6
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
.sass-cache
|
||||
.DS_Store
|
||||
node_modules
|
@ -64,7 +64,7 @@ class AssetAdmin extends LeftAndMain implements PermissionProvider{
|
||||
parent::init();
|
||||
|
||||
|
||||
Requirements::javascript(CMS_DIR . "/javascript/AssetAdmin.js");
|
||||
Requirements::javascript(CMS_DIR . "/javascript/dist/AssetAdmin.js");
|
||||
Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang', false, true);
|
||||
Requirements::css(CMS_DIR . "/css/screen.css");
|
||||
CMSBatchActionHandler::register('delete', 'AssetAdmin_DeleteBatchAction', 'Folder');
|
||||
|
@ -78,22 +78,19 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr
|
||||
|
||||
Requirements::css(CMS_DIR . '/css/screen.css');
|
||||
Requirements::customCSS($this->generatePageIconsCss());
|
||||
|
||||
Requirements::combine_files(
|
||||
'cmsmain.js',
|
||||
array_merge(
|
||||
array(
|
||||
CMS_DIR . '/javascript/CMSMain.js',
|
||||
CMS_DIR . '/javascript/CMSMain.EditForm.js',
|
||||
CMS_DIR . '/javascript/CMSMain.AddForm.js',
|
||||
CMS_DIR . '/javascript/CMSPageHistoryController.js',
|
||||
CMS_DIR . '/javascript/CMSMain.Tree.js',
|
||||
CMS_DIR . '/javascript/SilverStripeNavigator.js',
|
||||
CMS_DIR . '/javascript/SiteTreeURLSegmentField.js'
|
||||
),
|
||||
Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang', true, true)
|
||||
)
|
||||
);
|
||||
Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang', true, true);
|
||||
Requirements::javascript(CMS_DIR . '/javascript/dist/bundle-lib.js', [
|
||||
'provides' => [
|
||||
CMS_DIR . '/javascript/dist/CMSMain.AddForm.js',
|
||||
CMS_DIR . '/javascript/dist/CMSMain.EditForm.js',
|
||||
CMS_DIR . '/javascript/dist/CMSMain.js',
|
||||
CMS_DIR . '/javascript/dist/CMSMain.Tree.js',
|
||||
CMS_DIR . '/javascript/dist/CMSPageHistoryController.js',
|
||||
CMS_DIR . '/javascript/dist/RedirectorPage.js',
|
||||
CMS_DIR . '/javascript/dist/SilverStripeNavigator.js',
|
||||
CMS_DIR . '/javascript/dist/SiteTreeURLSegmentField.js'
|
||||
]
|
||||
]);
|
||||
|
||||
CMSBatchActionHandler::register('publish', 'CMSBatchAction_Publish');
|
||||
CMSBatchActionHandler::register('unpublish', 'CMSBatchAction_Unpublish');
|
||||
|
@ -268,7 +268,7 @@ class ContentController extends Controller {
|
||||
if($this->dataRecord) {
|
||||
Requirements::css(CMS_DIR . '/css/SilverStripeNavigator.css');
|
||||
Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js');
|
||||
Requirements::javascript(CMS_DIR . '/javascript/SilverStripeNavigator.js');
|
||||
Requirements::javascript(CMS_DIR . '/javascript/dist/SilverStripeNavigator.js');
|
||||
|
||||
$return = $nav = SilverStripeNavigator::get_for_record($this->dataRecord);
|
||||
$items = $return['items'];
|
||||
|
@ -37,7 +37,7 @@ class SiteTreeURLSegmentField extends TextField {
|
||||
}
|
||||
|
||||
public function Field($properties = array()) {
|
||||
Requirements::javascript(CMS_DIR . '/javascript/SiteTreeURLSegmentField.js');
|
||||
Requirements::javascript(CMS_DIR . '/javascript/dist/SiteTreeURLSegmentField.js');
|
||||
Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang', false, true);
|
||||
Requirements::css(CMS_DIR . "/css/screen.css");
|
||||
return parent::Field($properties);
|
||||
|
@ -117,7 +117,7 @@ class RedirectorPage extends Page {
|
||||
}
|
||||
|
||||
public function getCMSFields() {
|
||||
Requirements::javascript(CMS_DIR . '/javascript/RedirectorPage.js');
|
||||
Requirements::javascript(CMS_DIR . '/javascript/dist/RedirectorPage.js');
|
||||
|
||||
$fields = parent::getCMSFields();
|
||||
$fields->removeByName('Content', true);
|
||||
|
97
gulpfile.js
Normal file
97
gulpfile.js
Normal file
@ -0,0 +1,97 @@
|
||||
var gulp = require('gulp'),
|
||||
babel = require('gulp-babel'),
|
||||
diff = require('gulp-diff'),
|
||||
notify = require('gulp-notify'),
|
||||
uglify = require('gulp-uglify');
|
||||
gulpUtil = require('gulp-util'),
|
||||
browserify = require('browserify'),
|
||||
babelify = require('babelify'),
|
||||
watchify = require('watchify'),
|
||||
source = require('vinyl-source-stream'),
|
||||
buffer = require('vinyl-buffer'),
|
||||
path = require('path'),
|
||||
glob = require('glob'),
|
||||
eventStream = require('event-stream'),
|
||||
semver = require('semver'),
|
||||
packageJson = require('./package.json');
|
||||
|
||||
var PATHS = {
|
||||
MODULES: './node_modules',
|
||||
CMS_JAVASCRIPT_SRC: './javascript/src',
|
||||
CMS_JAVASCRIPT_DIST: './javascript/dist'
|
||||
};
|
||||
|
||||
var browserifyOptions = {
|
||||
cache: {},
|
||||
packageCache: {},
|
||||
poll: true,
|
||||
plugin: [watchify]
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms the passed JavaScript files to UMD modules.
|
||||
*
|
||||
* @param array files - The files to transform.
|
||||
* @param string dest - The output directory.
|
||||
* @return object
|
||||
*/
|
||||
function transformToUmd(files, dest) {
|
||||
return eventStream.merge(files.map(function (file) {
|
||||
return gulp.src(file)
|
||||
.pipe(babel({
|
||||
presets: ['es2015'],
|
||||
moduleId: 'ss.' + path.parse(file).name,
|
||||
plugins: ['transform-es2015-modules-umd']
|
||||
}))
|
||||
.on('error', notify.onError({
|
||||
message: 'Error: <%= error.message %>',
|
||||
}))
|
||||
.pipe(gulp.dest(dest));
|
||||
}));
|
||||
}
|
||||
|
||||
// Make sure the version of Node being used is valid.
|
||||
if (!semver.satisfies(process.versions.node, packageJson.engines.node)) {
|
||||
console.error('Invalid Node.js version. You need to be using ' + packageJson.engines.node + '. If you want to manage multiple Node.js versions try https://github.com/creationix/nvm');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (process.env.npm_config_development) {
|
||||
browserifyOptions.debug = true;
|
||||
}
|
||||
|
||||
gulp.task('build', ['umd-cms', 'umd-watch', 'bundle-lib']);
|
||||
|
||||
gulp.task('bundle-lib', function bundleLib() {
|
||||
var stream = browserify(Object.assign({}, browserifyOptions, {
|
||||
entries: PATHS.CMS_JAVASCRIPT_SRC + '/bundles/lib.js'
|
||||
}))
|
||||
.transform(babelify.configure({
|
||||
presets: ['es2015'],
|
||||
ignore: /(thirdparty)/
|
||||
}))
|
||||
.on('log', function (msg) { gulpUtil.log('Finished bundle-lib.js ' + msg); })
|
||||
.on('update', bundleLib)
|
||||
.external('jQuery')
|
||||
.external('i18n')
|
||||
.bundle()
|
||||
.on('error', notify.onError({
|
||||
message: 'Error: <%= error.message %>',
|
||||
}))
|
||||
.pipe(source('bundle-lib.js'))
|
||||
.pipe(buffer());
|
||||
|
||||
if (typeof process.env.npm_config_development === 'undefined') {
|
||||
stream.pipe(uglify());
|
||||
}
|
||||
|
||||
return stream.pipe(gulp.dest(PATHS.CMS_JAVASCRIPT_DIST));
|
||||
});
|
||||
|
||||
gulp.task('umd-cms', function () {
|
||||
return transformToUmd(glob.sync(PATHS.CMS_JAVASCRIPT_SRC + '/*.js'), PATHS.CMS_JAVASCRIPT_DIST);
|
||||
});
|
||||
|
||||
gulp.task('umd-watch', function () {
|
||||
gulp.watch(PATHS.CMS_JAVASCRIPT_SRC + '/*.js', ['umd-cms']);
|
||||
});
|
@ -1,99 +0,0 @@
|
||||
/**
|
||||
* File: AssetAdmin.DragDrop.js
|
||||
*/
|
||||
(function($) {
|
||||
$.entwine('ss', function($){
|
||||
|
||||
/**
|
||||
* Class: .AssetTableField.dragdrop
|
||||
*/
|
||||
$('.AssetTableField.dragdrop').entwine({
|
||||
onmatch: function() {
|
||||
var self = this;
|
||||
$('.cms-tree li').each(function() {
|
||||
$(this).droppable({
|
||||
greedy: true,
|
||||
hoverClass: 'over', // same hover effect as normal tree
|
||||
drop: function(e, ui) {self.drop(e, ui);}
|
||||
});
|
||||
});
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
/**
|
||||
* Function: drop
|
||||
*
|
||||
* Take selected files and move them to a folder target in the tree.
|
||||
*/
|
||||
drop: function(e, ui) {
|
||||
var self = this;
|
||||
if(e.target.id.match(/-([^-]+)$/)) {
|
||||
var folderId = RegExp.$1;
|
||||
$.post(
|
||||
this.attr('href') + '/movemarked',
|
||||
this.parents('form').serialize() + '&DestFolderID=' + folderId,
|
||||
function(data, status) {
|
||||
self.refresh();
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: getSelected
|
||||
*
|
||||
* Get the IDs of all selected files in the table.
|
||||
* Used for drag'n'drop.
|
||||
*
|
||||
* Returns:
|
||||
* Array
|
||||
*/
|
||||
getSelected: function() {
|
||||
return this.find(':input[name=Files\[\]]:checked').map(function() {
|
||||
return $(this).val();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('.AssetTableField .dragfile').entwine({
|
||||
// Constructor: onmatch
|
||||
onmatch: function() {
|
||||
var self = this;
|
||||
var container = this.parents('.AssetTableField');
|
||||
|
||||
this.draggable({
|
||||
zIndex: 4000,
|
||||
appendTo: 'body',
|
||||
helper: function() {
|
||||
return $(
|
||||
'<div class="NumFilesIndicator">'
|
||||
ss.i18n.sprintf(ss.i18n._t('AssetTableField.MOVING'),container.getSelected().length)
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
/**
|
||||
* Function: onmousedown
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*
|
||||
* Automatically select the checkbox in the same table row
|
||||
* to signify that this element is moved, and hint that
|
||||
* all checkboxed elements will be moved along with it.
|
||||
*/
|
||||
onmousedown: function(e) {
|
||||
this.siblings('.markingcheckbox').find(':input').attr('checked', 'checked');
|
||||
}
|
||||
});
|
||||
});
|
||||
}(jQuery));
|
@ -1,141 +0,0 @@
|
||||
/**
|
||||
* File: AssetAdmin.js
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
$.entwine('ss', function($){
|
||||
/**
|
||||
* Delete selected folders through "batch actions" tab.
|
||||
*/
|
||||
/* assets don't currently have batch actions; disabling for now
|
||||
$(document).ready(function() {
|
||||
$('#Form_BatchActionsForm').entwine('.ss.tree').register(
|
||||
// TODO Hardcoding of base URL
|
||||
'admin/assets/batchactions/delete',
|
||||
function(ids) {
|
||||
var confirmed = confirm(
|
||||
ss.i18n.sprintf(
|
||||
ss.i18n._t('AssetAdmin.BATCHACTIONSDELETECONFIRM'),
|
||||
ids.length
|
||||
)
|
||||
);
|
||||
return (confirmed) ? ids : false;
|
||||
}
|
||||
);
|
||||
});
|
||||
*/
|
||||
|
||||
/**
|
||||
* Load folder detail view via controller methods
|
||||
* rather than built-in GridField view (which is only geared towards showing files).
|
||||
*/
|
||||
$('.AssetAdmin.cms-edit-form .ss-gridfield-item').entwine({
|
||||
onclick: function(e) {
|
||||
// Let actions do their own thing
|
||||
if($(e.target).closest('.action').length) {
|
||||
this._super(e);
|
||||
return;
|
||||
}
|
||||
|
||||
var grid = this.closest('.ss-gridfield');
|
||||
if(this.data('class') == 'Folder') {
|
||||
var url = grid.data('urlFolderTemplate').replace('%s', this.data('id'));
|
||||
$('.cms-container').loadPanel(url);
|
||||
return false;
|
||||
}
|
||||
|
||||
this._super(e);
|
||||
}
|
||||
});
|
||||
|
||||
$('.AssetAdmin.cms-edit-form .ss-gridfield .col-buttons .action.gridfield-button-delete, .AssetAdmin.cms-edit-form .Actions button.action.action-delete').entwine({
|
||||
onclick: function(e) {
|
||||
var msg;
|
||||
if(this.closest('.ss-gridfield-item').data('class') == 'Folder') {
|
||||
msg = ss.i18n._t('AssetAdmin.ConfirmDelete');
|
||||
} else {
|
||||
msg = ss.i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE');
|
||||
}
|
||||
if(!confirm(msg)) return false;
|
||||
|
||||
this.getGridField().reload({data: [{name: this.attr('name'), value: this.val()}]});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$('.AssetAdmin.cms-edit-form :submit[name=action_delete]').entwine({
|
||||
onclick: function(e) {
|
||||
if(!confirm(ss.i18n._t('AssetAdmin.ConfirmDelete'))) return false;
|
||||
else this._super(e);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Prompt for a new foldername, rather than using dedicated form.
|
||||
* Better usability, but less flexibility in terms of inputs and validation.
|
||||
* Mainly necessary because AssetAdmin->AddForm() returns don't play nicely
|
||||
* with the nested AssetAdmin->EditForm() DOM structures.
|
||||
*/
|
||||
$('.AssetAdmin .cms-add-folder-link').entwine({
|
||||
onclick: function(e) {
|
||||
var name = prompt(ss.i18n._t('Folder.Name'));
|
||||
if(!name) return false;
|
||||
|
||||
this.closest('.cms-container').loadPanel(this.data('url') + '&Name=' + name);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: #Form_SyncForm
|
||||
*/
|
||||
$('#Form_SyncForm').entwine({
|
||||
|
||||
/**
|
||||
* Function: onsubmit
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onsubmit: function(e) {
|
||||
var button = jQuery(this).find(':submit:first');
|
||||
button.addClass('loading');
|
||||
$.ajax({
|
||||
url: jQuery(this).attr('action'),
|
||||
data: this.serializeArray(),
|
||||
success: function() {
|
||||
button.removeClass('loading');
|
||||
// reload current form and tree
|
||||
var currNode = $('.cms-tree')[0].firstSelected();
|
||||
if(currNode) {
|
||||
var url = $(currNode).find('a').attr('href');
|
||||
$('.cms-content').loadPanel(url);
|
||||
}
|
||||
$('.cms-tree')[0].setCustomURL('admin/assets/getsubtree');
|
||||
$('.cms-tree')[0].reload({onSuccess: function() {
|
||||
// TODO Reset current tree node
|
||||
}});
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Reload the gridfield to show the user the file has been added
|
||||
*/
|
||||
$('.AssetAdmin.cms-edit-form .ss-uploadfield-item-progress').entwine({
|
||||
onunmatch: function () {
|
||||
$('.AssetAdmin.cms-edit-form .ss-gridfield').reload();
|
||||
}
|
||||
});
|
||||
|
||||
$('.AssetAdmin .grid-levelup').entwine({
|
||||
onmatch: function () {
|
||||
this.closest('.ui-tabs-panel').find('.cms-actions-row').prepend(this);
|
||||
}
|
||||
})
|
||||
});
|
||||
}(jQuery));
|
@ -1,196 +0,0 @@
|
||||
(function($) {
|
||||
$.entwine('ss', function($){
|
||||
/**
|
||||
* Reset the parent node selection if the type is
|
||||
* set back to "toplevel page", to avoid submitting inconsistent state.
|
||||
*/
|
||||
$(".cms-add-form .parent-mode :input").entwine({
|
||||
onclick: function(e) {
|
||||
if(this.val() == 'top') {
|
||||
var parentField = this.closest('form').find('#Form_AddForm_ParentID_Holder .TreeDropdownField')
|
||||
parentField.setValue('');
|
||||
parentField.setTitle('');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(".cms-add-form").entwine({
|
||||
ParentID: 0, // Last selected parentID
|
||||
ParentCache: {}, // Cache allowed children for each selected page
|
||||
onadd: function() {
|
||||
var self = this;
|
||||
this.find('#Form_AddForm_ParentID_Holder .TreeDropdownField').bind('change', function() {
|
||||
self.updateTypeList();
|
||||
});
|
||||
this.find(".SelectionGroup.parent-mode").bind('change', function() {
|
||||
self.updateTypeList();
|
||||
});
|
||||
this.updateTypeList();
|
||||
},
|
||||
loadCachedChildren: function(parentID) {
|
||||
var cache = this.getParentCache();
|
||||
if(typeof cache[parentID] !== 'undefined') return cache[parentID];
|
||||
else return null;
|
||||
},
|
||||
saveCachedChildren: function(parentID, children) {
|
||||
var cache = this.getParentCache();
|
||||
cache[parentID] = children;
|
||||
this.setParentCache(cache);
|
||||
},
|
||||
/**
|
||||
* Limit page type selection based on parent selection.
|
||||
* Select of root classes is pre-computed, but selections with a given parent
|
||||
* are updated on-demand.
|
||||
* Similar implementation to LeftAndMain.Tree.js.
|
||||
*/
|
||||
updateTypeList: function() {
|
||||
var hints = this.data('hints'),
|
||||
parentTree = this.find('#Form_AddForm_ParentID_Holder .TreeDropdownField'),
|
||||
parentMode = this.find("input[name=ParentModeField]:checked").val(),
|
||||
metadata = parentTree.data('metadata'),
|
||||
id = (metadata && parentMode === 'child')
|
||||
? (parentTree.getValue() || this.getParentID())
|
||||
: null,
|
||||
newClassName = metadata ? metadata.ClassName : null,
|
||||
hintKey = (newClassName && parentMode === 'child')
|
||||
? newClassName
|
||||
: 'Root',
|
||||
hint = (typeof hints[hintKey] !== 'undefined') ? hints[hintKey] : null,
|
||||
self = this,
|
||||
defaultChildClass = (hint && typeof hint.defaultChild !== 'undefined')
|
||||
? hint.defaultChild
|
||||
: null,
|
||||
disallowedChildren = [];
|
||||
|
||||
if(id) {
|
||||
// Prevent interface operations
|
||||
if(this.hasClass('loading')) return;
|
||||
this.addClass('loading');
|
||||
|
||||
// Enable last parent ID to be re-selected from memory
|
||||
this.setParentID(id);
|
||||
if(!parentTree.getValue()) parentTree.setValue(id);
|
||||
|
||||
// Use cached data if available
|
||||
disallowedChildren = this.loadCachedChildren(id);
|
||||
if(disallowedChildren !== null) {
|
||||
this.updateSelectionFilter(disallowedChildren, defaultChildClass);
|
||||
this.removeClass('loading');
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: self.data('childfilter'),
|
||||
data: {'ParentID': id},
|
||||
success: function(data) {
|
||||
// reload current form and tree
|
||||
self.saveCachedChildren(id, data);
|
||||
self.updateSelectionFilter(data, defaultChildClass);
|
||||
},
|
||||
complete: function() {
|
||||
self.removeClass('loading');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
} else {
|
||||
disallowedChildren = (hint && typeof hint.disallowedChildren !== 'undefined')
|
||||
? hint.disallowedChildren
|
||||
: [],
|
||||
this.updateSelectionFilter(disallowedChildren, defaultChildClass);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Update the selection filter with the given blacklist and default selection
|
||||
*
|
||||
* @param array disallowedChildren
|
||||
* @param string defaultChildClass
|
||||
*/
|
||||
updateSelectionFilter: function(disallowedChildren, defaultChildClass) {
|
||||
// Limit selection
|
||||
var allAllowed = null; // troolian
|
||||
this.find('#Form_AddForm_PageType li').each(function() {
|
||||
var className = $(this).find('input').val(),
|
||||
isAllowed = ($.inArray(className, disallowedChildren) === -1);
|
||||
|
||||
$(this).setEnabled(isAllowed);
|
||||
if(!isAllowed) $(this).setSelected(false);
|
||||
if(allAllowed === null) allAllowed = isAllowed;
|
||||
else allAllowed = allAllowed && isAllowed;
|
||||
});
|
||||
|
||||
// Set default child selection, or fall back to first available option
|
||||
if(defaultChildClass) {
|
||||
var selectedEl = this
|
||||
.find('#Form_AddForm_PageType li input[value=' + defaultChildClass + ']')
|
||||
.parents('li:first');
|
||||
} else {
|
||||
var selectedEl = this.find('#Form_AddForm_PageType li:not(.disabled):first');
|
||||
}
|
||||
selectedEl.setSelected(true);
|
||||
selectedEl.siblings().setSelected(false);
|
||||
|
||||
// Disable the "Create" button if none of the pagetypes are available
|
||||
var buttonState = this.find('#Form_AddForm_PageType li:not(.disabled)').length
|
||||
? 'enable'
|
||||
: 'disable';
|
||||
this.find('button[name=action_doAdd]').button(buttonState);
|
||||
|
||||
this.find('.message-restricted')[allAllowed ? 'hide' : 'show']();
|
||||
}
|
||||
});
|
||||
|
||||
$(".cms-add-form #Form_AddForm_PageType li").entwine({
|
||||
onclick: function(e) {
|
||||
this.setSelected(true);
|
||||
},
|
||||
setSelected: function(bool) {
|
||||
var input = this.find('input');
|
||||
if(bool && !input.is(':disabled')) {
|
||||
this.siblings().setSelected(false);
|
||||
this.toggleClass('selected', true);
|
||||
input.prop('checked', true);
|
||||
} else {
|
||||
this.toggleClass('selected', false);
|
||||
input.prop('checked', false);
|
||||
}
|
||||
},
|
||||
setEnabled: function(bool) {
|
||||
$(this).toggleClass('disabled', !bool);
|
||||
if(!bool) $(this).find('input').attr('disabled', 'disabled').removeAttr('checked');
|
||||
else $(this).find('input').removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
$(".cms-content-addpage-button").entwine({
|
||||
onclick: function(e) {
|
||||
var tree = $('.cms-tree'), list = $('.cms-list'), parentId = 0;
|
||||
|
||||
// Choose parent ID either from tree or list view, depending which is visible
|
||||
if(tree.is(':visible')) {
|
||||
var selected = tree.jstree('get_selected');
|
||||
parentId = selected ? $(selected[0]).data('id') : null;
|
||||
} else {
|
||||
var state = list.find('input[name="Page[GridState]"]').val();
|
||||
if(state) parentId = parseInt(JSON.parse(state).ParentID, 10);
|
||||
}
|
||||
|
||||
var data = {selector: this.data('targetPanel'),pjax: this.data('pjax')}, url;
|
||||
if(parentId) {
|
||||
extraParams = this.data('extraParams') ? this.data('extraParams') : '';
|
||||
url = $.path.addSearchParams(ss.i18n.sprintf(this.data('urlAddpage'), parentId), extraParams);
|
||||
} else {
|
||||
url = this.attr('href');
|
||||
}
|
||||
|
||||
$('.cms-container').loadPanel(url, null, data);
|
||||
e.preventDefault();
|
||||
|
||||
// Remove focussed state from button
|
||||
this.blur();
|
||||
|
||||
// $('.cms-page-add-form-dialog').dialog('open');
|
||||
// e.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
}(jQuery));
|
@ -1,469 +0,0 @@
|
||||
/**
|
||||
* File: CMSMain.EditForm.js
|
||||
*/
|
||||
(function($) {
|
||||
$.entwine('ss', function($){
|
||||
/**
|
||||
* Class: .cms-edit-form :input[name=ClassName]
|
||||
* Alert the user on change of page-type. This might have implications
|
||||
* on the available form fields etc.
|
||||
*/
|
||||
$('.cms-edit-form :input[name=ClassName]').entwine({
|
||||
// Function: onchange
|
||||
onchange: function() {
|
||||
alert(ss.i18n._t('CMSMAIN.ALERTCLASSNAME'));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form input[name=Title]
|
||||
*
|
||||
* Input validation on the Title field
|
||||
*/
|
||||
$('.cms-edit-form input[name=Title]').entwine({
|
||||
// Constructor: onmatch
|
||||
onmatch : function() {
|
||||
var self = this;
|
||||
|
||||
self.data('OrigVal', self.val());
|
||||
|
||||
var form = self.closest('form');
|
||||
var urlSegmentInput = $('input:text[name=URLSegment]', form);
|
||||
var liveLinkInput = $('input[name=LiveLink]', form);
|
||||
|
||||
if (urlSegmentInput.length > 0) {
|
||||
self._addActions();
|
||||
this.bind('change', function(e) {
|
||||
var origTitle = self.data('OrigVal');
|
||||
var title = self.val();
|
||||
self.data('OrigVal', title);
|
||||
|
||||
// Criteria for defining a "new" page
|
||||
if (
|
||||
urlSegmentInput.val().indexOf(urlSegmentInput.data('defaultUrl')) === 0
|
||||
&& liveLinkInput.val() == ''
|
||||
) {
|
||||
self.updateURLSegment(title);
|
||||
} else {
|
||||
$('.update', self.parent()).show();
|
||||
}
|
||||
|
||||
self.updateRelatedFields(title, origTitle);
|
||||
self.updateBreadcrumbLabel(title);
|
||||
});
|
||||
}
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: updateRelatedFields
|
||||
*
|
||||
* Update the related fields if appropriate
|
||||
* (String) title The new title
|
||||
* (Stirng) origTitle The original title
|
||||
*/
|
||||
updateRelatedFields: function(title, origTitle) {
|
||||
// Update these fields only if their value was originally the same as the title
|
||||
this.parents('form').find('input[name=MetaTitle], input[name=MenuTitle]').each(function() {
|
||||
var $this = $(this);
|
||||
if($this.val() == origTitle) {
|
||||
$this.val(title);
|
||||
// Onchange bubbling didn't work in IE8, so .trigger('change') couldn't be used
|
||||
if($this.updatedRelatedFields) $this.updatedRelatedFields();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: updateURLSegment
|
||||
*
|
||||
* Update the URLSegment
|
||||
* (String) title
|
||||
*/
|
||||
updateURLSegment: function(title) {
|
||||
var urlSegmentInput = $('input:text[name=URLSegment]', this.closest('form'));
|
||||
var urlSegmentField = urlSegmentInput.closest('.field.urlsegment');
|
||||
var updateURLFromTitle = $('.update', this.parent());
|
||||
urlSegmentField.update(title);
|
||||
if (updateURLFromTitle.is(':visible')) {
|
||||
updateURLFromTitle.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: updateBreadcrumbLabel
|
||||
*
|
||||
* Update the breadcrumb
|
||||
* (String) title
|
||||
*/
|
||||
updateBreadcrumbLabel: function(title) {
|
||||
var pageID = $('.cms-edit-form input[name=ID]').val();
|
||||
var panelCrumb = $('span.cms-panel-link.crumb');
|
||||
if (title && title != "") {
|
||||
panelCrumb.text(title);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _addActions
|
||||
*
|
||||
* Utility to add update from title action
|
||||
*
|
||||
*/
|
||||
_addActions: function() {
|
||||
var self = this;
|
||||
var updateURLFromTitle;
|
||||
|
||||
// update button
|
||||
updateURLFromTitle = $('<button />', {
|
||||
'class': 'update ss-ui-button-small',
|
||||
'text': ss.i18n._t('URLSEGMENT.UpdateURL'),
|
||||
'type': 'button',
|
||||
'click': function(e) {
|
||||
e.preventDefault();
|
||||
self.updateURLSegment(self.val());
|
||||
}
|
||||
});
|
||||
|
||||
// insert elements
|
||||
updateURLFromTitle.insertAfter(self);
|
||||
updateURLFromTitle.hide();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .parentTypeSelector
|
||||
*
|
||||
* ParentID field combination - mostly toggling between
|
||||
* the two radiobuttons and setting the hidden "ParentID" field
|
||||
*/
|
||||
$('.cms-edit-form .parentTypeSelector').entwine({
|
||||
// Constructor: onmatch
|
||||
onmatch : function() {
|
||||
var self = this;
|
||||
this.find(':input[name=ParentType]').bind('click', function(e) {self._toggleSelection(e);});
|
||||
this.find('.TreeDropdownField').bind('change', function(e) {self._changeParentId(e);});
|
||||
|
||||
this._changeParentId();
|
||||
this._toggleSelection();
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _toggleSelection
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
_toggleSelection: function(e) {
|
||||
var selected = this.find(':input[name=ParentType]:checked').val();
|
||||
// reset parent id if 'root' radiobutton is selected
|
||||
if(selected == 'root') this.find(':input[name=ParentID]').val(0);
|
||||
// otherwise use the old value
|
||||
else this.find(':input[name=ParentID]').val(this.find('#Form_EditForm_ParentType_subpage').data('parentIdValue'));
|
||||
// toggle tree dropdown based on selection
|
||||
this.find('#Form_EditForm_ParentID_Holder').toggle(selected != 'root');
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _changeParentId
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
_changeParentId: function(e) {
|
||||
var value = this.find(':input[name=ParentID]').val();
|
||||
// set a data attribute so we know what to use in _toggleSelection
|
||||
this.find('#Form_EditForm_ParentType_subpage').data('parentIdValue', value);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form #CanViewType, .cms-edit-form #CanEditType
|
||||
*
|
||||
* Toggle display of group dropdown in "access" tab,
|
||||
* based on selection of radiobuttons.
|
||||
*/
|
||||
$('.cms-edit-form #CanViewType, .cms-edit-form #CanEditType, .cms-edit-form #CanCreateTopLevelType').entwine({
|
||||
// Constructor: onmatch
|
||||
onmatch: function() {
|
||||
// TODO Decouple
|
||||
var dropdown;
|
||||
if(this.attr('id') == 'CanViewType') dropdown = $('#Form_EditForm_ViewerGroups_Holder');
|
||||
else if(this.attr('id') == 'CanEditType') dropdown = $('#Form_EditForm_EditorGroups_Holder');
|
||||
else if(this.attr('id') == 'CanCreateTopLevelType') dropdown = $('#Form_EditForm_CreateTopLevelGroups_Holder');
|
||||
|
||||
this.find('.optionset :input').bind('change', function(e) {
|
||||
var wrapper = $(this).closest('.middleColumn').parent('div');
|
||||
if(e.target.value == 'OnlyTheseUsers') {
|
||||
wrapper.addClass('remove-splitter');
|
||||
dropdown['show']();
|
||||
}
|
||||
else {
|
||||
wrapper.removeClass('remove-splitter');
|
||||
dropdown['hide']();
|
||||
}
|
||||
});
|
||||
|
||||
// initial state
|
||||
var currentVal = this.find('input[name=' + this.attr('id') + ']:checked').val();
|
||||
dropdown[currentVal == 'OnlyTheseUsers' ? 'show' : 'hide']();
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_print
|
||||
*
|
||||
* Open a printable representation of the form in a new window.
|
||||
* Used for readonly older versions of a specific page.
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_print').entwine({
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var printURL = $(this[0].form).attr('action').replace(/\?.*$/,'')
|
||||
+ '/printable/'
|
||||
+ $(':input[name=ID]',this[0].form).val();
|
||||
if(printURL.substr(0,7) != 'http://') printURL = $('base').attr('href') + printURL;
|
||||
|
||||
window.open(printURL, 'printable');
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_rollback
|
||||
*
|
||||
* A "rollback" to a specific version needs user confirmation.
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_rollback').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
if(version) {
|
||||
message = ss.i18n.sprintf(
|
||||
ss.i18n._t('CMSMain.RollbackToVersion'),
|
||||
version
|
||||
);
|
||||
} else {
|
||||
message = ss.i18n._t('CMSMain.ConfirmRestoreFromLive');
|
||||
}
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_archive
|
||||
*
|
||||
* Informing the user about the archive action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_archive').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
message = ss.i18n.sprintf(
|
||||
ss.i18n._t('CMSMain.Archive'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_restore
|
||||
*
|
||||
* Informing the user about the archive action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_restore').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'),
|
||||
version = form.find(':input[name=Version]').val(),
|
||||
message = '',
|
||||
toRoot = this.data('toRoot');
|
||||
message = ss.i18n.sprintf(
|
||||
ss.i18n._t(toRoot ? 'CMSMain.RestoreToRoot' : 'CMSMain.Restore'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_delete
|
||||
*
|
||||
* Informing the user about the delete from draft action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_delete').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
message = ss.i18n.sprintf(
|
||||
ss.i18n._t('CMSMain.DeleteFromDraft'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_unpublish
|
||||
* Informing the user about the unpublish action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_unpublish').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
message = ss.i18n.sprintf(
|
||||
ss.i18n._t('CMSMain.Unpublish'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Enable save buttons upon detecting changes to content.
|
||||
* "changed" class is added by jQuery.changetracker.
|
||||
*/
|
||||
$('.cms-edit-form.changed').entwine({
|
||||
onmatch: function(e) {
|
||||
this.find('button[name=action_save]').button('option', 'showingAlternate', true);
|
||||
this.find('button[name=action_publish]').button('option', 'showingAlternate', true);
|
||||
this._super(e);
|
||||
},
|
||||
onunmatch: function(e) {
|
||||
var saveButton = this.find('button[name=action_save]');
|
||||
if(saveButton.data('button')) saveButton.button('option', 'showingAlternate', false);
|
||||
var publishButton = this.find('button[name=action_publish]');
|
||||
if(publishButton.data('button')) publishButton.button('option', 'showingAlternate', false);
|
||||
this._super(e);
|
||||
}
|
||||
});
|
||||
|
||||
$('.cms-edit-form .Actions button[name=action_publish]').entwine({
|
||||
/**
|
||||
* Bind to ssui.button event to trigger stylistic changes.
|
||||
*/
|
||||
onbuttonafterrefreshalternate: function() {
|
||||
if (this.button('option', 'showingAlternate')) {
|
||||
this.addClass('ss-ui-action-constructive');
|
||||
}
|
||||
else {
|
||||
this.removeClass('ss-ui-action-constructive');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.cms-edit-form .Actions button[name=action_save]').entwine({
|
||||
/**
|
||||
* Bind to ssui.button event to trigger stylistic changes.
|
||||
*/
|
||||
onbuttonafterrefreshalternate: function() {
|
||||
if (this.button('option', 'showingAlternate')) {
|
||||
this.addClass('ss-ui-action-constructive');
|
||||
}
|
||||
else {
|
||||
this.removeClass('ss-ui-action-constructive');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked
|
||||
*
|
||||
* Showing the "Page location" "Parent page" chooser only when the "Sub-page underneath a parent page"
|
||||
* radio button is selected
|
||||
*/
|
||||
$('.cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked').entwine({
|
||||
onmatch: function() {
|
||||
this.redraw();
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
redraw: function() {
|
||||
var treeField = $('.cms-edit-form.CMSPageSettingsController #Form_EditForm_ParentID_Holder');
|
||||
if ($(this).attr('id') == 'Form_EditForm_ParentType_root') treeField.slideUp();
|
||||
else treeField.slideDown();
|
||||
},
|
||||
onclick: function() {
|
||||
this.redraw();
|
||||
}
|
||||
});
|
||||
|
||||
//trigger an initial change event to do the initial hiding of the element, if necessary
|
||||
if ($('.cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked').attr('id') == 'Form_EditForm_ParentType_root') {
|
||||
$('.cms-edit-form.CMSPageSettingsController #Form_EditForm_ParentID_Holder').hide(); //quick hide on first run
|
||||
}
|
||||
});
|
||||
}(jQuery));
|
@ -1,176 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
$.entwine('ss.tree', function($){
|
||||
$('.cms-tree').entwine({
|
||||
fromDocument: {
|
||||
'oncontext_show.vakata': function(e){
|
||||
this.adjustContextClass();
|
||||
}
|
||||
},
|
||||
/*
|
||||
* Add and remove classes from context menus to allow for
|
||||
* adjusting the display
|
||||
*/
|
||||
adjustContextClass: function(){
|
||||
var menus = $('#vakata-contextmenu').find("ul ul");
|
||||
|
||||
menus.each(function(i){
|
||||
var col = "1",
|
||||
count = $(menus[i]).find('li').length;
|
||||
|
||||
//Assign columns to menus over 10 items long
|
||||
if(count > 20){
|
||||
col = "3";
|
||||
}else if(count > 10){
|
||||
col = "2";
|
||||
}
|
||||
|
||||
$(menus[i]).addClass('col-' + col).removeClass('right');
|
||||
|
||||
//Remove "right" class that jstree adds on mouseenter
|
||||
$(menus[i]).find('li').on("mouseenter", function (e) {
|
||||
$(this).parent('ul').removeClass("right");
|
||||
});
|
||||
});
|
||||
},
|
||||
getTreeConfig: function() {
|
||||
var self = this, config = this._super(), hints = this.getHints();
|
||||
config.plugins.push('contextmenu');
|
||||
config.contextmenu = {
|
||||
'items': function(node) {
|
||||
|
||||
var menuitems = {
|
||||
'edit': {
|
||||
'label': ss.i18n._t('Tree.EditPage', 'Edit page', 100, 'Used in the context menu when right-clicking on a page node in the CMS tree'),
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(ss.i18n.sprintf(
|
||||
self.data('urlEditpage'), obj.data('id')
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Add "show as list"
|
||||
if(!node.hasClass('nochildren')) {
|
||||
menuitems['showaslist'] = {
|
||||
'label': ss.i18n._t('Tree.ShowAsList'),
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(
|
||||
self.data('urlListview') + '&ParentID=' + obj.data('id'),
|
||||
null,
|
||||
// Default to list view tab
|
||||
{tabState: {'pages-controller-cms-content': {'tabSelector': '.content-listview'}}}
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Build a list for allowed children as submenu entries
|
||||
var pagetype = node.data('pagetype'),
|
||||
id = node.data('id'),
|
||||
allowedChildren = node.find('>a .item').data('allowedchildren'),
|
||||
menuAllowedChildren = {},
|
||||
hasAllowedChildren = false;
|
||||
|
||||
// Convert to menu entries
|
||||
$.each(allowedChildren, function(klass, title){
|
||||
hasAllowedChildren = true;
|
||||
menuAllowedChildren["allowedchildren-" + klass ] = {
|
||||
'label': '<span class="jstree-pageicon"></span>' + title,
|
||||
'_class': 'class-' + klass,
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(
|
||||
$.path.addSearchParams(
|
||||
ss.i18n.sprintf(self.data('urlAddpage'), id, klass),
|
||||
self.data('extraParams')
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if(hasAllowedChildren) {
|
||||
menuitems['addsubpage'] = {
|
||||
'label': ss.i18n._t('Tree.AddSubPage', 'Add page under this page', 100, 'Used in the context menu when right-clicking on a page node in the CMS tree'),
|
||||
'submenu': menuAllowedChildren
|
||||
};
|
||||
}
|
||||
|
||||
menuitems['duplicate'] = {
|
||||
'label': ss.i18n._t('Tree.Duplicate'),
|
||||
'submenu': [
|
||||
{
|
||||
'label': ss.i18n._t('Tree.ThisPageOnly'),
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(
|
||||
$.path.addSearchParams(
|
||||
ss.i18n.sprintf(self.data('urlDuplicate'), obj.data('id')),
|
||||
self.data('extraParams')
|
||||
)
|
||||
);
|
||||
}
|
||||
},{
|
||||
'label': ss.i18n._t('Tree.ThisPageAndSubpages'),
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(
|
||||
$.path.addSearchParams(
|
||||
ss.i18n.sprintf(self.data('urlDuplicatewithchildren'), obj.data('id')),
|
||||
self.data('extraParams')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return menuitems;
|
||||
}
|
||||
};
|
||||
return config;
|
||||
}
|
||||
});
|
||||
|
||||
// Scroll tree down to context of the current page, if it isn't
|
||||
// already visible
|
||||
$('.cms-tree a.jstree-clicked').entwine({
|
||||
onmatch: function(){
|
||||
var self = this,
|
||||
panel = self.parents('.cms-panel-content'),
|
||||
scrollTo;
|
||||
|
||||
if(self.offset().top < 0 ||
|
||||
self.offset().top > panel.height() - self.height()) {
|
||||
// Current scroll top + our current offset top is our
|
||||
// position in the panel
|
||||
scrollTo = panel.scrollTop() + self.offset().top
|
||||
+ (panel.height() / 2);
|
||||
|
||||
panel.animate({
|
||||
scrollTop: scrollTo
|
||||
}, 'slow');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Clear filters button
|
||||
$('.cms-tree-filtered .clear-filter').entwine({
|
||||
onclick: function () {
|
||||
window.location = location.protocol + '//' + location.host + location.pathname;
|
||||
}
|
||||
});
|
||||
|
||||
$('.cms-tree-filtered').entwine({
|
||||
onmatch: function () {
|
||||
var self = this,
|
||||
setHeight = function () {
|
||||
var height = $('.cms-content-tools .cms-panel-content').height() - self.parent().siblings('.cms-content-toolbar').outerHeight(true);
|
||||
self.css('height', height + 'px');
|
||||
};
|
||||
|
||||
setHeight();
|
||||
$(window).on('resize', window.ss.debounce(setHeight, 300));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}(jQuery));
|
@ -1,111 +0,0 @@
|
||||
(function ($) {
|
||||
/**
|
||||
* Behaviour for the CMS Content Toolbar.
|
||||
* Applies to tools on top-level views i.e. '/admin/pages' and '/admin/assets' and
|
||||
* their corresponding tools in the SiteTree panel.
|
||||
* An example is 'bulk actions' on the Pages view.
|
||||
*/
|
||||
$.entwine('ss', function ($) {
|
||||
|
||||
// Faux three column layout
|
||||
$('.cms-content-header-info').entwine({
|
||||
'from .cms-panel': {
|
||||
// Keep the header info's width synced with the TreeView panel's width.
|
||||
ontoggle: function (e) {
|
||||
var $treeViewPanel = this.closest('.cms-content').find(e.target);
|
||||
|
||||
if ($treeViewPanel.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.parent()[$treeViewPanel.hasClass('collapsed') ? 'addClass' : 'removeClass']('collapsed');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.cms-content-toolbar').entwine({
|
||||
|
||||
onmatch: function () {
|
||||
var self = this;
|
||||
|
||||
this._super();
|
||||
|
||||
// Initialise the buttons
|
||||
$.each(this.find('.cms-actions-buttons-row .tool-button'), function () {
|
||||
var $button = $(this),
|
||||
toolId = $button.data('toolid'),
|
||||
isActive = $button.hasClass('active');
|
||||
|
||||
// We don't care about tools that don't have a related 'action'.
|
||||
if (toolId !== void 0) {
|
||||
// Set the tool to its closed state.
|
||||
$button.data('active', false).removeClass('active');
|
||||
$('#' + toolId).hide();
|
||||
|
||||
self.bindActionButtonEvents($button);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onunmatch: function () {
|
||||
var self = this;
|
||||
|
||||
this._super();
|
||||
|
||||
$.each(this.find('.cms-actions-buttons-row .tool-button'), function () {
|
||||
var $button = $(this);
|
||||
self.unbindActionButtonEvents($button);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @func bindActionButtonEvents
|
||||
* @param {object} $button
|
||||
* @desc Add event handlers in the '.cmsContentToolbar' namespace.
|
||||
*/
|
||||
bindActionButtonEvents: function ($button) {
|
||||
var self = this;
|
||||
|
||||
$button.on('click.cmsContentToolbar', function (e) {
|
||||
self.showHideTool($button);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @func unbindActionButtonEvents
|
||||
* @param {object} $button
|
||||
* @desc Remove all event handlers in the '.cmsContentToolbar' namespace.
|
||||
*/
|
||||
unbindActionButtonEvents: function ($button) {
|
||||
$button.off('.cmsContentToolbar');
|
||||
},
|
||||
|
||||
/**
|
||||
* @func showTool
|
||||
* @param {object} $button
|
||||
* @desc Show a tool in the tools row. Hides all other tools.
|
||||
*/
|
||||
showHideTool: function ($button) {
|
||||
var isActive = $button.data('active'),
|
||||
toolId = $button.data('toolid'),
|
||||
$action = $('#' + toolId);
|
||||
|
||||
// Hide all tools except the one passed as a param,
|
||||
// which gets handled separately.
|
||||
$.each(this.find('.cms-actions-buttons-row .tool-button'), function () {
|
||||
var $currentButton = $(this),
|
||||
$currentAction = $('#' + $currentButton.data('toolid'));
|
||||
|
||||
if ($currentButton.data('toolid') !== toolId) {
|
||||
$currentAction.hide();
|
||||
$currentButton.data('active', false);
|
||||
}
|
||||
});
|
||||
|
||||
$button[isActive ? 'removeClass' : 'addClass']('active');
|
||||
$action[isActive ? 'hide' : 'show']();
|
||||
$button.data('active', !isActive);
|
||||
}
|
||||
});
|
||||
});
|
||||
}(jQuery));
|
@ -1,177 +0,0 @@
|
||||
(function($) {
|
||||
/**
|
||||
* File: CMSPageHistoryController.js
|
||||
*
|
||||
* Handles related interactions between the version selection form on the
|
||||
* left hand side of the panel and the version displaying on the right
|
||||
* hand side.
|
||||
*/
|
||||
|
||||
$.entwine('ss', function($){
|
||||
|
||||
/**
|
||||
* Class: #Form_VersionsForm
|
||||
*
|
||||
* The left hand side version selection form is the main interface for
|
||||
* users to select a version to view, or to compare two versions
|
||||
*/
|
||||
$('#Form_VersionsForm').entwine({
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
onmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
/**
|
||||
* Function: submit.
|
||||
*
|
||||
* Submits either the compare versions form or the view single form
|
||||
* display based on whether we have two or 1 option selected
|
||||
*
|
||||
* Todo:
|
||||
* Handle coupling to admin url
|
||||
*/
|
||||
onsubmit: function(e, d) {
|
||||
e.preventDefault();
|
||||
|
||||
var id, self = this;
|
||||
|
||||
id = this.find(':input[name=ID]').val();
|
||||
|
||||
if(!id) return false;
|
||||
|
||||
var button, url, selected, to, from, compare, data;
|
||||
|
||||
compare = (this.find(":input[name=CompareMode]").is(":checked"));
|
||||
selected = this.find("table input[type=checkbox]").filter(":checked");
|
||||
|
||||
if(compare) {
|
||||
if(selected.length != 2) return false;
|
||||
|
||||
to = selected.eq(0).val();
|
||||
from = selected.eq(1).val();
|
||||
button = this.find(':submit[name=action_doCompare]');
|
||||
url = ss.i18n.sprintf(this.data('linkTmplCompare'), id,from,to);
|
||||
}
|
||||
else {
|
||||
to = selected.eq(0).val();
|
||||
button = this.find(':submit[name=action_doShowVersion]');
|
||||
url = ss.i18n.sprintf(this.data('linkTmplShow'), id,to);
|
||||
}
|
||||
|
||||
$('.cms-container').loadPanel(url, '', {pjax: 'CurrentForm'});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: :input[name=ShowUnpublished]
|
||||
*
|
||||
* Used for toggling whether to show or hide unpublished versions.
|
||||
*/
|
||||
$('#Form_VersionsForm input[name=ShowUnpublished]').entwine({
|
||||
onmatch: function() {
|
||||
this.toggle();
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
/**
|
||||
* Event: :input[name=ShowUnpublished] change
|
||||
*
|
||||
* Changing the show unpublished checkbox toggles whether to show
|
||||
* or hide the unpublished versions. Because those rows may be being
|
||||
* compared this also ensures those rows are unselected.
|
||||
*/
|
||||
onchange: function() {
|
||||
this.toggle();
|
||||
},
|
||||
toggle: function() {
|
||||
var self = $(this);
|
||||
var form = self.parents('form');
|
||||
|
||||
if(self.attr('checked')) {
|
||||
form.find('tr[data-published=false]').show();
|
||||
} else {
|
||||
form.find("tr[data-published=false]").hide()._unselect();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: #Form_VersionsForm tr
|
||||
*
|
||||
* An individual row in the versions form. Selecting the row updates
|
||||
* the edit form depending on whether we're showing individual version
|
||||
* information or displaying comparsion.
|
||||
*/
|
||||
$("#Form_VersionsForm tbody tr").entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Selects or deselects the row (if in compare mode). Will trigger
|
||||
* an update of the edit form if either selected (in single mode)
|
||||
* or if this is the second row selected (in compare mode)
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var compare, selected;
|
||||
|
||||
// compare mode
|
||||
compare = this.parents("form").find(':input[name=CompareMode]').attr("checked");
|
||||
selected = this.siblings(".active");
|
||||
|
||||
if(compare && this.hasClass('active')) {
|
||||
this._unselect();
|
||||
|
||||
return;
|
||||
}
|
||||
else if(compare) {
|
||||
// check if we have already selected more than two.
|
||||
if(selected.length > 1) {
|
||||
return alert(ss.i18n._t('ONLYSELECTTWO', 'You can only compare two versions at this time.'));
|
||||
}
|
||||
|
||||
this._select();
|
||||
|
||||
// if this is the second selected then we can compare.
|
||||
if(selected.length == 1) {
|
||||
this.parents('form').submit();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
this._select();
|
||||
selected._unselect();
|
||||
|
||||
this.parents("form").submit();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _unselect()
|
||||
*
|
||||
* Unselects the row from the form selection.
|
||||
*/
|
||||
_unselect: function() {
|
||||
this.removeClass('active');
|
||||
this.find(":input[type=checkbox]").attr("checked", false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _select()
|
||||
*
|
||||
* Selects the currently matched row in the form selection
|
||||
*/
|
||||
_select: function() {
|
||||
this.addClass('active');
|
||||
this.find(":input[type=checkbox]").attr("checked", true);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
@ -1,27 +0,0 @@
|
||||
(function($) {
|
||||
$.entwine('ss', function($){
|
||||
$('#Form_EditForm_RedirectionType input').entwine({
|
||||
onmatch: function() {
|
||||
var self = $(this);
|
||||
if(self.attr('checked')) this.toggle();
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
onclick: function() {
|
||||
this.toggle();
|
||||
},
|
||||
toggle: function() {
|
||||
if($(this).attr('value') == 'Internal') {
|
||||
$('#Form_EditForm_ExternalURL_Holder').hide();
|
||||
$('#Form_EditForm_LinkToID_Holder').show();
|
||||
} else {
|
||||
$('#Form_EditForm_ExternalURL_Holder').show();
|
||||
$('#Form_EditForm_LinkToID_Holder').hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
|
@ -1,29 +0,0 @@
|
||||
function windowName(suffix) {
|
||||
var base = document.getElementsByTagName('base')[0].href.replace('http://','').replace(/\//g,'_').replace(/\./g,'_');
|
||||
return base + suffix;
|
||||
}
|
||||
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
$('#switchView a.newWindow').on('click', function(e) {
|
||||
var w = window.open(this.href, windowName(this.target));
|
||||
w.focus();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#SilverStripeNavigatorLink').on('click', function(e) {
|
||||
$('#SilverStripeNavigatorLinkPopup').toggle();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#SilverStripeNavigatorLinkPopup a.close').on('click', function(e) {
|
||||
$('#SilverStripeNavigatorLinkPopup').hide();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#SilverStripeNavigatorLinkPopup input').on('focus',function(e) {
|
||||
this.select();
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery);
|
@ -1,138 +0,0 @@
|
||||
(function($) {
|
||||
$.entwine('ss', function($) {
|
||||
/**
|
||||
* Class: .field.urlsegment
|
||||
*
|
||||
* Provides enhanced functionality (read-only/edit switch) and
|
||||
* input validation on the URLSegment field
|
||||
*/
|
||||
$('.field.urlsegment:not(.readonly)').entwine({
|
||||
|
||||
// Roughly matches the field width including edit button
|
||||
MaxPreviewLength: 55,
|
||||
|
||||
Ellipsis: '...',
|
||||
|
||||
onmatch : function() {
|
||||
// Only initialize the field if it contains an editable field.
|
||||
// This ensures we don't get bogus previews on readonly fields.
|
||||
if(this.find(':text').length) this.toggleEdit(false);
|
||||
this.redraw();
|
||||
|
||||
this._super();
|
||||
},
|
||||
|
||||
redraw: function() {
|
||||
var field = this.find(':text'),
|
||||
url = decodeURI(field.data('prefix') + field.val()),
|
||||
previewUrl = url;
|
||||
|
||||
// Truncate URL if required (ignoring the suffix, retaining the full value)
|
||||
if(url.length > this.getMaxPreviewLength()) {
|
||||
previewUrl = this.getEllipsis() + url.substr(url.length - this.getMaxPreviewLength(), url.length);
|
||||
}
|
||||
|
||||
// Transfer current value to holder
|
||||
this.find('.preview').attr('href', encodeURI(url + field.data('suffix'))).text(previewUrl);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param Boolean
|
||||
*/
|
||||
toggleEdit: function(toggle) {
|
||||
var field = this.find(':text');
|
||||
|
||||
this.find('.preview-holder')[toggle ? 'hide' : 'show']();
|
||||
this.find('.edit-holder')[toggle ? 'show' : 'hide']();
|
||||
|
||||
if(toggle) {
|
||||
field.data("origval", field.val()); //retain current value for cancel
|
||||
field.focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Commits the change of the URLSegment to the field
|
||||
* Optional: pass in (String) to update the URLSegment
|
||||
*/
|
||||
update: function() {
|
||||
var self = this,
|
||||
field = this.find(':text'),
|
||||
currentVal = field.data('origval'),
|
||||
title = arguments[0],
|
||||
updateVal = (title && title !== "") ? title : field.val();
|
||||
|
||||
if (currentVal != updateVal) {
|
||||
this.addClass('loading');
|
||||
this.suggest(updateVal, function(data) {
|
||||
field.val(decodeURIComponent(data.value));
|
||||
self.toggleEdit(false);
|
||||
self.removeClass('loading');
|
||||
self.redraw();
|
||||
});
|
||||
} else {
|
||||
this.toggleEdit(false);
|
||||
this.redraw();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancels any changes to the field
|
||||
*/
|
||||
cancel: function() {
|
||||
var field = this.find(':text');
|
||||
field.val(field.data("origval"));
|
||||
this.toggleEdit(false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return a value matching the criteria.
|
||||
*
|
||||
* @param (String)
|
||||
* @param (Function)
|
||||
*/
|
||||
suggest: function(val, callback) {
|
||||
var self = this,
|
||||
field = self.find(':text'),
|
||||
urlParts = $.path.parseUrl(self.closest('form').attr('action')),
|
||||
url = urlParts.hrefNoSearch + '/field/' + field.attr('name') + '/suggest/?value=' + encodeURIComponent(val);
|
||||
if(urlParts.search) url += '&' + urlParts.search.replace(/^\?/, '');
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
success: function(data) {
|
||||
callback.apply(this, arguments);
|
||||
},
|
||||
error: function(xhr, status) {
|
||||
xhr.statusText = xhr.responseText;
|
||||
},
|
||||
complete: function() {
|
||||
self.removeClass('loading');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('.field.urlsegment .edit').entwine({
|
||||
onclick: function(e) {
|
||||
e.preventDefault();
|
||||
this.closest('.field').toggleEdit(true);
|
||||
}
|
||||
});
|
||||
|
||||
$('.field.urlsegment .update').entwine({
|
||||
onclick: function(e) {
|
||||
e.preventDefault();
|
||||
this.closest('.field').update();
|
||||
}
|
||||
});
|
||||
|
||||
$('.field.urlsegment .cancel').entwine({
|
||||
onclick: function(e) {
|
||||
e.preventDefault();
|
||||
this.closest('.field').cancel();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}(jQuery));
|
116
javascript/dist/AssetAdmin.js
vendored
Normal file
116
javascript/dist/AssetAdmin.js
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define('ss.AssetAdmin', ['../../../framework/javascript/dist/jQuery', '../../../framework/javascript/dist/i18n'], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(require('../../../framework/javascript/dist/jQuery'), require('../../../framework/javascript/dist/i18n'));
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(global.jQuery, global.i18n);
|
||||
global.ssAssetAdmin = mod.exports;
|
||||
}
|
||||
})(this, function (_jQuery, _i18n) {
|
||||
'use strict';
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
var _i18n2 = _interopRequireDefault(_i18n);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
|
||||
_jQuery2.default.entwine('ss', function ($) {
|
||||
$('.AssetAdmin.cms-edit-form .ss-gridfield-item').entwine({
|
||||
onclick: function onclick(e) {
|
||||
if ($(e.target).closest('.action').length) {
|
||||
this._super(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var grid = this.closest('.ss-gridfield');
|
||||
|
||||
if (this.data('class') == 'Folder') {
|
||||
var url = grid.data('urlFolderTemplate').replace('%s', this.data('id'));
|
||||
$('.cms-container').loadPanel(url);
|
||||
return false;
|
||||
}
|
||||
|
||||
this._super(e);
|
||||
}
|
||||
});
|
||||
$('.AssetAdmin.cms-edit-form .ss-gridfield .col-buttons .action.gridfield-button-delete, .AssetAdmin.cms-edit-form .Actions button.action.action-delete').entwine({
|
||||
onclick: function onclick(e) {
|
||||
var msg;
|
||||
|
||||
if (this.closest('.ss-gridfield-item').data('class') == 'Folder') {
|
||||
msg = _i18n2.default._t('AssetAdmin.ConfirmDelete');
|
||||
} else {
|
||||
msg = _i18n2.default._t('TABLEFIELD.DELETECONFIRMMESSAGE');
|
||||
}
|
||||
|
||||
if (!confirm(msg)) return false;
|
||||
this.getGridField().reload({
|
||||
data: [{
|
||||
name: this.attr('name'),
|
||||
value: this.val()
|
||||
}]
|
||||
});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$('.AssetAdmin.cms-edit-form :submit[name=action_delete]').entwine({
|
||||
onclick: function onclick(e) {
|
||||
if (!confirm(_i18n2.default._t('AssetAdmin.ConfirmDelete'))) return false;else this._super(e);
|
||||
}
|
||||
});
|
||||
$('.AssetAdmin .cms-add-folder-link').entwine({
|
||||
onclick: function onclick(e) {
|
||||
var name = prompt(_i18n2.default._t('Folder.Name'));
|
||||
if (!name) return false;
|
||||
this.closest('.cms-container').loadPanel(this.data('url') + '&Name=' + name);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$('#Form_SyncForm').entwine({
|
||||
onsubmit: function onsubmit(e) {
|
||||
var button = jQuery(this).find(':submit:first');
|
||||
button.addClass('loading');
|
||||
$.ajax({
|
||||
url: jQuery(this).attr('action'),
|
||||
data: this.serializeArray(),
|
||||
success: function success() {
|
||||
button.removeClass('loading');
|
||||
var currNode = $('.cms-tree')[0].firstSelected();
|
||||
|
||||
if (currNode) {
|
||||
var url = $(currNode).find('a').attr('href');
|
||||
$('.cms-content').loadPanel(url);
|
||||
}
|
||||
|
||||
$('.cms-tree')[0].setCustomURL('admin/assets/getsubtree');
|
||||
$('.cms-tree')[0].reload({
|
||||
onSuccess: function onSuccess() {}
|
||||
});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$('.AssetAdmin.cms-edit-form .ss-uploadfield-item-progress').entwine({
|
||||
onunmatch: function onunmatch() {
|
||||
$('.AssetAdmin.cms-edit-form .ss-gridfield').reload();
|
||||
}
|
||||
});
|
||||
$('.AssetAdmin .grid-levelup').entwine({
|
||||
onmatch: function onmatch() {
|
||||
this.closest('.ui-tabs-panel').find('.cms-actions-row').prepend(this);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
177
javascript/dist/CMSMain.AddForm.js
vendored
Normal file
177
javascript/dist/CMSMain.AddForm.js
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define('ss.CMSMain.AddForm', ['../../../framework/javascript/dist/jQuery'], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(require('../../../framework/javascript/dist/jQuery'));
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(global.jQuery);
|
||||
global.ssCMSMainAddForm = mod.exports;
|
||||
}
|
||||
})(this, function (_jQuery) {
|
||||
'use strict';
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
|
||||
_jQuery2.default.entwine('ss', function ($) {
|
||||
$(".cms-add-form .parent-mode :input").entwine({
|
||||
onclick: function onclick(e) {
|
||||
if (this.val() == 'top') {
|
||||
var parentField = this.closest('form').find('#Form_AddForm_ParentID_Holder .TreeDropdownField');
|
||||
parentField.setValue('');
|
||||
parentField.setTitle('');
|
||||
}
|
||||
}
|
||||
});
|
||||
$(".cms-add-form").entwine({
|
||||
ParentID: 0,
|
||||
ParentCache: {},
|
||||
onadd: function onadd() {
|
||||
var self = this;
|
||||
this.find('#Form_AddForm_ParentID_Holder .TreeDropdownField').bind('change', function () {
|
||||
self.updateTypeList();
|
||||
});
|
||||
this.find(".SelectionGroup.parent-mode").bind('change', function () {
|
||||
self.updateTypeList();
|
||||
});
|
||||
this.updateTypeList();
|
||||
},
|
||||
loadCachedChildren: function loadCachedChildren(parentID) {
|
||||
var cache = this.getParentCache();
|
||||
if (typeof cache[parentID] !== 'undefined') return cache[parentID];else return null;
|
||||
},
|
||||
saveCachedChildren: function saveCachedChildren(parentID, children) {
|
||||
var cache = this.getParentCache();
|
||||
cache[parentID] = children;
|
||||
this.setParentCache(cache);
|
||||
},
|
||||
updateTypeList: function updateTypeList() {
|
||||
var hints = this.data('hints'),
|
||||
parentTree = this.find('#Form_AddForm_ParentID_Holder .TreeDropdownField'),
|
||||
parentMode = this.find("input[name=ParentModeField]:checked").val(),
|
||||
metadata = parentTree.data('metadata'),
|
||||
id = metadata && parentMode === 'child' ? parentTree.getValue() || this.getParentID() : null,
|
||||
newClassName = metadata ? metadata.ClassName : null,
|
||||
hintKey = newClassName && parentMode === 'child' ? newClassName : 'Root',
|
||||
hint = typeof hints[hintKey] !== 'undefined' ? hints[hintKey] : null,
|
||||
self = this,
|
||||
defaultChildClass = hint && typeof hint.defaultChild !== 'undefined' ? hint.defaultChild : null,
|
||||
disallowedChildren = [];
|
||||
|
||||
if (id) {
|
||||
if (this.hasClass('loading')) return;
|
||||
this.addClass('loading');
|
||||
this.setParentID(id);
|
||||
if (!parentTree.getValue()) parentTree.setValue(id);
|
||||
disallowedChildren = this.loadCachedChildren(id);
|
||||
|
||||
if (disallowedChildren !== null) {
|
||||
this.updateSelectionFilter(disallowedChildren, defaultChildClass);
|
||||
this.removeClass('loading');
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: self.data('childfilter'),
|
||||
data: {
|
||||
'ParentID': id
|
||||
},
|
||||
success: function success(data) {
|
||||
self.saveCachedChildren(id, data);
|
||||
self.updateSelectionFilter(data, defaultChildClass);
|
||||
},
|
||||
complete: function complete() {
|
||||
self.removeClass('loading');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
} else {
|
||||
disallowedChildren = hint && typeof hint.disallowedChildren !== 'undefined' ? hint.disallowedChildren : [], this.updateSelectionFilter(disallowedChildren, defaultChildClass);
|
||||
}
|
||||
},
|
||||
updateSelectionFilter: function updateSelectionFilter(disallowedChildren, defaultChildClass) {
|
||||
var allAllowed = null;
|
||||
this.find('#Form_AddForm_PageType li').each(function () {
|
||||
var className = $(this).find('input').val(),
|
||||
isAllowed = $.inArray(className, disallowedChildren) === -1;
|
||||
$(this).setEnabled(isAllowed);
|
||||
if (!isAllowed) $(this).setSelected(false);
|
||||
if (allAllowed === null) allAllowed = isAllowed;else allAllowed = allAllowed && isAllowed;
|
||||
});
|
||||
|
||||
if (defaultChildClass) {
|
||||
var selectedEl = this.find('#Form_AddForm_PageType li input[value=' + defaultChildClass + ']').parents('li:first');
|
||||
} else {
|
||||
var selectedEl = this.find('#Form_AddForm_PageType li:not(.disabled):first');
|
||||
}
|
||||
|
||||
selectedEl.setSelected(true);
|
||||
selectedEl.siblings().setSelected(false);
|
||||
var buttonState = this.find('#Form_AddForm_PageType li:not(.disabled)').length ? 'enable' : 'disable';
|
||||
this.find('button[name=action_doAdd]').button(buttonState);
|
||||
this.find('.message-restricted')[allAllowed ? 'hide' : 'show']();
|
||||
}
|
||||
});
|
||||
$(".cms-add-form #Form_AddForm_PageType li").entwine({
|
||||
onclick: function onclick(e) {
|
||||
this.setSelected(true);
|
||||
},
|
||||
setSelected: function setSelected(bool) {
|
||||
var input = this.find('input');
|
||||
|
||||
if (bool && !input.is(':disabled')) {
|
||||
this.siblings().setSelected(false);
|
||||
this.toggleClass('selected', true);
|
||||
input.prop('checked', true);
|
||||
} else {
|
||||
this.toggleClass('selected', false);
|
||||
input.prop('checked', false);
|
||||
}
|
||||
},
|
||||
setEnabled: function setEnabled(bool) {
|
||||
$(this).toggleClass('disabled', !bool);
|
||||
if (!bool) $(this).find('input').attr('disabled', 'disabled').removeAttr('checked');else $(this).find('input').removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
$(".cms-page-add-button").entwine({
|
||||
onclick: function onclick(e) {
|
||||
var tree = $('.cms-tree'),
|
||||
list = $('.cms-list'),
|
||||
parentId = 0;
|
||||
|
||||
if (tree.is(':visible')) {
|
||||
var selected = tree.jstree('get_selected');
|
||||
parentId = selected ? $(selected[0]).data('id') : null;
|
||||
} else {
|
||||
var state = list.find('input[name="Page[GridState]"]').val();
|
||||
if (state) parentId = parseInt(JSON.parse(state).ParentID, 10);
|
||||
}
|
||||
|
||||
var data = {
|
||||
selector: this.data('targetPanel'),
|
||||
pjax: this.data('pjax')
|
||||
},
|
||||
url;
|
||||
|
||||
if (parentId) {
|
||||
extraParams = this.data('extraParams') ? this.data('extraParams') : '';
|
||||
url = $.path.addSearchParams(i18n.sprintf(this.data('urlAddpage'), parentId), extraParams);
|
||||
} else {
|
||||
url = this.attr('href');
|
||||
}
|
||||
|
||||
$('.cms-container').loadPanel(url, null, data);
|
||||
e.preventDefault();
|
||||
this.blur();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
301
javascript/dist/CMSMain.EditForm.js
vendored
Normal file
301
javascript/dist/CMSMain.EditForm.js
vendored
Normal file
@ -0,0 +1,301 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define('ss.CMSMain.EditForm', ['../../../framework/javascript/dist/jQuery', '../../../framework/javascript/dist/i18n'], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(require('../../../framework/javascript/dist/jQuery'), require('../../../framework/javascript/dist/i18n'));
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(global.jQuery, global.i18n);
|
||||
global.ssCMSMainEditForm = mod.exports;
|
||||
}
|
||||
})(this, function (_jQuery, _i18n) {
|
||||
'use strict';
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
var _i18n2 = _interopRequireDefault(_i18n);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
|
||||
_jQuery2.default.entwine('ss', function ($) {
|
||||
$('.cms-edit-form :input[name=ClassName]').entwine({
|
||||
onchange: function onchange() {
|
||||
alert(_i18n2.default._t('CMSMAIN.ALERTCLASSNAME'));
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form input[name=Title]').entwine({
|
||||
onmatch: function onmatch() {
|
||||
var self = this;
|
||||
self.data('OrigVal', self.val());
|
||||
var form = self.closest('form');
|
||||
var urlSegmentInput = $('input:text[name=URLSegment]', form);
|
||||
var liveLinkInput = $('input[name=LiveLink]', form);
|
||||
|
||||
if (urlSegmentInput.length > 0) {
|
||||
self._addActions();
|
||||
|
||||
this.bind('change', function (e) {
|
||||
var origTitle = self.data('OrigVal');
|
||||
var title = self.val();
|
||||
self.data('OrigVal', title);
|
||||
|
||||
if (urlSegmentInput.val().indexOf(urlSegmentInput.data('defaultUrl')) === 0 && liveLinkInput.val() == '') {
|
||||
self.updateURLSegment(title);
|
||||
} else {
|
||||
$('.update', self.parent()).show();
|
||||
}
|
||||
|
||||
self.updateRelatedFields(title, origTitle);
|
||||
self.updateBreadcrumbLabel(title);
|
||||
});
|
||||
}
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function onunmatch() {
|
||||
this._super();
|
||||
},
|
||||
updateRelatedFields: function updateRelatedFields(title, origTitle) {
|
||||
this.parents('form').find('input[name=MetaTitle], input[name=MenuTitle]').each(function () {
|
||||
var $this = $(this);
|
||||
|
||||
if ($this.val() == origTitle) {
|
||||
$this.val(title);
|
||||
if ($this.updatedRelatedFields) $this.updatedRelatedFields();
|
||||
}
|
||||
});
|
||||
},
|
||||
updateURLSegment: function updateURLSegment(title) {
|
||||
var urlSegmentInput = $('input:text[name=URLSegment]', this.closest('form'));
|
||||
var urlSegmentField = urlSegmentInput.closest('.field.urlsegment');
|
||||
var updateURLFromTitle = $('.update', this.parent());
|
||||
urlSegmentField.update(title);
|
||||
|
||||
if (updateURLFromTitle.is(':visible')) {
|
||||
updateURLFromTitle.hide();
|
||||
}
|
||||
},
|
||||
updateBreadcrumbLabel: function updateBreadcrumbLabel(title) {
|
||||
var pageID = $('.cms-edit-form input[name=ID]').val();
|
||||
var panelCrumb = $('span.cms-panel-link.crumb');
|
||||
|
||||
if (title && title != "") {
|
||||
panelCrumb.text(title);
|
||||
}
|
||||
},
|
||||
_addActions: function _addActions() {
|
||||
var self = this;
|
||||
var updateURLFromTitle;
|
||||
updateURLFromTitle = $('<button />', {
|
||||
'class': 'update ss-ui-button-small',
|
||||
'text': _i18n2.default._t('URLSEGMENT.UpdateURL'),
|
||||
'type': 'button',
|
||||
'click': function click(e) {
|
||||
e.preventDefault();
|
||||
self.updateURLSegment(self.val());
|
||||
}
|
||||
});
|
||||
updateURLFromTitle.insertAfter(self);
|
||||
updateURLFromTitle.hide();
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form .parentTypeSelector').entwine({
|
||||
onmatch: function onmatch() {
|
||||
var self = this;
|
||||
this.find(':input[name=ParentType]').bind('click', function (e) {
|
||||
self._toggleSelection(e);
|
||||
});
|
||||
this.find('.TreeDropdownField').bind('change', function (e) {
|
||||
self._changeParentId(e);
|
||||
});
|
||||
|
||||
this._changeParentId();
|
||||
|
||||
this._toggleSelection();
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function onunmatch() {
|
||||
this._super();
|
||||
},
|
||||
_toggleSelection: function _toggleSelection(e) {
|
||||
var selected = this.find(':input[name=ParentType]:checked').val();
|
||||
if (selected == 'root') this.find(':input[name=ParentID]').val(0);else this.find(':input[name=ParentID]').val(this.find('#Form_EditForm_ParentType_subpage').data('parentIdValue'));
|
||||
this.find('#Form_EditForm_ParentID_Holder').toggle(selected != 'root');
|
||||
},
|
||||
_changeParentId: function _changeParentId(e) {
|
||||
var value = this.find(':input[name=ParentID]').val();
|
||||
this.find('#Form_EditForm_ParentType_subpage').data('parentIdValue', value);
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form #CanViewType, .cms-edit-form #CanEditType, .cms-edit-form #CanCreateTopLevelType').entwine({
|
||||
onmatch: function onmatch() {
|
||||
var dropdown;
|
||||
if (this.attr('id') == 'CanViewType') dropdown = $('#Form_EditForm_ViewerGroups_Holder');else if (this.attr('id') == 'CanEditType') dropdown = $('#Form_EditForm_EditorGroups_Holder');else if (this.attr('id') == 'CanCreateTopLevelType') dropdown = $('#Form_EditForm_CreateTopLevelGroups_Holder');
|
||||
this.find('.optionset :input').bind('change', function (e) {
|
||||
var wrapper = $(this).closest('.middleColumn').parent('div');
|
||||
|
||||
if (e.target.value == 'OnlyTheseUsers') {
|
||||
wrapper.addClass('remove-splitter');
|
||||
dropdown['show']();
|
||||
} else {
|
||||
wrapper.removeClass('remove-splitter');
|
||||
dropdown['hide']();
|
||||
}
|
||||
});
|
||||
var currentVal = this.find('input[name=' + this.attr('id') + ']:checked').val();
|
||||
dropdown[currentVal == 'OnlyTheseUsers' ? 'show' : 'hide']();
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function onunmatch() {
|
||||
this._super();
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_print').entwine({
|
||||
onclick: function onclick(e) {
|
||||
var printURL = $(this[0].form).attr('action').replace(/\?.*$/, '') + '/printable/' + $(':input[name=ID]', this[0].form).val();
|
||||
if (printURL.substr(0, 7) != 'http://') printURL = $('base').attr('href') + printURL;
|
||||
window.open(printURL, 'printable');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_rollback').entwine({
|
||||
onclick: function onclick(e) {
|
||||
var form = this.parents('form:first'),
|
||||
version = form.find(':input[name=Version]').val(),
|
||||
message = '';
|
||||
|
||||
if (version) {
|
||||
message = _i18n2.default.sprintf(_i18n2.default._t('CMSMain.RollbackToVersion'), version);
|
||||
} else {
|
||||
message = _i18n2.default._t('CMSMain.ConfirmRestoreFromLive');
|
||||
}
|
||||
|
||||
if (confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_archive').entwine({
|
||||
onclick: function onclick(e) {
|
||||
var form = this.parents('form:first'),
|
||||
version = form.find(':input[name=Version]').val(),
|
||||
message = '';
|
||||
message = _i18n2.default.sprintf(_i18n2.default._t('CMSMain.Archive'), version);
|
||||
|
||||
if (confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_restore').entwine({
|
||||
onclick: function onclick(e) {
|
||||
var form = this.parents('form:first'),
|
||||
version = form.find(':input[name=Version]').val(),
|
||||
message = '',
|
||||
toRoot = this.data('toRoot');
|
||||
message = _i18n2.default.sprintf(_i18n2.default._t(toRoot ? 'CMSMain.RestoreToRoot' : 'CMSMain.Restore'), version);
|
||||
|
||||
if (confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_delete').entwine({
|
||||
onclick: function onclick(e) {
|
||||
var form = this.parents('form:first'),
|
||||
version = form.find(':input[name=Version]').val(),
|
||||
message = '';
|
||||
message = _i18n2.default.sprintf(_i18n2.default._t('CMSMain.DeleteFromDraft'), version);
|
||||
|
||||
if (confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_unpublish').entwine({
|
||||
onclick: function onclick(e) {
|
||||
var form = this.parents('form:first'),
|
||||
version = form.find(':input[name=Version]').val(),
|
||||
message = '';
|
||||
message = _i18n2.default.sprintf(_i18n2.default._t('CMSMain.Unpublish'), version);
|
||||
|
||||
if (confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form.changed').entwine({
|
||||
onmatch: function onmatch(e) {
|
||||
this.find('button[name=action_save]').button('option', 'showingAlternate', true);
|
||||
this.find('button[name=action_publish]').button('option', 'showingAlternate', true);
|
||||
|
||||
this._super(e);
|
||||
},
|
||||
onunmatch: function onunmatch(e) {
|
||||
var saveButton = this.find('button[name=action_save]');
|
||||
if (saveButton.data('button')) saveButton.button('option', 'showingAlternate', false);
|
||||
var publishButton = this.find('button[name=action_publish]');
|
||||
if (publishButton.data('button')) publishButton.button('option', 'showingAlternate', false);
|
||||
|
||||
this._super(e);
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form .Actions button[name=action_publish]').entwine({
|
||||
onbuttonafterrefreshalternate: function onbuttonafterrefreshalternate() {
|
||||
if (this.button('option', 'showingAlternate')) {
|
||||
this.addClass('ss-ui-action-constructive');
|
||||
} else {
|
||||
this.removeClass('ss-ui-action-constructive');
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form .Actions button[name=action_save]').entwine({
|
||||
onbuttonafterrefreshalternate: function onbuttonafterrefreshalternate() {
|
||||
if (this.button('option', 'showingAlternate')) {
|
||||
this.addClass('ss-ui-action-constructive');
|
||||
} else {
|
||||
this.removeClass('ss-ui-action-constructive');
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked').entwine({
|
||||
onmatch: function onmatch() {
|
||||
this.redraw();
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function onunmatch() {
|
||||
this._super();
|
||||
},
|
||||
redraw: function redraw() {
|
||||
var treeField = $('.cms-edit-form.CMSPageSettingsController #Form_EditForm_ParentID_Holder');
|
||||
if ($(this).attr('id') == 'Form_EditForm_ParentType_root') treeField.slideUp();else treeField.slideDown();
|
||||
},
|
||||
onclick: function onclick() {
|
||||
this.redraw();
|
||||
}
|
||||
});
|
||||
|
||||
if ($('.cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked').attr('id') == 'Form_EditForm_ParentType_root') {
|
||||
$('.cms-edit-form.CMSPageSettingsController #Form_EditForm_ParentID_Holder').hide();
|
||||
}
|
||||
});
|
||||
});
|
158
javascript/dist/CMSMain.Tree.js
vendored
Normal file
158
javascript/dist/CMSMain.Tree.js
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define('ss.CMSMain.Tree', ['../../../framework/javascript/dist/jQuery', '../../../framework/javascript/dist/i18n'], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(require('../../../framework/javascript/dist/jQuery'), require('../../../framework/javascript/dist/i18n'));
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(global.jQuery, global.i18n);
|
||||
global.ssCMSMainTree = mod.exports;
|
||||
}
|
||||
})(this, function (_jQuery, _i18n) {
|
||||
'use strict';
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
var _i18n2 = _interopRequireDefault(_i18n);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
|
||||
_jQuery2.default.entwine('ss.tree', function ($) {
|
||||
$('.cms-tree').entwine({
|
||||
fromDocument: {
|
||||
'oncontext_show.vakata': function oncontext_showVakata(e) {
|
||||
this.adjustContextClass();
|
||||
}
|
||||
},
|
||||
adjustContextClass: function adjustContextClass() {
|
||||
var menus = $('#vakata-contextmenu').find("ul ul");
|
||||
menus.each(function (i) {
|
||||
var col = "1",
|
||||
count = $(menus[i]).find('li').length;
|
||||
|
||||
if (count > 20) {
|
||||
col = "3";
|
||||
} else if (count > 10) {
|
||||
col = "2";
|
||||
}
|
||||
|
||||
$(menus[i]).addClass('col-' + col).removeClass('right');
|
||||
$(menus[i]).find('li').on("mouseenter", function (e) {
|
||||
$(this).parent('ul').removeClass("right");
|
||||
});
|
||||
});
|
||||
},
|
||||
getTreeConfig: function getTreeConfig() {
|
||||
var self = this,
|
||||
config = this._super(),
|
||||
hints = this.getHints();
|
||||
|
||||
config.plugins.push('contextmenu');
|
||||
config.contextmenu = {
|
||||
'items': function items(node) {
|
||||
var menuitems = {
|
||||
'edit': {
|
||||
'label': _i18n2.default._t('Tree.EditPage', 'Edit page', 100, 'Used in the context menu when right-clicking on a page node in the CMS tree'),
|
||||
'action': function action(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(_i18n2.default.sprintf(self.data('urlEditpage'), obj.data('id')));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!node.hasClass('nochildren')) {
|
||||
menuitems['showaslist'] = {
|
||||
'label': _i18n2.default._t('Tree.ShowAsList'),
|
||||
'action': function action(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(self.data('urlListview') + '&ParentID=' + obj.data('id'), null, {
|
||||
tabState: {
|
||||
'pages-controller-cms-content': {
|
||||
'tabSelector': '.content-listview'
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var pagetype = node.data('pagetype'),
|
||||
id = node.data('id'),
|
||||
allowedChildren = node.find('>a .item').data('allowedchildren'),
|
||||
menuAllowedChildren = {},
|
||||
hasAllowedChildren = false;
|
||||
$.each(allowedChildren, function (klass, title) {
|
||||
hasAllowedChildren = true;
|
||||
menuAllowedChildren["allowedchildren-" + klass] = {
|
||||
'label': '<span class="jstree-pageicon"></span>' + title,
|
||||
'_class': 'class-' + klass,
|
||||
'action': function action(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel($.path.addSearchParams(_i18n2.default.sprintf(self.data('urlAddpage'), id, klass), self.data('extraParams')));
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if (hasAllowedChildren) {
|
||||
menuitems['addsubpage'] = {
|
||||
'label': _i18n2.default._t('Tree.AddSubPage', 'Add page under this page', 100, 'Used in the context menu when right-clicking on a page node in the CMS tree'),
|
||||
'submenu': menuAllowedChildren
|
||||
};
|
||||
}
|
||||
|
||||
menuitems['duplicate'] = {
|
||||
'label': _i18n2.default._t('Tree.Duplicate'),
|
||||
'submenu': [{
|
||||
'label': _i18n2.default._t('Tree.ThisPageOnly'),
|
||||
'action': function action(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel($.path.addSearchParams(_i18n2.default.sprintf(self.data('urlDuplicate'), obj.data('id')), self.data('extraParams')));
|
||||
}
|
||||
}, {
|
||||
'label': _i18n2.default._t('Tree.ThisPageAndSubpages'),
|
||||
'action': function action(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel($.path.addSearchParams(_i18n2.default.sprintf(self.data('urlDuplicatewithchildren'), obj.data('id')), self.data('extraParams')));
|
||||
}
|
||||
}]
|
||||
};
|
||||
return menuitems;
|
||||
}
|
||||
};
|
||||
return config;
|
||||
}
|
||||
});
|
||||
$('.cms-tree a.jstree-clicked').entwine({
|
||||
onmatch: function onmatch() {
|
||||
var self = this,
|
||||
panel = self.parents('.cms-panel-content'),
|
||||
scrollTo;
|
||||
|
||||
if (self.offset().top < 0 || self.offset().top > panel.height() - self.height()) {
|
||||
scrollTo = panel.scrollTop() + self.offset().top + panel.height() / 2;
|
||||
panel.animate({
|
||||
scrollTop: scrollTo
|
||||
}, 'slow');
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.cms-tree-filtered .clear-filter').entwine({
|
||||
onclick: function onclick() {
|
||||
window.location = location.protocol + '//' + location.host + location.pathname;
|
||||
}
|
||||
});
|
||||
$('.cms-tree-filtered').entwine({
|
||||
onmatch: function onmatch() {
|
||||
var self = this,
|
||||
setHeight = function setHeight() {
|
||||
var height = $('.cms-content-tools .cms-panel-content').height() - self.parent().siblings('.cms-content-toolbar').outerHeight(true);
|
||||
self.css('height', height + 'px');
|
||||
};
|
||||
|
||||
setHeight();
|
||||
$(window).on('resize', window.ss.debounce(setHeight, 300));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
94
javascript/dist/CMSMain.js
vendored
Normal file
94
javascript/dist/CMSMain.js
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define('ss.CMSMain', ['../../../framework/javascript/dist/jQuery'], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(require('../../../framework/javascript/dist/jQuery'));
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(global.jQuery);
|
||||
global.ssCMSMain = mod.exports;
|
||||
}
|
||||
})(this, function (_jQuery) {
|
||||
'use strict';
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
|
||||
_jQuery2.default.entwine('ss', function ($) {
|
||||
$('.cms-content-header-info').entwine({
|
||||
'from .cms-panel': {
|
||||
ontoggle: function ontoggle(e) {
|
||||
var $treeViewPanel = this.closest('.cms-content').find(e.target);
|
||||
|
||||
if ($treeViewPanel.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.parent()[$treeViewPanel.hasClass('collapsed') ? 'addClass' : 'removeClass']('collapsed');
|
||||
}
|
||||
}
|
||||
});
|
||||
$('.cms-content-toolbar').entwine({
|
||||
onmatch: function onmatch() {
|
||||
var self = this;
|
||||
|
||||
this._super();
|
||||
|
||||
$.each(this.find('.cms-actions-buttons-row .tool-button'), function () {
|
||||
var $button = $(this),
|
||||
toolId = $button.data('toolid'),
|
||||
isActive = $button.hasClass('active');
|
||||
|
||||
if (toolId !== void 0) {
|
||||
$button.data('active', false).removeClass('active');
|
||||
$('#' + toolId).hide();
|
||||
self.bindActionButtonEvents($button);
|
||||
}
|
||||
});
|
||||
},
|
||||
onunmatch: function onunmatch() {
|
||||
var self = this;
|
||||
|
||||
this._super();
|
||||
|
||||
$.each(this.find('.cms-actions-buttons-row .tool-button'), function () {
|
||||
var $button = $(this);
|
||||
self.unbindActionButtonEvents($button);
|
||||
});
|
||||
},
|
||||
bindActionButtonEvents: function bindActionButtonEvents($button) {
|
||||
var self = this;
|
||||
$button.on('click.cmsContentToolbar', function (e) {
|
||||
self.showHideTool($button);
|
||||
});
|
||||
},
|
||||
unbindActionButtonEvents: function unbindActionButtonEvents($button) {
|
||||
$button.off('.cmsContentToolbar');
|
||||
},
|
||||
showHideTool: function showHideTool($button) {
|
||||
var isActive = $button.data('active'),
|
||||
toolId = $button.data('toolid'),
|
||||
$action = $('#' + toolId);
|
||||
$.each(this.find('.cms-actions-buttons-row .tool-button'), function () {
|
||||
var $currentButton = $(this),
|
||||
$currentAction = $('#' + $currentButton.data('toolid'));
|
||||
|
||||
if ($currentButton.data('toolid') !== toolId) {
|
||||
$currentAction.hide();
|
||||
$currentButton.data('active', false);
|
||||
}
|
||||
});
|
||||
$button[isActive ? 'removeClass' : 'addClass']('active');
|
||||
$action[isActive ? 'hide' : 'show']();
|
||||
$button.data('active', !isActive);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
124
javascript/dist/CMSPageHistoryController.js
vendored
Normal file
124
javascript/dist/CMSPageHistoryController.js
vendored
Normal file
@ -0,0 +1,124 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define('ss.CMSPageHistoryController', ['../../../framework/javascript/dist/jQuery', '../../../framework/javascript/dist/i18n'], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(require('../../../framework/javascript/dist/jQuery'), require('../../../framework/javascript/dist/i18n'));
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(global.jQuery, global.i18n);
|
||||
global.ssCMSPageHistoryController = mod.exports;
|
||||
}
|
||||
})(this, function (_jQuery, _i18n) {
|
||||
'use strict';
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
var _i18n2 = _interopRequireDefault(_i18n);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
|
||||
_jQuery2.default.entwine('ss', function ($) {
|
||||
$('#Form_VersionsForm').entwine({
|
||||
onmatch: function onmatch() {
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function onunmatch() {
|
||||
this._super();
|
||||
},
|
||||
onsubmit: function onsubmit(e, d) {
|
||||
e.preventDefault();
|
||||
var id,
|
||||
self = this;
|
||||
id = this.find(':input[name=ID]').val();
|
||||
if (!id) return false;
|
||||
var button, url, selected, to, from, compare, data;
|
||||
compare = this.find(":input[name=CompareMode]").is(":checked");
|
||||
selected = this.find("table input[type=checkbox]").filter(":checked");
|
||||
|
||||
if (compare) {
|
||||
if (selected.length != 2) return false;
|
||||
to = selected.eq(0).val();
|
||||
from = selected.eq(1).val();
|
||||
button = this.find(':submit[name=action_doCompare]');
|
||||
url = _i18n2.default.sprintf(this.data('linkTmplCompare'), id, from, to);
|
||||
} else {
|
||||
to = selected.eq(0).val();
|
||||
button = this.find(':submit[name=action_doShowVersion]');
|
||||
url = _i18n2.default.sprintf(this.data('linkTmplShow'), id, to);
|
||||
}
|
||||
|
||||
$('.cms-container').loadPanel(url, '', {
|
||||
pjax: 'CurrentForm'
|
||||
});
|
||||
}
|
||||
});
|
||||
$('#Form_VersionsForm input[name=ShowUnpublished]').entwine({
|
||||
onmatch: function onmatch() {
|
||||
this.toggle();
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function onunmatch() {
|
||||
this._super();
|
||||
},
|
||||
onchange: function onchange() {
|
||||
this.toggle();
|
||||
},
|
||||
toggle: function toggle() {
|
||||
var self = $(this);
|
||||
var form = self.parents('form');
|
||||
|
||||
if (self.attr('checked')) {
|
||||
form.find('tr[data-published=false]').show();
|
||||
} else {
|
||||
form.find("tr[data-published=false]").hide()._unselect();
|
||||
}
|
||||
}
|
||||
});
|
||||
$("#Form_VersionsForm tbody tr").entwine({
|
||||
onclick: function onclick(e) {
|
||||
var compare, selected;
|
||||
compare = this.parents("form").find(':input[name=CompareMode]').attr("checked");
|
||||
selected = this.siblings(".active");
|
||||
|
||||
if (compare && this.hasClass('active')) {
|
||||
this._unselect();
|
||||
|
||||
return;
|
||||
} else if (compare) {
|
||||
if (selected.length > 1) {
|
||||
return alert(_i18n2.default._t('ONLYSELECTTWO', 'You can only compare two versions at this time.'));
|
||||
}
|
||||
|
||||
this._select();
|
||||
|
||||
if (selected.length == 1) {
|
||||
this.parents('form').submit();
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
this._select();
|
||||
|
||||
selected._unselect();
|
||||
|
||||
this.parents("form").submit();
|
||||
}
|
||||
},
|
||||
_unselect: function _unselect() {
|
||||
this.removeClass('active');
|
||||
this.find(":input[type=checkbox]").attr("checked", false);
|
||||
},
|
||||
_select: function _select() {
|
||||
this.addClass('active');
|
||||
this.find(":input[type=checkbox]").attr("checked", true);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
49
javascript/dist/RedirectorPage.js
vendored
Normal file
49
javascript/dist/RedirectorPage.js
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define('ss.RedirectorPage', ['../../../framework/javascript/dist/jQuery'], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(require('../../../framework/javascript/dist/jQuery'));
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(global.jQuery);
|
||||
global.ssRedirectorPage = mod.exports;
|
||||
}
|
||||
})(this, function (_jQuery) {
|
||||
'use strict';
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
|
||||
_jQuery2.default.entwine('ss', function ($) {
|
||||
$('#Form_EditForm_RedirectionType input').entwine({
|
||||
onmatch: function onmatch() {
|
||||
var self = $(this);
|
||||
if (self.attr('checked')) this.toggle();
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function onunmatch() {
|
||||
this._super();
|
||||
},
|
||||
onclick: function onclick() {
|
||||
this.toggle();
|
||||
},
|
||||
toggle: function toggle() {
|
||||
if ($(this).attr('value') == 'Internal') {
|
||||
$('#Form_EditForm_ExternalURL_Holder').hide();
|
||||
$('#Form_EditForm_LinkToID_Holder').show();
|
||||
} else {
|
||||
$('#Form_EditForm_ExternalURL_Holder').show();
|
||||
$('#Form_EditForm_LinkToID_Holder').hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
47
javascript/dist/SilverStripeNavigator.js
vendored
Normal file
47
javascript/dist/SilverStripeNavigator.js
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define('ss.SilverStripeNavigator', ['../../../framework/javascript/dist/jQuery'], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(require('../../../framework/javascript/dist/jQuery'));
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(global.jQuery);
|
||||
global.ssSilverStripeNavigator = mod.exports;
|
||||
}
|
||||
})(this, function (_jQuery) {
|
||||
'use strict';
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
|
||||
function windowName(suffix) {
|
||||
var base = document.getElementsByTagName('base')[0].href.replace('http://', '').replace(/\//g, '_').replace(/\./g, '_');
|
||||
return base + suffix;
|
||||
}
|
||||
|
||||
(0, _jQuery2.default)(document).ready(function () {
|
||||
(0, _jQuery2.default)('#switchView a.newWindow').on('click', function (e) {
|
||||
var w = window.open(this.href, windowName(this.target));
|
||||
w.focus();
|
||||
return false;
|
||||
});
|
||||
(0, _jQuery2.default)('#SilverStripeNavigatorLink').on('click', function (e) {
|
||||
(0, _jQuery2.default)('#SilverStripeNavigatorLinkPopup').toggle();
|
||||
return false;
|
||||
});
|
||||
(0, _jQuery2.default)('#SilverStripeNavigatorLinkPopup a.close').on('click', function (e) {
|
||||
(0, _jQuery2.default)('#SilverStripeNavigatorLinkPopup').hide();
|
||||
return false;
|
||||
});
|
||||
(0, _jQuery2.default)('#SilverStripeNavigatorLinkPopup input').on('focus', function (e) {
|
||||
this.select();
|
||||
});
|
||||
});
|
||||
});
|
119
javascript/dist/SiteTreeURLSegmentField.js
vendored
Normal file
119
javascript/dist/SiteTreeURLSegmentField.js
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
(function (global, factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
define('ss.SiteTreeURLSegmentField', ['../../../framework/javascript/dist/jQuery'], factory);
|
||||
} else if (typeof exports !== "undefined") {
|
||||
factory(require('../../../framework/javascript/dist/jQuery'));
|
||||
} else {
|
||||
var mod = {
|
||||
exports: {}
|
||||
};
|
||||
factory(global.jQuery);
|
||||
global.ssSiteTreeURLSegmentField = mod.exports;
|
||||
}
|
||||
})(this, function (_jQuery) {
|
||||
'use strict';
|
||||
|
||||
var _jQuery2 = _interopRequireDefault(_jQuery);
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
|
||||
_jQuery2.default.entwine('ss', function ($) {
|
||||
$('.field.urlsegment:not(.readonly)').entwine({
|
||||
MaxPreviewLength: 55,
|
||||
Ellipsis: '...',
|
||||
onmatch: function onmatch() {
|
||||
if (this.find(':text').length) this.toggleEdit(false);
|
||||
this.redraw();
|
||||
|
||||
this._super();
|
||||
},
|
||||
redraw: function redraw() {
|
||||
var field = this.find(':text'),
|
||||
url = decodeURI(field.data('prefix') + field.val()),
|
||||
previewUrl = url;
|
||||
|
||||
if (url.length > this.getMaxPreviewLength()) {
|
||||
previewUrl = this.getEllipsis() + url.substr(url.length - this.getMaxPreviewLength(), url.length);
|
||||
}
|
||||
|
||||
this.find('.preview').attr('href', encodeURI(url + field.data('suffix'))).text(previewUrl);
|
||||
},
|
||||
toggleEdit: function toggleEdit(toggle) {
|
||||
var field = this.find(':text');
|
||||
this.find('.preview-holder')[toggle ? 'hide' : 'show']();
|
||||
this.find('.edit-holder')[toggle ? 'show' : 'hide']();
|
||||
|
||||
if (toggle) {
|
||||
field.data("origval", field.val());
|
||||
field.focus();
|
||||
}
|
||||
},
|
||||
update: function update() {
|
||||
var self = this,
|
||||
field = this.find(':text'),
|
||||
currentVal = field.data('origval'),
|
||||
title = arguments[0],
|
||||
updateVal = title && title !== "" ? title : field.val();
|
||||
|
||||
if (currentVal != updateVal) {
|
||||
this.addClass('loading');
|
||||
this.suggest(updateVal, function (data) {
|
||||
field.val(decodeURIComponent(data.value));
|
||||
self.toggleEdit(false);
|
||||
self.removeClass('loading');
|
||||
self.redraw();
|
||||
});
|
||||
} else {
|
||||
this.toggleEdit(false);
|
||||
this.redraw();
|
||||
}
|
||||
},
|
||||
cancel: function cancel() {
|
||||
var field = this.find(':text');
|
||||
field.val(field.data("origval"));
|
||||
this.toggleEdit(false);
|
||||
},
|
||||
suggest: function suggest(val, callback) {
|
||||
var self = this,
|
||||
field = self.find(':text'),
|
||||
urlParts = $.path.parseUrl(self.closest('form').attr('action')),
|
||||
url = urlParts.hrefNoSearch + '/field/' + field.attr('name') + '/suggest/?value=' + encodeURIComponent(val);
|
||||
if (urlParts.search) url += '&' + urlParts.search.replace(/^\?/, '');
|
||||
$.ajax({
|
||||
url: url,
|
||||
success: function success(data) {
|
||||
callback.apply(this, arguments);
|
||||
},
|
||||
error: function error(xhr, status) {
|
||||
xhr.statusText = xhr.responseText;
|
||||
},
|
||||
complete: function complete() {
|
||||
self.removeClass('loading');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
$('.field.urlsegment .edit').entwine({
|
||||
onclick: function onclick(e) {
|
||||
e.preventDefault();
|
||||
this.closest('.field').toggleEdit(true);
|
||||
}
|
||||
});
|
||||
$('.field.urlsegment .update').entwine({
|
||||
onclick: function onclick(e) {
|
||||
e.preventDefault();
|
||||
this.closest('.field').update();
|
||||
}
|
||||
});
|
||||
$('.field.urlsegment .cancel').entwine({
|
||||
onclick: function onclick(e) {
|
||||
e.preventDefault();
|
||||
this.closest('.field').cancel();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
1
javascript/dist/bundle-lib.js
vendored
Normal file
1
javascript/dist/bundle-lib.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
!function t(e,n,i){function a(o,s){if(!n[o]){if(!e[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(r)return r(o,!0);var d=new Error("Cannot find module '"+o+"'");throw d.code="MODULE_NOT_FOUND",d}var c=n[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return a(n?n:t)},c,c.exports,t,e,n,i)}return n[o].exports}for(var r="function"==typeof require&&require,o=0;o<i.length;o++)a(i[o]);return a}({1:[function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}var a=t("../../../framework/javascript/dist/jQuery"),r=i(a);r["default"].entwine("ss",function(t){t(".cms-add-form .parent-mode :input").entwine({onclick:function(t){if("top"==this.val()){var e=this.closest("form").find("#Form_AddForm_ParentID_Holder .TreeDropdownField");e.setValue(""),e.setTitle("")}}}),t(".cms-add-form").entwine({ParentID:0,ParentCache:{},onadd:function(){var t=this;this.find("#Form_AddForm_ParentID_Holder .TreeDropdownField").bind("change",function(){t.updateTypeList()}),this.find(".SelectionGroup.parent-mode").bind("change",function(){t.updateTypeList()}),this.updateTypeList()},loadCachedChildren:function(t){var e=this.getParentCache();return"undefined"!=typeof e[t]?e[t]:null},saveCachedChildren:function(t,e){var n=this.getParentCache();n[t]=e,this.setParentCache(n)},updateTypeList:function(){var e=this.data("hints"),n=this.find("#Form_AddForm_ParentID_Holder .TreeDropdownField"),i=this.find("input[name=ParentModeField]:checked").val(),a=n.data("metadata"),r=a&&"child"===i?n.getValue()||this.getParentID():null,o=a?a.ClassName:null,s=o&&"child"===i?o:"Root",l="undefined"!=typeof e[s]?e[s]:null,d=this,c=l&&"undefined"!=typeof l.defaultChild?l.defaultChild:null,u=[];if(r){if(this.hasClass("loading"))return;return this.addClass("loading"),this.setParentID(r),n.getValue()||n.setValue(r),u=this.loadCachedChildren(r),null!==u?(this.updateSelectionFilter(u,c),void this.removeClass("loading")):(t.ajax({url:d.data("childfilter"),data:{ParentID:r},success:function(t){d.saveCachedChildren(r,t),d.updateSelectionFilter(t,c)},complete:function(){d.removeClass("loading")}}),!1)}u=l&&"undefined"!=typeof l.disallowedChildren?l.disallowedChildren:[],this.updateSelectionFilter(u,c)},updateSelectionFilter:function(e,n){var i=null;if(this.find("#Form_AddForm_PageType li").each(function(){var n=t(this).find("input").val(),a=-1===t.inArray(n,e);t(this).setEnabled(a),a||t(this).setSelected(!1),i=null===i?a:i&&a}),n)var a=this.find("#Form_AddForm_PageType li input[value="+n+"]").parents("li:first");else var a=this.find("#Form_AddForm_PageType li:not(.disabled):first");a.setSelected(!0),a.siblings().setSelected(!1);var r=this.find("#Form_AddForm_PageType li:not(.disabled)").length?"enable":"disable";this.find("button[name=action_doAdd]").button(r),this.find(".message-restricted")[i?"hide":"show"]()}}),t(".cms-add-form #Form_AddForm_PageType li").entwine({onclick:function(t){this.setSelected(!0)},setSelected:function(t){var e=this.find("input");t&&!e.is(":disabled")?(this.siblings().setSelected(!1),this.toggleClass("selected",!0),e.prop("checked",!0)):(this.toggleClass("selected",!1),e.prop("checked",!1))},setEnabled:function(e){t(this).toggleClass("disabled",!e),e?t(this).find("input").removeAttr("disabled"):t(this).find("input").attr("disabled","disabled").removeAttr("checked")}}),t(".cms-page-add-button").entwine({onclick:function(e){var n=t(".cms-tree"),i=t(".cms-list"),a=0;if(n.is(":visible")){var r=n.jstree("get_selected");a=r?t(r[0]).data("id"):null}else{var o=i.find('input[name="Page[GridState]"]').val();o&&(a=parseInt(JSON.parse(o).ParentID,10))}var s,l={selector:this.data("targetPanel"),pjax:this.data("pjax")};a?(extraParams=this.data("extraParams")?this.data("extraParams"):"",s=t.path.addSearchParams(i18n.sprintf(this.data("urlAddpage"),a),extraParams)):s=this.attr("href"),t(".cms-container").loadPanel(s,null,l),e.preventDefault(),this.blur()}})})},{"../../../framework/javascript/dist/jQuery":11}],2:[function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}var a=t("../../../framework/javascript/dist/jQuery"),r=i(a),o=t("../../../framework/javascript/dist/i18n"),s=i(o);r["default"].entwine("ss",function(t){t(".cms-edit-form :input[name=ClassName]").entwine({onchange:function(){alert(s["default"]._t("CMSMAIN.ALERTCLASSNAME"))}}),t(".cms-edit-form input[name=Title]").entwine({onmatch:function(){var e=this;e.data("OrigVal",e.val());var n=e.closest("form"),i=t("input:text[name=URLSegment]",n),a=t("input[name=LiveLink]",n);i.length>0&&(e._addActions(),this.bind("change",function(n){var r=e.data("OrigVal"),o=e.val();e.data("OrigVal",o),0===i.val().indexOf(i.data("defaultUrl"))&&""==a.val()?e.updateURLSegment(o):t(".update",e.parent()).show(),e.updateRelatedFields(o,r),e.updateBreadcrumbLabel(o)})),this._super()},onunmatch:function(){this._super()},updateRelatedFields:function(e,n){this.parents("form").find("input[name=MetaTitle], input[name=MenuTitle]").each(function(){var i=t(this);i.val()==n&&(i.val(e),i.updatedRelatedFields&&i.updatedRelatedFields())})},updateURLSegment:function(e){var n=t("input:text[name=URLSegment]",this.closest("form")),i=n.closest(".field.urlsegment"),a=t(".update",this.parent());i.update(e),a.is(":visible")&&a.hide()},updateBreadcrumbLabel:function(e){var n=(t(".cms-edit-form input[name=ID]").val(),t("span.cms-panel-link.crumb"));e&&""!=e&&n.text(e)},_addActions:function(){var e,n=this;e=t("<button />",{"class":"update ss-ui-button-small",text:s["default"]._t("URLSEGMENT.UpdateURL"),type:"button",click:function(t){t.preventDefault(),n.updateURLSegment(n.val())}}),e.insertAfter(n),e.hide()}}),t(".cms-edit-form .parentTypeSelector").entwine({onmatch:function(){var t=this;this.find(":input[name=ParentType]").bind("click",function(e){t._toggleSelection(e)}),this.find(".TreeDropdownField").bind("change",function(e){t._changeParentId(e)}),this._changeParentId(),this._toggleSelection(),this._super()},onunmatch:function(){this._super()},_toggleSelection:function(t){var e=this.find(":input[name=ParentType]:checked").val();"root"==e?this.find(":input[name=ParentID]").val(0):this.find(":input[name=ParentID]").val(this.find("#Form_EditForm_ParentType_subpage").data("parentIdValue")),this.find("#Form_EditForm_ParentID_Holder").toggle("root"!=e)},_changeParentId:function(t){var e=this.find(":input[name=ParentID]").val();this.find("#Form_EditForm_ParentType_subpage").data("parentIdValue",e)}}),t(".cms-edit-form #CanViewType, .cms-edit-form #CanEditType, .cms-edit-form #CanCreateTopLevelType").entwine({onmatch:function(){var e;"CanViewType"==this.attr("id")?e=t("#Form_EditForm_ViewerGroups_Holder"):"CanEditType"==this.attr("id")?e=t("#Form_EditForm_EditorGroups_Holder"):"CanCreateTopLevelType"==this.attr("id")&&(e=t("#Form_EditForm_CreateTopLevelGroups_Holder")),this.find(".optionset :input").bind("change",function(n){var i=t(this).closest(".middleColumn").parent("div");"OnlyTheseUsers"==n.target.value?(i.addClass("remove-splitter"),e.show()):(i.removeClass("remove-splitter"),e.hide())});var n=this.find("input[name="+this.attr("id")+"]:checked").val();e["OnlyTheseUsers"==n?"show":"hide"](),this._super()},onunmatch:function(){this._super()}}),t(".cms-edit-form .Actions #Form_EditForm_action_print").entwine({onclick:function(e){var n=t(this[0].form).attr("action").replace(/\?.*$/,"")+"/printable/"+t(":input[name=ID]",this[0].form).val();return"http://"!=n.substr(0,7)&&(n=t("base").attr("href")+n),window.open(n,"printable"),!1}}),t(".cms-edit-form .Actions #Form_EditForm_action_rollback").entwine({onclick:function(t){var e=this.parents("form:first"),n=e.find(":input[name=Version]").val(),i="";return i=n?s["default"].sprintf(s["default"]._t("CMSMain.RollbackToVersion"),n):s["default"]._t("CMSMain.ConfirmRestoreFromLive"),confirm(i)?this._super(t):!1}}),t(".cms-edit-form .Actions #Form_EditForm_action_archive").entwine({onclick:function(t){var e=this.parents("form:first"),n=e.find(":input[name=Version]").val(),i="";return i=s["default"].sprintf(s["default"]._t("CMSMain.Archive"),n),confirm(i)?this._super(t):!1}}),t(".cms-edit-form .Actions #Form_EditForm_action_restore").entwine({onclick:function(t){var e=this.parents("form:first"),n=e.find(":input[name=Version]").val(),i="",a=this.data("toRoot");return i=s["default"].sprintf(s["default"]._t(a?"CMSMain.RestoreToRoot":"CMSMain.Restore"),n),confirm(i)?this._super(t):!1}}),t(".cms-edit-form .Actions #Form_EditForm_action_delete").entwine({onclick:function(t){var e=this.parents("form:first"),n=e.find(":input[name=Version]").val(),i="";return i=s["default"].sprintf(s["default"]._t("CMSMain.DeleteFromDraft"),n),confirm(i)?this._super(t):!1}}),t(".cms-edit-form .Actions #Form_EditForm_action_unpublish").entwine({onclick:function(t){var e=this.parents("form:first"),n=e.find(":input[name=Version]").val(),i="";return i=s["default"].sprintf(s["default"]._t("CMSMain.Unpublish"),n),confirm(i)?this._super(t):!1}}),t(".cms-edit-form.changed").entwine({onmatch:function(t){this.find("button[name=action_save]").button("option","showingAlternate",!0),this.find("button[name=action_publish]").button("option","showingAlternate",!0),this._super(t)},onunmatch:function(t){var e=this.find("button[name=action_save]");e.data("button")&&e.button("option","showingAlternate",!1);var n=this.find("button[name=action_publish]");n.data("button")&&n.button("option","showingAlternate",!1),this._super(t)}}),t(".cms-edit-form .Actions button[name=action_publish]").entwine({onbuttonafterrefreshalternate:function(){this.button("option","showingAlternate")?this.addClass("ss-ui-action-constructive"):this.removeClass("ss-ui-action-constructive")}}),t(".cms-edit-form .Actions button[name=action_save]").entwine({onbuttonafterrefreshalternate:function(){this.button("option","showingAlternate")?this.addClass("ss-ui-action-constructive"):this.removeClass("ss-ui-action-constructive")}}),t('.cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked').entwine({onmatch:function(){this.redraw(),this._super()},onunmatch:function(){this._super()},redraw:function(){var e=t(".cms-edit-form.CMSPageSettingsController #Form_EditForm_ParentID_Holder");"Form_EditForm_ParentType_root"==t(this).attr("id")?e.slideUp():e.slideDown()},onclick:function(){this.redraw()}}),"Form_EditForm_ParentType_root"==t('.cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked').attr("id")&&t(".cms-edit-form.CMSPageSettingsController #Form_EditForm_ParentID_Holder").hide()})},{"../../../framework/javascript/dist/i18n":10,"../../../framework/javascript/dist/jQuery":11}],3:[function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}var a=t("../../../framework/javascript/dist/jQuery"),r=i(a),o=t("../../../framework/javascript/dist/i18n"),s=i(o);r["default"].entwine("ss.tree",function(t){t(".cms-tree").entwine({fromDocument:{"oncontext_show.vakata":function(t){this.adjustContextClass()}},adjustContextClass:function(){var e=t("#vakata-contextmenu").find("ul ul");e.each(function(n){var i="1",a=t(e[n]).find("li").length;a>20?i="3":a>10&&(i="2"),t(e[n]).addClass("col-"+i).removeClass("right"),t(e[n]).find("li").on("mouseenter",function(e){t(this).parent("ul").removeClass("right")})})},getTreeConfig:function(){var e=this,n=this._super();this.getHints();return n.plugins.push("contextmenu"),n.contextmenu={items:function(n){var i={edit:{label:s["default"]._t("Tree.EditPage","Edit page",100,"Used in the context menu when right-clicking on a page node in the CMS tree"),action:function(n){t(".cms-container").entwine(".ss").loadPanel(s["default"].sprintf(e.data("urlEditpage"),n.data("id")))}}};n.hasClass("nochildren")||(i.showaslist={label:s["default"]._t("Tree.ShowAsList"),action:function(n){t(".cms-container").entwine(".ss").loadPanel(e.data("urlListview")+"&ParentID="+n.data("id"),null,{tabState:{"pages-controller-cms-content":{tabSelector:".content-listview"}}})}});var a=(n.data("pagetype"),n.data("id")),r=n.find(">a .item").data("allowedchildren"),o={},l=!1;return t.each(r,function(n,i){l=!0,o["allowedchildren-"+n]={label:'<span class="jstree-pageicon"></span>'+i,_class:"class-"+n,action:function(i){t(".cms-container").entwine(".ss").loadPanel(t.path.addSearchParams(s["default"].sprintf(e.data("urlAddpage"),a,n),e.data("extraParams")))}}}),l&&(i.addsubpage={label:s["default"]._t("Tree.AddSubPage","Add page under this page",100,"Used in the context menu when right-clicking on a page node in the CMS tree"),submenu:o}),i.duplicate={label:s["default"]._t("Tree.Duplicate"),submenu:[{label:s["default"]._t("Tree.ThisPageOnly"),action:function(n){t(".cms-container").entwine(".ss").loadPanel(t.path.addSearchParams(s["default"].sprintf(e.data("urlDuplicate"),n.data("id")),e.data("extraParams")))}},{label:s["default"]._t("Tree.ThisPageAndSubpages"),action:function(n){t(".cms-container").entwine(".ss").loadPanel(t.path.addSearchParams(s["default"].sprintf(e.data("urlDuplicatewithchildren"),n.data("id")),e.data("extraParams")))}}]},i}},n}}),t(".cms-tree a.jstree-clicked").entwine({onmatch:function(){var t,e=this,n=e.parents(".cms-panel-content");(e.offset().top<0||e.offset().top>n.height()-e.height())&&(t=n.scrollTop()+e.offset().top+n.height()/2,n.animate({scrollTop:t},"slow"))}}),t(".cms-tree-filtered .clear-filter").entwine({onclick:function(){window.location=location.protocol+"//"+location.host+location.pathname}}),t(".cms-tree-filtered").entwine({onmatch:function(){var e=this,n=function(){var n=t(".cms-content-tools .cms-panel-content").height()-e.parent().siblings(".cms-content-toolbar").outerHeight(!0);e.css("height",n+"px")};n(),t(window).on("resize",window.ss.debounce(n,300))}})})},{"../../../framework/javascript/dist/i18n":10,"../../../framework/javascript/dist/jQuery":11}],4:[function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}var a=t("../../../framework/javascript/dist/jQuery"),r=i(a);r["default"].entwine("ss",function(t){t(".cms-content-header-info").entwine({"from .cms-panel":{ontoggle:function(t){var e=this.closest(".cms-content").find(t.target);0!==e.length&&this.parent()[e.hasClass("collapsed")?"addClass":"removeClass"]("collapsed")}}}),t(".cms-content-toolbar").entwine({onmatch:function(){var e=this;this._super(),t.each(this.find(".cms-actions-buttons-row .tool-button"),function(){var n=t(this),i=n.data("toolid");n.hasClass("active");void 0!==i&&(n.data("active",!1).removeClass("active"),t("#"+i).hide(),e.bindActionButtonEvents(n))})},onunmatch:function(){var e=this;this._super(),t.each(this.find(".cms-actions-buttons-row .tool-button"),function(){var n=t(this);e.unbindActionButtonEvents(n)})},bindActionButtonEvents:function(t){var e=this;t.on("click.cmsContentToolbar",function(n){e.showHideTool(t)})},unbindActionButtonEvents:function(t){t.off(".cmsContentToolbar")},showHideTool:function(e){var n=e.data("active"),i=e.data("toolid"),a=t("#"+i);t.each(this.find(".cms-actions-buttons-row .tool-button"),function(){var e=t(this),n=t("#"+e.data("toolid"));e.data("toolid")!==i&&(n.hide(),e.data("active",!1))}),e[n?"removeClass":"addClass"]("active"),a[n?"hide":"show"](),e.data("active",!n)}})})},{"../../../framework/javascript/dist/jQuery":11}],5:[function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}var a=t("../../../framework/javascript/dist/jQuery"),r=i(a),o=t("../../../framework/javascript/dist/i18n"),s=i(o);r["default"].entwine("ss",function(t){t("#Form_VersionsForm").entwine({onmatch:function(){this._super()},onunmatch:function(){this._super()},onsubmit:function(e,n){e.preventDefault();var i;if(i=this.find(":input[name=ID]").val(),!i)return!1;var a,r,o,l,d,c;if(c=this.find(":input[name=CompareMode]").is(":checked"),o=this.find("table input[type=checkbox]").filter(":checked"),c){if(2!=o.length)return!1;l=o.eq(0).val(),d=o.eq(1).val(),a=this.find(":submit[name=action_doCompare]"),r=s["default"].sprintf(this.data("linkTmplCompare"),i,d,l)}else l=o.eq(0).val(),a=this.find(":submit[name=action_doShowVersion]"),r=s["default"].sprintf(this.data("linkTmplShow"),i,l);t(".cms-container").loadPanel(r,"",{pjax:"CurrentForm"})}}),t("#Form_VersionsForm input[name=ShowUnpublished]").entwine({onmatch:function(){this.toggle(),this._super()},onunmatch:function(){this._super()},onchange:function(){this.toggle()},toggle:function(){var e=t(this),n=e.parents("form");e.attr("checked")?n.find("tr[data-published=false]").show():n.find("tr[data-published=false]").hide()._unselect()}}),t("#Form_VersionsForm tbody tr").entwine({onclick:function(t){var e,n;return e=this.parents("form").find(":input[name=CompareMode]").attr("checked"),n=this.siblings(".active"),e&&this.hasClass("active")?void this._unselect():e?n.length>1?alert(s["default"]._t("ONLYSELECTTWO","You can only compare two versions at this time.")):(this._select(),void(1==n.length&&this.parents("form").submit())):(this._select(),n._unselect(),this.parents("form").submit(),void 0)},_unselect:function(){this.removeClass("active"),this.find(":input[type=checkbox]").attr("checked",!1)},_select:function(){this.addClass("active"),this.find(":input[type=checkbox]").attr("checked",!0)}})})},{"../../../framework/javascript/dist/i18n":10,"../../../framework/javascript/dist/jQuery":11}],6:[function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}var a=t("../../../framework/javascript/dist/jQuery"),r=i(a);r["default"].entwine("ss",function(t){t("#Form_EditForm_RedirectionType input").entwine({onmatch:function(){var e=t(this);e.attr("checked")&&this.toggle(),this._super()},onunmatch:function(){this._super()},onclick:function(){this.toggle()},toggle:function(){"Internal"==t(this).attr("value")?(t("#Form_EditForm_ExternalURL_Holder").hide(),t("#Form_EditForm_LinkToID_Holder").show()):(t("#Form_EditForm_ExternalURL_Holder").show(),t("#Form_EditForm_LinkToID_Holder").hide())}})})},{"../../../framework/javascript/dist/jQuery":11}],7:[function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}function a(t){var e=document.getElementsByTagName("base")[0].href.replace("http://","").replace(/\//g,"_").replace(/\./g,"_");return e+t}var r=t("../../../framework/javascript/dist/jQuery"),o=i(r);(0,o["default"])(document).ready(function(){(0,o["default"])("#switchView a.newWindow").on("click",function(t){var e=window.open(this.href,a(this.target));return e.focus(),!1}),(0,o["default"])("#SilverStripeNavigatorLink").on("click",function(t){return(0,o["default"])("#SilverStripeNavigatorLinkPopup").toggle(),!1}),(0,o["default"])("#SilverStripeNavigatorLinkPopup a.close").on("click",function(t){return(0,o["default"])("#SilverStripeNavigatorLinkPopup").hide(),!1}),(0,o["default"])("#SilverStripeNavigatorLinkPopup input").on("focus",function(t){this.select()})})},{"../../../framework/javascript/dist/jQuery":11}],8:[function(t,e,n){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}var a=t("../../../framework/javascript/dist/jQuery"),r=i(a);r["default"].entwine("ss",function(t){t(".field.urlsegment:not(.readonly)").entwine({MaxPreviewLength:55,Ellipsis:"...",onmatch:function(){this.find(":text").length&&this.toggleEdit(!1),this.redraw(),this._super()},redraw:function(){var t=this.find(":text"),e=decodeURI(t.data("prefix")+t.val()),n=e;e.length>this.getMaxPreviewLength()&&(n=this.getEllipsis()+e.substr(e.length-this.getMaxPreviewLength(),e.length)),this.find(".preview").attr("href",encodeURI(e+t.data("suffix"))).text(n)},toggleEdit:function(t){var e=this.find(":text");this.find(".preview-holder")[t?"hide":"show"](),this.find(".edit-holder")[t?"show":"hide"](),t&&(e.data("origval",e.val()),e.focus())},update:function(){var t=this,e=this.find(":text"),n=e.data("origval"),i=arguments[0],a=i&&""!==i?i:e.val();n!=a?(this.addClass("loading"),this.suggest(a,function(n){e.val(decodeURIComponent(n.value)),t.toggleEdit(!1),t.removeClass("loading"),t.redraw()})):(this.toggleEdit(!1),this.redraw())},cancel:function(){var t=this.find(":text");t.val(t.data("origval")),this.toggleEdit(!1)},suggest:function(e,n){var i=this,a=i.find(":text"),r=t.path.parseUrl(i.closest("form").attr("action")),o=r.hrefNoSearch+"/field/"+a.attr("name")+"/suggest/?value="+encodeURIComponent(e);r.search&&(o+="&"+r.search.replace(/^\?/,"")),t.ajax({url:o,success:function(t){n.apply(this,arguments)},error:function(t,e){t.statusText=t.responseText},complete:function(){i.removeClass("loading")}})}}),t(".field.urlsegment .edit").entwine({onclick:function(t){t.preventDefault(),this.closest(".field").toggleEdit(!0)}}),t(".field.urlsegment .update").entwine({onclick:function(t){t.preventDefault(),this.closest(".field").update()}}),t(".field.urlsegment .cancel").entwine({onclick:function(t){t.preventDefault(),this.closest(".field").cancel()}})})},{"../../../framework/javascript/dist/jQuery":11}],9:[function(t,e,n){"use strict";t("../../src/CMSMain.AddForm.js"),t("../../src/CMSMain.EditForm.js"),t("../../src/CMSMain.js"),t("../../src/CMSMain.Tree.js"),t("../../src/CMSPageHistoryController.js"),t("../../src/RedirectorPage.js"),t("../../src/SilverStripeNavigator.js"),t("../../src/SiteTreeURLSegmentField.js")},{"../../src/CMSMain.AddForm.js":1,"../../src/CMSMain.EditForm.js":2,"../../src/CMSMain.Tree.js":3,"../../src/CMSMain.js":4,"../../src/CMSPageHistoryController.js":5,"../../src/RedirectorPage.js":6,"../../src/SilverStripeNavigator.js":7,"../../src/SiteTreeURLSegmentField.js":8}],10:[function(t,e,n){"use strict";!function(t,e){if("function"==typeof define&&define.amd)define("ss.i18n",["exports"],e);else if("undefined"!=typeof n)e(n);else{var i={exports:{}};e(i.exports),t.ssI18n=i.exports}}(void 0,function(t){function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function t(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}return function(e,n,i){return n&&t(e.prototype,n),i&&t(e,i),e}}(),i=function(){function t(){e(this,t),this.currentLocale=null,this.defaultLocale="en_US",this.lang={}}return n(t,[{key:"setLocale",value:function(t){this.currentLocale=t}},{key:"getLocale",value:function(){return null!==this.currentLocale?this.currentLocale:this.defaultLocale}},{key:"_t",value:function(t,e,n,i){var a=this.getLocale().replace(/_[\w]+/i,""),r=this.defaultLocale.replace(/_[\w]+/i,"");return this.lang&&this.lang[this.getLocale()]&&this.lang[this.getLocale()][t]?this.lang[this.getLocale()][t]:this.lang&&this.lang[a]&&this.lang[a][t]?this.lang[a][t]:this.lang&&this.lang[this.defaultLocale]&&this.lang[this.defaultLocale][t]?this.lang[this.defaultLocale][t]:this.lang&&this.lang[r]&&this.lang[r][t]?this.lang[r][t]:e?e:""}},{key:"addDictionary",value:function(t,e){"undefined"==typeof this.lang[t]&&(this.lang[t]={});for(var n in e)this.lang[t][n]=e[n]}},{key:"getDictionary",value:function(t){return this.lang[t]}},{key:"stripStr",value:function(t){return t.replace(/^\s*/,"").replace(/\s*$/,"")}},{key:"stripStrML",value:function(t){for(var e=t.split("\n"),n=0;n<e.length;n+=1)e[n]=stripStr(e[n]);return stripStr(e.join(" "))}},{key:"sprintf",value:function(t){for(var e=arguments.length,n=Array(e>1?e-1:0),i=1;e>i;i++)n[i-1]=arguments[i];if(0===n.length)return t;var a=new RegExp("(.?)(%s)","g"),r=0;return t.replace(a,function(t,e,i,a,o){return"%"===e?t:e+n[r+=1]})}},{key:"inject",value:function(t,e){var n=new RegExp("{([A-Za-z0-9_]*)}","g");return t.replace(n,function(t,n,i,a){return e[n]?e[n]:t})}},{key:"detectLocale",value:function(){var e,n;if(e=jQuery("body").attr("lang"),!e)for(var i=document.getElementsByTagName("meta"),a=0;a<i.length;a++)i[a].attributes["http-equiv"]&&"content-language"==i[a].attributes["http-equiv"].nodeValue.toLowerCase()&&(e=i[a].attributes.content.nodeValue);e||(e=this.defaultLocale);var r=e.match(/([^-|_]*)[-|_](.*)/);if(2==e.length){for(var o in t.lang)if(o.substr(0,2).toLowerCase()==e.toLowerCase()){n=o;break}}else r&&(n=r[1].toLowerCase()+"_"+r[2].toUpperCase());return n}},{key:"addEvent",value:function(t,e,n,i){return t.addEventListener?(t.addEventListener(e,n,i),!0):t.attachEvent?t.attachEvent("on"+e,n):void console.log("Handler could not be attached")}}]),t}(),a=new i;window.ss="undefined"!=typeof window.ss?window.ss:{},window.ss.i18n=window.i18n=a,t["default"]=a})},{}],11:[function(t,e,n){"use strict";!function(t,e){if("function"==typeof define&&define.amd)define("ss.jQuery",["exports"],e);else if("undefined"!=typeof n)e(n);else{var i={exports:{}};e(i.exports),t.ssJQuery=i.exports}}(void 0,function(t){Object.defineProperty(t,"__esModule",{value:!0});var e="undefined"!=typeof window.jQuery?window.jQuery:null;t["default"]=e})},{}]},{},[9]);
|
142
javascript/src/AssetAdmin.js
Normal file
142
javascript/src/AssetAdmin.js
Normal file
@ -0,0 +1,142 @@
|
||||
/**
|
||||
* File: AssetAdmin.js
|
||||
*/
|
||||
|
||||
import $ from '../../../framework/javascript/dist/jQuery';
|
||||
import i18n from '../../../framework/javascript/dist/i18n';
|
||||
|
||||
$.entwine('ss', function($){
|
||||
/**
|
||||
* Delete selected folders through "batch actions" tab.
|
||||
*/
|
||||
/* assets don't currently have batch actions; disabling for now
|
||||
$(document).ready(function() {
|
||||
$('#Form_BatchActionsForm').entwine('.ss.tree').register(
|
||||
// TODO Hardcoding of base URL
|
||||
'admin/assets/batchactions/delete',
|
||||
function(ids) {
|
||||
var confirmed = confirm(
|
||||
i18n.sprintf(
|
||||
i18n._t('AssetAdmin.BATCHACTIONSDELETECONFIRM'),
|
||||
ids.length
|
||||
)
|
||||
);
|
||||
return (confirmed) ? ids : false;
|
||||
}
|
||||
);
|
||||
});
|
||||
*/
|
||||
|
||||
/**
|
||||
* Load folder detail view via controller methods
|
||||
* rather than built-in GridField view (which is only geared towards showing files).
|
||||
*/
|
||||
$('.AssetAdmin.cms-edit-form .ss-gridfield-item').entwine({
|
||||
onclick: function(e) {
|
||||
// Let actions do their own thing
|
||||
if($(e.target).closest('.action').length) {
|
||||
this._super(e);
|
||||
return;
|
||||
}
|
||||
|
||||
var grid = this.closest('.ss-gridfield');
|
||||
if(this.data('class') == 'Folder') {
|
||||
var url = grid.data('urlFolderTemplate').replace('%s', this.data('id'));
|
||||
$('.cms-container').loadPanel(url);
|
||||
return false;
|
||||
}
|
||||
|
||||
this._super(e);
|
||||
}
|
||||
});
|
||||
|
||||
$('.AssetAdmin.cms-edit-form .ss-gridfield .col-buttons .action.gridfield-button-delete, .AssetAdmin.cms-edit-form .Actions button.action.action-delete').entwine({
|
||||
onclick: function(e) {
|
||||
var msg;
|
||||
if(this.closest('.ss-gridfield-item').data('class') == 'Folder') {
|
||||
msg = i18n._t('AssetAdmin.ConfirmDelete');
|
||||
} else {
|
||||
msg = i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE');
|
||||
}
|
||||
if(!confirm(msg)) return false;
|
||||
|
||||
this.getGridField().reload({data: [{name: this.attr('name'), value: this.val()}]});
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
$('.AssetAdmin.cms-edit-form :submit[name=action_delete]').entwine({
|
||||
onclick: function(e) {
|
||||
if(!confirm(i18n._t('AssetAdmin.ConfirmDelete'))) return false;
|
||||
else this._super(e);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Prompt for a new foldername, rather than using dedicated form.
|
||||
* Better usability, but less flexibility in terms of inputs and validation.
|
||||
* Mainly necessary because AssetAdmin->AddForm() returns don't play nicely
|
||||
* with the nested AssetAdmin->EditForm() DOM structures.
|
||||
*/
|
||||
$('.AssetAdmin .cms-add-folder-link').entwine({
|
||||
onclick: function(e) {
|
||||
var name = prompt(i18n._t('Folder.Name'));
|
||||
if(!name) return false;
|
||||
|
||||
this.closest('.cms-container').loadPanel(this.data('url') + '&Name=' + name);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: #Form_SyncForm
|
||||
*/
|
||||
$('#Form_SyncForm').entwine({
|
||||
|
||||
/**
|
||||
* Function: onsubmit
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onsubmit: function(e) {
|
||||
var button = jQuery(this).find(':submit:first');
|
||||
button.addClass('loading');
|
||||
$.ajax({
|
||||
url: jQuery(this).attr('action'),
|
||||
data: this.serializeArray(),
|
||||
success: function() {
|
||||
button.removeClass('loading');
|
||||
// reload current form and tree
|
||||
var currNode = $('.cms-tree')[0].firstSelected();
|
||||
if(currNode) {
|
||||
var url = $(currNode).find('a').attr('href');
|
||||
$('.cms-content').loadPanel(url);
|
||||
}
|
||||
$('.cms-tree')[0].setCustomURL('admin/assets/getsubtree');
|
||||
$('.cms-tree')[0].reload({onSuccess: function() {
|
||||
// TODO Reset current tree node
|
||||
}});
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Reload the gridfield to show the user the file has been added
|
||||
*/
|
||||
$('.AssetAdmin.cms-edit-form .ss-uploadfield-item-progress').entwine({
|
||||
onunmatch: function () {
|
||||
$('.AssetAdmin.cms-edit-form .ss-gridfield').reload();
|
||||
}
|
||||
});
|
||||
|
||||
$('.AssetAdmin .grid-levelup').entwine({
|
||||
onmatch: function () {
|
||||
this.closest('.ui-tabs-panel').find('.cms-actions-row').prepend(this);
|
||||
}
|
||||
})
|
||||
});
|
196
javascript/src/CMSMain.AddForm.js
Normal file
196
javascript/src/CMSMain.AddForm.js
Normal file
@ -0,0 +1,196 @@
|
||||
import $ from '../../../framework/javascript/dist/jQuery';
|
||||
|
||||
$.entwine('ss', function($){
|
||||
/**
|
||||
* Reset the parent node selection if the type is
|
||||
* set back to "toplevel page", to avoid submitting inconsistent state.
|
||||
*/
|
||||
$(".cms-add-form .parent-mode :input").entwine({
|
||||
onclick: function(e) {
|
||||
if(this.val() == 'top') {
|
||||
var parentField = this.closest('form').find('#Form_AddForm_ParentID_Holder .TreeDropdownField')
|
||||
parentField.setValue('');
|
||||
parentField.setTitle('');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(".cms-add-form").entwine({
|
||||
ParentID: 0, // Last selected parentID
|
||||
ParentCache: {}, // Cache allowed children for each selected page
|
||||
onadd: function() {
|
||||
var self = this;
|
||||
this.find('#Form_AddForm_ParentID_Holder .TreeDropdownField').bind('change', function() {
|
||||
self.updateTypeList();
|
||||
});
|
||||
this.find(".SelectionGroup.parent-mode").bind('change', function() {
|
||||
self.updateTypeList();
|
||||
});
|
||||
this.updateTypeList();
|
||||
},
|
||||
loadCachedChildren: function(parentID) {
|
||||
var cache = this.getParentCache();
|
||||
if(typeof cache[parentID] !== 'undefined') return cache[parentID];
|
||||
else return null;
|
||||
},
|
||||
saveCachedChildren: function(parentID, children) {
|
||||
var cache = this.getParentCache();
|
||||
cache[parentID] = children;
|
||||
this.setParentCache(cache);
|
||||
},
|
||||
/**
|
||||
* Limit page type selection based on parent selection.
|
||||
* Select of root classes is pre-computed, but selections with a given parent
|
||||
* are updated on-demand.
|
||||
* Similar implementation to LeftAndMain.Tree.js.
|
||||
*/
|
||||
updateTypeList: function() {
|
||||
var hints = this.data('hints'),
|
||||
parentTree = this.find('#Form_AddForm_ParentID_Holder .TreeDropdownField'),
|
||||
parentMode = this.find("input[name=ParentModeField]:checked").val(),
|
||||
metadata = parentTree.data('metadata'),
|
||||
id = (metadata && parentMode === 'child')
|
||||
? (parentTree.getValue() || this.getParentID())
|
||||
: null,
|
||||
newClassName = metadata ? metadata.ClassName : null,
|
||||
hintKey = (newClassName && parentMode === 'child')
|
||||
? newClassName
|
||||
: 'Root',
|
||||
hint = (typeof hints[hintKey] !== 'undefined') ? hints[hintKey] : null,
|
||||
self = this,
|
||||
defaultChildClass = (hint && typeof hint.defaultChild !== 'undefined')
|
||||
? hint.defaultChild
|
||||
: null,
|
||||
disallowedChildren = [];
|
||||
|
||||
if(id) {
|
||||
// Prevent interface operations
|
||||
if(this.hasClass('loading')) return;
|
||||
this.addClass('loading');
|
||||
|
||||
// Enable last parent ID to be re-selected from memory
|
||||
this.setParentID(id);
|
||||
if(!parentTree.getValue()) parentTree.setValue(id);
|
||||
|
||||
// Use cached data if available
|
||||
disallowedChildren = this.loadCachedChildren(id);
|
||||
if(disallowedChildren !== null) {
|
||||
this.updateSelectionFilter(disallowedChildren, defaultChildClass);
|
||||
this.removeClass('loading');
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: self.data('childfilter'),
|
||||
data: {'ParentID': id},
|
||||
success: function(data) {
|
||||
// reload current form and tree
|
||||
self.saveCachedChildren(id, data);
|
||||
self.updateSelectionFilter(data, defaultChildClass);
|
||||
},
|
||||
complete: function() {
|
||||
self.removeClass('loading');
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
} else {
|
||||
disallowedChildren = (hint && typeof hint.disallowedChildren !== 'undefined')
|
||||
? hint.disallowedChildren
|
||||
: [],
|
||||
this.updateSelectionFilter(disallowedChildren, defaultChildClass);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Update the selection filter with the given blacklist and default selection
|
||||
*
|
||||
* @param array disallowedChildren
|
||||
* @param string defaultChildClass
|
||||
*/
|
||||
updateSelectionFilter: function(disallowedChildren, defaultChildClass) {
|
||||
// Limit selection
|
||||
var allAllowed = null; // troolian
|
||||
this.find('#Form_AddForm_PageType li').each(function() {
|
||||
var className = $(this).find('input').val(),
|
||||
isAllowed = ($.inArray(className, disallowedChildren) === -1);
|
||||
|
||||
$(this).setEnabled(isAllowed);
|
||||
if(!isAllowed) $(this).setSelected(false);
|
||||
if(allAllowed === null) allAllowed = isAllowed;
|
||||
else allAllowed = allAllowed && isAllowed;
|
||||
});
|
||||
|
||||
// Set default child selection, or fall back to first available option
|
||||
if(defaultChildClass) {
|
||||
var selectedEl = this
|
||||
.find('#Form_AddForm_PageType li input[value=' + defaultChildClass + ']')
|
||||
.parents('li:first');
|
||||
} else {
|
||||
var selectedEl = this.find('#Form_AddForm_PageType li:not(.disabled):first');
|
||||
}
|
||||
selectedEl.setSelected(true);
|
||||
selectedEl.siblings().setSelected(false);
|
||||
|
||||
// Disable the "Create" button if none of the pagetypes are available
|
||||
var buttonState = this.find('#Form_AddForm_PageType li:not(.disabled)').length
|
||||
? 'enable'
|
||||
: 'disable';
|
||||
this.find('button[name=action_doAdd]').button(buttonState);
|
||||
|
||||
this.find('.message-restricted')[allAllowed ? 'hide' : 'show']();
|
||||
}
|
||||
});
|
||||
|
||||
$(".cms-add-form #Form_AddForm_PageType li").entwine({
|
||||
onclick: function(e) {
|
||||
this.setSelected(true);
|
||||
},
|
||||
setSelected: function(bool) {
|
||||
var input = this.find('input');
|
||||
if(bool && !input.is(':disabled')) {
|
||||
this.siblings().setSelected(false);
|
||||
this.toggleClass('selected', true);
|
||||
input.prop('checked', true);
|
||||
} else {
|
||||
this.toggleClass('selected', false);
|
||||
input.prop('checked', false);
|
||||
}
|
||||
},
|
||||
setEnabled: function(bool) {
|
||||
$(this).toggleClass('disabled', !bool);
|
||||
if(!bool) $(this).find('input').attr('disabled', 'disabled').removeAttr('checked');
|
||||
else $(this).find('input').removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
$(".cms-page-add-button").entwine({
|
||||
onclick: function(e) {
|
||||
var tree = $('.cms-tree'), list = $('.cms-list'), parentId = 0;
|
||||
|
||||
// Choose parent ID either from tree or list view, depending which is visible
|
||||
if(tree.is(':visible')) {
|
||||
var selected = tree.jstree('get_selected');
|
||||
parentId = selected ? $(selected[0]).data('id') : null;
|
||||
} else {
|
||||
var state = list.find('input[name="Page[GridState]"]').val();
|
||||
if(state) parentId = parseInt(JSON.parse(state).ParentID, 10);
|
||||
}
|
||||
|
||||
var data = {selector: this.data('targetPanel'),pjax: this.data('pjax')}, url;
|
||||
if(parentId) {
|
||||
extraParams = this.data('extraParams') ? this.data('extraParams') : '';
|
||||
url = $.path.addSearchParams(i18n.sprintf(this.data('urlAddpage'), parentId), extraParams);
|
||||
} else {
|
||||
url = this.attr('href');
|
||||
}
|
||||
|
||||
$('.cms-container').loadPanel(url, null, data);
|
||||
e.preventDefault();
|
||||
|
||||
// Remove focussed state from button
|
||||
this.blur();
|
||||
|
||||
// $('.cms-page-add-form-dialog').dialog('open');
|
||||
// e.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
471
javascript/src/CMSMain.EditForm.js
Normal file
471
javascript/src/CMSMain.EditForm.js
Normal file
@ -0,0 +1,471 @@
|
||||
|
||||
/**
|
||||
* File: CMSMain.EditForm.js
|
||||
*/
|
||||
import $ from '../../../framework/javascript/dist/jQuery';
|
||||
import i18n from '../../../framework/javascript/dist/i18n';
|
||||
|
||||
$.entwine('ss', function($){
|
||||
/**
|
||||
* Class: .cms-edit-form :input[name=ClassName]
|
||||
* Alert the user on change of page-type. This might have implications
|
||||
* on the available form fields etc.
|
||||
*/
|
||||
$('.cms-edit-form :input[name=ClassName]').entwine({
|
||||
// Function: onchange
|
||||
onchange: function() {
|
||||
alert(i18n._t('CMSMAIN.ALERTCLASSNAME'));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form input[name=Title]
|
||||
*
|
||||
* Input validation on the Title field
|
||||
*/
|
||||
$('.cms-edit-form input[name=Title]').entwine({
|
||||
// Constructor: onmatch
|
||||
onmatch : function() {
|
||||
var self = this;
|
||||
|
||||
self.data('OrigVal', self.val());
|
||||
|
||||
var form = self.closest('form');
|
||||
var urlSegmentInput = $('input:text[name=URLSegment]', form);
|
||||
var liveLinkInput = $('input[name=LiveLink]', form);
|
||||
|
||||
if (urlSegmentInput.length > 0) {
|
||||
self._addActions();
|
||||
this.bind('change', function(e) {
|
||||
var origTitle = self.data('OrigVal');
|
||||
var title = self.val();
|
||||
self.data('OrigVal', title);
|
||||
|
||||
// Criteria for defining a "new" page
|
||||
if (
|
||||
urlSegmentInput.val().indexOf(urlSegmentInput.data('defaultUrl')) === 0
|
||||
&& liveLinkInput.val() == ''
|
||||
) {
|
||||
self.updateURLSegment(title);
|
||||
} else {
|
||||
$('.update', self.parent()).show();
|
||||
}
|
||||
|
||||
self.updateRelatedFields(title, origTitle);
|
||||
self.updateBreadcrumbLabel(title);
|
||||
});
|
||||
}
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: updateRelatedFields
|
||||
*
|
||||
* Update the related fields if appropriate
|
||||
* (String) title The new title
|
||||
* (Stirng) origTitle The original title
|
||||
*/
|
||||
updateRelatedFields: function(title, origTitle) {
|
||||
// Update these fields only if their value was originally the same as the title
|
||||
this.parents('form').find('input[name=MetaTitle], input[name=MenuTitle]').each(function() {
|
||||
var $this = $(this);
|
||||
if($this.val() == origTitle) {
|
||||
$this.val(title);
|
||||
// Onchange bubbling didn't work in IE8, so .trigger('change') couldn't be used
|
||||
if($this.updatedRelatedFields) $this.updatedRelatedFields();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: updateURLSegment
|
||||
*
|
||||
* Update the URLSegment
|
||||
* (String) title
|
||||
*/
|
||||
updateURLSegment: function(title) {
|
||||
var urlSegmentInput = $('input:text[name=URLSegment]', this.closest('form'));
|
||||
var urlSegmentField = urlSegmentInput.closest('.field.urlsegment');
|
||||
var updateURLFromTitle = $('.update', this.parent());
|
||||
urlSegmentField.update(title);
|
||||
if (updateURLFromTitle.is(':visible')) {
|
||||
updateURLFromTitle.hide();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: updateBreadcrumbLabel
|
||||
*
|
||||
* Update the breadcrumb
|
||||
* (String) title
|
||||
*/
|
||||
updateBreadcrumbLabel: function(title) {
|
||||
var pageID = $('.cms-edit-form input[name=ID]').val();
|
||||
var panelCrumb = $('span.cms-panel-link.crumb');
|
||||
if (title && title != "") {
|
||||
panelCrumb.text(title);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _addActions
|
||||
*
|
||||
* Utility to add update from title action
|
||||
*
|
||||
*/
|
||||
_addActions: function() {
|
||||
var self = this;
|
||||
var updateURLFromTitle;
|
||||
|
||||
// update button
|
||||
updateURLFromTitle = $('<button />', {
|
||||
'class': 'update ss-ui-button-small',
|
||||
'text': i18n._t('URLSEGMENT.UpdateURL'),
|
||||
'type': 'button',
|
||||
'click': function(e) {
|
||||
e.preventDefault();
|
||||
self.updateURLSegment(self.val());
|
||||
}
|
||||
});
|
||||
|
||||
// insert elements
|
||||
updateURLFromTitle.insertAfter(self);
|
||||
updateURLFromTitle.hide();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .parentTypeSelector
|
||||
*
|
||||
* ParentID field combination - mostly toggling between
|
||||
* the two radiobuttons and setting the hidden "ParentID" field
|
||||
*/
|
||||
$('.cms-edit-form .parentTypeSelector').entwine({
|
||||
// Constructor: onmatch
|
||||
onmatch : function() {
|
||||
var self = this;
|
||||
this.find(':input[name=ParentType]').bind('click', function(e) {self._toggleSelection(e);});
|
||||
this.find('.TreeDropdownField').bind('change', function(e) {self._changeParentId(e);});
|
||||
|
||||
this._changeParentId();
|
||||
this._toggleSelection();
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _toggleSelection
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
_toggleSelection: function(e) {
|
||||
var selected = this.find(':input[name=ParentType]:checked').val();
|
||||
// reset parent id if 'root' radiobutton is selected
|
||||
if(selected == 'root') this.find(':input[name=ParentID]').val(0);
|
||||
// otherwise use the old value
|
||||
else this.find(':input[name=ParentID]').val(this.find('#Form_EditForm_ParentType_subpage').data('parentIdValue'));
|
||||
// toggle tree dropdown based on selection
|
||||
this.find('#Form_EditForm_ParentID_Holder').toggle(selected != 'root');
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _changeParentId
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
_changeParentId: function(e) {
|
||||
var value = this.find(':input[name=ParentID]').val();
|
||||
// set a data attribute so we know what to use in _toggleSelection
|
||||
this.find('#Form_EditForm_ParentType_subpage').data('parentIdValue', value);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form #CanViewType, .cms-edit-form #CanEditType
|
||||
*
|
||||
* Toggle display of group dropdown in "access" tab,
|
||||
* based on selection of radiobuttons.
|
||||
*/
|
||||
$('.cms-edit-form #CanViewType, .cms-edit-form #CanEditType, .cms-edit-form #CanCreateTopLevelType').entwine({
|
||||
// Constructor: onmatch
|
||||
onmatch: function() {
|
||||
// TODO Decouple
|
||||
var dropdown;
|
||||
if(this.attr('id') == 'CanViewType') dropdown = $('#Form_EditForm_ViewerGroups_Holder');
|
||||
else if(this.attr('id') == 'CanEditType') dropdown = $('#Form_EditForm_EditorGroups_Holder');
|
||||
else if(this.attr('id') == 'CanCreateTopLevelType') dropdown = $('#Form_EditForm_CreateTopLevelGroups_Holder');
|
||||
|
||||
this.find('.optionset :input').bind('change', function(e) {
|
||||
var wrapper = $(this).closest('.middleColumn').parent('div');
|
||||
if(e.target.value == 'OnlyTheseUsers') {
|
||||
wrapper.addClass('remove-splitter');
|
||||
dropdown['show']();
|
||||
}
|
||||
else {
|
||||
wrapper.removeClass('remove-splitter');
|
||||
dropdown['hide']();
|
||||
}
|
||||
});
|
||||
|
||||
// initial state
|
||||
var currentVal = this.find('input[name=' + this.attr('id') + ']:checked').val();
|
||||
dropdown[currentVal == 'OnlyTheseUsers' ? 'show' : 'hide']();
|
||||
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_print
|
||||
*
|
||||
* Open a printable representation of the form in a new window.
|
||||
* Used for readonly older versions of a specific page.
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_print').entwine({
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var printURL = $(this[0].form).attr('action').replace(/\?.*$/,'')
|
||||
+ '/printable/'
|
||||
+ $(':input[name=ID]',this[0].form).val();
|
||||
if(printURL.substr(0,7) != 'http://') printURL = $('base').attr('href') + printURL;
|
||||
|
||||
window.open(printURL, 'printable');
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_rollback
|
||||
*
|
||||
* A "rollback" to a specific version needs user confirmation.
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_rollback').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
if(version) {
|
||||
message = i18n.sprintf(
|
||||
i18n._t('CMSMain.RollbackToVersion'),
|
||||
version
|
||||
);
|
||||
} else {
|
||||
message = i18n._t('CMSMain.ConfirmRestoreFromLive');
|
||||
}
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_archive
|
||||
*
|
||||
* Informing the user about the archive action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_archive').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
message = i18n.sprintf(
|
||||
i18n._t('CMSMain.Archive'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_restore
|
||||
*
|
||||
* Informing the user about the archive action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_restore').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'),
|
||||
version = form.find(':input[name=Version]').val(),
|
||||
message = '',
|
||||
toRoot = this.data('toRoot');
|
||||
message = i18n.sprintf(
|
||||
i18n._t(toRoot ? 'CMSMain.RestoreToRoot' : 'CMSMain.Restore'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_delete
|
||||
*
|
||||
* Informing the user about the delete from draft action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_delete').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
message = i18n.sprintf(
|
||||
i18n._t('CMSMain.DeleteFromDraft'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form .Actions #Form_EditForm_action_unpublish
|
||||
* Informing the user about the unpublish action while requiring confirmation
|
||||
*/
|
||||
$('.cms-edit-form .Actions #Form_EditForm_action_unpublish').entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Parameters:
|
||||
* (Event) e
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var form = this.parents('form:first'), version = form.find(':input[name=Version]').val(), message = '';
|
||||
message = i18n.sprintf(
|
||||
i18n._t('CMSMain.Unpublish'),
|
||||
version
|
||||
);
|
||||
if(confirm(message)) {
|
||||
return this._super(e);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Enable save buttons upon detecting changes to content.
|
||||
* "changed" class is added by jQuery.changetracker.
|
||||
*/
|
||||
$('.cms-edit-form.changed').entwine({
|
||||
onmatch: function(e) {
|
||||
this.find('button[name=action_save]').button('option', 'showingAlternate', true);
|
||||
this.find('button[name=action_publish]').button('option', 'showingAlternate', true);
|
||||
this._super(e);
|
||||
},
|
||||
onunmatch: function(e) {
|
||||
var saveButton = this.find('button[name=action_save]');
|
||||
if(saveButton.data('button')) saveButton.button('option', 'showingAlternate', false);
|
||||
var publishButton = this.find('button[name=action_publish]');
|
||||
if(publishButton.data('button')) publishButton.button('option', 'showingAlternate', false);
|
||||
this._super(e);
|
||||
}
|
||||
});
|
||||
|
||||
$('.cms-edit-form .Actions button[name=action_publish]').entwine({
|
||||
/**
|
||||
* Bind to ssui.button event to trigger stylistic changes.
|
||||
*/
|
||||
onbuttonafterrefreshalternate: function() {
|
||||
if (this.button('option', 'showingAlternate')) {
|
||||
this.addClass('ss-ui-action-constructive');
|
||||
}
|
||||
else {
|
||||
this.removeClass('ss-ui-action-constructive');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.cms-edit-form .Actions button[name=action_save]').entwine({
|
||||
/**
|
||||
* Bind to ssui.button event to trigger stylistic changes.
|
||||
*/
|
||||
onbuttonafterrefreshalternate: function() {
|
||||
if (this.button('option', 'showingAlternate')) {
|
||||
this.addClass('ss-ui-action-constructive');
|
||||
}
|
||||
else {
|
||||
this.removeClass('ss-ui-action-constructive');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: .cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked
|
||||
*
|
||||
* Showing the "Page location" "Parent page" chooser only when the "Sub-page underneath a parent page"
|
||||
* radio button is selected
|
||||
*/
|
||||
$('.cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked').entwine({
|
||||
onmatch: function() {
|
||||
this.redraw();
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
redraw: function() {
|
||||
var treeField = $('.cms-edit-form.CMSPageSettingsController #Form_EditForm_ParentID_Holder');
|
||||
if ($(this).attr('id') == 'Form_EditForm_ParentType_root') treeField.slideUp();
|
||||
else treeField.slideDown();
|
||||
},
|
||||
onclick: function() {
|
||||
this.redraw();
|
||||
}
|
||||
});
|
||||
|
||||
//trigger an initial change event to do the initial hiding of the element, if necessary
|
||||
if ($('.cms-edit-form.CMSPageSettingsController input[name="ParentType"]:checked').attr('id') == 'Form_EditForm_ParentType_root') {
|
||||
$('.cms-edit-form.CMSPageSettingsController #Form_EditForm_ParentID_Holder').hide(); //quick hide on first run
|
||||
}
|
||||
});
|
175
javascript/src/CMSMain.Tree.js
Normal file
175
javascript/src/CMSMain.Tree.js
Normal file
@ -0,0 +1,175 @@
|
||||
import $ from '../../../framework/javascript/dist/jQuery';
|
||||
import i18n from '../../../framework/javascript/dist/i18n';
|
||||
|
||||
$.entwine('ss.tree', function($){
|
||||
$('.cms-tree').entwine({
|
||||
fromDocument: {
|
||||
'oncontext_show.vakata': function(e){
|
||||
this.adjustContextClass();
|
||||
}
|
||||
},
|
||||
/*
|
||||
* Add and remove classes from context menus to allow for
|
||||
* adjusting the display
|
||||
*/
|
||||
adjustContextClass: function(){
|
||||
var menus = $('#vakata-contextmenu').find("ul ul");
|
||||
|
||||
menus.each(function(i){
|
||||
var col = "1",
|
||||
count = $(menus[i]).find('li').length;
|
||||
|
||||
//Assign columns to menus over 10 items long
|
||||
if(count > 20){
|
||||
col = "3";
|
||||
}else if(count > 10){
|
||||
col = "2";
|
||||
}
|
||||
|
||||
$(menus[i]).addClass('col-' + col).removeClass('right');
|
||||
|
||||
//Remove "right" class that jstree adds on mouseenter
|
||||
$(menus[i]).find('li').on("mouseenter", function (e) {
|
||||
$(this).parent('ul').removeClass("right");
|
||||
});
|
||||
});
|
||||
},
|
||||
getTreeConfig: function() {
|
||||
var self = this, config = this._super(), hints = this.getHints();
|
||||
config.plugins.push('contextmenu');
|
||||
config.contextmenu = {
|
||||
'items': function(node) {
|
||||
|
||||
var menuitems = {
|
||||
'edit': {
|
||||
'label': i18n._t('Tree.EditPage', 'Edit page', 100, 'Used in the context menu when right-clicking on a page node in the CMS tree'),
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(i18n.sprintf(
|
||||
self.data('urlEditpage'), obj.data('id')
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Add "show as list"
|
||||
if(!node.hasClass('nochildren')) {
|
||||
menuitems['showaslist'] = {
|
||||
'label': i18n._t('Tree.ShowAsList'),
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(
|
||||
self.data('urlListview') + '&ParentID=' + obj.data('id'),
|
||||
null,
|
||||
// Default to list view tab
|
||||
{tabState: {'pages-controller-cms-content': {'tabSelector': '.content-listview'}}}
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Build a list for allowed children as submenu entries
|
||||
var pagetype = node.data('pagetype'),
|
||||
id = node.data('id'),
|
||||
allowedChildren = node.find('>a .item').data('allowedchildren'),
|
||||
menuAllowedChildren = {},
|
||||
hasAllowedChildren = false;
|
||||
|
||||
// Convert to menu entries
|
||||
$.each(allowedChildren, function(klass, title){
|
||||
hasAllowedChildren = true;
|
||||
menuAllowedChildren["allowedchildren-" + klass ] = {
|
||||
'label': '<span class="jstree-pageicon"></span>' + title,
|
||||
'_class': 'class-' + klass,
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(
|
||||
$.path.addSearchParams(
|
||||
i18n.sprintf(self.data('urlAddpage'), id, klass),
|
||||
self.data('extraParams')
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
if(hasAllowedChildren) {
|
||||
menuitems['addsubpage'] = {
|
||||
'label': i18n._t('Tree.AddSubPage', 'Add page under this page', 100, 'Used in the context menu when right-clicking on a page node in the CMS tree'),
|
||||
'submenu': menuAllowedChildren
|
||||
};
|
||||
}
|
||||
|
||||
menuitems['duplicate'] = {
|
||||
'label': i18n._t('Tree.Duplicate'),
|
||||
'submenu': [
|
||||
{
|
||||
'label': i18n._t('Tree.ThisPageOnly'),
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(
|
||||
$.path.addSearchParams(
|
||||
i18n.sprintf(self.data('urlDuplicate'), obj.data('id')),
|
||||
self.data('extraParams')
|
||||
)
|
||||
);
|
||||
}
|
||||
},{
|
||||
'label': i18n._t('Tree.ThisPageAndSubpages'),
|
||||
'action': function(obj) {
|
||||
$('.cms-container').entwine('.ss').loadPanel(
|
||||
$.path.addSearchParams(
|
||||
i18n.sprintf(self.data('urlDuplicatewithchildren'), obj.data('id')),
|
||||
self.data('extraParams')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return menuitems;
|
||||
}
|
||||
};
|
||||
return config;
|
||||
}
|
||||
});
|
||||
|
||||
// Scroll tree down to context of the current page, if it isn't
|
||||
// already visible
|
||||
$('.cms-tree a.jstree-clicked').entwine({
|
||||
onmatch: function(){
|
||||
var self = this,
|
||||
panel = self.parents('.cms-panel-content'),
|
||||
scrollTo;
|
||||
|
||||
if(self.offset().top < 0 ||
|
||||
self.offset().top > panel.height() - self.height()) {
|
||||
// Current scroll top + our current offset top is our
|
||||
// position in the panel
|
||||
scrollTo = panel.scrollTop() + self.offset().top
|
||||
+ (panel.height() / 2);
|
||||
|
||||
panel.animate({
|
||||
scrollTop: scrollTo
|
||||
}, 'slow');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Clear filters button
|
||||
$('.cms-tree-filtered .clear-filter').entwine({
|
||||
onclick: function () {
|
||||
window.location = location.protocol + '//' + location.host + location.pathname;
|
||||
}
|
||||
});
|
||||
|
||||
$('.cms-tree-filtered').entwine({
|
||||
onmatch: function () {
|
||||
var self = this,
|
||||
setHeight = function () {
|
||||
var height = $('.cms-content-tools .cms-panel-content').height() - self.parent().siblings('.cms-content-toolbar').outerHeight(true);
|
||||
self.css('height', height + 'px');
|
||||
};
|
||||
|
||||
setHeight();
|
||||
$(window).on('resize', window.ss.debounce(setHeight, 300));
|
||||
}
|
||||
});
|
||||
});
|
111
javascript/src/CMSMain.js
Normal file
111
javascript/src/CMSMain.js
Normal file
@ -0,0 +1,111 @@
|
||||
import $ from '../../../framework/javascript/dist/jQuery';
|
||||
|
||||
/**
|
||||
* Behaviour for the CMS Content Toolbar.
|
||||
* Applies to tools on top-level views i.e. '/admin/pages' and '/admin/assets' and
|
||||
* their corresponding tools in the SiteTree panel.
|
||||
* An example is 'bulk actions' on the Pages view.
|
||||
*/
|
||||
$.entwine('ss', function ($) {
|
||||
|
||||
// Faux three column layout
|
||||
$('.cms-content-header-info').entwine({
|
||||
'from .cms-panel': {
|
||||
// Keep the header info's width synced with the TreeView panel's width.
|
||||
ontoggle: function (e) {
|
||||
var $treeViewPanel = this.closest('.cms-content').find(e.target);
|
||||
|
||||
if ($treeViewPanel.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.parent()[$treeViewPanel.hasClass('collapsed') ? 'addClass' : 'removeClass']('collapsed');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('.cms-content-toolbar').entwine({
|
||||
|
||||
onmatch: function () {
|
||||
var self = this;
|
||||
|
||||
this._super();
|
||||
|
||||
// Initialise the buttons
|
||||
$.each(this.find('.cms-actions-buttons-row .tool-button'), function () {
|
||||
var $button = $(this),
|
||||
toolId = $button.data('toolid'),
|
||||
isActive = $button.hasClass('active');
|
||||
|
||||
// We don't care about tools that don't have a related 'action'.
|
||||
if (toolId !== void 0) {
|
||||
// Set the tool to its closed state.
|
||||
$button.data('active', false).removeClass('active');
|
||||
$('#' + toolId).hide();
|
||||
|
||||
self.bindActionButtonEvents($button);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onunmatch: function () {
|
||||
var self = this;
|
||||
|
||||
this._super();
|
||||
|
||||
$.each(this.find('.cms-actions-buttons-row .tool-button'), function () {
|
||||
var $button = $(this);
|
||||
self.unbindActionButtonEvents($button);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @func bindActionButtonEvents
|
||||
* @param {object} $button
|
||||
* @desc Add event handlers in the '.cmsContentToolbar' namespace.
|
||||
*/
|
||||
bindActionButtonEvents: function ($button) {
|
||||
var self = this;
|
||||
|
||||
$button.on('click.cmsContentToolbar', function (e) {
|
||||
self.showHideTool($button);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @func unbindActionButtonEvents
|
||||
* @param {object} $button
|
||||
* @desc Remove all event handlers in the '.cmsContentToolbar' namespace.
|
||||
*/
|
||||
unbindActionButtonEvents: function ($button) {
|
||||
$button.off('.cmsContentToolbar');
|
||||
},
|
||||
|
||||
/**
|
||||
* @func showTool
|
||||
* @param {object} $button
|
||||
* @desc Show a tool in the tools row. Hides all other tools.
|
||||
*/
|
||||
showHideTool: function ($button) {
|
||||
var isActive = $button.data('active'),
|
||||
toolId = $button.data('toolid'),
|
||||
$action = $('#' + toolId);
|
||||
|
||||
// Hide all tools except the one passed as a param,
|
||||
// which gets handled separately.
|
||||
$.each(this.find('.cms-actions-buttons-row .tool-button'), function () {
|
||||
var $currentButton = $(this),
|
||||
$currentAction = $('#' + $currentButton.data('toolid'));
|
||||
|
||||
if ($currentButton.data('toolid') !== toolId) {
|
||||
$currentAction.hide();
|
||||
$currentButton.data('active', false);
|
||||
}
|
||||
});
|
||||
|
||||
$button[isActive ? 'removeClass' : 'addClass']('active');
|
||||
$action[isActive ? 'hide' : 'show']();
|
||||
$button.data('active', !isActive);
|
||||
}
|
||||
});
|
||||
});
|
178
javascript/src/CMSPageHistoryController.js
Normal file
178
javascript/src/CMSPageHistoryController.js
Normal file
@ -0,0 +1,178 @@
|
||||
import $ from '../../../framework/javascript/dist/jQuery';
|
||||
import i18n from '../../../framework/javascript/dist/i18n';
|
||||
|
||||
/**
|
||||
* File: CMSPageHistoryController.js
|
||||
*
|
||||
* Handles related interactions between the version selection form on the
|
||||
* left hand side of the panel and the version displaying on the right
|
||||
* hand side.
|
||||
*/
|
||||
|
||||
$.entwine('ss', function($){
|
||||
|
||||
/**
|
||||
* Class: #Form_VersionsForm
|
||||
*
|
||||
* The left hand side version selection form is the main interface for
|
||||
* users to select a version to view, or to compare two versions
|
||||
*/
|
||||
$('#Form_VersionsForm').entwine({
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
onmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
/**
|
||||
* Function: submit.
|
||||
*
|
||||
* Submits either the compare versions form or the view single form
|
||||
* display based on whether we have two or 1 option selected
|
||||
*
|
||||
* Todo:
|
||||
* Handle coupling to admin url
|
||||
*/
|
||||
onsubmit: function(e, d) {
|
||||
e.preventDefault();
|
||||
|
||||
var id, self = this;
|
||||
|
||||
id = this.find(':input[name=ID]').val();
|
||||
|
||||
if(!id) return false;
|
||||
|
||||
var button, url, selected, to, from, compare, data;
|
||||
|
||||
compare = (this.find(":input[name=CompareMode]").is(":checked"));
|
||||
selected = this.find("table input[type=checkbox]").filter(":checked");
|
||||
|
||||
if(compare) {
|
||||
if(selected.length != 2) return false;
|
||||
|
||||
to = selected.eq(0).val();
|
||||
from = selected.eq(1).val();
|
||||
button = this.find(':submit[name=action_doCompare]');
|
||||
url = i18n.sprintf(this.data('linkTmplCompare'), id,from,to);
|
||||
}
|
||||
else {
|
||||
to = selected.eq(0).val();
|
||||
button = this.find(':submit[name=action_doShowVersion]');
|
||||
url = i18n.sprintf(this.data('linkTmplShow'), id,to);
|
||||
}
|
||||
|
||||
$('.cms-container').loadPanel(url, '', {pjax: 'CurrentForm'});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: :input[name=ShowUnpublished]
|
||||
*
|
||||
* Used for toggling whether to show or hide unpublished versions.
|
||||
*/
|
||||
$('#Form_VersionsForm input[name=ShowUnpublished]').entwine({
|
||||
onmatch: function() {
|
||||
this.toggle();
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
/**
|
||||
* Event: :input[name=ShowUnpublished] change
|
||||
*
|
||||
* Changing the show unpublished checkbox toggles whether to show
|
||||
* or hide the unpublished versions. Because those rows may be being
|
||||
* compared this also ensures those rows are unselected.
|
||||
*/
|
||||
onchange: function() {
|
||||
this.toggle();
|
||||
},
|
||||
toggle: function() {
|
||||
var self = $(this);
|
||||
var form = self.parents('form');
|
||||
|
||||
if(self.attr('checked')) {
|
||||
form.find('tr[data-published=false]').show();
|
||||
} else {
|
||||
form.find("tr[data-published=false]").hide()._unselect();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Class: #Form_VersionsForm tr
|
||||
*
|
||||
* An individual row in the versions form. Selecting the row updates
|
||||
* the edit form depending on whether we're showing individual version
|
||||
* information or displaying comparsion.
|
||||
*/
|
||||
$("#Form_VersionsForm tbody tr").entwine({
|
||||
|
||||
/**
|
||||
* Function: onclick
|
||||
*
|
||||
* Selects or deselects the row (if in compare mode). Will trigger
|
||||
* an update of the edit form if either selected (in single mode)
|
||||
* or if this is the second row selected (in compare mode)
|
||||
*/
|
||||
onclick: function(e) {
|
||||
var compare, selected;
|
||||
|
||||
// compare mode
|
||||
compare = this.parents("form").find(':input[name=CompareMode]').attr("checked");
|
||||
selected = this.siblings(".active");
|
||||
|
||||
if(compare && this.hasClass('active')) {
|
||||
this._unselect();
|
||||
|
||||
return;
|
||||
}
|
||||
else if(compare) {
|
||||
// check if we have already selected more than two.
|
||||
if(selected.length > 1) {
|
||||
return alert(i18n._t('ONLYSELECTTWO', 'You can only compare two versions at this time.'));
|
||||
}
|
||||
|
||||
this._select();
|
||||
|
||||
// if this is the second selected then we can compare.
|
||||
if(selected.length == 1) {
|
||||
this.parents('form').submit();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
this._select();
|
||||
selected._unselect();
|
||||
|
||||
this.parents("form").submit();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _unselect()
|
||||
*
|
||||
* Unselects the row from the form selection.
|
||||
*/
|
||||
_unselect: function() {
|
||||
this.removeClass('active');
|
||||
this.find(":input[type=checkbox]").attr("checked", false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _select()
|
||||
*
|
||||
* Selects the currently matched row in the form selection
|
||||
*/
|
||||
_select: function() {
|
||||
this.addClass('active');
|
||||
this.find(":input[type=checkbox]").attr("checked", true);
|
||||
}
|
||||
|
||||
});
|
||||
});
|
27
javascript/src/RedirectorPage.js
Normal file
27
javascript/src/RedirectorPage.js
Normal file
@ -0,0 +1,27 @@
|
||||
import $ from '../../../framework/javascript/dist/jQuery';
|
||||
|
||||
$.entwine('ss', function($){
|
||||
$('#Form_EditForm_RedirectionType input').entwine({
|
||||
onmatch: function() {
|
||||
var self = $(this);
|
||||
if(self.attr('checked')) this.toggle();
|
||||
this._super();
|
||||
},
|
||||
onunmatch: function() {
|
||||
this._super();
|
||||
},
|
||||
onclick: function() {
|
||||
this.toggle();
|
||||
},
|
||||
toggle: function() {
|
||||
if($(this).attr('value') == 'Internal') {
|
||||
$('#Form_EditForm_ExternalURL_Holder').hide();
|
||||
$('#Form_EditForm_LinkToID_Holder').show();
|
||||
} else {
|
||||
$('#Form_EditForm_ExternalURL_Holder').show();
|
||||
$('#Form_EditForm_LinkToID_Holder').hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
29
javascript/src/SilverStripeNavigator.js
Normal file
29
javascript/src/SilverStripeNavigator.js
Normal file
@ -0,0 +1,29 @@
|
||||
import $ from '../../../framework/javascript/dist/jQuery';
|
||||
|
||||
function windowName(suffix) {
|
||||
var base = document.getElementsByTagName('base')[0].href.replace('http://','').replace(/\//g,'_').replace(/\./g,'_');
|
||||
return base + suffix;
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
$('#switchView a.newWindow').on('click', function(e) {
|
||||
var w = window.open(this.href, windowName(this.target));
|
||||
w.focus();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#SilverStripeNavigatorLink').on('click', function(e) {
|
||||
$('#SilverStripeNavigatorLinkPopup').toggle();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#SilverStripeNavigatorLinkPopup a.close').on('click', function(e) {
|
||||
$('#SilverStripeNavigatorLinkPopup').hide();
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#SilverStripeNavigatorLinkPopup input').on('focus',function(e) {
|
||||
this.select();
|
||||
});
|
||||
});
|
137
javascript/src/SiteTreeURLSegmentField.js
Normal file
137
javascript/src/SiteTreeURLSegmentField.js
Normal file
@ -0,0 +1,137 @@
|
||||
import $ from '../../../framework/javascript/dist/jQuery';
|
||||
|
||||
$.entwine('ss', function($) {
|
||||
/**
|
||||
* Class: .field.urlsegment
|
||||
*
|
||||
* Provides enhanced functionality (read-only/edit switch) and
|
||||
* input validation on the URLSegment field
|
||||
*/
|
||||
$('.field.urlsegment:not(.readonly)').entwine({
|
||||
|
||||
// Roughly matches the field width including edit button
|
||||
MaxPreviewLength: 55,
|
||||
|
||||
Ellipsis: '...',
|
||||
|
||||
onmatch : function() {
|
||||
// Only initialize the field if it contains an editable field.
|
||||
// This ensures we don't get bogus previews on readonly fields.
|
||||
if(this.find(':text').length) this.toggleEdit(false);
|
||||
this.redraw();
|
||||
|
||||
this._super();
|
||||
},
|
||||
|
||||
redraw: function() {
|
||||
var field = this.find(':text'),
|
||||
url = decodeURI(field.data('prefix') + field.val()),
|
||||
previewUrl = url;
|
||||
|
||||
// Truncate URL if required (ignoring the suffix, retaining the full value)
|
||||
if(url.length > this.getMaxPreviewLength()) {
|
||||
previewUrl = this.getEllipsis() + url.substr(url.length - this.getMaxPreviewLength(), url.length);
|
||||
}
|
||||
|
||||
// Transfer current value to holder
|
||||
this.find('.preview').attr('href', encodeURI(url + field.data('suffix'))).text(previewUrl);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param Boolean
|
||||
*/
|
||||
toggleEdit: function(toggle) {
|
||||
var field = this.find(':text');
|
||||
|
||||
this.find('.preview-holder')[toggle ? 'hide' : 'show']();
|
||||
this.find('.edit-holder')[toggle ? 'show' : 'hide']();
|
||||
|
||||
if(toggle) {
|
||||
field.data("origval", field.val()); //retain current value for cancel
|
||||
field.focus();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Commits the change of the URLSegment to the field
|
||||
* Optional: pass in (String) to update the URLSegment
|
||||
*/
|
||||
update: function() {
|
||||
var self = this,
|
||||
field = this.find(':text'),
|
||||
currentVal = field.data('origval'),
|
||||
title = arguments[0],
|
||||
updateVal = (title && title !== "") ? title : field.val();
|
||||
|
||||
if (currentVal != updateVal) {
|
||||
this.addClass('loading');
|
||||
this.suggest(updateVal, function(data) {
|
||||
field.val(decodeURIComponent(data.value));
|
||||
self.toggleEdit(false);
|
||||
self.removeClass('loading');
|
||||
self.redraw();
|
||||
});
|
||||
} else {
|
||||
this.toggleEdit(false);
|
||||
this.redraw();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancels any changes to the field
|
||||
*/
|
||||
cancel: function() {
|
||||
var field = this.find(':text');
|
||||
field.val(field.data("origval"));
|
||||
this.toggleEdit(false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return a value matching the criteria.
|
||||
*
|
||||
* @param (String)
|
||||
* @param (Function)
|
||||
*/
|
||||
suggest: function(val, callback) {
|
||||
var self = this,
|
||||
field = self.find(':text'),
|
||||
urlParts = $.path.parseUrl(self.closest('form').attr('action')),
|
||||
url = urlParts.hrefNoSearch + '/field/' + field.attr('name') + '/suggest/?value=' + encodeURIComponent(val);
|
||||
if(urlParts.search) url += '&' + urlParts.search.replace(/^\?/, '');
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
success: function(data) {
|
||||
callback.apply(this, arguments);
|
||||
},
|
||||
error: function(xhr, status) {
|
||||
xhr.statusText = xhr.responseText;
|
||||
},
|
||||
complete: function() {
|
||||
self.removeClass('loading');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('.field.urlsegment .edit').entwine({
|
||||
onclick: function(e) {
|
||||
e.preventDefault();
|
||||
this.closest('.field').toggleEdit(true);
|
||||
}
|
||||
});
|
||||
|
||||
$('.field.urlsegment .update').entwine({
|
||||
onclick: function(e) {
|
||||
e.preventDefault();
|
||||
this.closest('.field').update();
|
||||
}
|
||||
});
|
||||
|
||||
$('.field.urlsegment .cancel').entwine({
|
||||
onclick: function(e) {
|
||||
e.preventDefault();
|
||||
this.closest('.field').cancel();
|
||||
}
|
||||
});
|
||||
});
|
8
javascript/src/bundles/lib.js
Normal file
8
javascript/src/bundles/lib.js
Normal file
@ -0,0 +1,8 @@
|
||||
require('../../src/CMSMain.AddForm.js');
|
||||
require('../../src/CMSMain.EditForm.js');
|
||||
require('../../src/CMSMain.js');
|
||||
require('../../src/CMSMain.Tree.js');
|
||||
require('../../src/CMSPageHistoryController.js');
|
||||
require('../../src/RedirectorPage.js');
|
||||
require('../../src/SilverStripeNavigator.js');
|
||||
require('../../src/SiteTreeURLSegmentField.js');
|
47
package.json
Normal file
47
package.json
Normal file
@ -0,0 +1,47 @@
|
||||
{
|
||||
"name": "silverstripe-cms",
|
||||
"version": "4.0.0",
|
||||
"description": "The SilverStripe CMS",
|
||||
"directories": {
|
||||
"test": "tests"
|
||||
},
|
||||
"engines": {
|
||||
"node": "~4.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp build"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/silverstripe/silverstripe-cms.git"
|
||||
},
|
||||
"keywords": [
|
||||
"silverstripe",
|
||||
"cms"
|
||||
],
|
||||
"author": "SilverStripe Ltd",
|
||||
"license": "BSD-3-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/silverstripe/silverstripe-cms/issues"
|
||||
},
|
||||
"homepage": "https://github.com/silverstripe/silverstripe-cms#readme",
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.4.0",
|
||||
"babel-plugin-transform-es2015-modules-umd": "^6.4.0",
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babelify": "^7.2.0",
|
||||
"browserify": "^13.0.0",
|
||||
"event-stream": "^3.3.2",
|
||||
"glob": "^6.0.4",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-babel": "^6.1.1",
|
||||
"gulp-diff": "^1.0.0",
|
||||
"gulp-notify": "^2.2.0",
|
||||
"gulp-uglify": "^1.5.1",
|
||||
"gulp-util": "^3.0.7",
|
||||
"semver": "^5.1.0",
|
||||
"vinyl-buffer": "^1.0.0",
|
||||
"vinyl-source-stream": "^1.1.0",
|
||||
"watchify": "^3.7.0"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user