Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed: popoverDidShow in Firefox. New: popover animation support in F…
…irefox, Opera and IE10.

Before this fix, popoverDidShow: would not be sent to popover delegates when the app ran in Firefox due to Firefox now recognising the -webkit-transition property, but not the webkitTransitionEnd event.

Also, before this fix popover animation was only implemented for Webkit based browsers.

This fix resolves that issue and in addition adds full support for animated popovers in all browsers that support CSS transitions. The fix also improves Cappuccino's general support for CSS3 animations.
  • Loading branch information
aljungberg committed Dec 13, 2012
1 parent 9035439 commit 0781a41
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 22 deletions.
87 changes: 86 additions & 1 deletion AppKit/CPCompatibility.j
Expand Up @@ -83,7 +83,8 @@ CPCanvasParentDrawErrorsOnMovementBug = 1 << 0;
var USER_AGENT = "",
PLATFORM_ENGINE = CPUnknownBrowserEngine,
PLATFORM_FEATURES = 0,
PLATFORM_BUGS = 0;
PLATFORM_BUGS = 0,
PLATFORM_STYLE_JS_PROPERTIES = {};

// default these features to true

Expand Down Expand Up @@ -273,3 +274,87 @@ else
CPUndoKeyEquivalentModifierMask = CPControlKeyMask;
CPRedoKeyEquivalentModifierMask = CPControlKeyMask;
}

/*!
Return the properly prefixed JS property for the given name. E.g. in a webkit browser,
CPBrowserStyleProperty('transition') -> WebkitTransition
While technically not a style property, style related event handler names are also supported.
CPBrowserStyleProperty('transitionend') -> 'webkitTransitionEnd'
CSS is only available in platform(dom), so don't rely too heavily on it.
*/
function CPBrowserStyleProperty(aProperty)
{
var lowerProperty = aProperty.toLowerCase();

if (PLATFORM_STYLE_JS_PROPERTIES[lowerProperty] === undefined)
{
var r = nil;

#if PLATFORM(DOM)
var testElement = document.createElement('div');

switch (lowerProperty)
{
case 'transitionend':
var candidates = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
};

r = candidates[PLATFORM_STYLE_JS_PROPERTIES['transition']] || nil;
break;
default:
var prefixes = ["Webkit", "Moz", "O", "ms"],
capProperty = [aProperty capitalizedString];

for (var i = 0; i < prefixes.length; i++)
{
if (prefixes[i] + capProperty in testElement.style)
{
r = prefixes[i] + capProperty;
break;
}
}

if (!r && lowerProperty in testElement.style)
r = lowerProperty;

break;
}
#endif

PLATFORM_STYLE_JS_PROPERTIES[lowerProperty] = r;
}

return PLATFORM_STYLE_JS_PROPERTIES[lowerProperty];
}

function CPBrowserCSSProperty(aProperty)
{
var browserProperty = CPBrowserStyleProperty(aProperty);

if (!browserProperty)
return nil;

var prefixes = {
'Webkit': '-webkit-',
'Moz': '-moz-',
'O': '-o-',
'ms': '-ms-'
};

for (var prefix in prefixes)
{
if (browserProperty.substring(0, prefix.length) == prefix)
{
return prefixes[prefix] + browserProperty.substring(prefix.length).toLowerCase();
}
}

return browserProperty.toLowerCase();
}
35 changes: 14 additions & 21 deletions AppKit/_CPAttachedWindow.j
Expand Up @@ -134,7 +134,7 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
[self setMovableByWindowBackground:YES];
[self setHasShadow:NO];

[self setCSS3Property:@"TransitionProperty" value:@"-webkit-transform, opacity"];
[self setCSS3Property:@"TransitionProperty" value:CPBrowserCSSProperty('transform') + @", opacity"];

[_windowView setNeedsDisplay:YES];
}
Expand Down Expand Up @@ -350,25 +350,18 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,
}

/*! @ignore */
- (void)setCSS3Property:(CPString)property value:(CPString)value
- (void)setCSS3Property:(CPString)aProperty value:(CPString)value
{
_DOMElement.style['webkit' + property] = value;
var browserProperty = CPBrowserStyleProperty(aProperty);

// Support other browsers here eventually
if (browserProperty)
_DOMElement.style[browserProperty] = value;
}

/*! @ignore */
- (BOOL)browserSupportsAnimation
{
return typeof(_DOMElement.style.webkitTransition) !== "undefined";

/*
No others browsers supported yet.
typeof(_DOMElement.style.MozTransition) !== "undefined" ||
typeof(_DOMElement.style.MsTransition) !== "undefined" ||
typeof(_DOMElement.style.OTransition) !== "undefined";
*/
return CPBrowserStyleProperty('transition') && CPBrowserStyleProperty('transitionend');
}

#pragma mark -
Expand Down Expand Up @@ -452,28 +445,28 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,

// Set up the pop-out transition
[self setCSS3Property:@"Transform" value:@"scale(1.1)"];
[self setCSS3Property:@"Transition" value:@"-webkit-transform 200ms ease-in"];
[self setCSS3Property:@"Transition" value:CPBrowserCSSProperty('transform') + @" 200ms ease-in"];

var transitionEndFunction = function()
{
_DOMElement.removeEventListener("webkitTransitionEnd", transitionEndFunction, YES);
_DOMElement.removeEventListener(CPBrowserStyleProperty('transitionend'), transitionEndFunction, YES);

// Now set up the pop-in to normal size transition.
// Because we are watching the -webkit-transform, it will occur now.
[self setCSS3Property:@"Transform" value:@"scale(1)"];
[self setCSS3Property:@"Transition" value:@"-webkit-transform 50ms linear"];
[self setCSS3Property:@"Transition" value:CPBrowserCSSProperty('transform') + @" 50ms linear"];

var transitionCompleteFunction = function()
{
_DOMElement.removeEventListener("webkitTransitionEnd", transitionCompleteFunction, YES);
_DOMElement.removeEventListener(CPBrowserStyleProperty('transitionend'), transitionCompleteFunction, YES);
if (_implementedDelegateMethods & _CPAttachedWindow_attachedWindowDidShow_)
[_delegate attachedWindowDidShow:self];
}

_DOMElement.addEventListener("webkitTransitionEnd", transitionCompleteFunction, YES);
_DOMElement.addEventListener(CPBrowserStyleProperty('transitionend'), transitionCompleteFunction, YES);
};

_DOMElement.addEventListener("webkitTransitionEnd", transitionEndFunction, YES);
_DOMElement.addEventListener(CPBrowserStyleProperty('transitionend'), transitionEndFunction, YES);
}, 0);
}
else
Expand Down Expand Up @@ -506,11 +499,11 @@ var _CPAttachedWindow_attachedWindowShouldClose_ = 1 << 0,

var transitionEndFunction = function()
{
_DOMElement.removeEventListener("webkitTransitionEnd", transitionEndFunction, YES);
_DOMElement.removeEventListener(CPBrowserStyleProperty("transitionend"), transitionEndFunction, YES);
[self _close];
};

_DOMElement.addEventListener("webkitTransitionEnd", transitionEndFunction, YES);
_DOMElement.addEventListener(CPBrowserStyleProperty("transitionend"), transitionEndFunction, YES);
}
else
{
Expand Down

0 comments on commit 0781a41

Please sign in to comment.