1+ /**
2+ * @license
3+ * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
4+ * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5+ * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6+ * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7+ * Code distributed by Google as part of the polymer project is also
8+ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
9+ */
10+ // @version 0.6.1
11+ if ( typeof WeakMap === "undefined" ) {
12+ ( function ( ) {
13+ var defineProperty = Object . defineProperty ;
14+ var counter = Date . now ( ) % 1e9 ;
15+ var WeakMap = function ( ) {
16+ this . name = "__st" + ( Math . random ( ) * 1e9 >>> 0 ) + ( counter ++ + "__" ) ;
17+ } ;
18+ WeakMap . prototype = {
19+ set : function ( key , value ) {
20+ var entry = key [ this . name ] ;
21+ if ( entry && entry [ 0 ] === key ) entry [ 1 ] = value ; else defineProperty ( key , this . name , {
22+ value : [ key , value ] ,
23+ writable : true
24+ } ) ;
25+ return this ;
26+ } ,
27+ get : function ( key ) {
28+ var entry ;
29+ return ( entry = key [ this . name ] ) && entry [ 0 ] === key ? entry [ 1 ] : undefined ;
30+ } ,
31+ "delete" : function ( key ) {
32+ var entry = key [ this . name ] ;
33+ if ( ! entry || entry [ 0 ] !== key ) return false ;
34+ entry [ 0 ] = entry [ 1 ] = undefined ;
35+ return true ;
36+ } ,
37+ has : function ( key ) {
38+ var entry = key [ this . name ] ;
39+ if ( ! entry ) return false ;
40+ return entry [ 0 ] === key ;
41+ }
42+ } ;
43+ window . WeakMap = WeakMap ;
44+ } ) ( ) ;
45+ }
46+
47+ ( function ( global ) {
48+ var registrationsTable = new WeakMap ( ) ;
49+ var setImmediate ;
50+ if ( / T r i d e n t | E d g e / . test ( navigator . userAgent ) ) {
51+ setImmediate = setTimeout ;
52+ } else if ( window . setImmediate ) {
53+ setImmediate = window . setImmediate ;
54+ } else {
55+ var setImmediateQueue = [ ] ;
56+ var sentinel = String ( Math . random ( ) ) ;
57+ window . addEventListener ( "message" , function ( e ) {
58+ if ( e . data === sentinel ) {
59+ var queue = setImmediateQueue ;
60+ setImmediateQueue = [ ] ;
61+ queue . forEach ( function ( func ) {
62+ func ( ) ;
63+ } ) ;
64+ }
65+ } ) ;
66+ setImmediate = function ( func ) {
67+ setImmediateQueue . push ( func ) ;
68+ window . postMessage ( sentinel , "*" ) ;
69+ } ;
70+ }
71+ var isScheduled = false ;
72+ var scheduledObservers = [ ] ;
73+ function scheduleCallback ( observer ) {
74+ scheduledObservers . push ( observer ) ;
75+ if ( ! isScheduled ) {
76+ isScheduled = true ;
77+ setImmediate ( dispatchCallbacks ) ;
78+ }
79+ }
80+ function wrapIfNeeded ( node ) {
81+ return window . ShadowDOMPolyfill && window . ShadowDOMPolyfill . wrapIfNeeded ( node ) || node ;
82+ }
83+ function dispatchCallbacks ( ) {
84+ isScheduled = false ;
85+ var observers = scheduledObservers ;
86+ scheduledObservers = [ ] ;
87+ observers . sort ( function ( o1 , o2 ) {
88+ return o1 . uid_ - o2 . uid_ ;
89+ } ) ;
90+ var anyNonEmpty = false ;
91+ observers . forEach ( function ( observer ) {
92+ var queue = observer . takeRecords ( ) ;
93+ removeTransientObserversFor ( observer ) ;
94+ if ( queue . length ) {
95+ observer . callback_ ( queue , observer ) ;
96+ anyNonEmpty = true ;
97+ }
98+ } ) ;
99+ if ( anyNonEmpty ) dispatchCallbacks ( ) ;
100+ }
101+ function removeTransientObserversFor ( observer ) {
102+ observer . nodes_ . forEach ( function ( node ) {
103+ var registrations = registrationsTable . get ( node ) ;
104+ if ( ! registrations ) return ;
105+ registrations . forEach ( function ( registration ) {
106+ if ( registration . observer === observer ) registration . removeTransientObservers ( ) ;
107+ } ) ;
108+ } ) ;
109+ }
110+ function forEachAncestorAndObserverEnqueueRecord ( target , callback ) {
111+ for ( var node = target ; node ; node = node . parentNode ) {
112+ var registrations = registrationsTable . get ( node ) ;
113+ if ( registrations ) {
114+ for ( var j = 0 ; j < registrations . length ; j ++ ) {
115+ var registration = registrations [ j ] ;
116+ var options = registration . options ;
117+ if ( node !== target && ! options . subtree ) continue ;
118+ var record = callback ( options ) ;
119+ if ( record ) registration . enqueue ( record ) ;
120+ }
121+ }
122+ }
123+ }
124+ var uidCounter = 0 ;
125+ function JsMutationObserver ( callback ) {
126+ this . callback_ = callback ;
127+ this . nodes_ = [ ] ;
128+ this . records_ = [ ] ;
129+ this . uid_ = ++ uidCounter ;
130+ }
131+ JsMutationObserver . prototype = {
132+ observe : function ( target , options ) {
133+ target = wrapIfNeeded ( target ) ;
134+ if ( ! options . childList && ! options . attributes && ! options . characterData || options . attributeOldValue && ! options . attributes || options . attributeFilter && options . attributeFilter . length && ! options . attributes || options . characterDataOldValue && ! options . characterData ) {
135+ throw new SyntaxError ( ) ;
136+ }
137+ var registrations = registrationsTable . get ( target ) ;
138+ if ( ! registrations ) registrationsTable . set ( target , registrations = [ ] ) ;
139+ var registration ;
140+ for ( var i = 0 ; i < registrations . length ; i ++ ) {
141+ if ( registrations [ i ] . observer === this ) {
142+ registration = registrations [ i ] ;
143+ registration . removeListeners ( ) ;
144+ registration . options = options ;
145+ break ;
146+ }
147+ }
148+ if ( ! registration ) {
149+ registration = new Registration ( this , target , options ) ;
150+ registrations . push ( registration ) ;
151+ this . nodes_ . push ( target ) ;
152+ }
153+ registration . addListeners ( ) ;
154+ } ,
155+ disconnect : function ( ) {
156+ this . nodes_ . forEach ( function ( node ) {
157+ var registrations = registrationsTable . get ( node ) ;
158+ for ( var i = 0 ; i < registrations . length ; i ++ ) {
159+ var registration = registrations [ i ] ;
160+ if ( registration . observer === this ) {
161+ registration . removeListeners ( ) ;
162+ registrations . splice ( i , 1 ) ;
163+ break ;
164+ }
165+ }
166+ } , this ) ;
167+ this . records_ = [ ] ;
168+ } ,
169+ takeRecords : function ( ) {
170+ var copyOfRecords = this . records_ ;
171+ this . records_ = [ ] ;
172+ return copyOfRecords ;
173+ }
174+ } ;
175+ function MutationRecord ( type , target ) {
176+ this . type = type ;
177+ this . target = target ;
178+ this . addedNodes = [ ] ;
179+ this . removedNodes = [ ] ;
180+ this . previousSibling = null ;
181+ this . nextSibling = null ;
182+ this . attributeName = null ;
183+ this . attributeNamespace = null ;
184+ this . oldValue = null ;
185+ }
186+ function copyMutationRecord ( original ) {
187+ var record = new MutationRecord ( original . type , original . target ) ;
188+ record . addedNodes = original . addedNodes . slice ( ) ;
189+ record . removedNodes = original . removedNodes . slice ( ) ;
190+ record . previousSibling = original . previousSibling ;
191+ record . nextSibling = original . nextSibling ;
192+ record . attributeName = original . attributeName ;
193+ record . attributeNamespace = original . attributeNamespace ;
194+ record . oldValue = original . oldValue ;
195+ return record ;
196+ }
197+ var currentRecord , recordWithOldValue ;
198+ function getRecord ( type , target ) {
199+ return currentRecord = new MutationRecord ( type , target ) ;
200+ }
201+ function getRecordWithOldValue ( oldValue ) {
202+ if ( recordWithOldValue ) return recordWithOldValue ;
203+ recordWithOldValue = copyMutationRecord ( currentRecord ) ;
204+ recordWithOldValue . oldValue = oldValue ;
205+ return recordWithOldValue ;
206+ }
207+ function clearRecords ( ) {
208+ currentRecord = recordWithOldValue = undefined ;
209+ }
210+ function recordRepresentsCurrentMutation ( record ) {
211+ return record === recordWithOldValue || record === currentRecord ;
212+ }
213+ function selectRecord ( lastRecord , newRecord ) {
214+ if ( lastRecord === newRecord ) return lastRecord ;
215+ if ( recordWithOldValue && recordRepresentsCurrentMutation ( lastRecord ) ) return recordWithOldValue ;
216+ return null ;
217+ }
218+ function Registration ( observer , target , options ) {
219+ this . observer = observer ;
220+ this . target = target ;
221+ this . options = options ;
222+ this . transientObservedNodes = [ ] ;
223+ }
224+ Registration . prototype = {
225+ enqueue : function ( record ) {
226+ var records = this . observer . records_ ;
227+ var length = records . length ;
228+ if ( records . length > 0 ) {
229+ var lastRecord = records [ length - 1 ] ;
230+ var recordToReplaceLast = selectRecord ( lastRecord , record ) ;
231+ if ( recordToReplaceLast ) {
232+ records [ length - 1 ] = recordToReplaceLast ;
233+ return ;
234+ }
235+ } else {
236+ scheduleCallback ( this . observer ) ;
237+ }
238+ records [ length ] = record ;
239+ } ,
240+ addListeners : function ( ) {
241+ this . addListeners_ ( this . target ) ;
242+ } ,
243+ addListeners_ : function ( node ) {
244+ var options = this . options ;
245+ if ( options . attributes ) node . addEventListener ( "DOMAttrModified" , this , true ) ;
246+ if ( options . characterData ) node . addEventListener ( "DOMCharacterDataModified" , this , true ) ;
247+ if ( options . childList ) node . addEventListener ( "DOMNodeInserted" , this , true ) ;
248+ if ( options . childList || options . subtree ) node . addEventListener ( "DOMNodeRemoved" , this , true ) ;
249+ } ,
250+ removeListeners : function ( ) {
251+ this . removeListeners_ ( this . target ) ;
252+ } ,
253+ removeListeners_ : function ( node ) {
254+ var options = this . options ;
255+ if ( options . attributes ) node . removeEventListener ( "DOMAttrModified" , this , true ) ;
256+ if ( options . characterData ) node . removeEventListener ( "DOMCharacterDataModified" , this , true ) ;
257+ if ( options . childList ) node . removeEventListener ( "DOMNodeInserted" , this , true ) ;
258+ if ( options . childList || options . subtree ) node . removeEventListener ( "DOMNodeRemoved" , this , true ) ;
259+ } ,
260+ addTransientObserver : function ( node ) {
261+ if ( node === this . target ) return ;
262+ this . addListeners_ ( node ) ;
263+ this . transientObservedNodes . push ( node ) ;
264+ var registrations = registrationsTable . get ( node ) ;
265+ if ( ! registrations ) registrationsTable . set ( node , registrations = [ ] ) ;
266+ registrations . push ( this ) ;
267+ } ,
268+ removeTransientObservers : function ( ) {
269+ var transientObservedNodes = this . transientObservedNodes ;
270+ this . transientObservedNodes = [ ] ;
271+ transientObservedNodes . forEach ( function ( node ) {
272+ this . removeListeners_ ( node ) ;
273+ var registrations = registrationsTable . get ( node ) ;
274+ for ( var i = 0 ; i < registrations . length ; i ++ ) {
275+ if ( registrations [ i ] === this ) {
276+ registrations . splice ( i , 1 ) ;
277+ break ;
278+ }
279+ }
280+ } , this ) ;
281+ } ,
282+ handleEvent : function ( e ) {
283+ e . stopImmediatePropagation ( ) ;
284+ switch ( e . type ) {
285+ case "DOMAttrModified" :
286+ var name = e . attrName ;
287+ var namespace = e . relatedNode . namespaceURI ;
288+ var target = e . target ;
289+ var record = new getRecord ( "attributes" , target ) ;
290+ record . attributeName = name ;
291+ record . attributeNamespace = namespace ;
292+ var oldValue = e . attrChange === MutationEvent . ADDITION ? null : e . prevValue ;
293+ forEachAncestorAndObserverEnqueueRecord ( target , function ( options ) {
294+ if ( ! options . attributes ) return ;
295+ if ( options . attributeFilter && options . attributeFilter . length && options . attributeFilter . indexOf ( name ) === - 1 && options . attributeFilter . indexOf ( namespace ) === - 1 ) {
296+ return ;
297+ }
298+ if ( options . attributeOldValue ) return getRecordWithOldValue ( oldValue ) ;
299+ return record ;
300+ } ) ;
301+ break ;
302+
303+ case "DOMCharacterDataModified" :
304+ var target = e . target ;
305+ var record = getRecord ( "characterData" , target ) ;
306+ var oldValue = e . prevValue ;
307+ forEachAncestorAndObserverEnqueueRecord ( target , function ( options ) {
308+ if ( ! options . characterData ) return ;
309+ if ( options . characterDataOldValue ) return getRecordWithOldValue ( oldValue ) ;
310+ return record ;
311+ } ) ;
312+ break ;
313+
314+ case "DOMNodeRemoved" :
315+ this . addTransientObserver ( e . target ) ;
316+
317+ case "DOMNodeInserted" :
318+ var changedNode = e . target ;
319+ var addedNodes , removedNodes ;
320+ if ( e . type === "DOMNodeInserted" ) {
321+ addedNodes = [ changedNode ] ;
322+ removedNodes = [ ] ;
323+ } else {
324+ addedNodes = [ ] ;
325+ removedNodes = [ changedNode ] ;
326+ }
327+ var previousSibling = changedNode . previousSibling ;
328+ var nextSibling = changedNode . nextSibling ;
329+ var record = getRecord ( "childList" , e . target . parentNode ) ;
330+ record . addedNodes = addedNodes ;
331+ record . removedNodes = removedNodes ;
332+ record . previousSibling = previousSibling ;
333+ record . nextSibling = nextSibling ;
334+ forEachAncestorAndObserverEnqueueRecord ( e . relatedNode , function ( options ) {
335+ if ( ! options . childList ) return ;
336+ return record ;
337+ } ) ;
338+ }
339+ clearRecords ( ) ;
340+ }
341+ } ;
342+ global . JsMutationObserver = JsMutationObserver ;
343+ if ( ! global . MutationObserver ) global . MutationObserver = JsMutationObserver ;
344+ } ) ( this ) ;
0 commit comments