| OLD | NEW |
| (Empty) |
| 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://polyme
r.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/CON
TRIBUTORS.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/PA
TENTS.txt | |
| 9 */ | |
| 10 // @version 0.7.22 | |
| 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] : undefin
ed; | |
| 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 if (global.JsMutationObserver) { | |
| 49 return; | |
| 50 } | |
| 51 var registrationsTable = new WeakMap(); | |
| 52 var setImmediate; | |
| 53 if (/Trident|Edge/.test(navigator.userAgent)) { | |
| 54 setImmediate = setTimeout; | |
| 55 } else if (window.setImmediate) { | |
| 56 setImmediate = window.setImmediate; | |
| 57 } else { | |
| 58 var setImmediateQueue = []; | |
| 59 var sentinel = String(Math.random()); | |
| 60 window.addEventListener("message", function(e) { | |
| 61 if (e.data === sentinel) { | |
| 62 var queue = setImmediateQueue; | |
| 63 setImmediateQueue = []; | |
| 64 queue.forEach(function(func) { | |
| 65 func(); | |
| 66 }); | |
| 67 } | |
| 68 }); | |
| 69 setImmediate = function(func) { | |
| 70 setImmediateQueue.push(func); | |
| 71 window.postMessage(sentinel, "*"); | |
| 72 }; | |
| 73 } | |
| 74 var isScheduled = false; | |
| 75 var scheduledObservers = []; | |
| 76 function scheduleCallback(observer) { | |
| 77 scheduledObservers.push(observer); | |
| 78 if (!isScheduled) { | |
| 79 isScheduled = true; | |
| 80 setImmediate(dispatchCallbacks); | |
| 81 } | |
| 82 } | |
| 83 function wrapIfNeeded(node) { | |
| 84 return window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrapIfNeeded(nod
e) || node; | |
| 85 } | |
| 86 function dispatchCallbacks() { | |
| 87 isScheduled = false; | |
| 88 var observers = scheduledObservers; | |
| 89 scheduledObservers = []; | |
| 90 observers.sort(function(o1, o2) { | |
| 91 return o1.uid_ - o2.uid_; | |
| 92 }); | |
| 93 var anyNonEmpty = false; | |
| 94 observers.forEach(function(observer) { | |
| 95 var queue = observer.takeRecords(); | |
| 96 removeTransientObserversFor(observer); | |
| 97 if (queue.length) { | |
| 98 observer.callback_(queue, observer); | |
| 99 anyNonEmpty = true; | |
| 100 } | |
| 101 }); | |
| 102 if (anyNonEmpty) dispatchCallbacks(); | |
| 103 } | |
| 104 function removeTransientObserversFor(observer) { | |
| 105 observer.nodes_.forEach(function(node) { | |
| 106 var registrations = registrationsTable.get(node); | |
| 107 if (!registrations) return; | |
| 108 registrations.forEach(function(registration) { | |
| 109 if (registration.observer === observer) registration.removeTransientObse
rvers(); | |
| 110 }); | |
| 111 }); | |
| 112 } | |
| 113 function forEachAncestorAndObserverEnqueueRecord(target, callback) { | |
| 114 for (var node = target; node; node = node.parentNode) { | |
| 115 var registrations = registrationsTable.get(node); | |
| 116 if (registrations) { | |
| 117 for (var j = 0; j < registrations.length; j++) { | |
| 118 var registration = registrations[j]; | |
| 119 var options = registration.options; | |
| 120 if (node !== target && !options.subtree) continue; | |
| 121 var record = callback(options); | |
| 122 if (record) registration.enqueue(record); | |
| 123 } | |
| 124 } | |
| 125 } | |
| 126 } | |
| 127 var uidCounter = 0; | |
| 128 function JsMutationObserver(callback) { | |
| 129 this.callback_ = callback; | |
| 130 this.nodes_ = []; | |
| 131 this.records_ = []; | |
| 132 this.uid_ = ++uidCounter; | |
| 133 } | |
| 134 JsMutationObserver.prototype = { | |
| 135 observe: function(target, options) { | |
| 136 target = wrapIfNeeded(target); | |
| 137 if (!options.childList && !options.attributes && !options.characterData ||
options.attributeOldValue && !options.attributes || options.attributeFilter &&
options.attributeFilter.length && !options.attributes || options.characterDataOl
dValue && !options.characterData) { | |
| 138 throw new SyntaxError(); | |
| 139 } | |
| 140 var registrations = registrationsTable.get(target); | |
| 141 if (!registrations) registrationsTable.set(target, registrations = []); | |
| 142 var registration; | |
| 143 for (var i = 0; i < registrations.length; i++) { | |
| 144 if (registrations[i].observer === this) { | |
| 145 registration = registrations[i]; | |
| 146 registration.removeListeners(); | |
| 147 registration.options = options; | |
| 148 break; | |
| 149 } | |
| 150 } | |
| 151 if (!registration) { | |
| 152 registration = new Registration(this, target, options); | |
| 153 registrations.push(registration); | |
| 154 this.nodes_.push(target); | |
| 155 } | |
| 156 registration.addListeners(); | |
| 157 }, | |
| 158 disconnect: function() { | |
| 159 this.nodes_.forEach(function(node) { | |
| 160 var registrations = registrationsTable.get(node); | |
| 161 for (var i = 0; i < registrations.length; i++) { | |
| 162 var registration = registrations[i]; | |
| 163 if (registration.observer === this) { | |
| 164 registration.removeListeners(); | |
| 165 registrations.splice(i, 1); | |
| 166 break; | |
| 167 } | |
| 168 } | |
| 169 }, this); | |
| 170 this.records_ = []; | |
| 171 }, | |
| 172 takeRecords: function() { | |
| 173 var copyOfRecords = this.records_; | |
| 174 this.records_ = []; | |
| 175 return copyOfRecords; | |
| 176 } | |
| 177 }; | |
| 178 function MutationRecord(type, target) { | |
| 179 this.type = type; | |
| 180 this.target = target; | |
| 181 this.addedNodes = []; | |
| 182 this.removedNodes = []; | |
| 183 this.previousSibling = null; | |
| 184 this.nextSibling = null; | |
| 185 this.attributeName = null; | |
| 186 this.attributeNamespace = null; | |
| 187 this.oldValue = null; | |
| 188 } | |
| 189 function copyMutationRecord(original) { | |
| 190 var record = new MutationRecord(original.type, original.target); | |
| 191 record.addedNodes = original.addedNodes.slice(); | |
| 192 record.removedNodes = original.removedNodes.slice(); | |
| 193 record.previousSibling = original.previousSibling; | |
| 194 record.nextSibling = original.nextSibling; | |
| 195 record.attributeName = original.attributeName; | |
| 196 record.attributeNamespace = original.attributeNamespace; | |
| 197 record.oldValue = original.oldValue; | |
| 198 return record; | |
| 199 } | |
| 200 var currentRecord, recordWithOldValue; | |
| 201 function getRecord(type, target) { | |
| 202 return currentRecord = new MutationRecord(type, target); | |
| 203 } | |
| 204 function getRecordWithOldValue(oldValue) { | |
| 205 if (recordWithOldValue) return recordWithOldValue; | |
| 206 recordWithOldValue = copyMutationRecord(currentRecord); | |
| 207 recordWithOldValue.oldValue = oldValue; | |
| 208 return recordWithOldValue; | |
| 209 } | |
| 210 function clearRecords() { | |
| 211 currentRecord = recordWithOldValue = undefined; | |
| 212 } | |
| 213 function recordRepresentsCurrentMutation(record) { | |
| 214 return record === recordWithOldValue || record === currentRecord; | |
| 215 } | |
| 216 function selectRecord(lastRecord, newRecord) { | |
| 217 if (lastRecord === newRecord) return lastRecord; | |
| 218 if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord)) retur
n recordWithOldValue; | |
| 219 return null; | |
| 220 } | |
| 221 function Registration(observer, target, options) { | |
| 222 this.observer = observer; | |
| 223 this.target = target; | |
| 224 this.options = options; | |
| 225 this.transientObservedNodes = []; | |
| 226 } | |
| 227 Registration.prototype = { | |
| 228 enqueue: function(record) { | |
| 229 var records = this.observer.records_; | |
| 230 var length = records.length; | |
| 231 if (records.length > 0) { | |
| 232 var lastRecord = records[length - 1]; | |
| 233 var recordToReplaceLast = selectRecord(lastRecord, record); | |
| 234 if (recordToReplaceLast) { | |
| 235 records[length - 1] = recordToReplaceLast; | |
| 236 return; | |
| 237 } | |
| 238 } else { | |
| 239 scheduleCallback(this.observer); | |
| 240 } | |
| 241 records[length] = record; | |
| 242 }, | |
| 243 addListeners: function() { | |
| 244 this.addListeners_(this.target); | |
| 245 }, | |
| 246 addListeners_: function(node) { | |
| 247 var options = this.options; | |
| 248 if (options.attributes) node.addEventListener("DOMAttrModified", this, tru
e); | |
| 249 if (options.characterData) node.addEventListener("DOMCharacterDataModified
", this, true); | |
| 250 if (options.childList) node.addEventListener("DOMNodeInserted", this, true
); | |
| 251 if (options.childList || options.subtree) node.addEventListener("DOMNodeRe
moved", this, true); | |
| 252 }, | |
| 253 removeListeners: function() { | |
| 254 this.removeListeners_(this.target); | |
| 255 }, | |
| 256 removeListeners_: function(node) { | |
| 257 var options = this.options; | |
| 258 if (options.attributes) node.removeEventListener("DOMAttrModified", this,
true); | |
| 259 if (options.characterData) node.removeEventListener("DOMCharacterDataModif
ied", this, true); | |
| 260 if (options.childList) node.removeEventListener("DOMNodeInserted", this, t
rue); | |
| 261 if (options.childList || options.subtree) node.removeEventListener("DOMNod
eRemoved", this, true); | |
| 262 }, | |
| 263 addTransientObserver: function(node) { | |
| 264 if (node === this.target) return; | |
| 265 this.addListeners_(node); | |
| 266 this.transientObservedNodes.push(node); | |
| 267 var registrations = registrationsTable.get(node); | |
| 268 if (!registrations) registrationsTable.set(node, registrations = []); | |
| 269 registrations.push(this); | |
| 270 }, | |
| 271 removeTransientObservers: function() { | |
| 272 var transientObservedNodes = this.transientObservedNodes; | |
| 273 this.transientObservedNodes = []; | |
| 274 transientObservedNodes.forEach(function(node) { | |
| 275 this.removeListeners_(node); | |
| 276 var registrations = registrationsTable.get(node); | |
| 277 for (var i = 0; i < registrations.length; i++) { | |
| 278 if (registrations[i] === this) { | |
| 279 registrations.splice(i, 1); | |
| 280 break; | |
| 281 } | |
| 282 } | |
| 283 }, this); | |
| 284 }, | |
| 285 handleEvent: function(e) { | |
| 286 e.stopImmediatePropagation(); | |
| 287 switch (e.type) { | |
| 288 case "DOMAttrModified": | |
| 289 var name = e.attrName; | |
| 290 var namespace = e.relatedNode.namespaceURI; | |
| 291 var target = e.target; | |
| 292 var record = new getRecord("attributes", target); | |
| 293 record.attributeName = name; | |
| 294 record.attributeNamespace = namespace; | |
| 295 var oldValue = e.attrChange === MutationEvent.ADDITION ? null : e.prevVa
lue; | |
| 296 forEachAncestorAndObserverEnqueueRecord(target, function(options) { | |
| 297 if (!options.attributes) return; | |
| 298 if (options.attributeFilter && options.attributeFilter.length && optio
ns.attributeFilter.indexOf(name) === -1 && options.attributeFilter.indexOf(names
pace) === -1) { | |
| 299 return; | |
| 300 } | |
| 301 if (options.attributeOldValue) return getRecordWithOldValue(oldValue); | |
| 302 return record; | |
| 303 }); | |
| 304 break; | |
| 305 | |
| 306 case "DOMCharacterDataModified": | |
| 307 var target = e.target; | |
| 308 var record = getRecord("characterData", target); | |
| 309 var oldValue = e.prevValue; | |
| 310 forEachAncestorAndObserverEnqueueRecord(target, function(options) { | |
| 311 if (!options.characterData) return; | |
| 312 if (options.characterDataOldValue) return getRecordWithOldValue(oldVal
ue); | |
| 313 return record; | |
| 314 }); | |
| 315 break; | |
| 316 | |
| 317 case "DOMNodeRemoved": | |
| 318 this.addTransientObserver(e.target); | |
| 319 | |
| 320 case "DOMNodeInserted": | |
| 321 var changedNode = e.target; | |
| 322 var addedNodes, removedNodes; | |
| 323 if (e.type === "DOMNodeInserted") { | |
| 324 addedNodes = [ changedNode ]; | |
| 325 removedNodes = []; | |
| 326 } else { | |
| 327 addedNodes = []; | |
| 328 removedNodes = [ changedNode ]; | |
| 329 } | |
| 330 var previousSibling = changedNode.previousSibling; | |
| 331 var nextSibling = changedNode.nextSibling; | |
| 332 var record = getRecord("childList", e.target.parentNode); | |
| 333 record.addedNodes = addedNodes; | |
| 334 record.removedNodes = removedNodes; | |
| 335 record.previousSibling = previousSibling; | |
| 336 record.nextSibling = nextSibling; | |
| 337 forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options)
{ | |
| 338 if (!options.childList) return; | |
| 339 return record; | |
| 340 }); | |
| 341 } | |
| 342 clearRecords(); | |
| 343 } | |
| 344 }; | |
| 345 global.JsMutationObserver = JsMutationObserver; | |
| 346 if (!global.MutationObserver) { | |
| 347 global.MutationObserver = JsMutationObserver; | |
| 348 JsMutationObserver._isPolyfilled = true; | |
| 349 } | |
| 350 })(self); | |
| OLD | NEW |