BUG Fix several issues around onmatch/onunmatch entwines.

1. Add missing _super calls.

2. Make UI widget destroys more consistent to avoid exceptions.
Selectable would throw an exception in the GridField.js if destroy
called from onunmatch - at that stage jQuery UI would have had called
the destroy already. Add a guard, and change to onremove, which triggers
before the element is removed from DOM.

3. DOM traversal fails after the element is removed from DOM.
Onunmatch triggers after the removal of the element from the DOM, which
makes DOM traversal fail. Use onremove instead, which triggers while the
element is still in DOM.
This commit is contained in:
Mateusz Uzdowski 2014-07-14 11:15:38 +12:00
parent c26df0b3c6
commit b34aaca2e8
10 changed files with 46 additions and 31 deletions

View File

@ -11,6 +11,8 @@
*/
$(".cms .field.cms-description-tooltip").entwine({
onmatch: function() {
this._super();
var descriptionEl = this.find('.description'), inputEl, tooltipEl;
if(descriptionEl.length) {
this
@ -19,8 +21,8 @@
.tooltip({content: descriptionEl.html()});
descriptionEl.remove();
}
}
});
},
});
$(".cms .field.cms-description-tooltip :input").entwine({
onfocusin: function(e) {

View File

@ -517,7 +517,8 @@
});
$('.cms-edit-form').entwine({
onadd: function() {
onadd: function() {
this._super();
$('.cms-preview')._initialiseFromContent();
}
});

View File

@ -948,8 +948,8 @@ jQuery.noConflict();
setTimeout(function() {
form.clickedButton = null;
}, 10);
}
});
}
});
this.redraw();
this._super();

View File

@ -1,6 +1,6 @@
(function($) {
$.entwine('ss', function($){
$('.memberdatetimeoptionset').entwine({
onmatch: function() {
this.find('.description .toggle-content').hide();

View File

@ -8,7 +8,7 @@
*/
reload: function(ajaxOpts, successCallback) {
var self = this, form = this.closest('form'),
var self = this, form = this.closest('form'),
focusedElName = this.find(':input:focus').attr('name'), // Save focused element for restoring after refresh
data = form.find(':input').serializeArray();
@ -23,7 +23,7 @@
ajaxOpts.data = window.location.search.replace(/^\?/, '') + '&' + $.param(ajaxOpts.data);
}
// For browsers which do not support history.pushState like IE9, ss framework uses hash to track
// For browsers which do not support history.pushState like IE9, ss framework uses hash to track
// the current location for PJAX, so for them we pass the query string stored in the hash instead
if(!window.history || !window.history.pushState){
if(window.location.hash && window.location.hash.indexOf('?') != -1){
@ -48,15 +48,15 @@
// multiple relationships via keyboard.
if(focusedElName) self.find(':input[name="' + focusedElName + '"]').focus();
// Update filter
// Update filter
if(self.find('.filter-header').length) {
var content;
if(ajaxOpts.data[0].filter=="show") {
content = '<span class="non-sortable"></span>';
self.addClass('show-filter').find('.filter-header').show();
self.addClass('show-filter').find('.filter-header').show();
} else {
content = '<button name="showFilter" class="ss-gridfield-button-filter trigger"></button>';
self.removeClass('show-filter').find('.filter-header').hide();
self.removeClass('show-filter').find('.filter-header').hide();
}
self.find('.sortable-header th:last').html(content);
@ -104,7 +104,7 @@
$('.ss-gridfield :button[name=showFilter]').entwine({
onclick: function(e) {
onclick: function(e) {
$('.filter-header')
.show('slow') // animate visibility
.find(':input:first').focus(); // focus first search field
@ -198,11 +198,13 @@
$('.ss-gridfield-print-iframe').entwine({
onmatch: function(){
this._super();
this.hide().bind('load', function() {
this.focus();
var ifWin = this.contentWindow || this;
ifWin.print();
});;
});
},
onunmatch: function() {
this._super();
@ -268,15 +270,15 @@
}
});
$('.ss-gridfield[data-selectable] .ss-gridfield-items').entwine({
onmatch: function() {
onadd: function() {
this._super();
// TODO Limit to single selection
this.selectable();
},
onunmatch: function() {
onremove: function() {
this._super();
this.selectable('destroy');
if (this.data('selectable')) this.selectable('destroy');
}
});

View File

@ -959,6 +959,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
$('form.htmleditorfield-form.htmleditorfield-mediaform input.remoteurl').entwine({
onadd: function() {
this._super();
this.validate();
},

View File

@ -12,7 +12,7 @@
this._super();
},
onremove: function() {
if(this.data('uiTabs')) this.tabs('destroy');
if(this.data('tabs')) this.tabs('destroy');
this._super();
},
redrawTabs: function() {
@ -32,7 +32,7 @@
if(!matches) return;
$(this).attr('href', document.location.href.replace(/#.*/, '') + matches[0]);
});
}
}
});
});
})(jQuery);

View File

@ -2,15 +2,16 @@
$.entwine('ss', function($){
$('.ss-toggle').entwine({
onadd: function() {
this._super();
this.accordion({
collapsible: true,
active: (this.hasClass("ss-toggle-start-closed")) ? false : 0
});
this._super();
},
onremove: function() {
this.accordion('destroy');
if (this.data('accordion')) this.accordion('destroy');
this._super();
},
getTabSet: function() {

View File

@ -423,11 +423,13 @@
$('.TreeDropdownField input[type=hidden]').entwine({
onadd: function() {
this._super();
this.bind('change.TreeDropdownField', function() {
$(this).getField().updateTitle();
});
},
onremove: function() {
this._super();
this.unbind('.TreeDropdownField');
}
});

View File

@ -328,11 +328,11 @@
}
});
$('div.ss-upload .ss-uploadfield-files .ss-uploadfield-item').entwine({
onmatch: function() {
onadd: function() {
this._super();
this.closest('.ss-upload').find('.ss-uploadfield-addfile').addClass('borderTop');
},
onunmatch: function() {
onremove: function() {
$('.ss-uploadfield-files:not(:has(.ss-uploadfield-item))').closest('.ss-upload').find('.ss-uploadfield-addfile').removeClass('borderTop');
this._super();
}
@ -365,19 +365,25 @@
if(config.changeDetection) {
this.closest('form').trigger('dirty');
}
fileupload._trigger('destroy', e, {
context: item,
url: this.data('href'),
type: 'get',
dataType: fileupload.options.dataType
});
if (fileupload) {
fileupload._trigger('destroy', e, {
context: item,
url: this.data('href'),
type: 'get',
dataType: fileupload.options.dataType
});
}
}
} else {
// Removed files will be applied to object on save
if(config.changeDetection) {
this.closest('form').trigger('dirty');
}
fileupload._trigger('destroy', e, {context: item});
if (fileupload) {
fileupload._trigger('destroy', e, {context: item});
}
}
e.preventDefault(); // Avoid a form submit