Skip to content
This repository

Streamlined and unified opacity methods #73

Open
wants to merge 1 commit into from

2 participants

Victor Homyakov Andrew Dupont
Victor Homyakov

Currently methods for getting/setting opacity have different and inefficient workflow:

  • in IE w/o opacity support getStyle_IE invokes getOpacity_IE (but only after useless operations like normalizeStyleName_IE())
  • in other browsers getOpacity invokes getStyle (doing useless operations like normalizeStyleName('opacity'))

Also setOpacity_IE and getOpacity_IE check STANDARD_CSS_OPACITY_SUPPORTED each time they are invoked (not good for animation performance).

Victor Homyakov victor-homyakov Streamlined and unified opacity methods
Currently methods for getting/setting opacity have different workflow:

- in IE w/o opacity support `getStyle_IE` invokes `getOpacity_IE`
- in other browsers `getOpacity` invokes `getStyle` (doing unneeded operations like `normalizeStyleName('opacity')`)

Also `setOpacity_IE` and `getOpacity_IE` check `STANDARD_CSS_OPACITY_SUPPORTED` each time they are invoked (not good for animation performance).
452d798
Andrew Dupont
Collaborator

Hey, can I ask a favor? I want to apply this, but before I do, I need to make absolutely sure that this works in:

  1. IE 6 (which supports only the filter syntax)
  2. IE 7–9 (which support both filter and standard CSS opacity)
  3. IE 10 (which supports opacity but removes support for filter)

If you can assure me that the tests pass in all three of the above (for #2, testing any one of IE 7, 8, or 9 works for me), then I'll merge this. I'm very cautious about this code because I last touched it to add support for IE 10, and it was painstaking surgery to arrive at something that worked everywhere.

Victor Homyakov
  1. I've ran Prototype opacity unit tests (in dom_test.html) in IE Tester (IE6, 7, 8, 9), and in standalone IE7, IE8, IE9, IE10 (on different PCs), and also in recent versions of Chrome, Firefox, Opera - OK (to be absolutely correct, I've got some test failures, e.g. in testGetElementsByClassName in IE6-7-8, testElementScrollTo in Chrome and Firefox, testElementSetStyle in Opera, testToQueryString in all browsers, many of selector_test.html in IEs, but those tests are not relevant to the subject).

  2. I've ran Scriptaculous unit and functional tests in the abovementioned browsers. Opacity in effects and draggables works fine (well, almost fine - all IEs including IE10 have smoothness/performance problems).

  3. I am using this code in production (24x7 cross-browser intranet web app) since at least 28.06.2012. Strictly speaking, I've started this code after profiling my app in IE8-9, then used it for a while in production, and only now made pull request.

Victor Homyakov

There is another opacity-related issue, now in Opera: https://prototype.lighthouseapp.com/projects/8886/tickets/1282-latest-prototypejs-from-github-repo-fails-in-opera - should I make another pull request or include in this one?

Andrew Dupont
Collaborator

I'd say make another one. I'll merge this one soon enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Oct 03, 2012
Victor Homyakov victor-homyakov Streamlined and unified opacity methods
Currently methods for getting/setting opacity have different workflow:

- in IE w/o opacity support `getStyle_IE` invokes `getOpacity_IE`
- in other browsers `getOpacity` invokes `getStyle` (doing unneeded operations like `normalizeStyleName('opacity')`)

Also `setOpacity_IE` and `getOpacity_IE` check `STANDARD_CSS_OPACITY_SUPPORTED` each time they are invoked (not good for animation performance).
452d798
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 23 additions and 19 deletions. Show diff stats Hide diff stats

  1. +23 19 src/prototype/dom/dom.js
42 src/prototype/dom/dom.js
@@ -2847,6 +2847,8 @@
2847 2847 *
2848 2848 **/
2849 2849 function getStyle(element, style) {
  2850 + if (style === 'opacity') return getOpacity(element);
  2851 +
2850 2852 element = $(element);
2851 2853 style = normalizeStyleName(style);
2852 2854
@@ -2858,7 +2860,6 @@
2858 2860 value = css ? css[style] : null;
2859 2861 }
2860 2862
2861   - if (style === 'opacity') return value ? parseFloat(value) : 1.0;
2862 2863 return value === 'auto' ? null : value;
2863 2864 }
2864 2865
@@ -2883,6 +2884,8 @@
2883 2884 }
2884 2885
2885 2886 function getStyle_IE(element, style) {
  2887 + if (style === 'opacity') return getOpacity_IE(element);
  2888 +
2886 2889 element = $(element);
2887 2890 style = normalizeStyleName_IE(style);
2888 2891
@@ -2893,9 +2896,6 @@
2893 2896 value = element.currentStyle[style];
2894 2897 }
2895 2898
2896   - if (style === 'opacity' && !STANDARD_CSS_OPACITY_SUPPORTED)
2897   - return getOpacity_IE(element);
2898   -
2899 2899 if (value === 'auto') {
2900 2900 // If we need a dimension, return null for hidden elements, but return
2901 2901 // pixel values for visible elements.
@@ -2955,14 +2955,13 @@
2955 2955 // the standard approach (an `opacity` property in CSS) and the old-style
2956 2956 // IE approach (a proprietary `filter` property). They are written to
2957 2957 // prefer the standard approach unless it isn't supported.
2958   - function setOpacity_IE(element, value) {
2959   - // Prefer the standard CSS approach unless it's not supported.
2960   - if (STANDARD_CSS_OPACITY_SUPPORTED)
2961   - return setOpacity(element, value);
  2958 + var setOpacity_IE = STANDARD_CSS_OPACITY_SUPPORTED ? setOpacity : function(element, value) {
  2959 + element = $(element);
  2960 + var style = element.style;
  2961 + if (!element.currentStyle || !element.currentStyle.hasLayout)
  2962 + style.zoom = 1;
2962 2963
2963   - element = hasLayout_IE($(element));
2964   - var filter = Element.getStyle(element, 'filter'),
2965   - style = element.style;
  2964 + var filter = Element.getStyle(element, 'filter');
2966 2965
2967 2966 if (value == 1 || value === '') {
2968 2967 // Remove the `alpha` filter from IE's `filter` CSS property. If there
@@ -2980,7 +2979,7 @@
2980 2979 'alpha(opacity=' + (value * 100) + ')';
2981 2980
2982 2981 return element;
2983   - }
  2982 + };
2984 2983
2985 2984
2986 2985 /**
@@ -2989,20 +2988,25 @@
2989 2988 * Returns the opacity of the element.
2990 2989 **/
2991 2990 function getOpacity(element) {
2992   - return Element.getStyle(element, 'opacity');
  2991 + element = $(element);
  2992 + // Try inline styles first.
  2993 + var value = element.style.opacity;
  2994 + if (!value || value === 'auto') {
  2995 + // Reluctantly retrieve the computed style.
  2996 + var css = document.defaultView.getComputedStyle(element, null);
  2997 + value = css ? css.opacity : null;
  2998 + }
  2999 + return value ? parseFloat(value) : 1.0;
2993 3000 }
2994 3001
2995   - function getOpacity_IE(element) {
2996   - // Prefer the standard CSS approach unless it's not supported.
2997   - if (STANDARD_CSS_OPACITY_SUPPORTED)
2998   - return getOpacity(element);
2999   -
  3002 + // Prefer the standard CSS approach unless it's not supported.
  3003 + var getOpacity_IE = STANDARD_CSS_OPACITY_SUPPORTED ? getOpacity : function(element) {
3000 3004 var filter = Element.getStyle(element, 'filter');
3001 3005 if (filter.length === 0) return 1.0;
3002 3006 var match = (filter || '').match(/alpha\(opacity=(.*)\)/);
3003 3007 if (match[1]) return parseFloat(match[1]) / 100;
3004 3008 return 1.0;
3005   - }
  3009 + };
3006 3010
3007 3011
3008 3012 Object.extend(methods, {

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.