Changeset 43 for trunk/npemap.org.uk
- Timestamp:
- Oct 15, 2006, 4:24:02 PM (14 years ago)
- Location:
- trunk/npemap.org.uk/static/tiles
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/npemap.org.uk/static/tiles/dom.js
r17 r43 1 /* 2 Copyright (c) 2006, Yahoo! Inc. All rights reserved. 3 Code licensed under the BSD License: 4 http://developer.yahoo.net/yui/license.txt 5 Version: 0.11.3 6 */ 7 8 /** 9 * @class Provides helper methods for DOM elements. 10 */ 11 YAHOO.util.Dom = function() { 12 var ua = navigator.userAgent.toLowerCase(); 13 var isOpera = (ua.indexOf('opera') > -1); 14 var isSafari = (ua.indexOf('safari') > -1); 15 var isIE = (window.ActiveXObject); 16 17 var id_counter = 0; 18 var util = YAHOO.util; // internal shorthand 19 var property_cache = {}; // to cache case conversion for set/getStyle 20 21 var toCamel = function(property) { 22 var convert = function(prop) { 23 var test = /(-[a-z])/i.exec(prop); 24 return prop.replace(RegExp.$1, RegExp.$1.substr(1).toUpperCase()); 25 }; 26 27 while(property.indexOf('-') > -1) { 28 property = convert(property); 29 } 30 31 return property; 32 //return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUpperCase()}) // cant use function as 2nd arg yet due to safari bug 33 }; 34 35 var toHyphen = function(property) { 36 if (property.indexOf('-') > -1) { // assume hyphen 37 return property; 38 } 39 40 var converted = ''; 41 for (var i = 0, len = property.length;i < len; ++i) { 42 if (property.charAt(i) == property.charAt(i).toUpperCase()) { 43 converted = converted + '-' + property.charAt(i).toLowerCase(); 44 } else { 45 converted = converted + property.charAt(i); 46 } 47 } 48 49 return converted; 50 //return property.replace(/([a-z])([A-Z]+)/g, function(m0, m1, m2) {return (m1 + '-' + m2.toLowerCase())}); 51 }; 52 53 // improve performance by only looking up once 54 var cacheConvertedProperties = function(property) { 55 property_cache[property] = { 56 camel: toCamel(property), 57 hyphen: toHyphen(property) 58 }; 59 }; 60 61 return { 62 /** 63 * Returns an HTMLElement reference 64 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID for getting a DOM reference, an actual DOM reference, or an Array of IDs and/or HTMLElements. 65 * @return {HTMLElement/Array} A DOM reference to an HTML element or an array of HTMLElements. 66 */ 67 get: function(el) { 68 if (!el) { return null; } // nothing to work with 69 70 if (typeof el != 'string' && !(el instanceof Array) ) { // assuming HTMLElement or HTMLCollection, so pass back as is 71 return el; 72 } 73 74 if (typeof el == 'string') { // ID 75 return document.getElementById(el); 76 } 77 else { // array of ID's and/or elements 78 var collection = []; 79 for (var i = 0, len = el.length; i < len; ++i) { 80 collection[collection.length] = util.Dom.get(el[i]); 81 } 82 83 return collection; 84 } 85 86 return null; // safety, should never happen 87 }, 88 89 /** 90 * Normalizes currentStyle and ComputedStyle. 91 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements. 92 * @param {String} property The style property whose value is returned. 93 * @return {String/Array} The current value of the style property for the element(s). 94 */ 95 getStyle: function(el, property) { 96 var f = function(el) { 97 var value = null; 98 var dv = document.defaultView; 99 100 if (!property_cache[property]) { 101 cacheConvertedProperties(property); 102 } 103 104 var camel = property_cache[property]['camel']; 105 var hyphen = property_cache[property]['hyphen']; 106 107 if (property == 'opacity' && el.filters) {// IE opacity 108 value = 1; 109 try { 110 value = el.filters.item('DXImageTransform.Microsoft.Alpha').opacity / 100; 111 } catch(e) { 112 try { 113 value = el.filters.item('alpha').opacity / 100; 114 } catch(e) {} 115 } 116 } else if (el.style[camel]) { // camelCase for valid styles 117 value = el.style[camel]; 118 } 119 else if (isIE && el.currentStyle && el.currentStyle[camel]) { // camelCase for currentStyle; isIE to workaround broken Opera 9 currentStyle 120 value = el.currentStyle[camel]; 121 } 122 else if ( dv && dv.getComputedStyle ) { // hyphen-case for computedStyle 123 var computed = dv.getComputedStyle(el, ''); 124 125 if (computed && computed.getPropertyValue(hyphen)) { 126 value = computed.getPropertyValue(hyphen); 127 } 128 } 129 130 return value; 131 }; 132 133 return util.Dom.batch(el, f, util.Dom, true); 134 }, 135 136 /** 137 * Wrapper for setting style properties of HTMLElements. Normalizes "opacity" across modern browsers. 138 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements. 139 * @param {String} property The style property to be set. 140 * @param {String} val The value to apply to the given property. 141 */ 142 setStyle: function(el, property, val) { 143 if (!property_cache[property]) { 144 cacheConvertedProperties(property); 145 } 146 147 var camel = property_cache[property]['camel']; 148 149 var f = function(el) { 150 switch(property) { 151 case 'opacity' : 152 if (isIE && typeof el.style.filter == 'string') { // in case not appended 153 el.style.filter = 'alpha(opacity=' + val * 100 + ')'; 154 155 if (!el.currentStyle || !el.currentStyle.hasLayout) { 156 el.style.zoom = 1; // when no layout or cant tell 157 } 158 } else { 159 el.style.opacity = val; 160 el.style['-moz-opacity'] = val; 161 el.style['-khtml-opacity'] = val; 162 } 163 164 break; 165 default : 166 el.style[camel] = val; 167 } 168 169 170 }; 171 172 util.Dom.batch(el, f, util.Dom, true); 173 }, 174 175 /** 176 * Gets the current position of an element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 177 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements 178 @ return {Array} The XY position of the element(s) 179 */ 180 getXY: function(el) { 181 var f = function(el) { 182 183 // has to be part of document to have pageXY 184 if (el.offsetParent === null || this.getStyle(el, 'display') == 'none') { 185 return false; 186 } 187 188 var parentNode = null; 189 var pos = []; 190 var box; 191 192 if (el.getBoundingClientRect) { // IE 193 box = el.getBoundingClientRect(); 194 var doc = document; 195 if ( !this.inDocument(el) && parent.document != document) {// might be in a frame, need to get its scroll 196 doc = parent.document; 197 198 if ( !this.isAncestor(doc.documentElement, el) ) { 199 return false; 200 } 201 202 } 203 204 var scrollTop = Math.max(doc.documentElement.scrollTop, doc.body.scrollTop); 205 var scrollLeft = Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft); 206 207 return [box.left + scrollLeft, box.top + scrollTop]; 208 } 209 else { // safari, opera, & gecko 210 pos = [el.offsetLeft, el.offsetTop]; 211 parentNode = el.offsetParent; 212 if (parentNode != el) { 213 while (parentNode) { 214 pos[0] += parentNode.offsetLeft; 215 pos[1] += parentNode.offsetTop; 216 parentNode = parentNode.offsetParent; 217 } 218 } 219 if (isSafari && this.getStyle(el, 'position') == 'absolute' ) { // safari doubles in some cases 220 pos[0] -= document.body.offsetLeft; 221 pos[1] -= document.body.offsetTop; 222 } 223 } 224 225 if (el.parentNode) { parentNode = el.parentNode; } 226 else { parentNode = null; } 227 228 while (parentNode && parentNode.tagName.toUpperCase() != 'BODY' && parentNode.tagName.toUpperCase() != 'HTML') 229 { // account for any scrolled ancestors 230 if (util.Dom.getStyle(parentNode, 'display') != 'inline') { // work around opera inline scrollLeft/Top bug 231 pos[0] -= parentNode.scrollLeft; 232 pos[1] -= parentNode.scrollTop; 233 } 234 235 if (parentNode.parentNode) { parentNode = parentNode.parentNode; } 236 else { parentNode = null; } 237 } 238 239 240 return pos; 241 }; 242 243 return util.Dom.batch(el, f, util.Dom, true); 244 }, 245 246 /** 247 * Gets the current X position of an element based on page coordinates. The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 248 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements 249 * @return {String/Array} The X position of the element(s) 250 */ 251 getX: function(el) { 252 var f = function(el) { 253 return util.Dom.getXY(el)[0]; 254 }; 255 256 return util.Dom.batch(el, f, util.Dom, true); 257 }, 258 259 /** 260 * Gets the current Y position of an element based on page coordinates. Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 261 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements 262 * @return {String/Array} The Y position of the element(s) 263 */ 264 getY: function(el) { 265 var f = function(el) { 266 return util.Dom.getXY(el)[1]; 267 }; 268 269 return util.Dom.batch(el, f, util.Dom, true); 270 }, 271 272 /** 273 * Set the position of an html element in page coordinates, regardless of how the element is positioned. 274 * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 275 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements 276 * @param {Array} pos Contains X & Y values for new position (coordinates are page-based) 277 * @param {Boolean} noRetry By default we try and set the position a second time if the first fails 278 */ 279 setXY: function(el, pos, noRetry) { 280 var f = function(el) { 281 var style_pos = this.getStyle(el, 'position'); 282 if (style_pos == 'static') { // default to relative 283 this.setStyle(el, 'position', 'relative'); 284 style_pos = 'relative'; 285 } 286 287 var pageXY = this.getXY(el); 288 if (pageXY === false) { // has to be part of doc to have pageXY 289 return false; 290 } 291 292 var delta = [ // assuming pixels; if not we will have to retry 293 parseInt( this.getStyle(el, 'left'), 10 ), 294 parseInt( this.getStyle(el, 'top'), 10 ) 295 ]; 296 297 if ( isNaN(delta[0]) ) {// in case of 'auto' 298 delta[0] = (style_pos == 'relative') ? 0 : el.offsetLeft; 299 } 300 if ( isNaN(delta[1]) ) { // in case of 'auto' 301 delta[1] = (style_pos == 'relative') ? 0 : el.offsetTop; 302 } 303 304 if (pos[0] !== null) { el.style.left = pos[0] - pageXY[0] + delta[0] + 'px'; } 305 if (pos[1] !== null) { el.style.top = pos[1] - pageXY[1] + delta[1] + 'px'; } 306 307 var newXY = this.getXY(el); 308 309 // if retry is true, try one more time if we miss 310 if (!noRetry && (newXY[0] != pos[0] || newXY[1] != pos[1]) ) { 311 this.setXY(el, pos, true); 312 } 313 314 }; 315 316 util.Dom.batch(el, f, util.Dom, true); 317 }, 318 319 /** 320 * Set the X position of an html element in page coordinates, regardless of how the element is positioned. 321 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 322 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements. 323 * @param {Int} x to use as the X coordinate for the element(s). 324 */ 325 setX: function(el, x) { 326 util.Dom.setXY(el, [x, null]); 327 }, 328 329 /** 330 * Set the Y position of an html element in page coordinates, regardless of how the element is positioned. 331 * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false). 332 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements. 333 * @param {Int} x to use as the Y coordinate for the element(s). 334 */ 335 setY: function(el, y) { 336 util.Dom.setXY(el, [null, y]); 337 }, 338 339 /** 340 * Returns the region position of the given element. 341 * The element must be part of the DOM tree to have a region (display:none or elements not appended return false). 342 * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements. 343 * @return {Region/Array} A Region or array of Region instances containing "top, left, bottom, right" member data. 344 */ 345 getRegion: function(el) { 346 var f = function(el) { 347 var region = new YAHOO.util.Region.getRegion(el); 348 return region; 349 }; 350 351 return util.Dom.batch(el, f, util.Dom, true); 352 }, 353 354 /** 355 * Returns the width of the client (viewport). 356 * Now using getViewportWidth. This interface left intact for back compat. 357 * @return {Int} The width of the viewable area of the page. 358 */ 359 getClientWidth: function() { 360 return util.Dom.getViewportWidth(); 361 }, 362 363 /** 364 * Returns the height of the client (viewport). 365 * Now using getViewportHeight. This interface left intact for back compat. 366 * @return {Int} The height of the viewable area of the page. 367 */ 368 getClientHeight: function() { 369 return util.Dom.getViewportHeight(); 370 }, 371 372 /** 373 * Returns a array of HTMLElements with the given class 374 * For optimized performance, include a tag and/or root node if possible 375 * @param {String} className The class name to match against 376 * @param {String} tag (optional) The tag name of the elements being collected 377 * @param {String/HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point 378 * @return {Array} An array of elements that have the given class name 379 */ 380 getElementsByClassName: function(className, tag, root) { 381 var method = function(el) { return util.Dom.hasClass(el, className) }; 382 return util.Dom.getElementsBy(method, tag, root); 383 }, 384 385 /** 386 * Determines whether an HTMLElement has the given className 387 * @param {String/HTMLElement/Array} el The element or collection to test 388 * @param {String} className the class name to search for 389 * @return {Boolean/Array} A boolean value or array of boolean values 390 */ 391 hasClass: function(el, className) { 392 var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)'); 393 394 var f = function(el) { 395 return re.test(el['className']); 396 }; 397 398 return util.Dom.batch(el, f, util.Dom, true); 399 }, 400 401 /** 402 * Adds a class name to a given element or collection of elements 403 * @param {String/HTMLElement/Array} el The element or collection to add the class to 404 * @param {String} className the class name to add to the class attribute 405 */ 406 addClass: function(el, className) { 407 var f = function(el) { 408 if (this.hasClass(el, className)) { return; } // already present 409 410 411 el['className'] = [el['className'], className].join(' '); 412 }; 413 414 util.Dom.batch(el, f, util.Dom, true); 415 }, 416 417 /** 418 * Removes a class name from a given element or collection of elements 419 * @param {String/HTMLElement/Array} el The element or collection to remove the class from 420 * @param {String} className the class name to remove from the class attribute 421 */ 422 removeClass: function(el, className) { 423 var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', 'g'); 424 425 var f = function(el) { 426 if (!this.hasClass(el, className)) { return; } // not present 427 428 429 var c = el['className']; 430 el['className'] = c.replace(re, ' '); 431 if ( this.hasClass(el, className) ) { // in case of multiple adjacent 432 this.removeClass(el, className); 433 } 434 435 }; 436 437 util.Dom.batch(el, f, util.Dom, true); 438 }, 439 440 /** 441 * Replace a class with another class for a given element or collection of elements. 442 * If no oldClassName is present, the newClassName is simply added. 443 * @param {String/HTMLElement/Array} el The element or collection to remove the class from 444 * @param {String} oldClassName the class name to be replaced 445 * @param {String} newClassName the class name that will be replacing the old class name 446 */ 447 replaceClass: function(el, oldClassName, newClassName) { 448 if (oldClassName === newClassName) { // avoid infinite loop 449 return false; 450 }; 451 452 var re = new RegExp('(?:^|\\s+)' + oldClassName + '(?:\\s+|$)', 'g'); 453 454 var f = function(el) { 455 456 if ( !this.hasClass(el, oldClassName) ) { 457 this.addClass(el, newClassName); // just add it if nothing to replace 458 return; // note return 459 } 460 461 el['className'] = el['className'].replace(re, ' ' + newClassName + ' '); 462 463 if ( this.hasClass(el, oldClassName) ) { // in case of multiple adjacent 464 this.replaceClass(el, oldClassName, newClassName); 465 } 466 }; 467 468 util.Dom.batch(el, f, util.Dom, true); 469 }, 470 471 /** 472 * Generates a unique ID 473 * @param {String/HTMLElement/Array} el (optional) An optional element array of elements to add an ID to (no ID is added if one is already present) 474 * @param {String} prefix (optional) an optional prefix to use (defaults to "yui-gen") 475 * @return {String/Array} The generated ID, or array of generated IDs (or original ID if already present on an element) 476 */ 477 generateId: function(el, prefix) { 478 prefix = prefix || 'yui-gen'; 479 el = el || {}; 480 481 var f = function(el) { 482 if (el) { 483 el = util.Dom.get(el); 484 } else { 485 el = {}; // just generating ID in this case 486 } 487 488 if (!el.id) { 489 el.id = prefix + id_counter++; 490 } // dont override existing 491 492 493 return el.id; 494 }; 495 496 return util.Dom.batch(el, f, util.Dom, true); 497 }, 498 499 /** 500 * Determines whether an HTMLElement is an ancestor of another HTML element in the DOM hierarchy 501 * @param {String/HTMLElement} haystack The possible ancestor 502 * @param {String/HTMLElement} needle The possible descendent 503 * @return {Boolean} Whether or not the haystack is an ancestor of needle 504 */ 505 isAncestor: function(haystack, needle) { 506 haystack = util.Dom.get(haystack); 507 if (!haystack || !needle) { return false; } 508 509 var f = function(needle) { 510 if (haystack.contains && !isSafari) { // safari "contains" is broken 511 return haystack.contains(needle); 512 } 513 else if ( haystack.compareDocumentPosition ) { 514 return !!(haystack.compareDocumentPosition(needle) & 16); 515 } 516 else { // loop up and test each parent 517 var parent = needle.parentNode; 518 519 while (parent) { 520 if (parent == haystack) { 521 return true; 522 } 523 else if (!parent.tagName || parent.tagName.toUpperCase() == 'HTML') { 524 return false; 525 } 526 527 parent = parent.parentNode; 528 } 529 return false; 530 } 531 }; 532 533 return util.Dom.batch(needle, f, util.Dom, true); 534 }, 535 536 /** 537 * Determines whether an HTMLElement is present in the current document 538 * @param {String/HTMLElement} el The element to search for 539 * @return {Boolean} Whether or not the element is present in the current document 540 */ 541 inDocument: function(el) { 542 var f = function(el) { 543 return this.isAncestor(document.documentElement, el); 544 }; 545 546 return util.Dom.batch(el, f, util.Dom, true); 547 }, 548 549 /** 550 * Returns a array of HTMLElements that pass the test applied by supplied boolean method 551 * For optimized performance, include a tag and/or root node if possible 552 * @param {Function} method A boolean method to test elements with 553 * @param {String} tag (optional) The tag name of the elements being collected 554 * @param {String/HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point 555 */ 556 getElementsBy: function(method, tag, root) { 557 tag = tag || '*'; 558 root = util.Dom.get(root) || document; 559 560 var nodes = []; 561 var elements = root.getElementsByTagName(tag); 562 563 if ( !elements.length && (tag == '*' && root.all) ) { 564 elements = root.all; // IE < 6 565 } 566 567 for (var i = 0, len = elements.length; i < len; ++i) 568 { 569 if ( method(elements[i]) ) { nodes[nodes.length] = elements[i]; } 570 } 571 572 573 return nodes; 574 }, 575 576 /** 577 * Returns an array of elements that have had the supplied method applied. 578 * The method is called with the element(s) as the first arg, and the optional param as the second ( method(el, o) ) 579 * @param {String/HTMLElement/Array} el (optional) An element or array of elements to apply the method to 580 * @param {Function} method The method to apply to the element(s) 581 * @param {Generic} (optional) o An optional arg that is passed to the supplied method 582 * @param {Boolean} (optional) override Whether or not to override the scope of "method" with "o" 583 * @return {HTMLElement/Array} The element(s) with the method applied 584 */ 585 batch: function(el, method, o, override) { 586 var id = el; 587 el = util.Dom.get(el); 588 589 var scope = (override) ? o : window; 590 591 if (!el || el.tagName || !el.length) { // is null or not a collection (tagName for SELECT and others that can be both an element and a collection) 592 if (!el) { 593 return false; 594 } 595 return method.call(scope, el, o); 596 } 597 598 var collection = []; 599 600 for (var i = 0, len = el.length; i < len; ++i) { 601 if (!el[i]) { 602 id = id[i]; 603 } 604 collection[collection.length] = method.call(scope, el[i], o); 605 } 606 607 return collection; 608 }, 609 610 /** 611 * Returns the height of the document. 612 * @return {Int} The height of the actual document (which includes the body and its margin). 613 */ 614 getDocumentHeight: function() { 615 var scrollHeight=-1,windowHeight=-1,bodyHeight=-1; 616 var marginTop = parseInt(util.Dom.getStyle(document.body, 'marginTop'), 10); 617 var marginBottom = parseInt(util.Dom.getStyle(document.body, 'marginBottom'), 10); 618 619 var mode = document.compatMode; 620 621 if ( (mode || isIE) && !isOpera ) { // (IE, Gecko) 622 switch (mode) { 623 case 'CSS1Compat': // Standards mode 624 scrollHeight = ((window.innerHeight && window.scrollMaxY) ? window.innerHeight+window.scrollMaxY : -1); 625 windowHeight = [document.documentElement.clientHeight,self.innerHeight||-1].sort(function(a, b){return(a-b);})[1]; 626 bodyHeight = document.body.offsetHeight + marginTop + marginBottom; 627 break; 628 629 default: // Quirks 630 scrollHeight = document.body.scrollHeight; 631 bodyHeight = document.body.clientHeight; 632 } 633 } else { // Safari & Opera 634 scrollHeight = document.documentElement.scrollHeight; 635 windowHeight = self.innerHeight; 636 bodyHeight = document.documentElement.clientHeight; 637 } 638 639 var h = [scrollHeight,windowHeight,bodyHeight].sort(function(a, b){return(a-b);}); 640 return h[2]; 641 }, 642 643 /** 644 * Returns the width of the document. 645 * @return {Int} The width of the actual document (which includes the body and its margin). 646 */ 647 getDocumentWidth: function() { 648 var docWidth=-1,bodyWidth=-1,winWidth=-1; 649 var marginRight = parseInt(util.Dom.getStyle(document.body, 'marginRight'), 10); 650 var marginLeft = parseInt(util.Dom.getStyle(document.body, 'marginLeft'), 10); 651 652 var mode = document.compatMode; 653 654 if (mode || isIE) { // (IE, Gecko, Opera) 655 switch (mode) { 656 case 'CSS1Compat': // Standards mode 657 docWidth = document.documentElement.clientWidth; 658 bodyWidth = document.body.offsetWidth + marginLeft + marginRight; 659 break; 660 661 default: // Quirks 662 bodyWidth = document.body.clientWidth; 663 docWidth = document.body.scrollWidth; 664 break; 665 } 666 } else { // Safari 667 docWidth = document.documentElement.clientWidth; 668 bodyWidth = document.body.offsetWidth + marginLeft + marginRight; 669 } 670 671 var w = Math.max(docWidth, bodyWidth); 672 return w; 673 }, 674 675 /** 676 * Returns the current height of the viewport. 677 * @return {Int} The height of the viewable area of the page (excludes scrollbars). 678 */ 679 getViewportHeight: function() { 680 var height = -1; 681 var mode = document.compatMode; 682 683 if ( (mode || isIE) && !isOpera ) { 684 switch (mode) { // (IE, Gecko) 685 case 'CSS1Compat': // Standards mode 686 height = document.documentElement.clientHeight; 687 break; 688 689 default: // Quirks 690 height = document.body.clientHeight; 691 } 692 } else { // Safari, Opera 693 height = self.innerHeight; 694 } 695 696 return height; 697 }, 698 699 /** 700 * Returns the current width of the viewport. 701 * @return {Int} The width of the viewable area of the page (excludes scrollbars). 702 */ 703 704 getViewportWidth: function() { 705 var width = -1; 706 var mode = document.compatMode; 707 708 if (mode || isIE) { // (IE, Gecko, Opera) 709 switch (mode) { 710 case 'CSS1Compat': // Standards mode 711 width = document.documentElement.clientWidth; 712 break; 713 714 default: // Quirks 715 width = document.body.clientWidth; 716 } 717 } else { // Safari 718 width = self.innerWidth; 719 } 720 return width; 721 } 722 }; 723 }(); 724 725 /** 726 * @class A region is a representation of an object on a grid. It is defined 727 * by the top, right, bottom, left extents, so is rectangular by default. If 728 * other shapes are required, this class could be extended to support it. 729 * 730 * @param {int} t the top extent 731 * @param {int} r the right extent 732 * @param {int} b the bottom extent 733 * @param {int} l the left extent 734 * @constructor 735 */ 736 YAHOO.util.Region = function(t, r, b, l) { 737 738 /** 739 * The region's top extent 740 * @type int 741 */ 742 this.top = t; 743 744 /** 745 * The region's top extent as index, for symmetry with set/getXY 746 * @type int 747 */ 748 this[1] = t; 749 750 /** 751 * The region's right extent 752 * @type int 753 */ 754 this.right = r; 755 756 /** 757 * The region's bottom extent 758 * @type int 759 */ 760 this.bottom = b; 761 762 /** 763 * The region's left extent 764 * @type int 765 */ 766 this.left = l; 767 768 /** 769 * The region's left extent as index, for symmetry with set/getXY 770 * @type int 771 */ 772 this[0] = l; 773 }; 774 775 /** 776 * Returns true if this region contains the region passed in 777 * 778 * @param {Region} region The region to evaluate 779 * @return {boolean} True if the region is contained with this region, 780 * else false 781 */ 782 YAHOO.util.Region.prototype.contains = function(region) { 783 return ( region.left >= this.left && 784 region.right <= this.right && 785 region.top >= this.top && 786 region.bottom <= this.bottom ); 787 788 }; 789 790 /** 791 * Returns the area of the region 792 * 793 * @return {int} the region's area 794 */ 795 YAHOO.util.Region.prototype.getArea = function() { 796 return ( (this.bottom - this.top) * (this.right - this.left) ); 797 }; 798 799 /** 800 * Returns the region where the passed in region overlaps with this one 801 * 802 * @param {Region} region The region that intersects 803 * @return {Region} The overlap region, or null if there is no overlap 804 */ 805 YAHOO.util.Region.prototype.intersect = function(region) { 806 var t = Math.max( this.top, region.top ); 807 var r = Math.min( this.right, region.right ); 808 var b = Math.min( this.bottom, region.bottom ); 809 var l = Math.max( this.left, region.left ); 810 811 if (b >= t && r >= l) { 812 return new YAHOO.util.Region(t, r, b, l); 813 } else { 814 return null; 815 } 816 }; 817 818 /** 819 * Returns the region representing the smallest region that can contain both 820 * the passed in region and this region. 821 * 822 * @param {Region} region The region that to create the union with 823 * @return {Region} The union region 824 */ 825 YAHOO.util.Region.prototype.union = function(region) { 826 var t = Math.min( this.top, region.top ); 827 var r = Math.max( this.right, region.right ); 828 var b = Math.max( this.bottom, region.bottom ); 829 var l = Math.min( this.left, region.left ); 830 831 return new YAHOO.util.Region(t, r, b, l); 832 }; 833 834 /** 835 * toString 836 * @return string the region properties 837 */ 838 YAHOO.util.Region.prototype.toString = function() { 839 return ( "Region {" + 840 "top: " + this.top + 841 ", right: " + this.right + 842 ", bottom: " + this.bottom + 843 ", left: " + this.left + 844 "}" ); 845 }; 846 847 /** 848 * Returns a region that is occupied by the DOM element 849 * 850 * @param {HTMLElement} el The element 851 * @return {Region} The region that the element occupies 852 * @static 853 */ 854 YAHOO.util.Region.getRegion = function(el) { 855 var p = YAHOO.util.Dom.getXY(el); 856 857 var t = p[1]; 858 var r = p[0] + el.offsetWidth; 859 var b = p[1] + el.offsetHeight; 860 var l = p[0]; 861 862 return new YAHOO.util.Region(t, r, b, l); 863 }; 864 865 ///////////////////////////////////////////////////////////////////////////// 866 867 /** 868 * @class 869 * 870 * A point is a region that is special in that it represents a single point on 871 * the grid. 872 * 873 * @param {int} x The X position of the point 874 * @param {int} y The Y position of the point 875 * @constructor 876 * @extends Region 877 */ 878 YAHOO.util.Point = function(x, y) { 879 if (x instanceof Array) { // accept output from Dom.getXY 880 y = x[1]; 881 x = x[0]; 882 } 883 884 /** 885 * The X position of the point, which is also the right, left and index zero (for Dom.getXY symmetry) 886 * @type int 887 */ 888 889 this.x = this.right = this.left = this[0] = x; 890 891 /** 892 * The Y position of the point, which is also the top, bottom and index one (for Dom.getXY symmetry) 893 * @type int 894 */ 895 this.y = this.top = this.bottom = this[1] = y; 896 }; 897 898 YAHOO.util.Point.prototype = new YAHOO.util.Region(); 899 1 /* Copyright (c) 2006, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.net/yui/license.txt Version: 0.11.3 */ YAHOO.util.Dom=function(){var ua=navigator.userAgent.toLowerCase();var isOpera=(ua.indexOf('opera')>-1);var isSafari=(ua.indexOf('safari')>-1);var isIE=(window.ActiveXObject);var id_counter=0;var util=YAHOO.util;var property_cache={};var toCamel=function(property){var convert=function(prop){var test=/(-[a-z])/i.exec(prop);return prop.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());};while(property.indexOf('-')>-1){property=convert(property);}return property;};var toHyphen=function(property){if(property.indexOf('-')>-1){return property;}var converted='';for(var i=0,len=property.length;i<len;++i){if(property.charAt(i)==property.charAt(i).toUpperCase()){converted=converted+'-'+property.charAt(i).toLowerCase();}else{converted=converted+property.charAt(i);}}return converted;};var cacheConvertedProperties=function(property){property_cache[property]={camel:toCamel(property),hyphen:toHyphen(property)};};return{get:function(el){if(!el){return null;}if(typeof el!='string'&&!(el instanceof Array)){return el;}if(typeof el=='string'){return document.getElementById(el);}else{var collection=[];for(var i=0,len=el.length;i<len;++i){collection[collection.length]=util.Dom.get(el[i]);}return collection;}return null;},getStyle:function(el,property){var f=function(el){var value=null;var dv=document.defaultView;if(!property_cache[property]){cacheConvertedProperties(property);}var camel=property_cache[property]['camel'];var hyphen=property_cache[property]['hyphen'];if(property=='opacity'&&el.filters){value=1;try{value=el.filters.item('DXImageTransform.Microsoft.Alpha').opacity/100;}catch(e){try{value=el.filters.item('alpha').opacity/100;}catch(e){}}}else if(el.style[camel]){value=el.style[camel];}else if(isIE&&el.currentStyle&&el.currentStyle[camel]){value=el.currentStyle[camel];}else if(dv&&dv.getComputedStyle){var computed=dv.getComputedStyle(el,'');if(computed&&computed.getPropertyValue(hyphen)){value=computed.getPropertyValue(hyphen);}}return value;};return util.Dom.batch(el,f,util.Dom,true);},setStyle:function(el,property,val){if(!property_cache[property]){cacheConvertedProperties(property);}var camel=property_cache[property]['camel'];var f=function(el){switch(property){case'opacity':if(isIE&&typeof el.style.filter=='string'){el.style.filter='alpha(opacity='+val*100+')';if(!el.currentStyle||!el.currentStyle.hasLayout){el.style.zoom=1;}}else{el.style.opacity=val;el.style['-moz-opacity']=val;el.style['-khtml-opacity']=val;}break;default:el.style[camel]=val;}};util.Dom.batch(el,f,util.Dom,true);},getXY:function(el){var f=function(el){if(el.offsetParent===null||this.getStyle(el,'display')=='none'){return false;}var parentNode=null;var pos=[];var box;if(el.getBoundingClientRect){box=el.getBoundingClientRect();var doc=document;if(!this.inDocument(el)&&parent.document!=document){doc=parent.document;if(!this.isAncestor(doc.documentElement,el)){return false;}}var scrollTop=Math.max(doc.documentElement.scrollTop,doc.body.scrollTop);var scrollLeft=Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft);return[box.left+scrollLeft,box.top+scrollTop];}else{pos=[el.offsetLeft,el.offsetTop];parentNode=el.offsetParent;if(parentNode!=el){while(parentNode){pos[0]+=parentNode.offsetLeft;pos[1]+=parentNode.offsetTop;parentNode=parentNode.offsetParent;}}if(isSafari&&this.getStyle(el,'position')=='absolute'){pos[0]-=document.body.offsetLeft;pos[1]-=document.body.offsetTop;}}if(el.parentNode){parentNode=el.parentNode;}else{parentNode=null;}while(parentNode&&parentNode.tagName.toUpperCase()!='BODY'&&parentNode.tagName.toUpperCase()!='HTML'){if(util.Dom.getStyle(parentNode,'display')!='inline'){pos[0]-=parentNode.scrollLeft;pos[1]-=parentNode.scrollTop;}if(parentNode.parentNode){parentNode=parentNode.parentNode;}else{parentNode=null;}}return pos;};return util.Dom.batch(el,f,util.Dom,true);},getX:function(el){var f=function(el){return util.Dom.getXY(el)[0];};return util.Dom.batch(el,f,util.Dom,true);},getY:function(el){var f=function(el){return util.Dom.getXY(el)[1];};return util.Dom.batch(el,f,util.Dom,true);},setXY:function(el,pos,noRetry){var f=function(el){var style_pos=this.getStyle(el,'position');if(style_pos=='static'){this.setStyle(el,'position','relative');style_pos='relative';}var pageXY=this.getXY(el);if(pageXY===false){return false;}var delta=[parseInt(this.getStyle(el,'left'),10),parseInt(this.getStyle(el,'top'),10)];if(isNaN(delta[0])){delta[0]=(style_pos=='relative')?0:el.offsetLeft;}if(isNaN(delta[1])){delta[1]=(style_pos=='relative')?0:el.offsetTop;}if(pos[0]!==null){el.style.left=pos[0]-pageXY[0]+delta[0]+'px';}if(pos[1]!==null){el.style.top=pos[1]-pageXY[1]+delta[1]+'px';}var newXY=this.getXY(el);if(!noRetry&&(newXY[0]!=pos[0]||newXY[1]!=pos[1])){this.setXY(el,pos,true);}};util.Dom.batch(el,f,util.Dom,true);},setX:function(el,x){util.Dom.setXY(el,[x,null]);},setY:function(el,y){util.Dom.setXY(el,[null,y]);},getRegion:function(el){var f=function(el){var region=new YAHOO.util.Region.getRegion(el);return region;};return util.Dom.batch(el,f,util.Dom,true);},getClientWidth:function(){return util.Dom.getViewportWidth();},getClientHeight:function(){return util.Dom.getViewportHeight();},getElementsByClassName:function(className,tag,root){var method=function(el){return util.Dom.hasClass(el,className)};return util.Dom.getElementsBy(method,tag,root);},hasClass:function(el,className){var re=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)');var f=function(el){return re.test(el['className']);};return util.Dom.batch(el,f,util.Dom,true);},addClass:function(el,className){var f=function(el){if(this.hasClass(el,className)){return;}el['className']=[el['className'],className].join(' ');};util.Dom.batch(el,f,util.Dom,true);},removeClass:function(el,className){var re=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)','g');var f=function(el){if(!this.hasClass(el,className)){return;}var c=el['className'];el['className']=c.replace(re,' ');if(this.hasClass(el,className)){this.removeClass(el,className);}};util.Dom.batch(el,f,util.Dom,true);},replaceClass:function(el,oldClassName,newClassName){if(oldClassName===newClassName){return false;};var re=new RegExp('(?:^|\\s+)'+oldClassName+'(?:\\s+|$)','g');var f=function(el){if(!this.hasClass(el,oldClassName)){this.addClass(el,newClassName);return;}el['className']=el['className'].replace(re,' '+newClassName+' ');if(this.hasClass(el,oldClassName)){this.replaceClass(el,oldClassName,newClassName);}};util.Dom.batch(el,f,util.Dom,true);},generateId:function(el,prefix){prefix=prefix||'yui-gen';el=el||{};var f=function(el){if(el){el=util.Dom.get(el);}else{el={};}if(!el.id){el.id=prefix+id_counter++;}return el.id;};return util.Dom.batch(el,f,util.Dom,true);},isAncestor:function(haystack,needle){haystack=util.Dom.get(haystack);if(!haystack||!needle){return false;}var f=function(needle){if(haystack.contains&&!isSafari){return haystack.contains(needle);}else if(haystack.compareDocumentPosition){return!!(haystack.compareDocumentPosition(needle)&16);}else{var parent=needle.parentNode;while(parent){if(parent==haystack){return true;}else if(!parent.tagName||parent.tagName.toUpperCase()=='HTML'){return false;}parent=parent.parentNode;}return false;}};return util.Dom.batch(needle,f,util.Dom,true);},inDocument:function(el){var f=function(el){return this.isAncestor(document.documentElement,el);};return util.Dom.batch(el,f,util.Dom,true);},getElementsBy:function(method,tag,root){tag=tag||'*';root=util.Dom.get(root)||document;var nodes=[];var elements=root.getElementsByTagName(tag);if(!elements.length&&(tag=='*'&&root.all)){elements=root.all;}for(var i=0,len=elements.length;i<len;++i){if(method(elements[i])){nodes[nodes.length]=elements[i];}}return nodes;},batch:function(el,method,o,override){var id=el;el=util.Dom.get(el);var scope=(override)?o:window;if(!el||el.tagName||!el.length){if(!el){return false;}return method.call(scope,el,o);}var collection=[];for(var i=0,len=el.length;i<len;++i){if(!el[i]){id=id[i];}collection[collection.length]=method.call(scope,el[i],o);}return collection;},getDocumentHeight:function(){var scrollHeight=-1,windowHeight=-1,bodyHeight=-1;var marginTop=parseInt(util.Dom.getStyle(document.body,'marginTop'),10);var marginBottom=parseInt(util.Dom.getStyle(document.body,'marginBottom'),10);var mode=document.compatMode;if((mode||isIE)&&!isOpera){switch(mode){case'CSS1Compat':scrollHeight=((window.innerHeight&&window.scrollMaxY)?window.innerHeight+window.scrollMaxY:-1);windowHeight=[document.documentElement.clientHeight,self.innerHeight||-1].sort(function(a,b){return(a-b);})[1];bodyHeight=document.body.offsetHeight+marginTop+marginBottom;break;default:scrollHeight=document.body.scrollHeight;bodyHeight=document.body.clientHeight;}}else{scrollHeight=document.documentElement.scrollHeight;windowHeight=self.innerHeight;bodyHeight=document.documentElement.clientHeight;}var h=[scrollHeight,windowHeight,bodyHeight].sort(function(a,b){return(a-b);});return h[2];},getDocumentWidth:function(){var docWidth=-1,bodyWidth=-1,winWidth=-1;var marginRight=parseInt(util.Dom.getStyle(document.body,'marginRight'),10);var marginLeft=parseInt(util.Dom.getStyle(document.body,'marginLeft'),10);var mode=document.compatMode;if(mode||isIE){switch(mode){case'CSS1Compat':docWidth=document.documentElement.clientWidth;bodyWidth=document.body.offsetWidth+marginLeft+marginRight;break;default:bodyWidth=document.body.clientWidth;docWidth=document.body.scrollWidth;break;}}else{docWidth=document.documentElement.clientWidth;bodyWidth=document.body.offsetWidth+marginLeft+marginRight;}var w=Math.max(docWidth,bodyWidth);return w;},getViewportHeight:function(){var height=-1;var mode=document.compatMode;if((mode||isIE)&&!isOpera){switch(mode){case'CSS1Compat':height=document.documentElement.clientHeight;break;default:height=document.body.clientHeight;}}else{height=self.innerHeight;}return height;},getViewportWidth:function(){var width=-1;var mode=document.compatMode;if(mode||isIE){switch(mode){case'CSS1Compat':width=document.documentElement.clientWidth;break;default:width=document.body.clientWidth;}}else{width=self.innerWidth;}return width;}};}();YAHOO.util.Region=function(t,r,b,l){this.top=t;this[1]=t;this.right=r;this.bottom=b;this.left=l;this[0]=l;};YAHOO.util.Region.prototype.contains=function(region){return(region.left>=this.left&®ion.right<=this.right&®ion.top>=this.top&®ion.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(region){var t=Math.max(this.top,region.top);var r=Math.min(this.right,region.right);var b=Math.min(this.bottom,region.bottom);var l=Math.max(this.left,region.left);if(b>=t&&r>=l){return new YAHOO.util.Region(t,r,b,l);}else{return null;}};YAHOO.util.Region.prototype.union=function(region){var t=Math.min(this.top,region.top);var r=Math.max(this.right,region.right);var b=Math.max(this.bottom,region.bottom);var l=Math.min(this.left,region.left);return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(el){var p=YAHOO.util.Dom.getXY(el);var t=p[1];var r=p[0]+el.offsetWidth;var b=p[1]+el.offsetHeight;var l=p[0];return new YAHOO.util.Region(t,r,b,l);};YAHOO.util.Point=function(x,y){if(x instanceof Array){y=x[1];x=x[0];}this.x=this.right=this.left=this[0]=x;this.y=this.top=this.bottom=this[1]=y;};YAHOO.util.Point.prototype=new YAHOO.util.Region(); -
trunk/npemap.org.uk/static/tiles/yahoo.js
r17 r43 1 /* 2 Copyright (c) 2006, Yahoo! Inc. All rights reserved. 3 Code licensed under the BSD License: 4 http://developer.yahoo.net/yui/license.txt 5 Version: 0.11.4 6 */ 7 8 /** 9 * The YAHOO object is the single global object used by YUI Library. It 10 * contains utility function for setting up namespaces, inheritance, and 11 * logging. YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces 12 * created automatically for and used by the library. 13 * @module YAHOO 14 */ 15 16 /** 17 * The YAHOO global namespace object 18 * @class YAHOO 19 * @static 20 */ 21 if (typeof YAHOO == "undefined") { 22 YAHOO = {}; 23 } 24 25 /** 26 * Returns the namespace specified and creates it if it doesn't exist 27 * 28 * YAHOO.namespace("property.package"); 29 * YAHOO.namespace("YAHOO.property.package"); 30 * 31 * Either of the above would create YAHOO.property, then 32 * YAHOO.property.package 33 * 34 * Be careful when naming packages. Reserved words may work in some browsers 35 * and not others. For instance, the following will fail in Safari: 36 * 37 * YAHOO.namespace("really.long.nested.namespace"); 38 * 39 * This fails because "long" is a future reserved word in ECMAScript 40 * @method namespace 41 * @static 42 * @param {String} ns The name of the namespace 43 * @return {Object} A reference to the namespace object 44 */ 45 YAHOO.namespace = function(ns) { 46 47 if (!ns || !ns.length) { 48 return null; 49 } 50 51 var levels = ns.split("."); 52 var nsobj = YAHOO; 53 54 // YAHOO is implied, so it is ignored if it is included 55 for (var i=(levels[0] == "YAHOO") ? 1 : 0; i<levels.length; ++i) { 56 nsobj[levels[i]] = nsobj[levels[i]] || {}; 57 nsobj = nsobj[levels[i]]; 58 } 59 60 return nsobj; 61 }; 62 63 /** 64 * Uses YAHOO.widget.Logger to output a log message, if the widget is available. 65 * 66 * @method log 67 * @static 68 * @param {string} sMsg The message to log. 69 * @param {string} sCategory The log category for the message. Default 70 * categories are "info", "warn", "error", time". 71 * Custom categories can be used as well. (opt) 72 * @param {string} sSource The source of the the message (opt) 73 * @return {boolean} True if the log operation was successful. 74 */ 75 YAHOO.log = function(sMsg, sCategory, sSource) { 76 var l = YAHOO.widget.Logger; 77 if(l && l.log) { 78 return l.log(sMsg, sCategory, sSource); 79 } else { 80 return false; 81 } 82 }; 83 84 /** 85 * Utility to set up the prototype, constructor and superclass properties to 86 * support an inheritance strategy that can chain constructors and methods. 87 * 88 * @method extend 89 * @static 90 * @param {function} subclass the object to modify 91 * @param {function} superclass the object to inherit 92 */ 93 YAHOO.extend = function(subclass, superclass) { 94 var f = function() {}; 95 f.prototype = superclass.prototype; 96 subclass.prototype = new f(); 97 subclass.prototype.constructor = subclass; 98 subclass.superclass = superclass.prototype; 99 if (superclass.prototype.constructor == Object.prototype.constructor) { 100 superclass.prototype.constructor = superclass; 101 } 102 }; 103 104 YAHOO.namespace("util"); 105 YAHOO.namespace("widget"); 106 YAHOO.namespace("example"); 107 1 /* Copyright (c) 2006, Yahoo! Inc. All rights reserved.Code licensed under the BSD License: http://developer.yahoo.net/yui/license.txt Version: 0.11.4*/ if(typeof YAHOO=="undefined"){YAHOO={};}YAHOO.namespace=function(ns){if(!ns||!ns.length){return null;}var _2=ns.split(".");var _3=YAHOO;for(var i=(_2[0]=="YAHOO")?1:0;i<_2.length;++i){_3[_2[i]]=_3[_2[i]]||{};_3=_3[_2[i]];}return _3;};YAHOO.log=function(_5,_6,_7){var l=YAHOO.widget.Logger;if(l&&l.log){return l.log(_5,_6,_7);}else{return false;}};YAHOO.extend=function(_9,_10){var f=function(){};f.prototype=_10.prototype;_9.prototype=new f();_9.prototype.constructor=_9;_9.superclass=_10.prototype;if(_10.prototype.constructor==Object.prototype.constructor){_10.prototype.constructor=_10;}};YAHOO.namespace("util");YAHOO.namespace("widget");YAHOO.namespace("example");
Note: See TracChangeset
for help on using the changeset viewer.