8889841cjs/attrchange.js000064400000010520150513452710007637 0ustar00/* A simple jQuery function that can add listeners on attribute change. http://meetselva.github.io/attrchange/ About License: Copyright (C) 2013-2014 Selvakumar Arumugam You may use attrchange plugin under the terms of the MIT Licese. https://github.com/meetselva/attrchange/blob/master/MIT-License.txt */ (function($) { function isDOMAttrModifiedSupported() { var p = document.createElement('p'); var flag = false; if (p.addEventListener) { p.addEventListener('DOMAttrModified', function() { flag = true }, false); } else if (p.attachEvent) { p.attachEvent('onDOMAttrModified', function() { flag = true }); } else { return false; } p.setAttribute('id', 'target'); return flag; } function checkAttributes(chkAttr, e) { if (chkAttr) { var attributes = this.data('attr-old-value'); if (e.attributeName.indexOf('style') >= 0) { if (!attributes['style']) attributes['style'] = {}; //initialize var keys = e.attributeName.split('.'); e.attributeName = keys[0]; e.oldValue = attributes['style'][keys[1]]; //old value e.newValue = keys[1] + ':' + this.prop("style")[$.camelCase(keys[1])]; //new value attributes['style'][keys[1]] = e.newValue; } else { e.oldValue = attributes[e.attributeName]; e.newValue = this.attr(e.attributeName); attributes[e.attributeName] = e.newValue; } this.data('attr-old-value', attributes); //update the old value object } } //initialize Mutation Observer var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; $.fn.attrchange = function(a, b) { if (typeof a == 'object') {//core var cfg = { trackValues : false, callback : $.noop }; //backward compatibility if (typeof a === "function") { cfg.callback = a; } else { $.extend(cfg, a); } if (cfg.trackValues) { //get attributes old value this.each(function(i, el) { var attributes = {}; for ( var attr, i = 0, attrs = el.attributes, l = attrs.length; i < l; i++) { attr = attrs.item(i); attributes[attr.nodeName] = attr.value; } $(this).data('attr-old-value', attributes); }); } if (MutationObserver) { //Modern Browsers supporting MutationObserver var mOptions = { subtree : false, attributes : true, attributeOldValue : cfg.trackValues }; var observer = new MutationObserver(function(mutations) { mutations.forEach(function(e) { var _this = e.target; //get new value if trackValues is true if (cfg.trackValues) { e.newValue = $(_this).attr(e.attributeName); } if (typeof $(this).data('attrchange-tdisconnect') === 'undefined') { //disconnected logically cfg.callback.call(_this, e); } }); }); return this.data('attrchange-method', 'Mutation Observer') .data('attrchange-obs', observer).each(function() { observer.observe(this, mOptions); }); } else if (isDOMAttrModifiedSupported()) { //Opera //Good old Mutation Events return this.data('attrchange-method', 'DOMAttrModified').on('DOMAttrModified', function(event) { if (event.originalEvent) { event = event.originalEvent; }//jQuery normalization is not required event.attributeName = event.attrName; //property names to be consistent with MutationObserver event.oldValue = event.prevValue; //property names to be consistent with MutationObserver if (typeof $(this).data('attrchange-tdisconnect') === 'undefined') { //disconnected logically cfg.callback.call(this, event); } }); } else if ('onpropertychange' in document.body) { //works only in IE return this.data('attrchange-method', 'propertychange').on('propertychange', function(e) { e.attributeName = window.event.propertyName; //to set the attr old value checkAttributes.call($(this), cfg.trackValues, e); if (typeof $(this).data('attrchange-tdisconnect') === 'undefined') { //disconnected logically cfg.callback.call(this, e); } }); } return this; } else if (typeof a == 'string' && $.fn.attrchange.hasOwnProperty('extensions') && $.fn.attrchange['extensions'].hasOwnProperty(a)) { //extensions/options return $.fn.attrchange['extensions'][a].call(this, b); } } })(jQuery);js/attrchange_ext.js000064400000011303150513452710010517 0ustar00/* An extension for attrchange jQuery plugin http://meetselva.github.io/attrchange/ About License: Copyright (C) 2013-2014 Selvakumar Arumugam You may use attrchange ext plugin under the terms of the MIT Licese. https://github.com/meetselva/attrchange/blob/master/MIT-License.txt */ $.fn.attrchange.extensions = { /*attrchange option/extension*/ disconnect: function (o) { if (typeof o !== 'undefined' && o.isPhysicalDisconnect) { return this.each(function() { var attrchangeMethod = $(this).data('attrchange-method'); if (attrchangeMethod == 'propertychange' || attrchangeMethod == 'DOMAttrModified') { $(this).off(attrchangeMethod); } else if (attrchangeMethod == 'Mutation Observer') { $(this).data('attrchange-obs').disconnect(); } else if (attrchangeMethod == 'polling') { clearInterval($(this).data('attrchange-polling-timer')); } }).removeData('attrchange-method'); } else { //logical disconnect return this.data('attrchange-tdisconnect', 'tdisconnect'); //set a flag that prevents triggering callback onattrchange } }, remove: function (o) { return $.fn.attrchange.extensions['disconnect'].call(this, {isPhysicalDisconnect: true}); }, getProperties: function (o) { var attrchangeMethod = $(this).data('attrchange-method'); var pollInterval = $(this).data('attrchange-pollInterval'); return { method: attrchangeMethod, isPolling: (attrchangeMethod == 'polling'), pollingInterval: (typeof pollInterval === 'undefined')?0:parseInt(pollInterval, 10), status: (typeof attrchangeMethod === 'undefined')?'removed': (typeof $(this).data('attrchange-tdisconnect') === 'undefined')?'connected':'disconnected' } }, reconnect: function (o) {//reconnect possible only when there is a logical disconnect return this.removeData('attrchange-tdisconnect'); }, polling: function (o) { if (o.hasOwnProperty('isComputedStyle') && o.isComputedStyle == 'true') { /* extensive and slow - polling to check on computed style properties */ return this.each(function(i, _this) { if (!o.hasOwnProperty('properties') || Object.prototype.toString.call(o.properties) !== '[object Array]' || o.properties.length == 0) { return false; } //return if no properties found var attributes = {}; //store computed properties for (var i = 0; i < o.properties.length; i++) { attributes[o.properties[i]] = $(this).css(o.properties[i]); } var _this = this; $(this).data('attrchange-polling-timer', setInterval(function () { var changes = {}, hasChanges = false; // attrName: { oldValue: xxx, newValue: yyy} for (var comuptedVal, i = 0; i < o.properties.length; i++){ comuptedVal = $(_this).css(o.properties[i]); if (attributes[o.properties[i]] !== comuptedVal) { hasChanges = true; changes[o.properties[i]] = {oldValue: attributes[o.properties[i]], newValue: comuptedVal}; attributes[o.properties[i]] = comuptedVal //add the attribute to the orig } } if (hasChanges && typeof $(_this).data('attrchange-tdisconnect') === 'undefined') { //disconnected logically o.callback.call(_this, changes); } }, (o.pollInterval)?o.pollInterval: 1000)).data('attrchange-method', 'polling').data('attrchange-pollInterval', o.pollInterval); }); } else { return this.each(function(i, _this) { /* this one is programmatic polling */ var attributes = {}; for (var attr, i=0, attrs=_this.attributes, l=attrs.length; i