testing/mochitest/tests/MochiKit-1.4.2/MochiKit/Style.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /***
     3 MochiKit.Style 1.4.2
     5 See <http://mochikit.com/> for documentation, downloads, license, etc.
     7 (c) 2005-2006 Bob Ippolito, Beau Hartshorne.  All rights Reserved.
     9 ***/
    11 MochiKit.Base._deps('Style', ['Base', 'DOM']);
    13 MochiKit.Style.NAME = 'MochiKit.Style';
    14 MochiKit.Style.VERSION = '1.4.2';
    15 MochiKit.Style.__repr__ = function () {
    16     return '[' + this.NAME + ' ' + this.VERSION + ']';
    17 };
    18 MochiKit.Style.toString = function () {
    19     return this.__repr__();
    20 };
    22 MochiKit.Style.EXPORT_OK = [];
    24 MochiKit.Style.EXPORT = [
    25     'setStyle',
    26     'setOpacity',
    27     'getStyle',
    28     'getElementDimensions',
    29     'elementDimensions', // deprecated
    30     'setElementDimensions',
    31     'getElementPosition',
    32     'elementPosition', // deprecated
    33     'setElementPosition',
    34     "makePositioned",
    35     "undoPositioned",
    36     "makeClipping",
    37     "undoClipping",
    38     'setDisplayForElement',
    39     'hideElement',
    40     'showElement',
    41     'getViewportDimensions',
    42     'getViewportPosition',
    43     'Dimensions',
    44     'Coordinates'
    45 ];
    48 /*
    50     Dimensions
    52 */
    53 /** @id MochiKit.Style.Dimensions */
    54 MochiKit.Style.Dimensions = function (w, h) {
    55     this.w = w;
    56     this.h = h;
    57 };
    59 MochiKit.Style.Dimensions.prototype.__repr__ = function () {
    60     var repr = MochiKit.Base.repr;
    61     return '{w: '  + repr(this.w) + ', h: ' + repr(this.h) + '}';
    62 };
    64 MochiKit.Style.Dimensions.prototype.toString = function () {
    65     return this.__repr__();
    66 };
    69 /*
    71     Coordinates
    73 */
    74 /** @id MochiKit.Style.Coordinates */
    75 MochiKit.Style.Coordinates = function (x, y) {
    76     this.x = x;
    77     this.y = y;
    78 };
    80 MochiKit.Style.Coordinates.prototype.__repr__ = function () {
    81     var repr = MochiKit.Base.repr;
    82     return '{x: '  + repr(this.x) + ', y: ' + repr(this.y) + '}';
    83 };
    85 MochiKit.Style.Coordinates.prototype.toString = function () {
    86     return this.__repr__();
    87 };
    90 MochiKit.Base.update(MochiKit.Style, {
    92     /** @id MochiKit.Style.getStyle */
    93     getStyle: function (elem, cssProperty) {
    94         var dom = MochiKit.DOM;
    95         var d = dom._document;
    97         elem = dom.getElement(elem);
    98         cssProperty = MochiKit.Base.camelize(cssProperty);
   100         if (!elem || elem == d) {
   101             return undefined;
   102         }
   103         if (cssProperty == 'opacity' && typeof(elem.filters) != 'undefined') {
   104             var opacity = (MochiKit.Style.getStyle(elem, 'filter') || '').match(/alpha\(opacity=(.*)\)/);
   105             if (opacity && opacity[1]) {
   106                 return parseFloat(opacity[1]) / 100;
   107             }
   108             return 1.0;
   109         }
   110         if (cssProperty == 'float' || cssProperty == 'cssFloat' || cssProperty == 'styleFloat') {
   111             if (elem.style["float"]) {
   112                 return elem.style["float"];
   113             } else if (elem.style.cssFloat) {
   114                 return elem.style.cssFloat;
   115             } else if (elem.style.styleFloat) {
   116                 return elem.style.styleFloat;
   117             } else {
   118                 return "none";
   119             }
   120         }
   121         var value = elem.style ? elem.style[cssProperty] : null;
   122         if (!value) {
   123             if (d.defaultView && d.defaultView.getComputedStyle) {
   124                 var css = d.defaultView.getComputedStyle(elem, null);
   125                 cssProperty = cssProperty.replace(/([A-Z])/g, '-$1'
   126                     ).toLowerCase(); // from dojo.style.toSelectorCase
   127                 value = css ? css.getPropertyValue(cssProperty) : null;
   128             } else if (elem.currentStyle) {
   129                 value = elem.currentStyle[cssProperty];
   130                 if (/^\d/.test(value) && !/px$/.test(value) && cssProperty != 'fontWeight') {
   131                     /* Convert to px using an hack from Dean Edwards */
   132                     var left = elem.style.left;
   133                     var rsLeft = elem.runtimeStyle.left;
   134                     elem.runtimeStyle.left = elem.currentStyle.left;
   135                     elem.style.left = value || 0;
   136                     value = elem.style.pixelLeft + "px";
   137                     elem.style.left = left;
   138                     elem.runtimeStyle.left = rsLeft;
   139                 }
   140             }
   141         }
   142         if (cssProperty == 'opacity') {
   143             value = parseFloat(value);
   144         }
   146         if (/Opera/.test(navigator.userAgent) && (MochiKit.Base.findValue(['left', 'top', 'right', 'bottom'], cssProperty) != -1)) {
   147             if (MochiKit.Style.getStyle(elem, 'position') == 'static') {
   148                 value = 'auto';
   149             }
   150         }
   152         return value == 'auto' ? null : value;
   153     },
   155     /** @id MochiKit.Style.setStyle */
   156     setStyle: function (elem, style) {
   157         elem = MochiKit.DOM.getElement(elem);
   158         for (var name in style) {
   159             switch (name) {
   160             case 'opacity':
   161                 MochiKit.Style.setOpacity(elem, style[name]);
   162                 break;
   163             case 'float':
   164             case 'cssFloat':
   165             case 'styleFloat':
   166                 if (typeof(elem.style["float"]) != "undefined") {
   167                     elem.style["float"] = style[name];
   168                 } else if (typeof(elem.style.cssFloat) != "undefined") {
   169                     elem.style.cssFloat = style[name];
   170                 } else {
   171                     elem.style.styleFloat = style[name];
   172                 }
   173                 break;
   174             default:
   175                 elem.style[MochiKit.Base.camelize(name)] = style[name];
   176             }
   177         }
   178     },
   180     /** @id MochiKit.Style.setOpacity */
   181     setOpacity: function (elem, o) {
   182         elem = MochiKit.DOM.getElement(elem);
   183         var self = MochiKit.Style;
   184         if (o == 1) {
   185             var toSet = /Gecko/.test(navigator.userAgent) && !(/Konqueror|AppleWebKit|KHTML/.test(navigator.userAgent));
   186             elem.style["opacity"] = toSet ? 0.999999 : 1.0;
   187             if (/MSIE/.test(navigator.userAgent)) {
   188                 elem.style['filter'] =
   189                     self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '');
   190             }
   191         } else {
   192             if (o < 0.00001) {
   193                 o = 0;
   194             }
   195             elem.style["opacity"] = o;
   196             if (/MSIE/.test(navigator.userAgent)) {
   197                 elem.style['filter'] =
   198                     self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + o * 100 + ')';
   199             }
   200         }
   201     },
   203     /*
   205         getElementPosition is adapted from YAHOO.util.Dom.getXY v0.9.0.
   206         Copyright: Copyright (c) 2006, Yahoo! Inc. All rights reserved.
   207         License: BSD, http://developer.yahoo.net/yui/license.txt
   209     */
   211     /** @id MochiKit.Style.getElementPosition */
   212     getElementPosition: function (elem, /* optional */relativeTo) {
   213         var self = MochiKit.Style;
   214         var dom = MochiKit.DOM;
   215         elem = dom.getElement(elem);
   217         if (!elem ||
   218             (!(elem.x && elem.y) &&
   219             (!elem.parentNode === null ||
   220             self.getStyle(elem, 'display') == 'none'))) {
   221             return undefined;
   222         }
   224         var c = new self.Coordinates(0, 0);
   225         var box = null;
   226         var parent = null;
   228         var d = MochiKit.DOM._document;
   229         var de = d.documentElement;
   230         var b = d.body;
   232         if (!elem.parentNode && elem.x && elem.y) {
   233             /* it's just a MochiKit.Style.Coordinates object */
   234             c.x += elem.x || 0;
   235             c.y += elem.y || 0;
   236         } else if (elem.getBoundingClientRect) { // IE shortcut
   237             /*
   239                 The IE shortcut can be off by two. We fix it. See:
   240                 http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
   242                 This is similar to the method used in
   243                 MochiKit.Signal.Event.mouse().
   245             */
   246             box = elem.getBoundingClientRect();
   248             c.x += box.left +
   249                 (de.scrollLeft || b.scrollLeft) -
   250                 (de.clientLeft || 0);
   252             c.y += box.top +
   253                 (de.scrollTop || b.scrollTop) -
   254                 (de.clientTop || 0);
   256         } else if (elem.offsetParent) {
   257             c.x += elem.offsetLeft;
   258             c.y += elem.offsetTop;
   259             parent = elem.offsetParent;
   261             if (parent != elem) {
   262                 while (parent) {
   263                     c.x += parseInt(parent.style.borderLeftWidth) || 0;
   264                     c.y += parseInt(parent.style.borderTopWidth) || 0;
   265                     c.x += parent.offsetLeft;
   266                     c.y += parent.offsetTop;
   267                     parent = parent.offsetParent;
   268                 }
   269             }
   271             /*
   273                 Opera < 9 and old Safari (absolute) incorrectly account for
   274                 body offsetTop and offsetLeft.
   276             */
   277             var ua = navigator.userAgent.toLowerCase();
   278             if ((typeof(opera) != 'undefined' &&
   279                 parseFloat(opera.version()) < 9) ||
   280                 (ua.indexOf('AppleWebKit') != -1 &&
   281                 self.getStyle(elem, 'position') == 'absolute')) {
   283                 c.x -= b.offsetLeft;
   284                 c.y -= b.offsetTop;
   286             }
   288             // Adjust position for strange Opera scroll bug
   289             if (elem.parentNode) {
   290                 parent = elem.parentNode;
   291             } else {
   292                 parent = null;
   293             }
   294             while (parent) {
   295                 var tagName = parent.tagName.toUpperCase();
   296                 if (tagName === 'BODY' || tagName === 'HTML') {
   297                     break;
   298                 }
   299                 var disp = self.getStyle(parent, 'display');
   300                 // Handle strange Opera bug for some display
   301                 if (disp.search(/^inline|table-row.*$/i)) {
   302                     c.x -= parent.scrollLeft;
   303                     c.y -= parent.scrollTop;
   304                 }
   305                 if (parent.parentNode) {
   306                     parent = parent.parentNode;
   307                 } else {
   308                     parent = null;
   309                 }
   310             }
   311         }
   313         if (typeof(relativeTo) != 'undefined') {
   314             relativeTo = arguments.callee(relativeTo);
   315             if (relativeTo) {
   316                 c.x -= (relativeTo.x || 0);
   317                 c.y -= (relativeTo.y || 0);
   318             }
   319         }
   321         return c;
   322     },
   324     /** @id MochiKit.Style.setElementPosition */
   325     setElementPosition: function (elem, newPos/* optional */, units) {
   326         elem = MochiKit.DOM.getElement(elem);
   327         if (typeof(units) == 'undefined') {
   328             units = 'px';
   329         }
   330         var newStyle = {};
   331         var isUndefNull = MochiKit.Base.isUndefinedOrNull;
   332         if (!isUndefNull(newPos.x)) {
   333             newStyle['left'] = newPos.x + units;
   334         }
   335         if (!isUndefNull(newPos.y)) {
   336             newStyle['top'] = newPos.y + units;
   337         }
   338         MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
   339     },
   341     /** @id MochiKit.Style.makePositioned */
   342     makePositioned: function (element) {
   343         element = MochiKit.DOM.getElement(element);
   344         var pos = MochiKit.Style.getStyle(element, 'position');
   345         if (pos == 'static' || !pos) {
   346             element.style.position = 'relative';
   347             // Opera returns the offset relative to the positioning context,
   348             // when an element is position relative but top and left have
   349             // not been defined
   350             if (/Opera/.test(navigator.userAgent)) {
   351                 element.style.top = 0;
   352                 element.style.left = 0;
   353             }
   354         }
   355     },
   357     /** @id MochiKit.Style.undoPositioned */
   358     undoPositioned: function (element) {
   359         element = MochiKit.DOM.getElement(element);
   360         if (element.style.position == 'relative') {
   361             element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = '';
   362         }
   363     },
   365     /** @id MochiKit.Style.makeClipping */
   366     makeClipping: function (element) {
   367         element = MochiKit.DOM.getElement(element);
   368         var s = element.style;
   369         var oldOverflow = { 'overflow': s.overflow,
   370                             'overflow-x': s.overflowX,
   371                             'overflow-y': s.overflowY };
   372         if ((MochiKit.Style.getStyle(element, 'overflow') || 'visible') != 'hidden') {
   373             element.style.overflow = 'hidden';
   374             element.style.overflowX = 'hidden';
   375             element.style.overflowY = 'hidden';
   376         }
   377         return oldOverflow;
   378     },
   380     /** @id MochiKit.Style.undoClipping */
   381     undoClipping: function (element, overflow) {
   382         element = MochiKit.DOM.getElement(element);
   383         if (typeof(overflow) == 'string') {
   384             element.style.overflow = overflow;
   385         } else if (overflow != null) {
   386             element.style.overflow = overflow['overflow'];
   387             element.style.overflowX = overflow['overflow-x'];
   388             element.style.overflowY = overflow['overflow-y'];
   389         }
   390     },
   392     /** @id MochiKit.Style.getElementDimensions */
   393     getElementDimensions: function (elem, contentSize/*optional*/) {
   394         var self = MochiKit.Style;
   395         var dom = MochiKit.DOM;
   396         if (typeof(elem.w) == 'number' || typeof(elem.h) == 'number') {
   397             return new self.Dimensions(elem.w || 0, elem.h || 0);
   398         }
   399         elem = dom.getElement(elem);
   400         if (!elem) {
   401             return undefined;
   402         }
   403         var disp = self.getStyle(elem, 'display');
   404         // display can be empty/undefined on WebKit/KHTML
   405         if (disp == 'none' || disp == '' || typeof(disp) == 'undefined') {
   406             var s = elem.style;
   407             var originalVisibility = s.visibility;
   408             var originalPosition = s.position;
   409             var originalDisplay = s.display;
   410             s.visibility = 'hidden';
   411             s.position = 'absolute';
   412             s.display = self._getDefaultDisplay(elem);
   413             var originalWidth = elem.offsetWidth;
   414             var originalHeight = elem.offsetHeight;
   415             s.display = originalDisplay;
   416             s.position = originalPosition;
   417             s.visibility = originalVisibility;
   418         } else {
   419             originalWidth = elem.offsetWidth || 0;
   420             originalHeight = elem.offsetHeight || 0;
   421         }
   422         if (contentSize) {
   423             var tableCell = 'colSpan' in elem && 'rowSpan' in elem;
   424             var collapse = (tableCell && elem.parentNode && self.getStyle(
   425                     elem.parentNode, 'borderCollapse') == 'collapse')
   426             if (collapse) {
   427                 if (/MSIE/.test(navigator.userAgent)) {
   428                     var borderLeftQuota = elem.previousSibling? 0.5 : 1;
   429                     var borderRightQuota = elem.nextSibling? 0.5 : 1;
   430                 }
   431                 else {
   432                     var borderLeftQuota = 0.5;
   433                     var borderRightQuota = 0.5;
   434                 }
   435             } else {
   436                 var borderLeftQuota = 1;
   437                 var borderRightQuota = 1;
   438             }
   439             originalWidth -= Math.round(
   440                 (parseFloat(self.getStyle(elem, 'paddingLeft')) || 0)
   441               + (parseFloat(self.getStyle(elem, 'paddingRight')) || 0)
   442               + borderLeftQuota *
   443                 (parseFloat(self.getStyle(elem, 'borderLeftWidth')) || 0)
   444               + borderRightQuota *
   445                 (parseFloat(self.getStyle(elem, 'borderRightWidth')) || 0)
   446             );
   447             if (tableCell) {
   448                 if (/Opera/.test(navigator.userAgent)
   449                     && !/Konqueror|AppleWebKit|KHTML/.test(navigator.userAgent)) {
   450                     var borderHeightQuota = 0;
   451                 } else if (/MSIE/.test(navigator.userAgent)) {
   452                     var borderHeightQuota = 1;
   453                 } else {
   454                     var borderHeightQuota = collapse? 0.5 : 1;
   455                 }
   456             } else {
   457                 var borderHeightQuota = 1;
   458             }
   459             originalHeight -= Math.round(
   460                 (parseFloat(self.getStyle(elem, 'paddingTop')) || 0)
   461               + (parseFloat(self.getStyle(elem, 'paddingBottom')) || 0)
   462               + borderHeightQuota * (
   463                 (parseFloat(self.getStyle(elem, 'borderTopWidth')) || 0)
   464               + (parseFloat(self.getStyle(elem, 'borderBottomWidth')) || 0))
   465             );
   466         }
   467         return new self.Dimensions(originalWidth, originalHeight);
   468     },
   470     /** @id MochiKit.Style.setElementDimensions */
   471     setElementDimensions: function (elem, newSize/* optional */, units) {
   472         elem = MochiKit.DOM.getElement(elem);
   473         if (typeof(units) == 'undefined') {
   474             units = 'px';
   475         }
   476         var newStyle = {};
   477         var isUndefNull = MochiKit.Base.isUndefinedOrNull;
   478         if (!isUndefNull(newSize.w)) {
   479             newStyle['width'] = newSize.w + units;
   480         }
   481         if (!isUndefNull(newSize.h)) {
   482             newStyle['height'] = newSize.h + units;
   483         }
   484         MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
   485     },
   487     _getDefaultDisplay: function (elem) {
   488         var self = MochiKit.Style;
   489         var dom = MochiKit.DOM;
   490         elem = dom.getElement(elem);
   491         if (!elem) {
   492             return undefined;
   493         }
   494         var tagName = elem.tagName.toUpperCase();
   495         return self._defaultDisplay[tagName] || 'block';
   496     },
   498     /** @id MochiKit.Style.setDisplayForElement */
   499     setDisplayForElement: function (display, element/*, ...*/) {
   500         var elements = MochiKit.Base.extend(null, arguments, 1);
   501         var getElement = MochiKit.DOM.getElement;
   502         for (var i = 0; i < elements.length; i++) {
   503             element = getElement(elements[i]);
   504             if (element) {
   505                 element.style.display = display;
   506             }
   507         }
   508     },
   510     /** @id MochiKit.Style.getViewportDimensions */
   511     getViewportDimensions: function () {
   512         var d = new MochiKit.Style.Dimensions();
   513         var w = MochiKit.DOM._window;
   514         var b = MochiKit.DOM._document.body;
   515         if (w.innerWidth) {
   516             d.w = w.innerWidth;
   517             d.h = w.innerHeight;
   518         } else if (b && b.parentElement && b.parentElement.clientWidth) {
   519             d.w = b.parentElement.clientWidth;
   520             d.h = b.parentElement.clientHeight;
   521         } else if (b && b.clientWidth) {
   522             d.w = b.clientWidth;
   523             d.h = b.clientHeight;
   524         }
   525         return d;
   526     },
   528     /** @id MochiKit.Style.getViewportPosition */
   529     getViewportPosition: function () {
   530         var c = new MochiKit.Style.Coordinates(0, 0);
   531         var d = MochiKit.DOM._document;
   532         var de = d.documentElement;
   533         var db = d.body;
   534         if (de && (de.scrollTop || de.scrollLeft)) {
   535             c.x = de.scrollLeft;
   536             c.y = de.scrollTop;
   537         } else if (db) {
   538             c.x = db.scrollLeft;
   539             c.y = db.scrollTop;
   540         }
   541         return c;
   542     },
   544     __new__: function () {
   545         var m = MochiKit.Base;
   547         var inlines = ['A','ABBR','ACRONYM','B','BASEFONT','BDO','BIG','BR',
   548                        'CITE','CODE','DFN','EM','FONT','I','IMG','KBD','LABEL',
   549                        'Q','S','SAMP','SMALL','SPAN','STRIKE','STRONG','SUB',
   550                        'SUP','TEXTAREA','TT','U','VAR'];
   551         this._defaultDisplay = { 'TABLE': 'table',
   552                                  'THEAD': 'table-header-group',
   553                                  'TBODY': 'table-row-group',
   554                                  'TFOOT': 'table-footer-group',
   555                                  'COLGROUP': 'table-column-group',
   556                                  'COL': 'table-column',
   557                                  'TR': 'table-row',
   558                                  'TD': 'table-cell',
   559                                  'TH': 'table-cell',
   560                                  'CAPTION': 'table-caption',
   561                                  'LI': 'list-item',
   562                                  'INPUT': 'inline-block',
   563                                  'SELECT': 'inline-block' };
   564         // CSS 'display' support in IE6/7 is just broken...
   565         if (/MSIE/.test(navigator.userAgent)) {
   566             for (var k in this._defaultDisplay) {
   567                 var v = this._defaultDisplay[k];
   568                 if (v.indexOf('table') == 0) {
   569                     this._defaultDisplay[k] = 'block';
   570                 }
   571             }
   572         }
   573         for (var i = 0; i < inlines.length; i++) {
   574             this._defaultDisplay[inlines[i]] = 'inline';
   575         }
   577         this.elementPosition = this.getElementPosition;
   578         this.elementDimensions = this.getElementDimensions;
   580         this.hideElement = m.partial(this.setDisplayForElement, 'none');
   581         // TODO: showElement could be improved by using getDefaultDisplay.
   582         this.showElement = m.partial(this.setDisplayForElement, 'block');
   584         this.EXPORT_TAGS = {
   585             ':common': this.EXPORT,
   586             ':all': m.concat(this.EXPORT, this.EXPORT_OK)
   587         };
   589         m.nameFunctions(this);
   590     }
   591 });
   593 MochiKit.Style.__new__();
   594 MochiKit.Base._exportSymbols(this, MochiKit.Style);

mercurial