Skip to content

Commit

Permalink
Completely refactored and restructured.
Browse files Browse the repository at this point in the history
Now use $.event.special to override jQuery function only when there
are bound mutation events.
  • Loading branch information
jollytoad committed May 7, 2009
1 parent aaf66d0 commit 515ad17
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 1 deletion.
61 changes: 61 additions & 0 deletions src/mutations.attr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* jQuery.attr Mutation Events
*
* Copyright (c) 2009 Adaptavist.com Ltd
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* Author: Mark Gibson (jollytoad at gmail dot com)
*/
(jQuery.mutations && (function($) {

$.mutations.register({
// The event type triggered after a mutation,
// "pre-" is prepended to this for the pre-mutation event.
type: 'attr',

// The blacklist can hold attributes that should never trigger an event
blacklist: {},

// Hook into jQuery when an event of this type is first bound
setup: function() {
var attr = $.attr,
blacklist = this.blacklist,
trigger = $.mutations.trigger;

// Save the original $.attr function
this.original = attr;


// Override $.attr
$.attr = function( elem, name, newValue, silent ) {
var prevValue = attr(elem, name);

if ( newValue === undefined ) {
return prevValue;
}

if ( silent || blacklist[name] ) {

return attr(elem, name, newValue);

} else if ( ""+newValue !== ""+prevValue ) {

return trigger( elem, 'attr', name, prevValue, newValue === "" ? undefined : newValue,
function( event ) {
attr( event.target, event.attrName, event.newValue );
}
);
}
};
},

// Remove hooks once all events of this type have been unbound
teardown: function() {
$.attr = this.original;
delete this.original;
}
});

})(jQuery));

94 changes: 94 additions & 0 deletions src/mutations.core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*!
* jQuery Mutation Events
*
* Copyright (c) 2009 Adaptavist.com Ltd
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* Author: Mark Gibson (jollytoad at gmail dot com)
*/
(jQuery.mutations || (function($) {

var m;
m = $.mutations = {

REMOVAL: 3,
ADDITION: 2,
MODIFICATION: 1,

// Construct a new mutation event
event: function( eventType, attrName, prevValue, newValue ) {
var event = new $.Event( eventType );

// Add MutationEvent fields
event.attrName = attrName;
event.newValue = newValue;
event.prevValue = prevValue;

event.attrChange =
newValue === null || newValue === undefined ? m.REMOVAL :
prevValue === null || prevValue === undefined ? m.ADDITION :
m.MODIFICATION;

return event;
},

// Trigger a pre and post mutation event, the pre mutation handlers may
// cancel the mutation using event.preventDefault(), it may also modify
// the mutation by setting the event fields.
trigger: function( elem, eventType, attrName, prevValue, newValue, commit ) {
var event = m.event('pre-' + eventType, attrName, prevValue, newValue),
ret;

// console.log('trigger %s %s: %o -> %o %o', event.type, event.attrName, event.prevValue, event.newValue, elem);

$.event.trigger( event, undefined, elem );

if ( !event.isDefaultPrevented() ) {
event.type = eventType;
ret = commit(event);
$.event.trigger( event, undefined, event.target );
}

return ret;
},

type: {},

// Register a new mutation event
register: function( opts ) {
m.type[opts.type] = opts;

// Track how many bindings we have for this event type
opts.usage = 0;

// Register the pre/post mutation event types as special event type
// so we can hook into jQuery on the first binding of this type
$.event.special['pre-'+opts.type] =
$.event.special[opts.type] = {

add: function() {
// Call the setup on the first binding
if ( !opts.usage++ ) {
opts.setup();
}
},

remove: function() {
// Call teardown when last binding is removed
if ( !--opts.usage ) {
opts.teardown();
}
}
};
},

unregister: function( type ) {
delete $.event.special['pre-'+type];
delete $.event.special[type];
delete this[type];
}
};

})(jQuery));

3 changes: 2 additions & 1 deletion test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
<!-- Includes -->
<script type="text/javascript" src="include/jquery.js"></script>
<script type="text/javascript" src="qunit/testrunner.js"></script>
<script type="text/javascript" src="../src/jquery.mutations.js"></script>
<script type="text/javascript" src="../src/mutations.core.js"></script>
<script type="text/javascript" src="../src/mutations.attr.js"></script>
<script type="text/javascript" src="unit/attr.js"></script>
<script type="text/javascript" src="unit/data.js"></script>
</head>
Expand Down

0 comments on commit 515ad17

Please sign in to comment.