Closes #429. Doesn't necessarily address the root cause however.

The problem stems from a bug in Safari which is allowing callbacks
to interrupt running code (which should be impossible in JavaScript).
The change essentially makes it so that in the case where this happens,
which is rare, we'll end up accidentally creating an extra iframe.
This isn't ideal, but it also isn't harmful, versus the current
situation where code will simply break.
This commit is contained in:
Ross Boucher committed 2010-01-31 15:07:23 -08:00
1 parent e9940d060a
commit 5366713790
2 files changed
+41 -16

No files matched your search

+5
View File
@@ -21,6 +21,7 @@
*/
CPPlatformDidClearBodyElementNotification = @"CPPlatformDidClearBodyElementNotification";
CPPlatformWillClearBodyElementNotification = @"CPPlatformWillClearBodyElementNotification";
var screenNeedsInitialization = NO,
mainBodyElement = nil;
@@ -91,6 +92,10 @@ var screenNeedsInitialization = NO,
screenNeedsInitialization = NO;
[[CPNotificationCenter defaultCenter]
postNotificationName:CPPlatformWillClearBodyElementNotification
object:self];
var bodyElement = [self mainBodyElement];
// Get rid of any of the original contents of the page.
+36 -16
View File
@@ -22,8 +22,8 @@
#include "../CoreGraphics/CGGeometry.h"
var DOMSpanElement = nil,
DOMIFrameElement = nil,
DefaultFont = nil;
@implementation CPPlatformString : CPBasePlatformString
@@ -39,11 +39,20 @@ var DOMSpanElement = nil,
selector:@selector(platformDidClearBodyElement:)
name:CPPlatformDidClearBodyElementNotification
object:CPPlatform];
[[CPNotificationCenter defaultCenter]
addObserver:self
selector:@selector(platformWillClearBodyElement:)
name:CPPlatformWillClearBodyElementNotification
object:CPPlatform];
}
+ (void)createDOMElements
{
var DOMIFrameElement = document.createElement("iframe");
if (DOMIFrameElement)
return;
DOMIFrameElement = document.createElement("iframe");
// necessary for Safari caching bug:
DOMIFrameElement.name = "iframe_" + FLOOR(RAND() * 10000);
DOMIFrameElement.style.position = "absolute";
@@ -80,11 +89,27 @@ var DOMSpanElement = nil,
DOMDivElement.appendChild(DOMSpanElement);
}
+ (void)removeDOMElements
{
var iframe = DOMIFrameElement,
bodyElement = [CPPlatform mainBodyElement];
DOMSpanElement = nil;
DOMIFrameElement = nil;
bodyElement.removeChild(iframe);
}
+ (void)platformDidClearBodyElement:(CPNotification)aNotification
{
[self createDOMElements];
}
+ (void)platformWillClearBodyElement:(CPNotification)aNotification
{
[self removeDOMElements];
}
+ (CGSize)sizeOfString:(CPString)aString withFont:(CPFont)aFont forWidth:(float)aWidth
{
if (!aFont)
@@ -95,35 +120,30 @@ var DOMSpanElement = nil,
aFont = DefaultFont;
}
if (!DOMIFrameElement)
[self createDOMElements];
var style = DOMSpanElement.style;
if (aWidth === NULL)
if (!aWidth)
{
style.width = "";
style.whiteSpace = "pre";
}
else
{
style.width = ROUND(aWidth) + "px";
if (document.attachEvent)
style.wordWrap = "break-word";
else
{
style.whiteSpace = "-o-pre-wrap";
style.whiteSpace = "-pre-wrap";
style.whiteSpace = "-moz-pre-wrap";
style.whiteSpace = "pre-wrap";
}
style.wordWrap = "break-word";
style.whiteSpace = "-o-pre-wrap";
style.whiteSpace = "-pre-wrap";
style.whiteSpace = "-moz-pre-wrap";
style.whiteSpace = "pre-wrap";
}
style.font = [aFont cssString];
if (CPFeatureIsCompatible(CPJavascriptInnerTextFeature))
DOMSpanElement.innerText = aString;
else if (CPFeatureIsCompatible(CPJavascriptTextContentFeature))
DOMSpanElement.textContent = aString;