From 7e2fe6d5be908326213cecea1b4f6e2aa383d5b7 Mon Sep 17 00:00:00 2001 From: Francisco Ryan Tolmasky I Date: Thu, 7 Jan 2010 19:30:17 -0800 Subject: [PATCH] Fix for white flash when loading Cappuccino apps. Reviewed by boucher. --- AppKit/Platform/CPPlatform+DOM.j | 65 ++++++++++++++++++++++ AppKit/Platform/CPPlatform.j | 14 ++--- AppKit/Platform/CPPlatformString.j | 6 +- AppKit/Platform/DOM/CPPlatformWindow+DOM.j | 18 +++++- 4 files changed, 88 insertions(+), 15 deletions(-) create mode 100644 AppKit/Platform/CPPlatform+DOM.j diff --git a/AppKit/Platform/CPPlatform+DOM.j b/AppKit/Platform/CPPlatform+DOM.j new file mode 100644 index 000000000..55c51bfbd --- /dev/null +++ b/AppKit/Platform/CPPlatform+DOM.j @@ -0,0 +1,65 @@ +/* + * CPPlatform+DOM.j + * AppKit + * + * Created by Francisco Tolmasky. + * Copyright 2010, 280 North, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +var DOMSafeElement = NULL, + screenNeedsInitialization = [CPPlatform isBrowser]; + +@implementation CPPlatform (DOM) + ++ (DOMElement)DOMSafeElement +{ + if (!DOMSafeElement) + { + DOMSafeElement = document.createElement("div"); + + DOMSafeElement.style.position = "absolute"; + DOMSafeElement.style.left = "-100000px"; + DOMSafeElement.style.top = "-100000px"; + DOMSafeElement.style.overflow = "visible"; + + document.body.appendChild(DOMSafeElement); + } + + return DOMSafeElement; +} + ++ (void)initializeScreenIfNecessary +{ + if (!screenNeedsInitialization) + return; + + screenNeedsInitialization = NO; + + var body = document.body; + + body.removeChild(DOMSafeElement); + + body.innerHTML = ""; // Get rid of anything that might be lingering in the body element. + body.style.overflow = "hidden"; + + body.appendChild(DOMSafeElement); + + if (document.documentElement) + document.documentElement.style.overflow = "hidden"; +} + +@end diff --git a/AppKit/Platform/CPPlatform.j b/AppKit/Platform/CPPlatform.j index 8635c7aac..ea156e7bd 100644 --- a/AppKit/Platform/CPPlatform.j +++ b/AppKit/Platform/CPPlatform.j @@ -10,16 +10,6 @@ + (void)bootstrap { -#if PLATFORM(DOM) - var body = document.getElementsByTagName("body")[0]; - - body.innerHTML = ""; // Get rid of anything that might be lingering in the body element. - body.style.overflow = "hidden"; - - if (document.documentElement) - document.documentElement.style.overflow = "hidden"; -#endif - [CPPlatformString bootstrap]; [CPPlatformWindow setPrimaryPlatformWindow:[[CPPlatformWindow alloc] _init]]; } @@ -70,3 +60,7 @@ } @end + +#if PLATFORM(DOM) +@import "CPPlatform+DOM.j" +#endif diff --git a/AppKit/Platform/CPPlatformString.j b/AppKit/Platform/CPPlatformString.j index 24e91d152..9f099569a 100644 --- a/AppKit/Platform/CPPlatformString.j +++ b/AppKit/Platform/CPPlatformString.j @@ -19,6 +19,8 @@ var DOMIFrameElement = nil, + (void)bootstrap { #if PLATFORM(DOM) + var DOMSafeElement = [CPPlatform DOMSafeElement]; + DOMIFrameElement = document.createElement("iframe"); DOMIFrameElement.name = name = "iframe_" + FLOOR(RAND() * 10000); @@ -32,7 +34,7 @@ var DOMIFrameElement = nil, DOMIFrameElement.style.overflow = "hidden"; DOMIFrameElement.style.zIndex = 100000000000; - document.getElementsByTagName("body")[0].appendChild(DOMIFrameElement); + DOMSafeElement.appendChild(DOMIFrameElement); var DOMIFrameDocument = (DOMIFrameElement.contentDocument || DOMIFrameElement.contentWindow.document); @@ -48,7 +50,7 @@ var DOMIFrameElement = nil, DOMSpanElement.style.margin = "0px"; DOMSpanElement.style.background = "red"; - DOMIFrameDocument.getElementsByTagName("body")[0].appendChild(DOMSpanElement); + DOMIFrameDocument.body.appendChild(DOMSpanElement); #endif } diff --git a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j index a2a336aef..3e38df165 100644 --- a/AppKit/Platform/DOM/CPPlatformWindow+DOM.j +++ b/AppKit/Platform/DOM/CPPlatformWindow+DOM.j @@ -1,5 +1,5 @@ /* - * _CPDOMWindow.j + * CPPlatformWindow+DOM.j * AppKit * * Created by Francisco Tolmasky. @@ -228,12 +228,22 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; _DOMWindow.blur(); } +- (void)DOMSafeElement +{ + if (_DOMWindow === window) + return [CPPlatform DOMSafeElement]; + + return _DOMBodyElement; +} + - (void)registerDOMWindow { var theDocument = _DOMWindow.document; _DOMBodyElement = theDocument.getElementsByTagName("body")[0]; + var DOMSafeElement = [self DOMSafeElement]; + // FIXME: Always do this? if ([CPPlatform supportsDragAndDrop]) _DOMBodyElement.style["-khtml-user-select"] = "none"; @@ -248,7 +258,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; _DOMFocusElement.style.opacity = "0"; _DOMFocusElement.style.filter = "alpha(opacity=0)"; - _DOMBodyElement.appendChild(_DOMFocusElement); + DOMSafeElement.appendChild(_DOMFocusElement); // Create Native Pasteboard handler. _DOMPasteboardElement = theDocument.createElement("textarea"); @@ -257,7 +267,7 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; _DOMPasteboardElement.style.top = "-10000px"; _DOMPasteboardElement.style.zIndex = "999"; - _DOMBodyElement.appendChild(_DOMPasteboardElement); + DOMSafeElement.appendChild(_DOMPasteboardElement); // Make sure the pastboard element is blurred. _DOMPasteboardElement.blur(); @@ -1138,6 +1148,8 @@ var supportsNativeDragAndDrop = [CPPlatform supportsDragAndDrop]; - (void)order:(CPWindowOrderingMode)aPlace window:(CPWindow)aWindow relativeTo:(CPWindow)otherWindow { + [CPPlatform initializeScreenIfNecessary]; + // Grab the appropriate level for the layer, and create it if // necessary (if we are not simply removing the window). var layer = [self layerAtLevel:[aWindow level] create:aPlace != CPWindowOut];