Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mutationobserver-shim

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mutationobserver-shim - npm Package Compare versions

Comparing version 0.2.8 to 0.3.0

16

dist/mutationobserver.min.js

@@ -1,9 +0,9 @@

// mutationobserver-shim v0.2.8 (github.com/megawac/MutationObserver.js)
// mutationobserver-shim v0.3.0 (github.com/megawac/MutationObserver.js)
// Authors: Graeme Yeates (github.com/megawac)
this.MutationObserver=this.MutationObserver||this.WebKitMutationObserver||function(v){function m(a){this.g=[];this.k=a}function F(a){(function c(){var d=a.takeRecords();d.length&&a.k(d,a);a.f=setTimeout(c,m._period)})()}function r(a){var b={type:null,target:null,addedNodes:[],removedNodes:[],previousSibling:null,nextSibling:null,attributeName:null,attributeNamespace:null,oldValue:null},c;for(c in a)b[c]!==v&&a[c]!==v&&(b[c]=a[c]);return b}function G(a,b){var c=A(a,b);return function(d){var g=d.length;
b.a&&c.a&&z(d,a,c.a,b.d);(b.c||b.e)&&H(d,a,c,b);d.length!==g&&(c=A(a,b))}}function z(a,b,c,d){for(var g={},u=b.attributes,w,h,p=u.length;p--;)w=u[p],h=w.name,d&&d[h]===v||(w.value!==c[h]&&a.push(r({type:"attributes",target:b,attributeName:h,oldValue:c[h],attributeNamespace:w.namespaceURI})),g[h]=!0);for(h in c)g[h]||a.push(r({target:b,type:"attributes",attributeName:h,oldValue:c[h]}))}function H(a,b,c,d){function g(b,c,g,n,x){var m=b.length-1;x=-~((m-x)/2);for(var f,k,e;e=b.pop();)f=g[e.h],k=n[e.i],
d.c&&x&&Math.abs(e.h-e.i)>=m&&(a.push(r({type:"childList",target:c,addedNodes:[f],removedNodes:[f],nextSibling:f.nextSibling,previousSibling:f.previousSibling})),x--),d.a&&k.a&&z(a,f,k.a,d.d),d.b&&3===f.nodeType&&f.nodeValue!==k.b&&a.push(r({type:"characterData",target:f,oldValue:k.b})),d.e&&u(f,k)}function u(b,c){for(var p=b.childNodes,n=c.c,m=p.length,v=n?n.length:0,f,k,e,l,s,y=0,t=0,q=0;t<m||q<v;)l=p[t],s=(e=n[q])&&e.j,l===s?(d.a&&e.a&&z(a,l,e.a,d.d),d.b&&3===l.nodeType&&l.nodeValue!==e.b&&a.push(r({type:"characterData",
target:l,oldValue:e.b})),k&&g(k,b,p,n,y),d.e&&(l.childNodes.length||e.c&&e.c.length)&&u(l,e),t++,q++):(f||(f={},k=[]),l&&(f[e=B(l)]||(f[e]=!0,-1===(e=C(n,l,q,"j"))?d.c&&(a.push(r({type:"childList",target:b,addedNodes:[l],nextSibling:l.nextSibling,previousSibling:l.previousSibling})),y++):k.push({h:t,i:e})),t++),s&&s!==p[t]&&(f[e=B(s)]||(f[e]=!0,-1===(e=C(p,s,t))?d.c&&(a.push(r({type:"childList",target:c.j,removedNodes:[s],nextSibling:n[q+1],previousSibling:n[q-1]})),y--):k.push({h:e,i:q})),q++));
k&&g(k,b,p,n,y)}u(b,c)}function A(a,b){var c=!0;return function g(a){var m=3===a.nodeType,h={j:a};m||8===a.nodeType?m&&b.b&&(h.b=a.nodeValue):(b.a&&c&&(h.a=D(a.attributes,function(a,c){if(!b.d||b.d[c.name])a[c.name]=c.value;return a})),c&&(b.c||b.b||b.a&&b.e)&&(h.c=I(a.childNodes,g)),c=b.e);return h}(a)}function B(a){try{return a.id||(a.mo_id=a.mo_id||E++)}catch(b){try{return a.nodeValue}catch(c){return E++}}}function I(a,b){for(var c=[],d=0;d<a.length;d++)c[d]=b(a[d],d,a);return c}function D(a,b){for(var c=
{},d=0;d<a.length;d++)c=b(c,a[d],d,a);return c}function C(a,b,c,d){for(;c<a.length;c++)if((d?a[c][d]:a[c])===b)return c;return-1}m._period=30;m.prototype={observe:function(a,b){for(var c={a:!!(b.attributes||b.attributeFilter||b.attributeOldValue),c:!!b.childList,e:!!b.subtree,b:!(!b.characterData&&!b.characterDataOldValue)},d=this.g,g=0;g<d.length;g++)d[g].m===a&&d.splice(g,1);b.attributeFilter&&(c.d=D(b.attributeFilter,function(a,b){a[b]=!0;return a}));d.push({m:a,l:G(a,c)});this.f||F(this)},takeRecords:function(){for(var a=
[],b=this.g,c=0;c<b.length;c++)b[c].l(a);return a},disconnect:function(){this.g=[];clearTimeout(this.f);this.f=null}};var E=1;return m}(void 0);
window.MutationObserver=window.MutationObserver||window.WebKitMutationObserver||function(x){function h(a){this.g=[];this.k=a}function G(a){(function c(){var d=a.takeRecords();d.length&&a.k(d,a);a.f=setTimeout(c,h._period)})()}function t(a){var b={type:null,target:null,addedNodes:[],removedNodes:[],previousSibling:null,nextSibling:null,attributeName:null,attributeNamespace:null,oldValue:null},c;for(c in a)b[c]!==x&&a[c]!==x&&(b[c]=a[c]);return b}function H(a,b){var c=A(a,b);return function(d){var g=
d.length,p;b.a&&c.a&&z(d,a,c.a,b.d);if(b.b||b.e)p=I(d,a,c,b);if(p||d.length!==g)c=A(a,b)}}function z(a,b,c,d){for(var g={},p=b.attributes,k,n,B=p.length;B--;)k=p[B],n=k.name,d&&d[n]===x||(k.value!==c[n]&&a.push(t({type:"attributes",target:b,attributeName:n,oldValue:c[n],attributeNamespace:k.namespaceURI})),g[n]=!0);for(n in c)g[n]||a.push(t({target:b,type:"attributes",attributeName:n,oldValue:c[n]}))}function I(a,b,c,d){function g(b,c,g,k,w){var h=b.length-1;w=-~((h-w)/2);for(var f,m,e;e=b.pop();)f=
g[e.h],m=k[e.i],d.b&&w&&Math.abs(e.h-e.i)>=h&&(a.push(t({type:"childList",target:c,addedNodes:[f],removedNodes:[f],nextSibling:f.nextSibling,previousSibling:f.previousSibling})),w--),d.a&&m.a&&z(a,f,m.a,d.d),d.c&&3===f.nodeType&&f.nodeValue!==m.c&&a.push(t({type:"characterData",target:f})),d.e&&p(f,m)}function p(b,c){for(var h=b.childNodes,q=c.b,w=h.length,x=q?q.length:0,f,m,e,l,u,y=0,v=0,r=0;v<w||r<x;)l=h[v],u=(e=q[r])&&e.j,l===u?(d.a&&e.a&&z(a,l,e.a,d.d),d.c&&3===l.nodeType&&l.nodeValue!==e.c&&
a.push(t({type:"characterData",target:l})),m&&g(m,b,h,q,y),d.e&&(l.childNodes.length||e.b&&e.b.length)&&p(l,e),v++,r++):(k=!0,f||(f={},m=[]),l&&(f[e=C(l)]||(f[e]=!0,-1===(e=D(q,l,r,"j"))?d.b&&(a.push(t({type:"childList",target:b,addedNodes:[l],nextSibling:l.nextSibling,previousSibling:l.previousSibling})),y++):m.push({h:v,i:e})),v++),u&&u!==h[v]&&(f[e=C(u)]||(f[e]=!0,-1===(e=D(h,u,v))?d.b&&(a.push(t({type:"childList",target:c.j,removedNodes:[u],nextSibling:q[r+1],previousSibling:q[r-1]})),y--):m.push({h:e,
i:r})),r++));m&&g(m,b,h,q,y)}var k;p(b,c);return k}function A(a,b){var c=!0;return function g(a){var k={j:a};3===a.nodeType&&b.c?k.c=a.nodeValue:(b.a&&c&&1===a.nodeType&&(k.a=E(a.attributes,function(a,c){if(!b.d||b.d[c.name])a[c.name]=c.value;return a})),c&&(b.b||b.c||b.a&&b.e)&&(k.b=J(a.childNodes,g)),c=b.e);return k}(a)}function C(a){try{return a.id||(a.mo_id=a.mo_id||F++)}catch(b){try{return a.nodeValue}catch(c){return F++}}}function J(a,b){for(var c=[],d=0;d<a.length;d++)c[d]=b(a[d],d,a);return c}
function E(a,b){for(var c={},d=0;d<a.length;d++)c=b(c,a[d],d,a);return c}function D(a,b,c,d){for(;c<a.length;c++)if((d?a[c][d]:a[c])===b)return c;return-1}h._period=30;h.prototype={observe:function(a,b){for(var c={a:!!(b.attributes||b.attributeFilter||b.attributeOldValue),b:!!b.childList,e:!!b.subtree,c:!(!b.characterData&&!b.characterDataOldValue)},d=this.g,g=0;g<d.length;g++)d[g].m===a&&d.splice(g,1);b.attributeFilter&&(c.d=E(b.attributeFilter,function(a,b){a[b]=!0;return a}));d.push({m:a,l:H(a,
c)});this.f||G(this)},takeRecords:function(){for(var a=[],b=this.g,c=0;c<b.length;c++)b[c].l(a);return a},disconnect:function(){this.g=[];clearTimeout(this.f);this.f=null}};var F=1;return h}(void 0);

@@ -5,4 +5,4 @@ ###Compiled files

- Original: 23.4 kB
- Original: 23 kB
- Minified: 3.4 kB
- Gzipped: 779 bytes

@@ -7,3 +7,3 @@ /*!

* Though credit and staring the repo will make me feel pretty, you can modify and redistribute as you please.
* Attempts to follow spec (http://www.w3.org/TR/dom/#mutation-observers) as closely as possible for native javascript
* Attempts to follow spec (http:// www.w3.org/TR/dom/#mutation-observers) as closely as possible for native javascript
* See https://github.com/WebKit/webkit/blob/master/Source/WebCore/dom/MutationObserver.cpp for current webkit source c++ implementation

@@ -14,6 +14,6 @@ */

* prefix bugs:
-https://bugs.webkit.org/show_bug.cgi?id=85161
-https://bugzilla.mozilla.org/show_bug.cgi?id=749920
- https://bugs.webkit.org/show_bug.cgi?id=85161
- https://bugzilla.mozilla.org/show_bug.cgi?id=749920
*/
this.MutationObserver = this.MutationObserver || this.WebKitMutationObserver || (function(undefined) {
window.MutationObserver = window.MutationObserver || window.WebKitMutationObserver || (function(undefined) {
"use strict";

@@ -43,4 +43,4 @@ /**

if (mutations.length) { //fire away
//calling the listener with context is not spec but currently consistent with FF and WebKit
if (mutations.length) { // fire away
// calling the listener with context is not spec but currently consistent with FF and WebKit
observer._listener(mutations, observer);

@@ -67,3 +67,3 @@ }

/**
* see http://dom.spec.whatwg.org/#dom-mutationobserver-observe
* see http:// dom.spec.whatwg.org/#dom-mutationobserver-observe
* not going to throw here but going to follow the current spec config sets

@@ -83,3 +83,3 @@ * @param {Node|null} $target

//some browsers are strict in their implementation that config.subtree and childList must be set together. We don't care - spec doesn't specify
// some browsers are strict in their implementation that config.subtree and childList must be set together. We don't care - spec doesn't specify
kids: !! config.childList,

@@ -92,3 +92,3 @@ descendents: !! config.subtree,

//remove already observed target element from pool
// remove already observed target element from pool
for (var i = 0; i < watched.length; i++) {

@@ -114,3 +114,3 @@ if (watched[i].tar === $target) watched.splice(i, 1);

//reconnect if not connected
// reconnect if not connected
if (!this._timeout) {

@@ -142,4 +142,4 @@ startMutationChecker(this);

disconnect: function() {
this._watched = []; //clear the stuff being observed
clearTimeout(this._timeout); //ready for garbage collection
this._watched = []; // clear the stuff being observed
clearTimeout(this._timeout); // ready for garbage collection
/** @private */

@@ -156,3 +156,3 @@ this._timeout = null;

function MutationRecord(data) {
var settings = { //technically these should be on proto so hasOwnProperty will return false for non explicitly props
var settings = { // technically these should be on proto so hasOwnProperty will return false for non explicitly props
type: null,

@@ -182,3 +182,3 @@ target: null,

/** type {Elestuct} */
var $oldstate = clone($target, config); //create the cloned datastructure
var $oldstate = clone($target, config); // create the cloned datastructure

@@ -191,5 +191,5 @@ /**

return function(mutations) {
var olen = mutations.length;
var olen = mutations.length, dirty;
//Alright we check base level changes in attributes... easy
// Alright we check base level changes in attributes... easy
if (config.attr && $oldstate.attr) {

@@ -199,10 +199,9 @@ findAttributeMutations(mutations, $target, $oldstate.attr, config.afilter);

//check childlist or subtree for mutations
// check childlist or subtree for mutations
if (config.kids || config.descendents) {
searchSubtree(mutations, $target, $oldstate, config);
dirty = searchSubtree(mutations, $target, $oldstate, config);
}
//reclone data structure if theres changes
if (mutations.length !== olen) {
// reclone data structure if theres changes
if (dirty || mutations.length !== olen) {
/** type {Elestuct} */

@@ -236,3 +235,3 @@ $oldstate = clone($target, config);

if (attr.value !== $oldstate[name]) {
//The pushing is redundant but gzips very nicely
// The pushing is redundant but gzips very nicely
mutations.push(MutationRecord({

@@ -243,3 +242,3 @@ type: "attributes",

oldValue: $oldstate[name],
attributeNamespace: attr.namespaceURI //in ie<8 it incorrectly will return undefined
attributeNamespace: attr.namespaceURI // in ie<8 it incorrectly will return undefined
}));

@@ -275,2 +274,4 @@ }

function searchSubtree(mutations, $target, $oldstate, config) {
// Track if the tree is dirty and has to be recomputed (#14).
var dirty;
/*

@@ -291,8 +292,8 @@ * Helper to identify node rearrangment and stuff...

var conflict;
while((conflict = conflicts.pop())) {
while ((conflict = conflicts.pop())) {
$cur = $kids[conflict.i];
oldstruct = $oldkids[conflict.j];
//attempt to determine if there was node rearrangement... won't gaurentee all matches
//also handles case where added/removed nodes cause nodes to be identified as conflicts
// attempt to determine if there was node rearrangement... won't gaurentee all matches
// also handles case where added/removed nodes cause nodes to be identified as conflicts
if (config.kids && counter && Math.abs(conflict.i - conflict.j) >= distance) {

@@ -308,6 +309,6 @@ mutations.push(MutationRecord({

}));
counter--; //found conflict
counter--; // found conflict
}
//Alright we found the resorted nodes now check for other types of mutations
// Alright we found the resorted nodes now check for other types of mutations
if (config.attr && oldstruct.attr) findAttributeMutations(mutations, $cur, oldstruct.attr, config.afilter);

@@ -317,7 +318,6 @@ if (config.charData && $cur.nodeType === 3 && $cur.nodeValue !== oldstruct.charData) {

type: "characterData",
target: $cur,
oldValue: oldstruct.charData
target: $cur
}));
}
//now look @ subtree
// now look @ subtree
if (config.descendents) findMutations($cur, oldstruct);

@@ -338,24 +338,24 @@ }

var olen = $oldkids ? $oldkids.length : 0;
// if (!olen && !klen) return; //both empty; clearly no changes
// if (!olen && !klen) return; // both empty; clearly no changes
//we delay the intialization of these for marginal performance in the expected case (actually quite signficant on large subtrees when these would be otherwise unused)
//map of checked element of ids to prevent registering the same conflict twice
// we delay the intialization of these for marginal performance in the expected case (actually quite signficant on large subtrees when these would be otherwise unused)
// map of checked element of ids to prevent registering the same conflict twice
var map;
//array of potential conflicts (ie nodes that may have been re arranged)
// array of potential conflicts (ie nodes that may have been re arranged)
var conflicts;
var id; //element id from getElementId helper
var idx; //index of a moved or inserted element
var id; // element id from getElementId helper
var idx; // index of a moved or inserted element
var oldstruct;
//current and old nodes
// current and old nodes
var $cur;
var $old;
//track the number of added nodes so we can resolve conflicts more accurately
// track the number of added nodes so we can resolve conflicts more accurately
var numAddedNodes = 0;
//iterate over both old and current child nodes at the same time
// iterate over both old and current child nodes at the same time
var i = 0, j = 0;
//while there is still anything left in $kids or $oldkids (same as i < $kids.length || j < $oldkids.length;)
// while there is still anything left in $kids or $oldkids (same as i < $kids.length || j < $oldkids.length;)
while( i < klen || j < olen ) {
//current and old nodes at the indexs
// current and old nodes at the indexs
$cur = $kids[i];

@@ -365,18 +365,17 @@ oldstruct = $oldkids[j];

if ($cur === $old) { //expected case - optimized for this case
//check attributes as specified by config
if ($cur === $old) { // expected case - optimized for this case
// check attributes as specified by config
if (config.attr && oldstruct.attr) /* oldstruct.attr instead of textnode check */findAttributeMutations(mutations, $cur, oldstruct.attr, config.afilter);
//check character data if set
// check character data if set
if (config.charData && $cur.nodeType === 3 && $cur.nodeValue !== oldstruct.charData) {
mutations.push(MutationRecord({
type: "characterData",
target: $cur,
oldValue: oldstruct.charData
target: $cur
}));
}
//resolve conflicts; it will be undefined if there are no conflicts - otherwise an array
// resolve conflicts; it will be undefined if there are no conflicts - otherwise an array
if (conflicts) resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes);
//recurse on next level of children. Avoids the recursive call when there are no children left to iterate
// recurse on next level of children. Avoids the recursive call when there are no children left to iterate
if (config.descendents && ($cur.childNodes.length || oldstruct.kids && oldstruct.kids.length)) findMutations($cur, oldstruct);

@@ -386,4 +385,5 @@

j++;
} else { //(uncommon case) lookahead until they are the same again or the end of children
if(!map) { //delayed initalization (big perf benefit)
} else { // (uncommon case) lookahead until they are the same again or the end of children
dirty = true;
if (!map) { // delayed initalization (big perf benefit)
map = {};

@@ -393,7 +393,7 @@ conflicts = [];

if ($cur) {
//check id is in the location map otherwise do a indexOf search
if (!(map[id = getElementId($cur)])) { //to prevent double checking
//mark id as found
// check id is in the location map otherwise do a indexOf search
if (!(map[id = getElementId($cur)])) { // to prevent double checking
// mark id as found
map[id] = true;
//custom indexOf using comparitor checking oldkids[i].node === $cur
// custom indexOf using comparitor checking oldkids[i].node === $cur
if ((idx = indexOfCustomNode($oldkids, $cur, j)) === -1) {

@@ -404,3 +404,3 @@ if (config.kids) {

target: node,
addedNodes: [$cur], //$cur is a new node
addedNodes: [$cur], // $cur is a new node
nextSibling: $cur.nextSibling,

@@ -412,3 +412,3 @@ previousSibling: $cur.previousSibling

} else {
conflicts.push({ //add conflict
conflicts.push({ // add conflict
i: i,

@@ -423,3 +423,3 @@ j: idx

if ($old &&
//special case: the changes may have been resolved: i and j appear congurent so we can continue using the expected case
// special case: the changes may have been resolved: i and j appear congurent so we can continue using the expected case
$old !== $kids[i]

@@ -430,3 +430,3 @@ ) {

if ((idx = indexOf($kids, $old, i)) === -1) {
if(config.kids) {
if (config.kids) {
mutations.push(MutationRecord({

@@ -436,3 +436,3 @@ type: "childList",

removedNodes: [$old],
nextSibling: $oldkids[j + 1], //praise no indexoutofbounds exception
nextSibling: $oldkids[j + 1], // praise no indexoutofbounds exception
previousSibling: $oldkids[j - 1]

@@ -451,9 +451,10 @@ }));

}
}//end uncommon case
}//end loop
}// end uncommon case
}// end loop
//resolve any remaining conflicts
// resolve any remaining conflicts
if (conflicts) resolveConflicts(conflicts, node, $kids, $oldkids, numAddedNodes);
}
findMutations($target, $oldstate);
return dirty;
}

@@ -472,3 +473,2 @@

return (function copy($target) {
var isText = $target.nodeType === 3;
var elestruct = {

@@ -479,10 +479,11 @@ /** @type {Node} */

//is text or comemnt node
if (isText || $target.nodeType === 8) {
if (isText && config.charData) {
elestruct.charData = $target.nodeValue;
}
} else { //its either a element or document node (or something stupid)
if(config.attr && recurse) { // add attr only if subtree is specified or top level
// Store current character data of target text node if observed
if ($target.nodeType === 3 && config.charData) {
elestruct.charData = $target.nodeValue;
}
// its either a element, comment, doc frag or document node
else {
// Add attr only if subtree is specified or top level and avoid if
// attributes is a document object (#13).
if (config.attr && recurse && $target.nodeType === 1) {
/**

@@ -501,3 +502,3 @@ * clone live attribute list to an object structure {name: val}

// whether we should iterate the children of $target node
if(recurse && ((config.kids || config.charData) || (config.attr && config.descendents)) ) {
if (recurse && ((config.kids || config.charData) || (config.attr && config.descendents)) ) {
/** @type {Array.<!Object>} : Array of custom clone */

@@ -525,4 +526,4 @@ elestruct.kids = map($target.childNodes, copy);

//using a non id (eg outerHTML or nodeValue) is extremely naive and will run into issues with nodes that may appear the same like <li></li>
var counter = 1; //don't use 0 as id (falsy)
// using a non id (eg outerHTML or nodeValue) is extremely naive and will run into issues with nodes that may appear the same like <li></li>
var counter = 1; // don't use 0 as id (falsy)
/** @const */

@@ -540,6 +541,6 @@ var expando = "mo_id";

return $ele.id || ($ele[expando] = $ele[expando] || counter++);
} catch (o_O) { //ie <8 will throw if you set an unknown property on a text node
} catch (o_O) { // ie <8 will throw if you set an unknown property on a text node
try {
return $ele.nodeValue; //naive
} catch (shitie) { //when text node is removed: https://gist.github.com/megawac/8355978 :(
return $ele.nodeValue; // naive
} catch (shitie) { // when text node is removed: https://gist.github.com/megawac/8355978 :(
return counter++;

@@ -584,3 +585,3 @@ }

function indexOf(set, item, idx, prop) {
for (/*idx = ~~idx*/; idx < set.length; idx++) {//start idx is always given as this is internal
for (/*idx = ~~idx*/; idx < set.length; idx++) {// start idx is always given as this is internal
if ((prop ? set[idx][prop] : set[idx]) === item) return idx;

@@ -597,6 +598,6 @@ }

function has(obj, prop) {
return obj[prop] !== undefined; //will be nicely inlined by gcc
return obj[prop] !== undefined; // will be nicely inlined by gcc
}
// GCC hack see http://stackoverflow.com/a/23202438/1517919
// GCC hack see http:// stackoverflow.com/a/23202438/1517919
function JSCompiler_renameProperty(a) {

@@ -603,0 +604,0 @@ return a;

@@ -5,3 +5,3 @@ {

"description": "MutationObserver shim for ES3 environments",
"version": "0.2.8",
"version": "0.3.0",
"keywords": [

@@ -24,3 +24,3 @@ "DOM",

},
"main": "MutationObserver.js",
"main": "dist/mutationobserver.min.js",
"scripts": {

@@ -46,3 +46,3 @@ "test": "grunt test --verbose"

"grunt-file-info": "1.0.4",
"grunt-saucelabs": "4.1.x",
"grunt-saucelabs": "~4.1.2",
"grunt-tagrelease": "~0.3.1",

@@ -49,0 +49,0 @@ "matchdep": "~0.3.0",

@@ -6,11 +6,16 @@ MutationObserver

<sup>Note: IE7 fails due to quirky attribute handling ([see #4](https://github.com/megawac/MutationObserver.js/issues/4))
Safari 6.0.5 uses a buggy `WebKitMutationObserver` (don't have a computer with Safari to test on unfortuantely)</sup>
Safari 6.0.5 uses a buggy `WebKitMutationObserver` (don't have a computer with Safari to test on unfortuantely)</sup>
<sup>Note: the svg swapped the working browsers; IE8 works and so does Safari 5</sup>
A polyfill for the [MutationObserver API](http://www.w3.org/TR/2013/WD-dom-20131107/#mutation-observers) ([can I use?](http://caniuse.com/mutationobserver)). The polyfill is more cause we can than should (with subtree at any rate)... It's async and uses a recursive timeout fallback (default checks changes every 30ms + runtime) instead of using the deprecated [DOM3 MutationEvents](http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents) so theoretically can support virtually any browser.
A polyfill for the [MutationObserver API](http://www.w3.org/TR/2013/WD-dom-20131107/#mutation-observers) ([can I use?](http://caniuse.com/mutationobserver)). The polyfill is more cause we can than should (with subtree at any rate)... It's async and uses a recursive timeout fallback (default checks changes every 30ms + runtime) instead of using the deprecated [DOM3 MutationEvents](http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents) so theoretically can support virtually any environment.
```sh
$ npm install mutationobser-shim
$ npm install mutationobserver-shim
$ bower install MutationObserver-shim
```
```html
<script src="//cdn.jsdelivr.net/g/mutationobserver/"></script>
```
### Polyfill differences from standard interface

@@ -43,3 +48,3 @@

By default, the polyfill will check observed nodes about 25 times per second (30 ms interval) for mutations. Try running [these jsperf.com tests](http://jsperf.com/mutationobserver-shim) and the JSLitmus tests in the test suite for usage performance tests. It may be worthwile to adapt `MutaitonObserver._period` based on UA or heuristics (todo).
By default, the polyfill will check observed nodes about 25 times per second (30 ms interval) for mutations. Try running [these jsperf.com tests](http://jsperf.com/mutationobserver-shim) and the JSLitmus tests in the test suite for usage performance tests. It may be worthwile to adapt `MutationObserver._period` based on UA or heuristics (todo).

@@ -64,5 +69,5 @@ From my tests observing any size element without `subtree` enabled is relatively cheap. Although I've optimized the subtree check to the best of my abilities it can be costly on large trees. You can draw your own conclusions based on the JSLitmus and jsperf tests noting that you can expect the `mo` to do its check 28+ times a second (by default).

* http://jsbin.com/uxAQEWuL/3 listen to images being appended dynamically
* http://jsbin.com/uxAQEWuL/5 autoscroll an element as new content is added
* http://jsbin.com/suqewogone listen to images being appended dynamically
* http://jsbin.com/bapohopuwi autoscroll an element as new content is added
See http://dev.opera.com/articles/view/mutation-observers-tutorial/ for some sample usage.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc