15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Google Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * its contributors may be used to endorse or promote products derived 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * from this software without specific prior written permission. 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Contains diff method based on Javascript Diff Algorithm By John Resig 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * http://ejohn.org/files/jsdiff.js (released under the MIT license). 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {string=} direction 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction) 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var startNode; 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var startOffset = 0; 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var endNode; 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var endOffset = 0; 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!stayWithinNode) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) stayWithinNode = this; 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!direction || direction === "backward" || direction === "both") { 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var node = this; 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (node) { 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node === stayWithinNode) { 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!startNode) 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startNode = stayWithinNode; 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node.nodeType === Node.TEXT_NODE) { 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1)); 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = start; i >= 0; --i) { 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) { 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startNode = node; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startOffset = i + 1; 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (startNode) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node.traversePreviousNode(stayWithinNode); 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!startNode) { 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startNode = stayWithinNode; 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startOffset = 0; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startNode = this; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) startOffset = offset; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!direction || direction === "forward" || direction === "both") { 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = this; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (node) { 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node === stayWithinNode) { 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!endNode) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endNode = stayWithinNode; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node.nodeType === Node.TEXT_NODE) { 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var start = (node === this ? offset : 0); 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = start; i < node.nodeValue.length; ++i) { 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) { 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endNode = node; 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endOffset = i; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (endNode) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node.traverseNextNode(stayWithinNode); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!endNode) { 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endNode = stayWithinNode; 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length; 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endNode = this; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) endOffset = offset; 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var result = this.ownerDocument.createRange(); 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.setStart(startNode, startOffset); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result.setEnd(endNode, endOffset); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.traverseNextTextNode = function(stayWithin) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var node = this.traverseNextNode(stayWithin); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!node) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (node && node.nodeType !== Node.TEXT_NODE) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node.traverseNextNode(stayWithin); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return node; 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.rangeBoundaryForOffset = function(offset) 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var node = this.traverseNextTextNode(this); 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (node && offset > node.nodeValue.length) { 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) offset -= node.nodeValue.length; 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node.traverseNextTextNode(this); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!node) 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return { container: this, offset: 0 }; 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return { container: node, offset: offset }; 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/** 148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {string} className 149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.removeStyleClass = function(className) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.classList.remove(className); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.removeMatchingStyleClasses = function(classNameRegex) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var regex = new RegExp("(^|\\s+)" + classNameRegex + "($|\\s+)"); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (regex.test(this.className)) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.className = this.className.replace(regex, " "); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/** 163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {string} className 164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.addStyleClass = function(className) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.classList.add(className); 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 170926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/** 171926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {string} className 172926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @return {boolean} 173926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.hasStyleClass = function(className) 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.classList.contains(className); 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 180926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {string} className 181926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {*} enable 182926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 183926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)Element.prototype.enableStyleClass = function(className, enable) 184926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 185926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (enable) 186926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) this.addStyleClass(className); 187926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else 188926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) this.removeStyleClass(className); 189926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 190926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 191926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/** 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {number|undefined} x 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {number|undefined} y 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.positionAt = function(x, y) 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (typeof x === "number") 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.style.setProperty("left", x + "px"); 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.style.removeProperty("left"); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (typeof y === "number") 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.style.setProperty("top", y + "px"); 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.style.removeProperty("top"); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.isScrolledToBottom = function() 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This code works only for 0-width border 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.scrollTop + this.clientHeight === this.scrollHeight; 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 214926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/** 215926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {Node} fromNode 216926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {Node} toNode 217926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 218926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)function removeSubsequentNodes(fromNode, toNode) 219926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 220926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (var node = fromNode; node && node !== toNode; ) { 221926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) var nodeToRemove = node; 222926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) node = node.nextSibling; 223591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch nodeToRemove.remove(); 224926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 225926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 226926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {number} width 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {number} height 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function Size(width, height) 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.width = width; 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.height = height; 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 23953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * @param {Element=} containerElement 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @return {Size} 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 24253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)Element.prototype.measurePreferredSize = function(containerElement) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 24453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) containerElement = containerElement || document.body; 24553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) containerElement.appendChild(this); 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.positionAt(0, 0); 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var result = new Size(this.offsetWidth, this.offsetHeight); 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.positionAt(undefined, undefined); 249591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch this.remove(); 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return result; 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var node = this; node && node !== this.ownerDocument; node = node.parentNode) 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var i = 0; i < nameArray.length; ++i) 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase()) 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return node; 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName) 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]); 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 267926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/** 268926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {string} className 269926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {Element=} stayWithin 270926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 271926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)Node.prototype.enclosingNodeOrSelfWithClass = function(className, stayWithin) 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 273926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) for (var node = this; node && node !== stayWithin && node !== this.ownerDocument; node = node.parentNode) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className)) 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return node; 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.query = function(query) 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.removeChildren = function() 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (this.firstChild) 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.textContent = ""; 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.isInsertionCaretInside = function() 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selection = window.getSelection(); 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!selection.rangeCount || !selection.isCollapsed) 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selectionRange = selection.getRangeAt(0); 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return selectionRange.startContainer.isSelfOrDescendant(this); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {string=} className 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.createChild = function(elementName, className) 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var element = this.ownerDocument.createElement(elementName); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (className) 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) element.className = className; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.appendChild(element); 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element; 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DocumentFragment.prototype.createChild = Element.prototype.createChild; 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {string} text 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.createTextChild = function(text) 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var element = this.ownerDocument.createTextNode(text); 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.appendChild(element); 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return element; 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild; 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @return {number} 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.totalOffsetLeft = function() 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.totalOffset().left; 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @return {number} 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.totalOffsetTop = function() 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.totalOffset().top; 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.totalOffset = function() 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var totalLeft = 0; 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var totalTop = 0; 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var element = this; element; element = element.offsetParent) { 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalLeft += element.offsetLeft; 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalTop += element.offsetTop; 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (this !== element) { 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalLeft += element.clientLeft - element.scrollLeft; 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) totalTop += element.clientTop - element.scrollTop; 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return { left: totalLeft, top: totalTop }; 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.scrollOffset = function() 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var curLeft = 0; 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var curTop = 0; 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (var element = this; element; element = element.scrollParent) { 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curLeft += element.scrollLeft; 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curTop += element.scrollTop; 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return { left: curLeft, top: curTop }; 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @constructor 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {number=} x 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {number=} y 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {number=} width 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {number=} height 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function AnchorBox(x, y, width, height) 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.x = x || 0; 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.y = y || 0; 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.width = width || 0; 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.height = height || 0; 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {Window} targetWindow 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @return {AnchorBox} 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.offsetRelativeToWindow = function(targetWindow) 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var elementOffset = new AnchorBox(); 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var curElement = this; 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var curWindow = this.ownerDocument.defaultView; 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (curWindow && curElement) { 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) elementOffset.x += curElement.totalOffsetLeft(); 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) elementOffset.y += curElement.totalOffsetTop(); 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (curWindow === targetWindow) 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curElement = curWindow.frameElement; 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) curWindow = curWindow.parent; 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return elementOffset; 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {Window} targetWindow 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @return {AnchorBox} 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.boxInWindow = function(targetWindow) 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) targetWindow = targetWindow || this.ownerDocument.defaultView; 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var anchorBox = this.offsetRelativeToWindow(window); 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) anchorBox.width = Math.min(this.offsetWidth, window.innerWidth - anchorBox.x); 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) anchorBox.height = Math.min(this.offsetHeight, window.innerHeight - anchorBox.y); 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return anchorBox; 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {string} text 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.setTextAndTitle = function(text) 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.textContent = text; 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.title = text; 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)KeyboardEvent.prototype.__defineGetter__("data", function() 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Emulate "data" attribute from DOM 3 TextInput event. 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See http://www.w3.org/TR/DOM-Level-3-Events/#events-Events-TextEvent-data 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (this.type) { 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case "keypress": 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!this.ctrlKey && !this.metaKey) 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return String.fromCharCode(this.charCode); 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ""; 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case "keydown": 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case "keyup": 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!this.ctrlKey && !this.metaKey && !this.altKey) 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return String.fromCharCode(this.which); 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ""; 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}); 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/** 4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * @param {boolean=} preventDefault 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Event.prototype.consume = function(preventDefault) 4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.stopImmediatePropagation(); 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (preventDefault) 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.preventDefault(); 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) this.handled = true; 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Text.prototype.select = function(start, end) 4625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) start = start || 0; 4645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) end = end || this.textContent.length; 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (start < 0) 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) start = end + start; 4685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selection = this.ownerDocument.defaultView.getSelection(); 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selection.removeAllRanges(); 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var range = this.ownerDocument.createRange(); 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) range.setStart(this, start); 4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) range.setEnd(this, end); 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) selection.addRange(range); 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this; 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Element.prototype.selectionLeftOffset = function() 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Calculate selection offset relative to the current element. 4815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var selection = window.getSelection(); 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!selection.containsNode(this, true)) 4845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 4855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var leftOffset = selection.anchorOffset; 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var node = selection.anchorNode; 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (node !== this) { 4905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (node.previousSibling) { 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node.previousSibling; 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) leftOffset += node.textContent.length; 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node.parentNode; 4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return leftOffset; 4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.isAncestor = function(node) 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!node) 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 5045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var currentNode = node.parentNode; 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (currentNode) { 5075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (this === currentNode) 5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) currentNode = currentNode.parentNode; 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.isDescendant = function(descendant) 5155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !!descendant && descendant.isAncestor(this); 5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.isSelfOrAncestor = function(node) 5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !!node && (node === this || this.isAncestor(node)); 5225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.isSelfOrDescendant = function(node) 5255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !!node && (node === this || this.isDescendant(node)); 5275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.traverseNextNode = function(stayWithin) 5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var node = this.firstChild; 5325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node) 5335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return node; 5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stayWithin && this === stayWithin) 5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = this.nextSibling; 5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node) 5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return node; 5415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = this; 5435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node.parentNode !== stayWithin)) 5445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node.parentNode; 5455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!node) 5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return node.nextSibling; 5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Node.prototype.traversePreviousNode = function(stayWithin) 5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (stayWithin && this === stayWithin) 5545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return null; 5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) var node = this.previousSibling; 5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (node && node.lastChild) 5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) node = node.lastChild; 5585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (node) 5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return node; 5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return this.parentNode; 5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function isEnterKey(event) { 5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check if in IME. 5655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return event.keyCode !== 229 && event.keyIdentifier === "Enter"; 5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)function consumeEvent(e) 5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) e.consume(); 5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 572926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 573926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/** 574926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Mutation observers leak memory. Keep track of them and disconnect 575926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * on unload. 576926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @constructor 577926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {function(Array.<WebKitMutation>)} handler 578926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 579926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)function NonLeakingMutationObserver(handler) 580926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 581926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) this._observer = new WebKitMutationObserver(handler); 582926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) NonLeakingMutationObserver._instances.push(this); 583926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!NonLeakingMutationObserver._unloadListener) { 584926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) NonLeakingMutationObserver._unloadListener = function() { 585926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) while (NonLeakingMutationObserver._instances.length) 586926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) NonLeakingMutationObserver._instances[NonLeakingMutationObserver._instances.length - 1].disconnect(); 587926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) }; 588926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) window.addEventListener("unload", NonLeakingMutationObserver._unloadListener, false); 589926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 590926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 591926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 592926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)NonLeakingMutationObserver._instances = []; 593926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 594926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)NonLeakingMutationObserver.prototype = { 595926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) /** 596926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {Element} element 597926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * @param {Object} config 598926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) */ 599926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) observe: function(element, config) 600926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 601926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (this._observer) 602926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) this._observer.observe(element, config); 603926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) }, 604926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 605926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) disconnect: function() 606926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) { 607926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (this._observer) 608926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) this._observer.disconnect(); 609926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) NonLeakingMutationObserver._instances.remove(this); 610926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) delete this._observer; 611926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) } 612926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 613926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 614