mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Rebase mozilla-inbound to 569a960b4a64 and then re-merge with mozilla-central so we're in a known good state.
This commit is contained in:
commit
43b3d449c6
@ -43,11 +43,11 @@
|
||||
* - and allows to restore everything into one window.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(e7bb7828-0e32-4995-a848-4aa35df603c7)]
|
||||
[scriptable, uuid(170c6857-7f71-46ce-bc9b-185723b1c3a8)]
|
||||
interface nsISessionStartup: nsISupports
|
||||
{
|
||||
// Get session state as string
|
||||
readonly attribute AString state;
|
||||
// Get session state
|
||||
readonly attribute jsval state;
|
||||
|
||||
/**
|
||||
* Determine if session should be restored
|
||||
|
@ -89,7 +89,7 @@ function SessionStartup() {
|
||||
SessionStartup.prototype = {
|
||||
|
||||
// the state to restore at startup
|
||||
_iniString: null,
|
||||
_initialState: null,
|
||||
_sessionType: Ci.nsISessionStartup.NO_SESSION,
|
||||
|
||||
/* ........ Global Event Handlers .............. */
|
||||
@ -121,31 +121,30 @@ SessionStartup.prototype = {
|
||||
return;
|
||||
|
||||
// get string containing session state
|
||||
this._iniString = this._readStateFile(sessionFile);
|
||||
if (!this._iniString)
|
||||
let iniString = this._readStateFile(sessionFile);
|
||||
if (!iniString)
|
||||
return;
|
||||
|
||||
// parse the session state into a JS object
|
||||
let initialState;
|
||||
try {
|
||||
// remove unneeded braces (added for compatibility with Firefox 2.0 and 3.0)
|
||||
if (this._iniString.charAt(0) == '(')
|
||||
this._iniString = this._iniString.slice(1, -1);
|
||||
if (iniString.charAt(0) == '(')
|
||||
iniString = iniString.slice(1, -1);
|
||||
try {
|
||||
initialState = JSON.parse(this._iniString);
|
||||
this._initialState = JSON.parse(iniString);
|
||||
}
|
||||
catch (exJSON) {
|
||||
var s = new Cu.Sandbox("about:blank");
|
||||
initialState = Cu.evalInSandbox("(" + this._iniString + ")", s);
|
||||
this._iniString = JSON.stringify(initialState);
|
||||
this._initialState = Cu.evalInSandbox("(" + iniString + ")", s);
|
||||
}
|
||||
}
|
||||
catch (ex) { debug("The session file is invalid: " + ex); }
|
||||
|
||||
let resumeFromCrash = prefBranch.getBoolPref("sessionstore.resume_from_crash");
|
||||
let lastSessionCrashed =
|
||||
initialState && initialState.session && initialState.session.state &&
|
||||
initialState.session.state == STATE_RUNNING_STR;
|
||||
this._initialState && this._initialState.session &&
|
||||
this._initialState.session.state &&
|
||||
this._initialState.session.state == STATE_RUNNING_STR;
|
||||
|
||||
// Report shutdown success via telemetry. Shortcoming here are
|
||||
// being-killed-by-OS-shutdown-logic, shutdown freezing after
|
||||
@ -158,17 +157,17 @@ SessionStartup.prototype = {
|
||||
this._sessionType = Ci.nsISessionStartup.RECOVER_SESSION;
|
||||
else if (!lastSessionCrashed && doResumeSession)
|
||||
this._sessionType = Ci.nsISessionStartup.RESUME_SESSION;
|
||||
else if (initialState)
|
||||
else if (this._initialState)
|
||||
this._sessionType = Ci.nsISessionStartup.DEFER_SESSION;
|
||||
else
|
||||
this._iniString = null; // reset the state string
|
||||
this._initialState = null; // reset the state
|
||||
|
||||
// wait for the first browser window to open
|
||||
// Don't reset the initial window's default args (i.e. the home page(s))
|
||||
// if all stored tabs are pinned.
|
||||
if (this.doRestore() &&
|
||||
(!initialState.windows ||
|
||||
!initialState.windows.every(function (win)
|
||||
(!this._initialState.windows ||
|
||||
!this._initialState.windows.every(function (win)
|
||||
win.tabs.every(function (tab) tab.pinned))))
|
||||
Services.obs.addObserver(this, "domwindowopened", true);
|
||||
|
||||
@ -204,8 +203,8 @@ SessionStartup.prototype = {
|
||||
break;
|
||||
case "sessionstore-windows-restored":
|
||||
Services.obs.removeObserver(this, "sessionstore-windows-restored");
|
||||
// free _iniString after nsSessionStore is done with it
|
||||
this._iniString = null;
|
||||
// free _initialState after nsSessionStore is done with it
|
||||
this._initialState = null;
|
||||
this._sessionType = Ci.nsISessionStartup.NO_SESSION;
|
||||
break;
|
||||
}
|
||||
@ -254,7 +253,7 @@ SessionStartup.prototype = {
|
||||
* Get the session state as a string
|
||||
*/
|
||||
get state() {
|
||||
return this._iniString;
|
||||
return this._initialState;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -304,33 +304,31 @@ SessionStoreService.prototype = {
|
||||
this._sessionFileBackup.append("sessionstore.bak");
|
||||
|
||||
// get string containing session state
|
||||
var iniString;
|
||||
var ss = Cc["@mozilla.org/browser/sessionstartup;1"].
|
||||
getService(Ci.nsISessionStartup);
|
||||
try {
|
||||
if (ss.doRestore() ||
|
||||
ss.sessionType == Ci.nsISessionStartup.DEFER_SESSION)
|
||||
iniString = ss.state;
|
||||
this._initialState = ss.state;
|
||||
}
|
||||
catch(ex) { dump(ex + "\n"); } // no state to restore, which is ok
|
||||
|
||||
if (iniString) {
|
||||
if (this._initialState) {
|
||||
try {
|
||||
// If we're doing a DEFERRED session, then we want to pull pinned tabs
|
||||
// out so they can be restored.
|
||||
if (ss.sessionType == Ci.nsISessionStartup.DEFER_SESSION) {
|
||||
let [iniState, remainingState] = this._prepDataForDeferredRestore(iniString);
|
||||
let [iniState, remainingState] = this._prepDataForDeferredRestore(this._initialState);
|
||||
// If we have a iniState with windows, that means that we have windows
|
||||
// with app tabs to restore.
|
||||
if (iniState.windows.length)
|
||||
this._initialState = iniState;
|
||||
else
|
||||
this._initialState = null;
|
||||
if (remainingState.windows.length)
|
||||
this._lastSessionState = remainingState;
|
||||
}
|
||||
else {
|
||||
// parse the session state into JS objects
|
||||
this._initialState = JSON.parse(iniString);
|
||||
|
||||
let lastSessionCrashed =
|
||||
this._initialState.session && this._initialState.session.state &&
|
||||
this._initialState.session.state == STATE_RUNNING_STR;
|
||||
@ -342,7 +340,7 @@ SessionStoreService.prototype = {
|
||||
// replace the crashed session with a restore-page-only session
|
||||
let pageData = {
|
||||
url: "about:sessionrestore",
|
||||
formdata: { "#sessionData": iniString }
|
||||
formdata: { "#sessionData": JSON.stringify(this._initialState) }
|
||||
};
|
||||
this._initialState = { windows: [{ tabs: [{ entries: [pageData] }] }] };
|
||||
}
|
||||
@ -811,7 +809,7 @@ SessionStoreService.prototype = {
|
||||
// We'll cheat a little bit and reuse _prepDataForDeferredRestore
|
||||
// even though it wasn't built exactly for this.
|
||||
let [appTabsState, normalTabsState] =
|
||||
this._prepDataForDeferredRestore(JSON.stringify({ windows: [closedWindowState] }));
|
||||
this._prepDataForDeferredRestore({ windows: [closedWindowState] });
|
||||
|
||||
// These are our pinned tabs, which we should restore
|
||||
if (appTabsState.windows.length) {
|
||||
@ -3794,12 +3792,11 @@ SessionStoreService.prototype = {
|
||||
* this._lastSessionState and will be kept in case the user explicitly wants
|
||||
* to restore the previous session (publicly exposed as restoreLastSession).
|
||||
*
|
||||
* @param stateString
|
||||
* The state string, presumably from nsISessionStartup.state
|
||||
* @param state
|
||||
* The state, presumably from nsISessionStartup.state
|
||||
* @returns [defaultState, state]
|
||||
*/
|
||||
_prepDataForDeferredRestore: function sss__prepDataForDeferredRestore(stateString) {
|
||||
let state = JSON.parse(stateString);
|
||||
_prepDataForDeferredRestore: function sss__prepDataForDeferredRestore(state) {
|
||||
let defaultState = { windows: [], selectedWindow: 1 };
|
||||
|
||||
state.selectedWindow = state.selectedWindow || 1;
|
||||
|
10
configure.in
10
configure.in
@ -7470,12 +7470,20 @@ else
|
||||
WIN32_CUSTOM_CRT_DIR="$_objdir_win/memory/jemalloc/crtsrc/build/$MOZ_CRT_CPU_ARCH"
|
||||
MOZ_MEMORY_LDFLAGS="-MANIFEST:NO -LIBPATH:\"$WIN32_CUSTOM_CRT_DIR\" -NODEFAULTLIB:msvcrt -NODEFAULTLIB:msvcrtd -NODEFAULTLIB:msvcprt -NODEFAULTLIB:msvcprtd -DEFAULTLIB:mozcrt19 -DEFAULTLIB:mozcpp19"
|
||||
else
|
||||
MOZ_MEMORY_LDFLAGS='-MANIFEST:NO -LIBPATH:$(DIST)/lib -NODEFAULTLIB:msvcrt -NODEFAULTLIB:msvcrtd -NODEFAULTLIB:msvcprt -NODEFAULTLIB:msvcprtd -DEFAULTLIB:mozcrt'
|
||||
if test -z "$MOZ_DEBUG"; then
|
||||
WIN32_CRT_LIBS="msvcrt.lib msvcprt.lib"
|
||||
else
|
||||
WIN32_CRT_LIBS="msvcrtd.lib msvcprtd.lib"
|
||||
fi
|
||||
dnl Look for a broken crtdll.obj
|
||||
WIN32_CRTDLL_FULLPATH=`lib -list $WIN32_CRT_LIBS | grep crtdll\\.obj`
|
||||
lib -OUT:crtdll.obj $WIN32_CRT_LIBS -EXTRACT:$WIN32_CRTDLL_FULLPATH
|
||||
if grep -q '__imp__?free' crtdll.obj; then
|
||||
MOZ_MEMORY_LDFLAGS='-MANIFEST:NO -LIBPATH:$(DIST)/lib -NODEFAULTLIB:msvcrt -NODEFAULTLIB:msvcrtd -NODEFAULTLIB:msvcprt -NODEFAULTLIB:msvcprtd -DEFAULTLIB:mozcrt'
|
||||
else
|
||||
MOZ_MEMORY_LDFLAGS='$(DIST)/../memory/jemalloc/jemalloc.lib'
|
||||
fi
|
||||
rm crtdll.obj
|
||||
fi
|
||||
dnl Also pass this to NSPR/NSS
|
||||
DLLFLAGS="$DLLFLAGS $MOZ_MEMORY_LDFLAGS"
|
||||
|
@ -1331,7 +1331,7 @@ nsIContent*
|
||||
nsIContent::GetEditingHost()
|
||||
{
|
||||
// If this isn't editable, return NULL.
|
||||
NS_ENSURE_TRUE(HasFlag(NODE_IS_EDITABLE), nsnull);
|
||||
NS_ENSURE_TRUE(IsEditableInternal(), nsnull);
|
||||
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
NS_ENSURE_TRUE(doc, nsnull);
|
||||
|
@ -512,14 +512,12 @@ ContentParent::RecvGetClipboardText(const PRInt32& whichClipboard, nsString* tex
|
||||
clipboard->GetData(trans, whichClipboard);
|
||||
nsCOMPtr<nsISupports> tmp;
|
||||
PRUint32 len;
|
||||
rv = trans->GetTransferData(kUnicodeMime, getter_AddRefs(tmp), &len);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
rv = trans->GetTransferData(kUnicodeMime, getter_AddRefs(tmp), &len);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupportsString> supportsString = do_QueryInterface(tmp);
|
||||
// No support for non-text data
|
||||
if (!supportsString)
|
||||
return false;
|
||||
NS_ENSURE_TRUE(supportsString, NS_ERROR_NOT_IMPLEMENTED);
|
||||
supportsString->GetData(*text);
|
||||
return true;
|
||||
}
|
||||
|
@ -460,13 +460,11 @@ TabChild::DestroyWindow()
|
||||
void
|
||||
TabChild::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (mTabChildGlobal) {
|
||||
// The messageManager relays messages via the TabChild which
|
||||
// no longer exists.
|
||||
static_cast<nsFrameMessageManager*>
|
||||
(mTabChildGlobal->mMessageManager.get())->Disconnect();
|
||||
mTabChildGlobal->mMessageManager = nsnull;
|
||||
}
|
||||
// The messageManager relays messages via the TabChild which
|
||||
// no longer exists.
|
||||
static_cast<nsFrameMessageManager*>
|
||||
(mTabChildGlobal->mMessageManager.get())->Disconnect();
|
||||
mTabChildGlobal->mMessageManager = nsnull;
|
||||
}
|
||||
|
||||
TabChild::~TabChild()
|
||||
@ -479,13 +477,11 @@ TabChild::~TabChild()
|
||||
DestroyCx();
|
||||
}
|
||||
|
||||
if (mTabChildGlobal) {
|
||||
nsEventListenerManager* elm = mTabChildGlobal->GetListenerManager(PR_FALSE);
|
||||
if (elm) {
|
||||
elm->Disconnect();
|
||||
}
|
||||
mTabChildGlobal->mTabChild = nsnull;
|
||||
nsEventListenerManager* elm = mTabChildGlobal->GetListenerManager(PR_FALSE);
|
||||
if (elm) {
|
||||
elm->Disconnect();
|
||||
}
|
||||
mTabChildGlobal->mTabChild = nsnull;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -500,7 +496,7 @@ TabChild::RecvLoadURL(const nsCString& uri)
|
||||
NS_WARNING("mWebNav->LoadURI failed. Eating exception, what else can I do?");
|
||||
}
|
||||
|
||||
return true;
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -515,11 +511,7 @@ TabChild::RecvShow(const nsIntSize& size)
|
||||
}
|
||||
|
||||
if (!InitWidget(size)) {
|
||||
// We can fail to initialize our widget if the <browser
|
||||
// remote> has already been destroyed, and we couldn't hook
|
||||
// into the parent-process's layer system. That's not a fatal
|
||||
// error.
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
baseWindow->InitWindow(0, mWidget,
|
||||
@ -545,9 +537,6 @@ bool
|
||||
TabChild::RecvMove(const nsIntSize& size)
|
||||
{
|
||||
printf("[TabChild] RESIZE to (w,h)= (%ud, %ud)\n", size.width, size.height);
|
||||
if (!mRemoteFrame) {
|
||||
return true;
|
||||
}
|
||||
|
||||
mWidget->Resize(0, 0, size.width, size.height,
|
||||
PR_TRUE);
|
||||
@ -786,9 +775,7 @@ bool
|
||||
TabChild::RecvLoadRemoteScript(const nsString& aURL)
|
||||
{
|
||||
if (!mCx && !InitTabChildGlobal())
|
||||
// This can happen if we're half-destroyed. It's not a fatal
|
||||
// error.
|
||||
return true;
|
||||
return false;
|
||||
|
||||
LoadFrameScriptInternal(aURL);
|
||||
return true;
|
||||
@ -838,12 +825,10 @@ public:
|
||||
bool
|
||||
TabChild::RecvDestroy()
|
||||
{
|
||||
if (mTabChildGlobal) {
|
||||
// Let the frame scripts know the child is being closed
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new UnloadScriptEvent(this, mTabChildGlobal)
|
||||
);
|
||||
}
|
||||
// Let the frame scripts know the child is being closed
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new UnloadScriptEvent(this, mTabChildGlobal)
|
||||
);
|
||||
|
||||
// XXX what other code in ~TabChild() should we be running here?
|
||||
DestroyWindow();
|
||||
@ -961,8 +946,7 @@ TabChild::InitWidget(const nsIntSize& size)
|
||||
|
||||
NS_ABORT_IF_FALSE(0 == remoteFrame->ManagedPLayersChild().Length(),
|
||||
"shouldn't have a shadow manager yet");
|
||||
LayerManager::LayersBackend be;
|
||||
PLayersChild* shadowManager = remoteFrame->SendPLayersConstructor(&be);
|
||||
PLayersChild* shadowManager = remoteFrame->SendPLayersConstructor();
|
||||
if (!shadowManager) {
|
||||
NS_WARNING("failed to construct LayersChild");
|
||||
// This results in |remoteFrame| being deleted.
|
||||
@ -970,11 +954,14 @@ TabChild::InitWidget(const nsIntSize& size)
|
||||
return false;
|
||||
}
|
||||
|
||||
ShadowLayerForwarder* lf =
|
||||
mWidget->GetLayerManager(shadowManager, be)->AsShadowForwarder();
|
||||
NS_ABORT_IF_FALSE(lf && lf->HasShadowManager(),
|
||||
"PuppetWidget should have shadow manager");
|
||||
lf->SetParentBackendType(be);
|
||||
LayerManager* lm = mWidget->GetLayerManager();
|
||||
NS_ABORT_IF_FALSE(LayerManager::LAYERS_BASIC == lm->GetBackendType(),
|
||||
"content processes should only be using BasicLayers");
|
||||
|
||||
BasicShadowLayerManager* bslm = static_cast<BasicShadowLayerManager*>(lm);
|
||||
NS_ABORT_IF_FALSE(!bslm->HasShadowManager(),
|
||||
"PuppetWidget shouldn't have shadow manager yet");
|
||||
bslm->SetShadowManager(shadowManager);
|
||||
|
||||
mRemoteFrame = remoteFrame;
|
||||
return true;
|
||||
|
@ -744,7 +744,8 @@ PRenderFrameParent*
|
||||
TabParent::AllocPRenderFrame()
|
||||
{
|
||||
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||
return new RenderFrameParent(frameLoader);
|
||||
NS_WARN_IF_FALSE(frameLoader, "'message sent to unknown actor ID' coming up");
|
||||
return frameLoader ? new RenderFrameParent(frameLoader) : nsnull;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -374,6 +374,11 @@ nsEditingSession::SetupEditorOnWindow(nsIDOMWindow *aWindow)
|
||||
document->FlushPendingNotifications(Flush_Frames);
|
||||
if (mMakeWholeDocumentEditable) {
|
||||
document->SetEditableFlag(PR_TRUE);
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(document);
|
||||
if (htmlDocument) {
|
||||
// Enable usage of the execCommand API
|
||||
htmlDocument->SetEditingState(nsIHTMLDocument::eDesignMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -611,6 +616,10 @@ nsEditingSession::TearDownEditorOnWindow(nsIDOMWindow *aWindow)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
doc->SetEditableFlag(PR_FALSE);
|
||||
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(doc);
|
||||
if (htmlDocument) {
|
||||
htmlDocument->SetEditingState(nsIHTMLDocument::eOff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,5 +51,12 @@ _TEST_FILES = \
|
||||
test_bug519928.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_TEST_FILES = \
|
||||
test_bug434998.xul \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
||||
|
||||
libs:: $(_CHROME_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
|
||||
|
110
editor/composer/test/test_bug434998.xul
Normal file
110
editor/composer/test/test_bug434998.xul
Normal file
@ -0,0 +1,110 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin"
|
||||
type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=434998
|
||||
-->
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Mozilla Bug 434998" onload="runTest();">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=434998"
|
||||
target="_blank">Mozilla Bug 434998</a>
|
||||
<p/>
|
||||
<editor xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="editor"
|
||||
type="content-primary"
|
||||
editortype="html"
|
||||
style="width: 400px; height: 100px; border: thin solid black"/>
|
||||
<p/>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function EditorContentListener(aEditor)
|
||||
{
|
||||
this.init(aEditor);
|
||||
}
|
||||
|
||||
EditorContentListener.prototype = {
|
||||
init : function(aEditor)
|
||||
{
|
||||
this.mEditor = aEditor;
|
||||
},
|
||||
|
||||
QueryInterface : function(aIID)
|
||||
{
|
||||
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
|
||||
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
|
||||
aIID.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
},
|
||||
|
||||
onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
|
||||
{
|
||||
if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
|
||||
{
|
||||
var editor = this.mEditor.getEditor(this.mEditor.contentWindow);
|
||||
if (editor) {
|
||||
// Should not throw
|
||||
var threw = false;
|
||||
try {
|
||||
this.mEditor.contentDocument.execCommand("bold", false, null);
|
||||
} catch (e) {
|
||||
threw = true;
|
||||
}
|
||||
ok(!threw, "The execCommand API should work on <xul:editor>");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
onProgressChange : function(aWebProgress, aRequest,
|
||||
aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress)
|
||||
{
|
||||
},
|
||||
|
||||
onLocationChange : function(aWebProgress, aRequest, aLocation)
|
||||
{
|
||||
},
|
||||
|
||||
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
|
||||
{
|
||||
},
|
||||
|
||||
onSecurityChange : function(aWebProgress, aRequest, aState)
|
||||
{
|
||||
},
|
||||
|
||||
mEditor: null
|
||||
};
|
||||
|
||||
var progress, progressListener;
|
||||
|
||||
function runTest() {
|
||||
var newEditorElement = document.getElementById("editor");
|
||||
newEditorElement.makeEditable("html", true);
|
||||
var docShell = newEditorElement.boxObject.QueryInterface(Components.interfaces.nsIEditorBoxObject).docShell;
|
||||
progress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);
|
||||
progressListener = new EditorContentListener(newEditorElement);
|
||||
progress.addProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
|
||||
newEditorElement.setAttribute("src", "data:text/html,");
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
@ -3792,7 +3792,20 @@ nsEditor::GetChildAt(nsIDOMNode *aParent, PRInt32 aOffset)
|
||||
|
||||
return resultNode;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// GetNodeAtRangeOffsetPoint: returns the node at this position in a range,
|
||||
// assuming that aParentOrNode is the node itself if it's a text node, or
|
||||
// the node's parent otherwise.
|
||||
//
|
||||
nsCOMPtr<nsIDOMNode>
|
||||
nsEditor::GetNodeAtRangeOffsetPoint(nsIDOMNode* aParentOrNode, PRInt32 aOffset)
|
||||
{
|
||||
if (IsTextNode(aParentOrNode)) {
|
||||
return aParentOrNode;
|
||||
}
|
||||
return GetChildAt(aParentOrNode, aOffset);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -566,7 +566,8 @@ public:
|
||||
|
||||
static PRInt32 GetIndexOf(nsIDOMNode *aParent, nsIDOMNode *aChild);
|
||||
static nsCOMPtr<nsIDOMNode> GetChildAt(nsIDOMNode *aParent, PRInt32 aOffset);
|
||||
|
||||
static nsCOMPtr<nsIDOMNode> GetNodeAtRangeOffsetPoint(nsIDOMNode* aParentOrNode, PRInt32 aOffset);
|
||||
|
||||
static nsresult GetStartNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outStartNode, PRInt32 *outStartOffset);
|
||||
static nsresult GetEndNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outEndNode, PRInt32 *outEndOffset);
|
||||
#if DEBUG_JOE
|
||||
|
@ -1886,22 +1886,21 @@ nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection,
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
res = mHTMLEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(startNode), &startOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
|
||||
|
||||
// get the root element
|
||||
nsIDOMElement *rootNode = mHTMLEditor->GetRoot();
|
||||
NS_ENSURE_TRUE(rootNode, NS_ERROR_UNEXPECTED);
|
||||
|
||||
if (bCollapsed)
|
||||
{
|
||||
// if we are inside an empty block, delete it.
|
||||
res = CheckForEmptyBlock(startNode, rootNode, aSelection, aHandled);
|
||||
nsCOMPtr<nsIContent> hostContent = mHTMLEditor->GetActiveEditingHost();
|
||||
nsCOMPtr<nsIDOMNode> hostNode = do_QueryInterface(hostContent);
|
||||
NS_ENSURE_TRUE(hostNode, NS_ERROR_FAILURE);
|
||||
res = CheckForEmptyBlock(startNode, hostNode, aSelection, aHandled);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (*aHandled) return NS_OK;
|
||||
|
||||
|
||||
// Test for distance between caret and text that will be deleted
|
||||
res = CheckBidiLevelForDeletion(aSelection, startNode, startOffset, aAction, aCancel);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
@ -4893,6 +4892,10 @@ nsHTMLEditRules::CheckForEmptyBlock(nsIDOMNode *aStartNode,
|
||||
nsISelection *aSelection,
|
||||
PRBool *aHandled)
|
||||
{
|
||||
// If the editing host is an inline element, bail out early.
|
||||
if (IsInlineNode(aBodyNode)) {
|
||||
return NS_OK;
|
||||
}
|
||||
// if we are inside an empty block, delete it.
|
||||
// Note: do NOT delete table elements this way.
|
||||
nsresult res = NS_OK;
|
||||
@ -5473,24 +5476,32 @@ nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode, PRInt
|
||||
*outNode = node;
|
||||
*outOffset = offset;
|
||||
|
||||
// we do one thing for InsertText actions, something else entirely for other actions
|
||||
if (actionID == kInsertText)
|
||||
// we do one thing for text actions, something else entirely for other actions
|
||||
if (actionID == nsEditor::kOpInsertText ||
|
||||
actionID == nsEditor::kOpInsertIMEText ||
|
||||
actionID == nsEditor::kOpInsertBreak ||
|
||||
actionID == nsEditor::kOpDeleteText)
|
||||
{
|
||||
PRBool isSpace, isNBSP;
|
||||
nsCOMPtr<nsIDOMNode> temp;
|
||||
// for insert text or delete actions, we want to look backwards (or forwards, as appropriate)
|
||||
PRBool isSpace, isNBSP;
|
||||
nsCOMPtr<nsIDOMNode> temp;
|
||||
// for text actions, we want to look backwards (or forwards, as appropriate)
|
||||
// for additional whitespace or nbsp's. We may have to act on these later even though
|
||||
// they are outside of the initial selection. Even if they are in another node!
|
||||
if (aWhere == kStart)
|
||||
{
|
||||
do
|
||||
{
|
||||
res = mHTMLEditor->IsPrevCharWhitespace(node, offset, &isSpace, &isNBSP, address_of(temp), &offset);
|
||||
PRInt32 prevOffset;
|
||||
res = mHTMLEditor->IsPrevCharWhitespace(node, offset, &isSpace, &isNBSP, address_of(temp), &prevOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (isSpace || isNBSP) node = temp;
|
||||
else break;
|
||||
if (isSpace || isNBSP) {
|
||||
node = temp;
|
||||
offset = prevOffset;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (node);
|
||||
|
||||
|
||||
*outNode = node;
|
||||
*outOffset = offset;
|
||||
}
|
||||
@ -5498,19 +5509,24 @@ nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode, PRInt
|
||||
{
|
||||
do
|
||||
{
|
||||
res = mHTMLEditor->IsNextCharWhitespace(node, offset, &isSpace, &isNBSP, address_of(temp), &offset);
|
||||
PRInt32 nextOffset;
|
||||
res = mHTMLEditor->IsNextCharWhitespace(node, offset, &isSpace, &isNBSP, address_of(temp), &nextOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (isSpace || isNBSP) node = temp;
|
||||
else break;
|
||||
if (isSpace || isNBSP) {
|
||||
node = temp;
|
||||
offset = nextOffset;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (node);
|
||||
|
||||
|
||||
*outNode = node;
|
||||
*outOffset = offset;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// else not kInsertText. In this case we want to see if we should
|
||||
|
||||
// else not a text section. In this case we want to see if we should
|
||||
// grab any adjacent inline nodes and/or parents and other ancestors
|
||||
if (aWhere == kStart)
|
||||
{
|
||||
@ -5549,11 +5565,21 @@ nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode, PRInt
|
||||
// as long as they are in one or the other it will work.
|
||||
// special case for outdent: don't keep looking up
|
||||
// if we have found a blockquote element to act on
|
||||
if ((actionID == kOutdent) && nsHTMLEditUtils::IsBlockquote(node))
|
||||
if ((actionID == nsHTMLEditor::kOpOutdent) && nsHTMLEditUtils::IsBlockquote(node))
|
||||
break;
|
||||
|
||||
res = nsEditor::GetNodeLocation(node, address_of(parent), &pOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// Don't walk past the editable section. Note that we need to check
|
||||
// before walking up to a parent because we need to return the parent
|
||||
// object, so the parent itself might not be in the editable area, but
|
||||
// it's OK.
|
||||
if (!mHTMLEditor->IsNodeInActiveEditor(node) &&
|
||||
!mHTMLEditor->IsNodeInActiveEditor(parent)) {
|
||||
break;
|
||||
}
|
||||
|
||||
node = parent;
|
||||
offset = pOffset;
|
||||
res = mHTMLEditor->GetPriorHTMLNode(node, offset, address_of(nearNode), PR_TRUE);
|
||||
@ -5600,6 +5626,16 @@ nsHTMLEditRules::GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode *aNode, PRInt
|
||||
{
|
||||
res = nsEditor::GetNodeLocation(node, address_of(parent), &pOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// Don't walk past the editable section. Note that we need to check
|
||||
// before walking up to a parent because we need to return the parent
|
||||
// object, so the parent itself might not be in the editable area, but
|
||||
// it's OK.
|
||||
if (!mHTMLEditor->IsNodeInActiveEditor(node) &&
|
||||
!mHTMLEditor->IsNodeInActiveEditor(parent)) {
|
||||
break;
|
||||
}
|
||||
|
||||
node = parent;
|
||||
offset = pOffset+1; // we want to be AFTER nearNode
|
||||
res = mHTMLEditor->GetNextHTMLNode(node, offset, address_of(nearNode), PR_TRUE);
|
||||
@ -5692,9 +5728,9 @@ nsHTMLEditRules::PromoteRange(nsIDOMRange *inRange,
|
||||
if (block)
|
||||
{
|
||||
PRBool bIsEmptyNode = PR_FALSE;
|
||||
// check for body
|
||||
nsIDOMElement *rootElement = mHTMLEditor->GetRoot();
|
||||
nsCOMPtr<nsINode> rootNode = do_QueryInterface(rootElement);
|
||||
// check for the editing host
|
||||
nsIContent *rootContent = mHTMLEditor->GetActiveEditingHost();
|
||||
nsCOMPtr<nsINode> rootNode = do_QueryInterface(rootContent);
|
||||
nsCOMPtr<nsINode> blockNode = do_QueryInterface(block);
|
||||
NS_ENSURE_TRUE(rootNode && blockNode, NS_ERROR_UNEXPECTED);
|
||||
// Make sure we don't go higher than our root element in the content tree
|
||||
@ -5727,6 +5763,13 @@ nsHTMLEditRules::PromoteRange(nsIDOMRange *inRange,
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = GetPromotedPoint( kEnd, endNode, endOffset, inOperationType, address_of(opEndNode), &opEndOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// Make sure that the new range ends up to be in the editable section.
|
||||
if (!mHTMLEditor->IsNodeInActiveEditor(nsEditor::GetNodeAtRangeOffsetPoint(opStartNode, opStartOffset)) ||
|
||||
!mHTMLEditor->IsNodeInActiveEditor(nsEditor::GetNodeAtRangeOffsetPoint(opEndNode, opEndOffset - 1))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
res = inRange->SetStart(opStartNode, opStartOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = inRange->SetEnd(opEndNode, opEndOffset);
|
||||
|
@ -2172,8 +2172,7 @@ nsHTMLEditor::SelectElement(nsIDOMElement* aElement)
|
||||
nsresult res = NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Must be sure that element is contained in the document body
|
||||
if (IsElementInBody(aElement))
|
||||
{
|
||||
if (IsNodeInActiveEditor(aElement)) {
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
@ -2205,8 +2204,7 @@ nsHTMLEditor::SetCaretAfterElement(nsIDOMElement* aElement)
|
||||
nsresult res = NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Be sure the element is contained in the document body
|
||||
if (aElement && IsElementInBody(aElement))
|
||||
{
|
||||
if (aElement && IsNodeInActiveEditor(aElement)) {
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
res = GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
@ -4281,9 +4279,16 @@ void nsHTMLEditor::IsTextPropertySetByContent(nsIDOMNode *aNode,
|
||||
//
|
||||
|
||||
|
||||
PRBool nsHTMLEditor::IsElementInBody(nsIDOMElement* aElement)
|
||||
PRBool
|
||||
nsHTMLEditor::IsNodeInActiveEditor(nsIDOMNode* aNode)
|
||||
{
|
||||
return nsTextEditUtils::InBody(aElement, this);
|
||||
nsIContent* activeEditingHost = GetActiveEditingHost();
|
||||
if (!activeEditingHost) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
NS_ENSURE_TRUE(node, PR_FALSE);
|
||||
return nsContentUtils::ContentIsDescendantOf(node, activeEditingHost);
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -4291,8 +4296,7 @@ nsHTMLEditor::SetCaretInTableCell(nsIDOMElement* aElement)
|
||||
{
|
||||
PRBool caretIsSet = PR_FALSE;
|
||||
|
||||
if (aElement && IsElementInBody(aElement))
|
||||
{
|
||||
if (aElement && IsNodeInActiveEditor(aElement)) {
|
||||
nsresult res = NS_OK;
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
|
||||
if (content)
|
||||
@ -4308,7 +4312,7 @@ nsHTMLEditor::SetCaretInTableCell(nsIDOMElement* aElement)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
// This MUST succeed if IsElementInBody was TRUE
|
||||
// This MUST succeed if IsNodeInActiveEditor was TRUE
|
||||
node->GetParentNode(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsIDOMNode>firstChild;
|
||||
// Find deepest child
|
||||
@ -4617,8 +4621,7 @@ nsHTMLEditor::GetPriorHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMP
|
||||
*outNode = nsnull;
|
||||
NS_ENSURE_TRUE(inOffset, NS_OK); // return null sibling if at offset zero
|
||||
nsCOMPtr<nsIDOMNode> node = nsEditor::GetChildAt(inParent,inOffset-1);
|
||||
if (IsEditable(node))
|
||||
{
|
||||
if (node && IsEditable(node)) {
|
||||
*outNode = node;
|
||||
return res;
|
||||
}
|
||||
@ -4669,8 +4672,7 @@ nsHTMLEditor::GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPt
|
||||
*outNode = nsnull;
|
||||
nsCOMPtr<nsIDOMNode> node = nsEditor::GetChildAt(inParent,inOffset);
|
||||
NS_ENSURE_TRUE(node, NS_OK); // return null sibling if no sibling
|
||||
if (IsEditable(node))
|
||||
{
|
||||
if (node && IsEditable(node)) {
|
||||
*outNode = node;
|
||||
return res;
|
||||
}
|
||||
@ -4692,8 +4694,7 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// if it's not in the body, then zero it out
|
||||
if (*outNode && !nsTextEditUtils::InBody(*outNode, this))
|
||||
{
|
||||
if (*outNode && !IsNodeInActiveEditor(*outNode)) {
|
||||
*outNode = nsnull;
|
||||
}
|
||||
return res;
|
||||
@ -4711,8 +4712,7 @@ nsHTMLEditor::GetPriorHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// if it's not in the body, then zero it out
|
||||
if (*outNode && !nsTextEditUtils::InBody(*outNode, this))
|
||||
{
|
||||
if (*outNode && !IsNodeInActiveEditor(*outNode)) {
|
||||
*outNode = nsnull;
|
||||
}
|
||||
return res;
|
||||
@ -4731,8 +4731,7 @@ nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNode,
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// if it's not in the body, then zero it out
|
||||
if (*outNode && !nsTextEditUtils::InBody(*outNode, this))
|
||||
{
|
||||
if (*outNode && !IsNodeInActiveEditor(*outNode)) {
|
||||
*outNode = nsnull;
|
||||
}
|
||||
return res;
|
||||
@ -4750,8 +4749,7 @@ nsHTMLEditor::GetNextHTMLNode(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPtr<n
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// if it's not in the body, then zero it out
|
||||
if (*outNode && !nsTextEditUtils::InBody(*outNode, this))
|
||||
{
|
||||
if (*outNode && !IsNodeInActiveEditor(*outNode)) {
|
||||
*outNode = nsnull;
|
||||
}
|
||||
return res;
|
||||
@ -5076,7 +5074,10 @@ nsHTMLEditor::IsEmptyNodeImpl( nsIDOMNode *aNode,
|
||||
{
|
||||
res = IsVisTextNode(node, outIsEmptyNode, aSafeToAskFrames);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(*outIsEmptyNode, NS_OK); // break out if we find we aren't emtpy
|
||||
// break out if we find we aren't emtpy
|
||||
if (!*outIsEmptyNode) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
else // an editable, non-text node. we need to check it's content.
|
||||
{
|
||||
@ -5822,6 +5823,38 @@ nsHTMLEditor::IsActiveInDOMWindow()
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsHTMLEditor::GetActiveEditingHost()
|
||||
{
|
||||
NS_ENSURE_TRUE(mDocWeak, PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocWeak);
|
||||
NS_ENSURE_TRUE(doc, nsnull);
|
||||
if (doc->HasFlag(NODE_IS_EDITABLE)) {
|
||||
return doc->GetBodyElement();
|
||||
}
|
||||
|
||||
// We're HTML editor for contenteditable
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
nsresult rv = GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
nsCOMPtr<nsIDOMNode> focusNode;
|
||||
rv = selection->GetFocusNode(getter_AddRefs(focusNode));
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(focusNode);
|
||||
if (!content) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// If the active content isn't editable, or it has independent selection,
|
||||
// we're not active.
|
||||
if (!content->HasFlag(NODE_IS_EDITABLE) ||
|
||||
content->HasIndependentSelection()) {
|
||||
return nsnull;
|
||||
}
|
||||
return content->GetEditingHost();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMEventTarget>
|
||||
nsHTMLEditor::GetDOMEventTarget()
|
||||
{
|
||||
|
@ -458,10 +458,13 @@ protected:
|
||||
// @return If the editor has focus, this returns the focused node.
|
||||
// Otherwise, returns null.
|
||||
already_AddRefed<nsINode> GetFocusedNode();
|
||||
// Get an active editor's editing host in DOM window. If this editor isn't
|
||||
// active in the DOM window, this returns NULL.
|
||||
nsIContent* GetActiveEditingHost();
|
||||
|
||||
// Return TRUE if aElement is a table-related elemet and caret was set
|
||||
PRBool SetCaretInTableCell(nsIDOMElement* aElement);
|
||||
PRBool IsElementInBody(nsIDOMElement* aElement);
|
||||
PRBool IsNodeInActiveEditor(nsIDOMNode* aNode);
|
||||
|
||||
// key event helpers
|
||||
NS_IMETHOD TabInTable(PRBool inIsShift, PRBool *outHandled);
|
||||
|
@ -51,6 +51,7 @@ _TEST_FILES = \
|
||||
test_bug366682.html \
|
||||
test_bug372345.html \
|
||||
test_bug410986.html \
|
||||
test_bug414526.html \
|
||||
test_bug432225.html \
|
||||
test_bug439808.html \
|
||||
test_bug455992.html \
|
||||
|
215
editor/libeditor/html/tests/test_bug414526.html
Normal file
215
editor/libeditor/html/tests/test_bug414526.html
Normal file
@ -0,0 +1,215 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for backspace key and delete key shouldn't remove another editing host's text</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="display"></div>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(runTests);
|
||||
|
||||
function runTests()
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var container = document.getElementById("display");
|
||||
|
||||
function reset()
|
||||
{
|
||||
document.execCommand("Undo", false, null);
|
||||
}
|
||||
|
||||
var selection = window.getSelection();
|
||||
function moveCaretToStartOf(aEditor)
|
||||
{
|
||||
selection.selectAllChildren(aEditor);
|
||||
selection.collapseToStart();
|
||||
}
|
||||
|
||||
function moveCaretToEndOf(aEditor)
|
||||
{
|
||||
selection.selectAllChildren(aEditor);
|
||||
selection.collapseToEnd();
|
||||
}
|
||||
|
||||
const kTestCase1 =
|
||||
"<p id=\"editor1\" contenteditable=\"true\">editor1</p>" +
|
||||
"<p id=\"editor2\" contenteditable=\"true\">editor2</p>" +
|
||||
"<div id=\"editor3\" contenteditable=\"true\"><div>editor3</div></div>" +
|
||||
"<p id=\"editor4\" contenteditable=\"true\">editor4</p>" +
|
||||
"non-editable text" +
|
||||
"<p id=\"editor5\" contenteditable=\"true\">editor5</p>";
|
||||
|
||||
const kTestCase1_editor3_specialcase =
|
||||
"<p id=\"editor1\" contenteditable=\"true\">editor1</p>" +
|
||||
"<p id=\"editor2\" contenteditable=\"true\">editor2</p>" +
|
||||
"<div id=\"editor3\" contenteditable=\"true\"><div>ditor3</div></div>" +
|
||||
"<p id=\"editor4\" contenteditable=\"true\">editor4</p>" +
|
||||
"non-editable text" +
|
||||
"<p id=\"editor5\" contenteditable=\"true\">editor5</p>";
|
||||
|
||||
container.innerHTML = kTestCase1;
|
||||
|
||||
var editor1 = document.getElementById("editor1");
|
||||
var editor2 = document.getElementById("editor2");
|
||||
var editor3 = document.getElementById("editor3");
|
||||
var editor4 = document.getElementById("editor4");
|
||||
var editor5 = document.getElementById("editor5");
|
||||
|
||||
editor2.focus();
|
||||
moveCaretToStartOf(editor2);
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(container.innerHTML, kTestCase1,
|
||||
"Pressing backspace key at start of editor2 changes the content");
|
||||
reset();
|
||||
|
||||
editor3.focus();
|
||||
moveCaretToStartOf(editor3);
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(container.innerHTML, kTestCase1,
|
||||
"Pressing backspace key at start of editor3 changes the content");
|
||||
reset();
|
||||
|
||||
editor4.focus();
|
||||
moveCaretToStartOf(editor4);
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(container.innerHTML, kTestCase1,
|
||||
"Pressing backspace key at start of editor4 changes the content");
|
||||
reset();
|
||||
|
||||
editor5.focus();
|
||||
moveCaretToStartOf(editor5);
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(container.innerHTML, kTestCase1,
|
||||
"Pressing backspace key at start of editor5 changes the content");
|
||||
reset();
|
||||
|
||||
editor1.focus();
|
||||
moveCaretToEndOf(editor1);
|
||||
synthesizeKey("VK_DELETE", { });
|
||||
is(container.innerHTML, kTestCase1,
|
||||
"Pressing delete key at end of editor1 changes the content");
|
||||
reset();
|
||||
|
||||
editor2.focus();
|
||||
moveCaretToEndOf(editor2);
|
||||
synthesizeKey("VK_DELETE", { });
|
||||
is(container.innerHTML, kTestCase1,
|
||||
"Pressing delete key at end of editor2 changes the content");
|
||||
reset();
|
||||
|
||||
editor3.focus();
|
||||
moveCaretToEndOf(editor3);
|
||||
synthesizeKey("VK_DELETE", { });
|
||||
// Because of a bug in nsFrameSelection::CharacterExtendForDelete, pressing Delete
|
||||
// here puts the selection in the text node inside editor3's inner div, which
|
||||
// causes us to delete the contents of that text node. This situation shouldn't
|
||||
// happen by the normal caret navigation functions that the user can invoke, so
|
||||
// we can fix it later.
|
||||
todo_is(container.innerHTML, kTestCase1,
|
||||
"Pressing delete key at end of editor3 changes the content");
|
||||
reset();
|
||||
|
||||
editor4.focus();
|
||||
moveCaretToEndOf(editor4);
|
||||
synthesizeKey("VK_DELETE", { });
|
||||
is(container.innerHTML, kTestCase1,
|
||||
"Pressing delete key at end of editor4 changes the content");
|
||||
reset();
|
||||
|
||||
// Cases when the caret is not on text node.
|
||||
editor3.focus();
|
||||
moveCaretToStartOf(editor3);
|
||||
synthesizeKey("VK_DELETE", { });
|
||||
is(container.innerHTML, kTestCase1_editor3_specialcase,
|
||||
"Pressing delete key at end of editor3 changes the content");
|
||||
reset();
|
||||
|
||||
editor3.focus();
|
||||
moveCaretToEndOf(editor3);
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(container.innerHTML, kTestCase1,
|
||||
"Pressing backspace key at end of editor3 changes the content");
|
||||
reset();
|
||||
|
||||
const kTestCase2 = "<table><tbody><tr><td><span id=\"editor1\" contenteditable=\"true\">test</span>" +
|
||||
"<span id=\"editor2\" contenteditable=\"true\">test</span></td></tr></tbody></table>";
|
||||
|
||||
container.innerHTML = kTestCase2;
|
||||
editor1 = document.getElementById("editor1");
|
||||
editor2 = document.getElementById("editor2");
|
||||
|
||||
editor2.focus();
|
||||
moveCaretToStartOf(editor2);
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(container.innerHTML, kTestCase2,
|
||||
"Pressing backspace key at the start of editor2 changes the content for kTestCase2");
|
||||
reset();
|
||||
|
||||
editor1.focus();
|
||||
moveCaretToEndOf(editor1);
|
||||
synthesizeKey("VK_DELETE", { });
|
||||
is(container.innerHTML, kTestCase2,
|
||||
"Pressing delete key at the end of editor1 changes the content for kTestCase2");
|
||||
reset();
|
||||
|
||||
const kTestCase3 = "<table><tbody><tr><td><span id=\"editor1\" contenteditable=\"true\">test</span></td>" +
|
||||
"<td><span id=\"editor2\" contenteditable=\"true\">test</span></td></tr></tbody></table>";
|
||||
|
||||
container.innerHTML = kTestCase3;
|
||||
editor1 = document.getElementById("editor1");
|
||||
editor2 = document.getElementById("editor2");
|
||||
|
||||
editor2.focus();
|
||||
moveCaretToStartOf(editor2);
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(container.innerHTML, kTestCase3,
|
||||
"Pressing backspace key at the start of editor2 changes the content for kTestCase3");
|
||||
reset();
|
||||
|
||||
editor1.focus();
|
||||
moveCaretToEndOf(editor1);
|
||||
synthesizeKey("VK_DELETE", { });
|
||||
is(container.innerHTML, kTestCase3,
|
||||
"Pressing delete key at the end of editor1 changes the content for kTestCase3");
|
||||
reset();
|
||||
|
||||
const kTestCase4 = "<table><tbody><tr><td><div id=\"editor1\" contenteditable=\"true\">test</div></td>" +
|
||||
"<td><div id=\"editor2\" contenteditable=\"true\">test</div></td></tr></tbody></table>";
|
||||
|
||||
container.innerHTML = kTestCase4;
|
||||
editor1 = document.getElementById("editor1");
|
||||
editor2 = document.getElementById("editor2");
|
||||
|
||||
editor2.focus();
|
||||
moveCaretToStartOf(editor2);
|
||||
synthesizeKey("VK_BACK_SPACE", { });
|
||||
is(container.innerHTML, kTestCase4,
|
||||
"Pressing backspace key at the start of editor2 changes the content for kTestCase4");
|
||||
reset();
|
||||
|
||||
editor1.focus();
|
||||
moveCaretToEndOf(editor1);
|
||||
synthesizeKey("VK_DELETE", { });
|
||||
is(container.innerHTML, kTestCase4,
|
||||
"Pressing delete key at the end of editor1 changes the content for kTestCase4");
|
||||
reset();
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -98,28 +98,6 @@ nsTextEditUtils::HasMozAttr(nsIDOMNode *node)
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// InBody: true if node is a descendant of the body
|
||||
//
|
||||
PRBool
|
||||
nsTextEditUtils::InBody(nsIDOMNode *node, nsIEditor *editor)
|
||||
{
|
||||
NS_ENSURE_TRUE(node, PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> rootElement;
|
||||
editor->GetRootElement(getter_AddRefs(rootElement));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> tmp;
|
||||
nsCOMPtr<nsIDOMNode> p = node;
|
||||
while (p != rootElement)
|
||||
{
|
||||
if (NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp)
|
||||
return PR_FALSE;
|
||||
p = tmp;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// nsAutoEditInitRulesTrigger methods
|
||||
//
|
||||
|
@ -53,7 +53,6 @@ public:
|
||||
static PRBool IsBreak(nsIDOMNode *aNode);
|
||||
static PRBool IsMozBR(nsIDOMNode *aNode);
|
||||
static PRBool HasMozAttr(nsIDOMNode *aNode);
|
||||
static PRBool InBody(nsIDOMNode *aNode, nsIEditor *aEditor);
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -38,7 +38,6 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
|
||||
#include "ImageLayers.h"
|
||||
@ -390,12 +389,6 @@ Layer::GetEffectiveOpacity()
|
||||
return opacity;
|
||||
}
|
||||
|
||||
void
|
||||
ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = ContainerLayerAttributes(GetFrameMetrics());
|
||||
}
|
||||
|
||||
PRBool
|
||||
ContainerLayer::HasMultipleChildren()
|
||||
{
|
||||
|
@ -79,11 +79,9 @@ class ImageLayer;
|
||||
class ColorLayer;
|
||||
class ImageContainer;
|
||||
class CanvasLayer;
|
||||
class ShadowLayer;
|
||||
class ReadbackLayer;
|
||||
class ReadbackProcessor;
|
||||
class ShadowLayer;
|
||||
class ShadowLayerForwarder;
|
||||
class ShadowLayerManager;
|
||||
class SpecificLayerAttributes;
|
||||
|
||||
/**
|
||||
@ -117,10 +115,6 @@ public:
|
||||
mDisplayPort.IsEqualEdges(aOther.mDisplayPort) &&
|
||||
mScrollId == aOther.mScrollId);
|
||||
}
|
||||
PRBool operator!=(const FrameMetrics& aOther) const
|
||||
{
|
||||
return !operator==(aOther);
|
||||
}
|
||||
|
||||
PRBool IsDefault() const
|
||||
{
|
||||
@ -289,12 +283,6 @@ public:
|
||||
virtual void Destroy() { mDestroyed = PR_TRUE; mUserData.Clear(); }
|
||||
PRBool IsDestroyed() { return mDestroyed; }
|
||||
|
||||
virtual ShadowLayerForwarder* AsShadowForwarder()
|
||||
{ return nsnull; }
|
||||
|
||||
virtual ShadowLayerManager* AsShadowManager()
|
||||
{ return nsnull; }
|
||||
|
||||
/**
|
||||
* Start a new transaction. Nested transactions are not allowed so
|
||||
* there must be no transaction currently in progress.
|
||||
@ -1083,11 +1071,8 @@ public:
|
||||
void SetFrameMetrics(const FrameMetrics& aFrameMetrics)
|
||||
{
|
||||
mFrameMetrics = aFrameMetrics;
|
||||
Mutated();
|
||||
}
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs);
|
||||
|
||||
// These getters can be used anytime.
|
||||
|
||||
virtual ContainerLayer* AsContainerLayer() { return this; }
|
||||
|
@ -114,14 +114,13 @@ EXPORTS += \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS += \
|
||||
CanvasLayerD3D10.cpp \
|
||||
ColorLayerD3D10.cpp \
|
||||
LayerManagerD3D10.cpp \
|
||||
ThebesLayerD3D10.cpp \
|
||||
ContainerLayerD3D10.cpp \
|
||||
ImageLayerD3D10.cpp \
|
||||
LayerManagerD3D10.cpp \
|
||||
ColorLayerD3D10.cpp \
|
||||
CanvasLayerD3D10.cpp \
|
||||
ReadbackManagerD3D10.cpp \
|
||||
ShadowLayerUtilsD3D10.cpp \
|
||||
ThebesLayerD3D10.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
@ -154,11 +153,6 @@ DEFINES += -DUSE_GLES2
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_D3D10_LAYER
|
||||
EXPORTS_mozilla/layers += ShadowLayerUtilsD3D10.h
|
||||
DEFINES += -DMOZ_ENABLE_D3D10_LAYER
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
|
@ -1871,6 +1871,11 @@ public:
|
||||
virtual void InsertAfter(Layer* aChild, Layer* aAfter);
|
||||
virtual void RemoveChild(Layer* aChild);
|
||||
|
||||
virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs)
|
||||
{
|
||||
aAttrs = ContainerLayerAttributes(GetFrameMetrics());
|
||||
}
|
||||
|
||||
virtual Layer* AsLayer() { return this; }
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return this; }
|
||||
|
||||
|
@ -224,15 +224,6 @@ public:
|
||||
BasicShadowLayerManager(nsIWidget* aWidget);
|
||||
virtual ~BasicShadowLayerManager();
|
||||
|
||||
virtual ShadowLayerForwarder* AsShadowForwarder()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
virtual ShadowLayerManager* AsShadowManager()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
|
||||
virtual bool EndEmptyTransaction();
|
||||
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
@ -256,6 +247,12 @@ public:
|
||||
ShadowableLayer* Hold(Layer* aLayer);
|
||||
|
||||
bool HasShadowManager() const { return ShadowLayerForwarder::HasShadowManager(); }
|
||||
PLayersChild* GetShadowManager() const { return mShadowManager; }
|
||||
|
||||
void SetShadowManager(PLayersChild* aShadowManager)
|
||||
{
|
||||
mShadowManager = aShadowManager;
|
||||
}
|
||||
|
||||
virtual PRBool IsCompositingCheap();
|
||||
virtual bool HasShadowManagerInternal() const { return HasShadowManager(); }
|
||||
|
@ -38,7 +38,6 @@
|
||||
|
||||
#include "CanvasLayerD3D10.h"
|
||||
|
||||
#include "../d3d9/Nv3DVUtils.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxWindowsSurface.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
|
@ -38,8 +38,6 @@
|
||||
|
||||
#include "ColorLayerD3D10.h"
|
||||
|
||||
#include "../d3d9/Nv3DVUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#ifndef GFX_COLORLAYERD3D10_H
|
||||
#define GFX_COLORLAYERD3D10_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "LayerManagerD3D10.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -40,7 +40,6 @@
|
||||
#include "gfxUtils.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
#include "../d3d9/Nv3DVUtils.h"
|
||||
#include "ThebesLayerD3D10.h"
|
||||
#include "ReadbackProcessor.h"
|
||||
|
||||
@ -375,55 +374,5 @@ ContainerLayerD3D10::Validate()
|
||||
}
|
||||
}
|
||||
|
||||
ShadowContainerLayerD3D10::ShadowContainerLayerD3D10(LayerManagerD3D10 *aManager)
|
||||
: ShadowContainerLayer(aManager, NULL)
|
||||
, LayerD3D10(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D10*>(this);
|
||||
}
|
||||
|
||||
ShadowContainerLayerD3D10::~ShadowContainerLayerD3D10() {}
|
||||
|
||||
void
|
||||
ShadowContainerLayerD3D10::InsertAfter(Layer* aChild, Layer* aAfter)
|
||||
{
|
||||
mFirstChild = aChild;
|
||||
}
|
||||
|
||||
void
|
||||
ShadowContainerLayerD3D10::RemoveChild(Layer* aChild)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ShadowContainerLayerD3D10::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
|
||||
{
|
||||
DefaultComputeEffectiveTransforms(aTransformToSurface);
|
||||
}
|
||||
|
||||
LayerD3D10*
|
||||
ShadowContainerLayerD3D10::GetFirstChildD3D10()
|
||||
{
|
||||
return static_cast<LayerD3D10*>(mFirstChild->ImplData());
|
||||
}
|
||||
|
||||
void
|
||||
ShadowContainerLayerD3D10::RenderLayer()
|
||||
{
|
||||
LayerD3D10* layerToRender = GetFirstChildD3D10();
|
||||
layerToRender->RenderLayer();
|
||||
}
|
||||
|
||||
void
|
||||
ShadowContainerLayerD3D10::Validate()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ShadowContainerLayerD3D10::LayerManagerDestroyed()
|
||||
{
|
||||
}
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -38,6 +38,7 @@
|
||||
#ifndef GFX_CONTAINERLAYERD3D10_H
|
||||
#define GFX_CONTAINERLAYERD3D10_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "LayerManagerD3D10.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -73,33 +74,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// This is a bare-bones implementation of a container layer, only
|
||||
// enough to contain a shadow "window texture". This impl doesn't
|
||||
// honor the transform/cliprect/etc. when rendering.
|
||||
class ShadowContainerLayerD3D10 : public ShadowContainerLayer,
|
||||
public LayerD3D10
|
||||
{
|
||||
public:
|
||||
ShadowContainerLayerD3D10(LayerManagerD3D10 *aManager);
|
||||
~ShadowContainerLayerD3D10();
|
||||
|
||||
void InsertAfter(Layer* aChild, Layer* aAfter);
|
||||
|
||||
void RemoveChild(Layer* aChild);
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface);
|
||||
|
||||
/* LayerD3D10 implementation */
|
||||
virtual LayerD3D10 *GetFirstChildD3D10();
|
||||
virtual Layer* GetLayer() { return this; }
|
||||
virtual void RenderLayer();
|
||||
virtual void Validate();
|
||||
virtual void LayerManagerDestroyed();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -35,8 +35,6 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "LayerManagerD3D10.h"
|
||||
#include "LayerManagerD3D10Effect.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
@ -51,13 +49,11 @@
|
||||
#include "CanvasLayerD3D10.h"
|
||||
#include "ReadbackLayerD3D10.h"
|
||||
#include "ImageLayerD3D10.h"
|
||||
#include "mozilla/layers/PLayerChild.h"
|
||||
|
||||
#include "../d3d9/Nv3DVUtils.h"
|
||||
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
@ -231,11 +227,6 @@ LayerManagerD3D10::Initialize()
|
||||
mInputLayout = attachments->mInputLayout;
|
||||
}
|
||||
|
||||
if (HasShadowManager()) {
|
||||
reporter.SetSuccessful();
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRefPtr<IDXGIDevice> dxgiDevice;
|
||||
nsRefPtr<IDXGIAdapter> dxgiAdapter;
|
||||
nsRefPtr<IDXGIFactory> dxgiFactory;
|
||||
@ -296,9 +287,6 @@ LayerManagerD3D10::Destroy()
|
||||
if (mRoot) {
|
||||
static_cast<LayerD3D10*>(mRoot->ImplData())->LayerManagerDestroyed();
|
||||
}
|
||||
mRootForShadowTree = nsnull;
|
||||
// XXX need to be careful here about surface destruction
|
||||
// racing with share-to-chrome message
|
||||
}
|
||||
LayerManager::Destroy();
|
||||
}
|
||||
@ -312,10 +300,6 @@ LayerManagerD3D10::SetRoot(Layer *aRoot)
|
||||
void
|
||||
LayerManagerD3D10::BeginTransaction()
|
||||
{
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
MOZ_LAYERS_LOG(("[----- BeginTransaction"));
|
||||
Log();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -346,21 +330,11 @@ LayerManagerD3D10::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||
// so we don't need to pass any global transform here.
|
||||
mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
MOZ_LAYERS_LOG((" ----- (beginning paint)"));
|
||||
Log();
|
||||
#endif
|
||||
|
||||
Render();
|
||||
mCurrentCallbackInfo.Callback = nsnull;
|
||||
mCurrentCallbackInfo.CallbackData = nsnull;
|
||||
}
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
Log();
|
||||
MOZ_LAYERS_LOG(("]----- EndTransaction"));
|
||||
#endif
|
||||
|
||||
mTarget = nsnull;
|
||||
}
|
||||
|
||||
@ -370,13 +344,6 @@ LayerManagerD3D10::CreateThebesLayer()
|
||||
nsRefPtr<ThebesLayer> layer = new ThebesLayerD3D10(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ShadowThebesLayer>
|
||||
LayerManagerD3D10::CreateShadowThebesLayer()
|
||||
{
|
||||
nsRefPtr<ShadowThebesLayerD3D10> layer = new ShadowThebesLayerD3D10(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ContainerLayer>
|
||||
LayerManagerD3D10::CreateContainerLayer()
|
||||
@ -385,13 +352,6 @@ LayerManagerD3D10::CreateContainerLayer()
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ShadowContainerLayer>
|
||||
LayerManagerD3D10::CreateShadowContainerLayer()
|
||||
{
|
||||
nsRefPtr<ShadowContainerLayer> layer = new ShadowContainerLayerD3D10(this);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<ImageLayer>
|
||||
LayerManagerD3D10::CreateImageLayer()
|
||||
{
|
||||
@ -586,13 +546,9 @@ LayerManagerD3D10::UpdateRenderTarget()
|
||||
|
||||
nsRefPtr<ID3D10Texture2D> backBuf;
|
||||
|
||||
if (mSwapChain) {
|
||||
hr = mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment());
|
||||
if (FAILED(hr)) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
backBuf = mBackBuffer;
|
||||
hr = mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (void**)backBuf.StartAssignment());
|
||||
if (FAILED(hr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mDevice->CreateRenderTargetView(backBuf, NULL, getter_AddRefs(mRTView));
|
||||
@ -601,57 +557,28 @@ LayerManagerD3D10::UpdateRenderTarget()
|
||||
void
|
||||
LayerManagerD3D10::VerifyBufferSize()
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
||||
mSwapChain->GetDesc(&swapDesc);
|
||||
|
||||
nsIntRect rect;
|
||||
mWidget->GetClientBounds(rect);
|
||||
|
||||
HRESULT hr;
|
||||
if (mSwapChain) {
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc;
|
||||
mSwapChain->GetDesc(&swapDesc);
|
||||
|
||||
if (swapDesc.BufferDesc.Width == rect.width &&
|
||||
swapDesc.BufferDesc.Height == rect.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
mRTView = nsnull;
|
||||
if (gfxWindowsPlatform::IsOptimus()) {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
} else {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
|
||||
}
|
||||
} else {
|
||||
D3D10_TEXTURE2D_DESC oldDesc;
|
||||
if (mBackBuffer) {
|
||||
mBackBuffer->GetDesc(&oldDesc);
|
||||
} else {
|
||||
oldDesc.Width = oldDesc.Height = 0;
|
||||
}
|
||||
if (oldDesc.Width == rect.width &&
|
||||
oldDesc.Height == rect.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
rect.width, rect.height, 1, 1);
|
||||
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
||||
desc.MiscFlags = D3D10_RESOURCE_MISC_SHARED
|
||||
// FIXME/bug 662109: synchronize using KeyedMutex
|
||||
/*D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX*/;
|
||||
hr = device()->CreateTexture2D(&desc, nsnull, getter_AddRefs(mBackBuffer));
|
||||
if (FAILED(hr)) {
|
||||
ReportFailure(nsDependentCString("Failed to create shared texture"),
|
||||
hr);
|
||||
NS_RUNTIMEABORT("Failed to create back buffer");
|
||||
}
|
||||
|
||||
// XXX resize texture?
|
||||
mRTView = nsnull;
|
||||
if (swapDesc.BufferDesc.Width == rect.width &&
|
||||
swapDesc.BufferDesc.Height == rect.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
mRTView = nsnull;
|
||||
if (gfxWindowsPlatform::IsOptimus()) {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
} else {
|
||||
mSwapChain->ResizeBuffers(1, rect.width, rect.height,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -711,75 +638,6 @@ LayerManagerD3D10::Render()
|
||||
|
||||
if (mTarget) {
|
||||
PaintToTarget();
|
||||
} else if (mBackBuffer) {
|
||||
ShadowLayerForwarder::BeginTransaction();
|
||||
|
||||
nsIntRect contentRect = nsIntRect(0, 0, rect.width, rect.height);
|
||||
if (!mRootForShadowTree) {
|
||||
mRootForShadowTree = new DummyRoot(this);
|
||||
mRootForShadowTree->SetShadow(ConstructShadowFor(mRootForShadowTree));
|
||||
CreatedContainerLayer(mRootForShadowTree);
|
||||
ShadowLayerForwarder::SetRoot(mRootForShadowTree);
|
||||
}
|
||||
|
||||
nsRefPtr<WindowLayer> windowLayer =
|
||||
static_cast<WindowLayer*>(mRootForShadowTree->GetFirstChild());
|
||||
if (!windowLayer) {
|
||||
windowLayer = new WindowLayer(this);
|
||||
windowLayer->SetShadow(ConstructShadowFor(windowLayer));
|
||||
CreatedThebesLayer(windowLayer);
|
||||
ShadowLayerForwarder::CreatedThebesBuffer(windowLayer,
|
||||
contentRect,
|
||||
contentRect,
|
||||
SurfaceDescriptor());
|
||||
|
||||
mRootForShadowTree->InsertAfter(windowLayer, nsnull);
|
||||
ShadowLayerForwarder::InsertAfter(mRootForShadowTree, windowLayer);
|
||||
}
|
||||
|
||||
if (!mRootForShadowTree->GetVisibleRegion().IsEqual(contentRect)) {
|
||||
mRootForShadowTree->SetVisibleRegion(contentRect);
|
||||
windowLayer->SetVisibleRegion(contentRect);
|
||||
|
||||
ShadowLayerForwarder::Mutated(mRootForShadowTree);
|
||||
ShadowLayerForwarder::Mutated(windowLayer);
|
||||
}
|
||||
|
||||
FrameMetrics m;
|
||||
if (ContainerLayer* cl = mRoot->AsContainerLayer()) {
|
||||
m = cl->GetFrameMetrics();
|
||||
} else {
|
||||
m.mScrollId = FrameMetrics::ROOT_SCROLL_ID;
|
||||
}
|
||||
if (m != mRootForShadowTree->GetFrameMetrics()) {
|
||||
mRootForShadowTree->SetFrameMetrics(m);
|
||||
ShadowLayerForwarder::Mutated(mRootForShadowTree);
|
||||
}
|
||||
|
||||
SurfaceDescriptorD3D10 sd;
|
||||
GetDescriptor(mBackBuffer, &sd);
|
||||
ShadowLayerForwarder::PaintedThebesBuffer(windowLayer,
|
||||
contentRect,
|
||||
contentRect, nsIntPoint(),
|
||||
sd);
|
||||
|
||||
// A source in the graphics pipeline can't also be a target. So
|
||||
// unbind here to avoid racing with the chrome process sourcing
|
||||
// the back texture.
|
||||
mDevice->OMSetRenderTargets(0, NULL, NULL);
|
||||
|
||||
// XXX revisit this Flush() in bug 662109. It's not clear it's
|
||||
// needed.
|
||||
mDevice->Flush();
|
||||
|
||||
mRTView = NULL;
|
||||
|
||||
AutoInfallibleTArray<EditReply, 10> replies;
|
||||
ShadowLayerForwarder::EndTransaction(&replies);
|
||||
// We expect only 1 reply, but might get none if the parent
|
||||
// process crashed
|
||||
|
||||
swap(mBackBuffer, mRemoteFrontBuffer);
|
||||
} else {
|
||||
mSwapChain->Present(0, 0);
|
||||
}
|
||||
@ -841,42 +699,5 @@ LayerD3D10::LayerD3D10(LayerManagerD3D10 *aManager)
|
||||
{
|
||||
}
|
||||
|
||||
WindowLayer::WindowLayer(LayerManagerD3D10* aManager)
|
||||
: ThebesLayer(aManager, nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
WindowLayer::~WindowLayer()
|
||||
{
|
||||
PLayerChild::Send__delete__(GetShadow());
|
||||
}
|
||||
|
||||
DummyRoot::DummyRoot(LayerManagerD3D10* aManager)
|
||||
: ContainerLayer(aManager, nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
DummyRoot::~DummyRoot()
|
||||
{
|
||||
RemoveChild(nsnull);
|
||||
PLayerChild::Send__delete__(GetShadow());
|
||||
}
|
||||
|
||||
void
|
||||
DummyRoot::InsertAfter(Layer* aLayer, Layer* aNull)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!mFirstChild && !aNull,
|
||||
"Expect to append one child, once");
|
||||
mFirstChild = nsRefPtr<Layer>(aLayer).forget().get();
|
||||
}
|
||||
|
||||
void
|
||||
DummyRoot::RemoveChild(Layer* aNull)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!aNull, "Unused argument should be null");
|
||||
NS_IF_RELEASE(mFirstChild);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -38,8 +38,6 @@
|
||||
#ifndef GFX_LAYERMANAGERD3D10_H
|
||||
#define GFX_LAYERMANAGERD3D10_H
|
||||
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "Layers.h"
|
||||
|
||||
#include <windows.h>
|
||||
@ -53,7 +51,6 @@
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class DummyRoot;
|
||||
class Nv3DVUtils;
|
||||
|
||||
/**
|
||||
@ -77,18 +74,11 @@ struct ShaderConstantRectD3D10
|
||||
extern cairo_user_data_key_t gKeyD3D10Texture;
|
||||
|
||||
/*
|
||||
* This is the LayerManager used for Direct3D 10. For now this will
|
||||
* render on the main thread.
|
||||
*
|
||||
* For the time being, LayerManagerD3D10 both forwards layers
|
||||
* transactions and receives forwarded transactions. In the Azure
|
||||
* future, it will only be a ShadowLayerManager.
|
||||
* This is the LayerManager used for Direct3D 9. For now this will render on
|
||||
* the main thread.
|
||||
*/
|
||||
class THEBES_API LayerManagerD3D10 : public ShadowLayerManager,
|
||||
public ShadowLayerForwarder {
|
||||
class THEBES_API LayerManagerD3D10 : public LayerManager {
|
||||
public:
|
||||
typedef LayerManager::LayersBackend LayersBackend;
|
||||
|
||||
LayerManagerD3D10(nsIWidget *aWidget);
|
||||
virtual ~LayerManagerD3D10();
|
||||
|
||||
@ -107,12 +97,6 @@ public:
|
||||
*/
|
||||
virtual void Destroy();
|
||||
|
||||
virtual ShadowLayerForwarder* AsShadowForwarder()
|
||||
{ return this; }
|
||||
|
||||
virtual ShadowLayerManager* AsShadowManager()
|
||||
{ return this; }
|
||||
|
||||
virtual void SetRoot(Layer *aLayer);
|
||||
|
||||
virtual void BeginTransaction();
|
||||
@ -141,22 +125,14 @@ public:
|
||||
}
|
||||
|
||||
virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
|
||||
virtual already_AddRefed<ShadowThebesLayer> CreateShadowThebesLayer();
|
||||
|
||||
virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
|
||||
virtual already_AddRefed<ShadowContainerLayer> CreateShadowContainerLayer();
|
||||
|
||||
virtual already_AddRefed<ImageLayer> CreateImageLayer();
|
||||
virtual already_AddRefed<ShadowImageLayer> CreateShadowImageLayer()
|
||||
{ return nsnull; }
|
||||
|
||||
virtual already_AddRefed<ColorLayer> CreateColorLayer();
|
||||
virtual already_AddRefed<ShadowColorLayer> CreateShadowColorLayer()
|
||||
{ return nsnull; }
|
||||
|
||||
virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
|
||||
virtual already_AddRefed<ShadowCanvasLayer> CreateShadowCanvasLayer()
|
||||
{ return nsnull; }
|
||||
|
||||
virtual already_AddRefed<ReadbackLayer> CreateReadbackLayer();
|
||||
|
||||
@ -228,28 +204,6 @@ private:
|
||||
*/
|
||||
nsRefPtr<gfxContext> mTarget;
|
||||
|
||||
/*
|
||||
* We use a double-buffered "window surface" to display our content
|
||||
* in the compositor process, if we're remote. The textures act
|
||||
* like the backing store for an OS window --- we render the layer
|
||||
* tree into the back texture and send it to the compositor, then
|
||||
* swap back/front textures. This means, obviously, that we've lost
|
||||
* all layer tree information after rendering.
|
||||
*
|
||||
* The remote front buffer is the texture currently being displayed
|
||||
* by chrome. We keep a reference to it to simplify resource
|
||||
* management; if we didn't, then there can be periods during IPC
|
||||
* transport when neither process holds a "real" ref. That's
|
||||
* solvable but not worth the complexity.
|
||||
*/
|
||||
nsRefPtr<ID3D10Texture2D> mBackBuffer;
|
||||
nsRefPtr<ID3D10Texture2D> mRemoteFrontBuffer;
|
||||
/*
|
||||
* If we're remote content, this is the root of the shadowable tree
|
||||
* we send to the compositor.
|
||||
*/
|
||||
nsRefPtr<DummyRoot> mRootForShadowTree;
|
||||
|
||||
/*
|
||||
* Copies the content of our backbuffer to the set transaction target.
|
||||
*/
|
||||
@ -302,44 +256,6 @@ protected:
|
||||
LayerManagerD3D10 *mD3DManager;
|
||||
};
|
||||
|
||||
/**
|
||||
* WindowLayer is a simple, special kinds of shadowable layer into
|
||||
* which layer trees are rendered. It represents something like an OS
|
||||
* window. It exists only to allow sharing textures with the
|
||||
* compositor while reusing existing shadow-layer machinery.
|
||||
*
|
||||
* WindowLayer being implemented as a thebes layer isn't an important
|
||||
* detail; other layer types could have been used.
|
||||
*/
|
||||
class WindowLayer : public ThebesLayer, public ShadowableLayer {
|
||||
public:
|
||||
WindowLayer(LayerManagerD3D10* aManager);
|
||||
virtual ~WindowLayer();
|
||||
|
||||
void InvalidateRegion(const nsIntRegion&) {}
|
||||
Layer* AsLayer() { return this; }
|
||||
|
||||
void SetShadow(PLayerChild* aChild) { mShadow = aChild; }
|
||||
};
|
||||
|
||||
/**
|
||||
* DummyRoot is the root of the shadowable layer tree created by
|
||||
* remote content. It exists only to contain WindowLayers. It always
|
||||
* has exactly one child WindowLayer.
|
||||
*/
|
||||
class DummyRoot : public ContainerLayer, public ShadowableLayer {
|
||||
public:
|
||||
DummyRoot(LayerManagerD3D10* aManager);
|
||||
virtual ~DummyRoot();
|
||||
|
||||
void ComputeEffectiveTransforms(const gfx3DMatrix&) {}
|
||||
void InsertAfter(Layer*, Layer*);
|
||||
void RemoveChild(Layer*);
|
||||
Layer* AsLayer() { return this; }
|
||||
|
||||
void SetShadow(PLayerChild* aChild) { mShadow = aChild; }
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -35,7 +35,6 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
#include "ThebesLayerD3D10.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
@ -44,7 +43,6 @@
|
||||
#include "gfxD2DSurface.h"
|
||||
#endif
|
||||
|
||||
#include "../d3d9/Nv3DVUtils.h"
|
||||
#include "gfxTeeSurface.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "ReadbackLayer.h"
|
||||
@ -286,7 +284,7 @@ ThebesLayerD3D10::Validate(ReadbackProcessor *aReadback)
|
||||
device()->CreateTexture2D(&desc, NULL, getter_AddRefs(readbackTexture));
|
||||
device()->CopyResource(readbackTexture, mTexture);
|
||||
|
||||
for (PRUint32 i = 0; i < readbackUpdates.Length(); i++) {
|
||||
for (int i = 0; i < readbackUpdates.Length(); i++) {
|
||||
mD3DManager->readbackManager()->PostTask(readbackTexture,
|
||||
&readbackUpdates[i],
|
||||
gfxPoint(newTextureRect.x, newTextureRect.y));
|
||||
@ -457,121 +455,6 @@ ThebesLayerD3D10::CreateNewTextures(const gfxIntSize &aSize, SurfaceMode aMode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShadowThebesLayerD3D10::ShadowThebesLayerD3D10(LayerManagerD3D10* aManager)
|
||||
: ShadowThebesLayer(aManager, NULL)
|
||||
, LayerD3D10(aManager)
|
||||
{
|
||||
mImplData = static_cast<LayerD3D10*>(this);
|
||||
}
|
||||
|
||||
ShadowThebesLayerD3D10::~ShadowThebesLayerD3D10()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ShadowThebesLayerD3D10::SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
|
||||
const nsIntRegion& aValidRegion)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(OptionalThebesBuffer::Tnull_t == aNewFront.type(),
|
||||
"Expected dummy front buffer initially");
|
||||
}
|
||||
|
||||
void
|
||||
ShadowThebesLayerD3D10::Swap(
|
||||
const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion,
|
||||
ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
|
||||
OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion)
|
||||
{
|
||||
nsRefPtr<ID3D10Texture2D> newBackBuffer = mTexture;
|
||||
|
||||
mTexture = OpenForeign(mD3DManager->device(), aNewFront.buffer());
|
||||
NS_ABORT_IF_FALSE(mTexture, "Couldn't open foreign texture");
|
||||
|
||||
// The content process tracks back/front buffers on its own, so
|
||||
// the newBack is in essence unused.
|
||||
aNewBack->buffer() = aNewFront.buffer();
|
||||
|
||||
// The content process doesn't need to read back from the front
|
||||
// buffer (yet).
|
||||
*aReadOnlyFront = null_t();
|
||||
|
||||
// FIXME/bug 662109: synchronize using KeyedMutex
|
||||
}
|
||||
|
||||
void
|
||||
ShadowThebesLayerD3D10::DestroyFrontBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ShadowThebesLayerD3D10::Disconnect()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ShadowThebesLayerD3D10::RenderLayer()
|
||||
{
|
||||
if (!mTexture) {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME/bug 662109: synchronize using KeyedMutex
|
||||
|
||||
nsRefPtr<ID3D10ShaderResourceView> srView;
|
||||
HRESULT hr = device()->CreateShaderResourceView(mTexture, NULL, getter_AddRefs(srView));
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Failed to create shader resource view for ThebesLayerD3D10.");
|
||||
}
|
||||
|
||||
|
||||
SetEffectTransformAndOpacity();
|
||||
|
||||
ID3D10EffectTechnique *technique =
|
||||
effect()->GetTechniqueByName("RenderRGBLayerPremul");
|
||||
|
||||
effect()->GetVariableByName("tRGB")->AsShaderResource()->SetResource(srView);
|
||||
|
||||
nsIntRect textureRect = GetVisibleRegion().GetBounds();
|
||||
|
||||
nsIntRegionRectIterator iter(mVisibleRegion);
|
||||
while (const nsIntRect *iterRect = iter.Next()) {
|
||||
effect()->GetVariableByName("vLayerQuad")->AsVector()->SetFloatVector(
|
||||
ShaderConstantRectD3D10(
|
||||
(float)iterRect->x,
|
||||
(float)iterRect->y,
|
||||
(float)iterRect->width,
|
||||
(float)iterRect->height)
|
||||
);
|
||||
|
||||
effect()->GetVariableByName("vTextureCoords")->AsVector()->SetFloatVector(
|
||||
ShaderConstantRectD3D10(
|
||||
(float)(iterRect->x - textureRect.x) / (float)textureRect.width,
|
||||
(float)(iterRect->y - textureRect.y) / (float)textureRect.height,
|
||||
(float)iterRect->width / (float)textureRect.width,
|
||||
(float)iterRect->height / (float)textureRect.height)
|
||||
);
|
||||
|
||||
technique->GetPassByIndex(0)->Apply(0);
|
||||
device()->Draw(4, 0);
|
||||
}
|
||||
|
||||
// FIXME/bug 662109: synchronize using KeyedMutex
|
||||
|
||||
// Set back to default.
|
||||
effect()->GetVariableByName("vTextureCoords")->AsVector()->
|
||||
SetFloatVector(ShaderConstantRectD3D10(0, 0, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
void
|
||||
ShadowThebesLayerD3D10::Validate()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ShadowThebesLayerD3D10::LayerManagerDestroyed()
|
||||
{
|
||||
}
|
||||
|
||||
} /* namespace layers */
|
||||
} /* namespace mozilla */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -38,6 +38,7 @@
|
||||
#ifndef GFX_THEBESLAYERD3D10_H
|
||||
#define GFX_THEBESLAYERD3D10_H
|
||||
|
||||
#include "Layers.h"
|
||||
#include "LayerManagerD3D10.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -101,35 +102,6 @@ private:
|
||||
const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion);
|
||||
};
|
||||
|
||||
class ShadowThebesLayerD3D10 : public ShadowThebesLayer,
|
||||
public LayerD3D10
|
||||
{
|
||||
public:
|
||||
ShadowThebesLayerD3D10(LayerManagerD3D10* aManager);
|
||||
virtual ~ShadowThebesLayerD3D10();
|
||||
|
||||
// ShadowThebesLayer impl
|
||||
virtual void SetFrontBuffer(const OptionalThebesBuffer& aNewFront,
|
||||
const nsIntRegion& aValidRegion);
|
||||
virtual void
|
||||
Swap(const ThebesBuffer& aNewFront, const nsIntRegion& aUpdatedRegion,
|
||||
ThebesBuffer* aNewBack, nsIntRegion* aNewBackValidRegion,
|
||||
OptionalThebesBuffer* aReadOnlyFront, nsIntRegion* aFrontUpdatedRegion);
|
||||
virtual void DestroyFrontBuffer();
|
||||
|
||||
virtual void Disconnect();
|
||||
|
||||
/* LayerD3D10 implementation */
|
||||
virtual Layer* GetLayer() { return this; }
|
||||
virtual void RenderLayer();
|
||||
virtual void Validate();
|
||||
virtual void LayerManagerDestroyed();
|
||||
|
||||
private:
|
||||
/* Texture with our surface data */
|
||||
nsRefPtr<ID3D10Texture2D> mTexture;
|
||||
};
|
||||
|
||||
} /* layers */
|
||||
} /* mozilla */
|
||||
#endif /* GFX_THEBESLAYERD3D10_H */
|
||||
|
@ -121,9 +121,6 @@ public:
|
||||
*/
|
||||
virtual void Destroy();
|
||||
|
||||
virtual ShadowLayerManager* AsShadowManager()
|
||||
{ return this; }
|
||||
|
||||
virtual void BeginTransaction();
|
||||
|
||||
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
|
||||
|
@ -54,7 +54,7 @@ using mozilla::GraphicsFilterType;
|
||||
using mozilla::layers::FrameMetrics;
|
||||
using mozilla::layers::SurfaceDescriptorX11;
|
||||
using mozilla::null_t;
|
||||
using mozilla::WindowsHandle;
|
||||
using mozilla::LayersBackend;
|
||||
|
||||
/**
|
||||
* The layers protocol is spoken between thread contexts that manage
|
||||
@ -73,14 +73,13 @@ struct OpCreateContainerLayer { PLayer layer; };
|
||||
struct OpCreateImageLayer { PLayer layer; };
|
||||
struct OpCreateColorLayer { PLayer layer; };
|
||||
struct OpCreateCanvasLayer { PLayer layer; };
|
||||
|
||||
struct SurfaceDescriptorD3D10 {
|
||||
WindowsHandle handle;
|
||||
};
|
||||
|
||||
// For the "buffer creation" operations, we send an initial front
|
||||
// buffer that only contains (transparent) black pixels just so that
|
||||
// we can swap it back after the first OpPaint without a special case.
|
||||
|
||||
union SurfaceDescriptor {
|
||||
Shmem;
|
||||
SurfaceDescriptorD3D10;
|
||||
SurfaceDescriptorX11;
|
||||
};
|
||||
|
||||
@ -103,10 +102,6 @@ struct ThebesBuffer {
|
||||
};
|
||||
union OptionalThebesBuffer { ThebesBuffer; null_t; };
|
||||
|
||||
// For the "buffer creation" operations, we send an initial front
|
||||
// buffer that only contains (transparent) black pixels just so that
|
||||
// we can swap it back after the first OpPaint without a special case.
|
||||
|
||||
struct OpCreateThebesBuffer {
|
||||
PLayer layer;
|
||||
OptionalThebesBuffer initialFront;
|
||||
@ -261,6 +256,9 @@ parent:
|
||||
sync Update(Edit[] cset)
|
||||
returns (EditReply[] reply);
|
||||
|
||||
sync GetParentType()
|
||||
returns (LayersBackend backend);
|
||||
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
|
@ -44,12 +44,8 @@
|
||||
#include "IPC/IPCMessageUtils.h"
|
||||
#include "Layers.h"
|
||||
|
||||
#if defined(MOZ_ENABLE_D3D10_LAYER)
|
||||
# include "mozilla/layers/ShadowLayerUtilsD3D10.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_X11)
|
||||
# include "mozilla/layers/ShadowLayerUtilsX11.h"
|
||||
# include "mozilla/layers/ShadowLayerUtilsX11.h"
|
||||
#else
|
||||
namespace mozilla { namespace layers {
|
||||
struct SurfaceDescriptorX11 {
|
||||
|
@ -1,128 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyrigght (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Jones <jones.chris.g@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <d3d10_1.h>
|
||||
#include <dxgi.h>
|
||||
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
#include "ShadowLayers.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
// Platform-specific shadow-layers interfaces. See ShadowLayers.h.
|
||||
// D3D10 doesn't need all these yet.
|
||||
PRBool
|
||||
ShadowLayerForwarder::PlatformAllocDoubleBuffer(const gfxIntSize&,
|
||||
gfxASurface::gfxContentType,
|
||||
SurfaceDescriptor*,
|
||||
SurfaceDescriptor*)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ShadowLayerForwarder::PlatformAllocBuffer(const gfxIntSize&,
|
||||
gfxASurface::gfxContentType,
|
||||
SurfaceDescriptor*)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/*static*/ already_AddRefed<gfxASurface>
|
||||
ShadowLayerForwarder::PlatformOpenDescriptor(const SurfaceDescriptor&)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool
|
||||
ShadowLayerForwarder::PlatformDestroySharedSurface(SurfaceDescriptor*)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
PRBool
|
||||
ShadowLayerManager::PlatformDestroySharedSurface(SurfaceDescriptor*)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
ShadowLayerManager::PlatformSyncBeforeReplyUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
GetDescriptor(ID3D10Texture2D* aTexture, SurfaceDescriptorD3D10* aDescr)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aTexture && aDescr, "Params must be nonnull");
|
||||
|
||||
HRESULT hr;
|
||||
IDXGIResource* dr = nsnull;
|
||||
hr = aTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&dr);
|
||||
if (!SUCCEEDED(hr) || !dr)
|
||||
return false;
|
||||
|
||||
hr = dr->GetSharedHandle(reinterpret_cast<HANDLE*>(&aDescr->handle()));
|
||||
return !!SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
already_AddRefed<ID3D10Texture2D>
|
||||
OpenForeign(ID3D10Device* aDevice, const SurfaceDescriptorD3D10& aDescr)
|
||||
{
|
||||
HRESULT hr;
|
||||
ID3D10Texture2D* tex = nsnull;
|
||||
hr = aDevice->OpenSharedResource(reinterpret_cast<HANDLE>(aDescr.handle()),
|
||||
__uuidof(ID3D10Texture2D),
|
||||
(void**)&tex);
|
||||
if (!SUCCEEDED(hr) || !tex)
|
||||
return nsnull;
|
||||
|
||||
// XXX FIXME TODO do we need this???
|
||||
return nsRefPtr<ID3D10Texture2D>(tex).forget();
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
@ -1,67 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Jones <jones.chris.g@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef mozilla_layers_ShadowLayerUtilsD3D10_h
|
||||
#define mozilla_layers_ShadowLayerUtilsD3D10_h
|
||||
|
||||
#define MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
|
||||
|
||||
struct ID3D10Device;
|
||||
struct ID3D10Texture2D;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class SurfaceDescriptorD3D10;
|
||||
|
||||
/**
|
||||
* Write into |aDescr| a cross-process descriptor of |aTexture|, if
|
||||
* possible. Return true iff |aDescr| was successfully set.
|
||||
*/
|
||||
bool
|
||||
GetDescriptor(ID3D10Texture2D* aTexture, SurfaceDescriptorD3D10* aDescr);
|
||||
|
||||
already_AddRefed<ID3D10Texture2D>
|
||||
OpenForeign(ID3D10Device* aDevice, const SurfaceDescriptorD3D10& aDescr);
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layers_ShadowLayerUtilsD3D10_h
|
@ -49,7 +49,6 @@
|
||||
#include "mozilla/layers/PLayersParent.h"
|
||||
#include "ShadowLayers.h"
|
||||
#include "ShadowLayerChild.h"
|
||||
#include "ShadowLayerUtils.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
@ -380,6 +379,18 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
LayersBackend
|
||||
ShadowLayerForwarder::GetParentBackendType()
|
||||
{
|
||||
if (mParentBackend == LayerManager::LAYERS_NONE) {
|
||||
LayersBackend backend;
|
||||
if (mShadowManager->SendGetParentType(&backend)) {
|
||||
mParentBackend = backend;
|
||||
}
|
||||
}
|
||||
return mParentBackend;
|
||||
}
|
||||
|
||||
static gfxASurface::gfxImageFormat
|
||||
OptimalFormatFor(gfxASurface::gfxContentType aContent)
|
||||
{
|
||||
|
@ -237,24 +237,10 @@ public:
|
||||
*/
|
||||
PRBool EndTransaction(InfallibleTArray<EditReply>* aReplies);
|
||||
|
||||
/**
|
||||
* Set an actor through which layer updates will be pushed.
|
||||
*/
|
||||
void SetShadowManager(PLayersChild* aShadowManager)
|
||||
{
|
||||
mShadowManager = aShadowManager;
|
||||
}
|
||||
|
||||
void SetParentBackendType(LayersBackend aBackendType)
|
||||
{
|
||||
mParentBackend = aBackendType;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this is forwarding to a ShadowLayerManager.
|
||||
*/
|
||||
PRBool HasShadowManager() const { return !!mShadowManager; }
|
||||
PLayersChild* GetShadowManager() const { return mShadowManager; }
|
||||
|
||||
/**
|
||||
* The following Alloc/Open/Destroy interfaces abstract over the
|
||||
@ -330,10 +316,7 @@ public:
|
||||
*/
|
||||
PLayerChild* ConstructShadowFor(ShadowableLayer* aLayer);
|
||||
|
||||
LayersBackend GetParentBackendType()
|
||||
{
|
||||
return mParentBackend;
|
||||
}
|
||||
LayersBackend GetParentBackendType();
|
||||
|
||||
/*
|
||||
* No need to use double buffer in system memory with GPU rendering,
|
||||
|
@ -126,11 +126,6 @@ public:
|
||||
/**
|
||||
* LayerManager implementation.
|
||||
*/
|
||||
virtual ShadowLayerManager* AsShadowManager()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
void BeginTransaction();
|
||||
|
||||
void BeginTransactionWithTarget(gfxContext* aTarget);
|
||||
|
@ -327,6 +327,7 @@ gfxGDIFont::Initialize()
|
||||
}
|
||||
}
|
||||
|
||||
mAdjustedSize = ROUND(mAdjustedSize);
|
||||
FillLogFont(logFont, mAdjustedSize);
|
||||
mFont = ::CreateFontIndirectW(&logFont);
|
||||
|
||||
|
@ -79,7 +79,6 @@ using namespace mozilla::gfx;
|
||||
#include "gfxD2DSurface.h"
|
||||
|
||||
#include <d3d10_1.h>
|
||||
#include <dxgi.h>
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
@ -153,11 +152,6 @@ typedef HRESULT (WINAPI*D3D10CreateDevice1Func)(
|
||||
UINT SDKVersion,
|
||||
ID3D10Device1 **ppDevice
|
||||
);
|
||||
|
||||
typedef HRESULT(WINAPI*CreateDXGIFactory1Func)(
|
||||
REFIID riid,
|
||||
void **ppFactory
|
||||
);
|
||||
#endif
|
||||
|
||||
static __inline void
|
||||
@ -324,34 +318,10 @@ gfxWindowsPlatform::VerifyD2DDevice(PRBool aAttemptForce)
|
||||
nsRefPtr<ID3D10Device1> device;
|
||||
|
||||
if (createD3DDevice) {
|
||||
HMODULE dxgiModule = LoadLibraryA("dxgi.dll");
|
||||
CreateDXGIFactory1Func createDXGIFactory1 = (CreateDXGIFactory1Func)
|
||||
GetProcAddress(dxgiModule, "CreateDXGIFactory1");
|
||||
|
||||
// Try to use a DXGI 1.1 adapter in order to share resources
|
||||
// across processes.
|
||||
nsRefPtr<IDXGIAdapter1> adapter1;
|
||||
if (createDXGIFactory1) {
|
||||
nsRefPtr<IDXGIFactory1> factory1;
|
||||
HRESULT hr = createDXGIFactory1(__uuidof(IDXGIFactory1),
|
||||
getter_AddRefs(factory1));
|
||||
|
||||
nsRefPtr<IDXGIAdapter1> adapter1;
|
||||
hr = factory1->EnumAdapters1(0, getter_AddRefs(adapter1));
|
||||
|
||||
if (SUCCEEDED(hr) && adapter1) {
|
||||
hr = adapter1->CheckInterfaceSupport(__uuidof(ID3D10Device1),
|
||||
nsnull);
|
||||
if (FAILED(hr)) {
|
||||
adapter1 = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We try 10.0 first even though we prefer 10.1, since we want to
|
||||
// fail as fast as possible if 10.x isn't supported.
|
||||
HRESULT hr = createD3DDevice(
|
||||
adapter1,
|
||||
NULL,
|
||||
D3D10_DRIVER_TYPE_HARDWARE,
|
||||
NULL,
|
||||
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
|
||||
@ -367,7 +337,7 @@ gfxWindowsPlatform::VerifyD2DDevice(PRBool aAttemptForce)
|
||||
// clever.
|
||||
nsRefPtr<ID3D10Device1> device1;
|
||||
hr = createD3DDevice(
|
||||
adapter1,
|
||||
NULL,
|
||||
D3D10_DRIVER_TYPE_HARDWARE,
|
||||
NULL,
|
||||
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
|
||||
|
@ -75,10 +75,6 @@ namespace mozilla {
|
||||
typedef gfxPattern::GraphicsFilter GraphicsFilterType;
|
||||
typedef gfxASurface::gfxSurfaceType gfxSurfaceType;
|
||||
typedef LayerManager::LayersBackend LayersBackend;
|
||||
typedef gfxASurface::gfxImageFormat PixelFormat;
|
||||
// This is a cross-platform approximation to HANDLE, which we expect
|
||||
// to be typedef'd to void* or thereabouts.
|
||||
typedef uintptr_t WindowsHandle;
|
||||
|
||||
// XXX there are out of place and might be generally useful. Could
|
||||
// move to nscore.h or something.
|
||||
@ -508,19 +504,19 @@ struct ParamTraits<mozilla::gfxSurfaceType>
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
template<>
|
||||
struct ParamTraits<mozilla::LayersBackend>
|
||||
{
|
||||
typedef mozilla::LayersBackend paramType;
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
if (LayerManager::LAYERS_NONE <= param &&
|
||||
if (LayerManager::LAYERS_NONE < param &&
|
||||
param < LayerManager::LAYERS_LAST) {
|
||||
WriteParam(msg, int32(param));
|
||||
return;
|
||||
}
|
||||
NS_RUNTIMEABORT("backend type not reached");
|
||||
NS_RUNTIMEABORT("surface type not reached");
|
||||
}
|
||||
|
||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||
@ -529,7 +525,7 @@ struct ParamTraits<mozilla::LayersBackend>
|
||||
if (!ReadParam(msg, iter, &type))
|
||||
return false;
|
||||
|
||||
if (LayerManager::LAYERS_NONE <= type &&
|
||||
if (LayerManager::LAYERS_NONE < type &&
|
||||
type < LayerManager::LAYERS_LAST) {
|
||||
*result = paramType(type);
|
||||
return true;
|
||||
@ -538,38 +534,6 @@ struct ParamTraits<mozilla::LayersBackend>
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::PixelFormat>
|
||||
{
|
||||
typedef mozilla::PixelFormat paramType;
|
||||
|
||||
static bool IsLegalPixelFormat(const paramType& format)
|
||||
{
|
||||
return (gfxASurface::ImageFormatARGB32 <= format &&
|
||||
format < gfxASurface::ImageFormatUnknown);
|
||||
}
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
if (!IsLegalPixelFormat(param)) {
|
||||
NS_RUNTIMEABORT("Unknown pixel format");
|
||||
}
|
||||
WriteParam(msg, int32(param));
|
||||
return;
|
||||
}
|
||||
|
||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||
{
|
||||
int32 format;
|
||||
if (!ReadParam(msg, iter, &format) ||
|
||||
!IsLegalPixelFormat(paramType(format))) {
|
||||
return false;
|
||||
}
|
||||
*result = paramType(format);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<gfxRGBA>
|
||||
{
|
||||
|
@ -41,8 +41,6 @@
|
||||
include protocol PBrowser;
|
||||
include protocol PLayers;
|
||||
|
||||
using mozilla::LayersBackend;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
@ -61,9 +59,7 @@ sync protocol PRenderFrame
|
||||
manages PLayers;
|
||||
|
||||
parent:
|
||||
sync PLayers()
|
||||
returns (LayersBackend backend);
|
||||
|
||||
async PLayers();
|
||||
async __delete__();
|
||||
|
||||
state EMPTY:
|
||||
|
@ -66,7 +66,7 @@ RenderFrameChild::Destroy()
|
||||
}
|
||||
|
||||
PLayersChild*
|
||||
RenderFrameChild::AllocPLayers(LayerManager::LayersBackend* aBackendType)
|
||||
RenderFrameChild::AllocPLayers()
|
||||
{
|
||||
return new ShadowLayersChild();
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
|
||||
protected:
|
||||
NS_OVERRIDE
|
||||
virtual PLayersChild* AllocPLayers(LayerManager::LayersBackend* aBackendType);
|
||||
virtual PLayersChild* AllocPLayers();
|
||||
NS_OVERRIDE
|
||||
virtual bool DeallocPLayers(PLayersChild* aLayers);
|
||||
};
|
||||
|
@ -565,11 +565,10 @@ BuildBackgroundPatternFor(ContainerLayer* aContainer,
|
||||
RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader)
|
||||
: mFrameLoader(aFrameLoader)
|
||||
{
|
||||
if (aFrameLoader) {
|
||||
mContentViews[FrameMetrics::ROOT_SCROLL_ID] =
|
||||
new nsContentView(aFrameLoader->GetOwnerContent(),
|
||||
FrameMetrics::ROOT_SCROLL_ID);
|
||||
}
|
||||
NS_ABORT_IF_FALSE(aFrameLoader, "Need a frameloader here");
|
||||
mContentViews[FrameMetrics::ROOT_SCROLL_ID] =
|
||||
new nsContentView(aFrameLoader->GetOwnerContent(),
|
||||
FrameMetrics::ROOT_SCROLL_ID);
|
||||
}
|
||||
|
||||
RenderFrameParent::~RenderFrameParent()
|
||||
@ -702,7 +701,7 @@ RenderFrameParent::OwnerContentChanged(nsIContent* aContent)
|
||||
void
|
||||
RenderFrameParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
if (mFrameLoader && mFrameLoader->GetCurrentRemoteFrame() == this) {
|
||||
if (mFrameLoader->GetCurrentRemoteFrame() == this) {
|
||||
// XXX this might cause some weird issues ... we'll just not
|
||||
// redraw the part of the window covered by this until the "next"
|
||||
// remote frame has a layer-tree transaction. For
|
||||
@ -715,20 +714,29 @@ RenderFrameParent::ActorDestroy(ActorDestroyReason why)
|
||||
}
|
||||
|
||||
PLayersParent*
|
||||
RenderFrameParent::AllocPLayers(LayerManager::LayersBackend* aBackendType)
|
||||
RenderFrameParent::AllocPLayers()
|
||||
{
|
||||
if (!mFrameLoader) {
|
||||
*aBackendType = LayerManager::LAYERS_NONE;
|
||||
LayerManager* lm = GetLayerManager();
|
||||
switch (lm->GetBackendType()) {
|
||||
case LayerManager::LAYERS_BASIC: {
|
||||
BasicShadowLayerManager* bslm = static_cast<BasicShadowLayerManager*>(lm);
|
||||
return new ShadowLayersParent(bslm);
|
||||
}
|
||||
case LayerManager::LAYERS_OPENGL: {
|
||||
LayerManagerOGL* lmo = static_cast<LayerManagerOGL*>(lm);
|
||||
return new ShadowLayersParent(lmo);
|
||||
}
|
||||
#ifdef MOZ_ENABLE_D3D9_LAYER
|
||||
case LayerManager::LAYERS_D3D9: {
|
||||
LayerManagerD3D9* lmd3d9 = static_cast<LayerManagerD3D9*>(lm);
|
||||
return new ShadowLayersParent(lmd3d9);
|
||||
}
|
||||
#endif //MOZ_ENABLE_D3D9_LAYER
|
||||
default: {
|
||||
NS_WARNING("shadow layers no sprechen D3D backend yet");
|
||||
return nsnull;
|
||||
}
|
||||
LayerManager* lm = GetLayerManager();
|
||||
ShadowLayerManager* slm = lm->AsShadowManager();
|
||||
if (!slm) {
|
||||
*aBackendType = LayerManager::LAYERS_NONE;
|
||||
return nsnull;
|
||||
}
|
||||
*aBackendType = lm->GetBackendType();
|
||||
return new ShadowLayersParent(slm);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -99,7 +99,7 @@ public:
|
||||
protected:
|
||||
NS_OVERRIDE void ActorDestroy(ActorDestroyReason why);
|
||||
|
||||
NS_OVERRIDE virtual PLayersParent* AllocPLayers(LayerManager::LayersBackend* aBackendType);
|
||||
NS_OVERRIDE virtual PLayersParent* AllocPLayers();
|
||||
NS_OVERRIDE virtual bool DeallocPLayers(PLayersParent* aLayers);
|
||||
|
||||
private:
|
||||
|
@ -22,7 +22,7 @@ function rootView() {
|
||||
}
|
||||
|
||||
function enableAsyncScrolling() {
|
||||
frameLoader().renderMode = Components.interfaces.nsIFrameLoader.RENDER_MODE_ASYNC_SCROLL;
|
||||
frameLoader().renderMode = Components.interfaces.nsIFrameLoaer.RENDER_MODE_ASYNC_SCROLL;
|
||||
}
|
||||
|
||||
// Functions affecting the content window.
|
||||
|
6
layout/style/crashtests/671799-1.html
Normal file
6
layout/style/crashtests/671799-1.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<iframe src="data:text/html,<style>@font-face { font-family: 'x'; src: url(x.ttf); } :root { font-family: 'x'; }</style>"></iframe>
|
||||
</body>
|
||||
</html>
|
17
layout/style/crashtests/671799-2.html
Normal file
17
layout/style/crashtests/671799-2.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
@font-face {
|
||||
font-family: foo;
|
||||
src: url("http://spaces in hostname/");
|
||||
}
|
||||
body {
|
||||
font-family: foo, monospace;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
foo bar
|
||||
</body>
|
||||
</html>
|
@ -69,3 +69,5 @@ load 645142.html
|
||||
load 611922-1.html
|
||||
== 645951-1.html 645951-1-ref.html
|
||||
load 665209-1.html
|
||||
asserts(2) load 671799-1.html
|
||||
asserts(2) load 671799-2.html
|
||||
|
@ -723,7 +723,11 @@ nsUserFontSet::LogMessage(gfxProxyFontEntry *aProxy,
|
||||
|
||||
NS_ConvertUTF16toUTF8 familyName(aProxy->FamilyName());
|
||||
nsCAutoString fontURI;
|
||||
aProxy->mSrcList[aProxy->mSrcIndex].mURI->GetSpec(fontURI);
|
||||
if (aProxy->mSrcList[aProxy->mSrcIndex].mURI) {
|
||||
aProxy->mSrcList[aProxy->mSrcIndex].mURI->GetSpec(fontURI);
|
||||
} else {
|
||||
fontURI.AppendLiteral("(invalid URI)");
|
||||
}
|
||||
|
||||
char weightKeywordBuf[8]; // plenty to sprintf() a PRUint16
|
||||
const char *weightKeyword;
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "nsStringGlue.h"
|
||||
|
||||
#include "prthread.h"
|
||||
#include "Layers.h"
|
||||
#include "nsEvent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITheme.h"
|
||||
@ -72,12 +71,12 @@ class nsIContent;
|
||||
class ViewWrapper;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class LayerManager;
|
||||
}
|
||||
namespace dom {
|
||||
class PBrowserChild;
|
||||
}
|
||||
namespace layers {
|
||||
class PLayersChild;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,8 +117,8 @@ typedef nsEventStatus (* EVENT_CALLBACK)(nsGUIEvent *event);
|
||||
#endif
|
||||
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0xf43254ce, 0xd315, 0x458b, \
|
||||
{ 0xba, 0x72, 0xa8, 0xdf, 0x21, 0xcf, 0xa7, 0x2a } }
|
||||
{ 0xac809e35, 0x632c, 0x448d, \
|
||||
{ 0x9e, 0x34, 0x11, 0x62, 0x32, 0x60, 0x5e, 0xe6 } }
|
||||
|
||||
/*
|
||||
* Window shadow styles
|
||||
@ -275,8 +274,6 @@ class nsIWidget : public nsISupports {
|
||||
|
||||
public:
|
||||
typedef mozilla::layers::LayerManager LayerManager;
|
||||
typedef LayerManager::LayersBackend LayersBackend;
|
||||
typedef mozilla::layers::PLayersChild PLayersChild;
|
||||
|
||||
// Used in UpdateThemeGeometries.
|
||||
struct ThemeGeometry {
|
||||
@ -897,12 +894,6 @@ class nsIWidget : public nsISupports {
|
||||
|
||||
virtual nsIToolkit* GetToolkit() = 0;
|
||||
|
||||
enum LayerManagerPersistence
|
||||
{
|
||||
LAYER_MANAGER_CURRENT = 0,
|
||||
LAYER_MANAGER_PERSISTENT
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the widget's LayerManager. The layer tree for that
|
||||
* LayerManager is what gets rendered to the widget.
|
||||
@ -912,25 +903,17 @@ class nsIWidget : public nsISupports {
|
||||
*/
|
||||
inline LayerManager* GetLayerManager(bool* aAllowRetaining = nsnull)
|
||||
{
|
||||
return GetLayerManager(nsnull, LayerManager::LAYERS_NONE,
|
||||
LAYER_MANAGER_CURRENT, aAllowRetaining);
|
||||
return GetLayerManager(LAYER_MANAGER_CURRENT, aAllowRetaining);
|
||||
}
|
||||
|
||||
inline LayerManager* GetLayerManager(LayerManagerPersistence aPersistence,
|
||||
bool* aAllowRetaining = nsnull)
|
||||
|
||||
enum LayerManagerPersistence
|
||||
{
|
||||
return GetLayerManager(nsnull, LayerManager::LAYERS_NONE,
|
||||
aPersistence, aAllowRetaining);
|
||||
}
|
||||
LAYER_MANAGER_CURRENT = 0,
|
||||
LAYER_MANAGER_PERSISTENT
|
||||
};
|
||||
|
||||
/**
|
||||
* Like GetLayerManager(), but prefers creating a layer manager of
|
||||
* type |aBackendHint| instead of what would normally be created.
|
||||
* LAYERS_NONE means "no hint".
|
||||
*/
|
||||
virtual LayerManager* GetLayerManager(PLayersChild* aShadowManager,
|
||||
LayersBackend aBackendHint,
|
||||
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
|
||||
virtual LayerManager *GetLayerManager(LayerManagerPersistence aPersistence,
|
||||
bool* aAllowRetaining = nsnull) = 0;
|
||||
|
||||
/**
|
||||
|
@ -3173,11 +3173,8 @@ GetLayerManagerPrefs(LayerManagerPrefs* aManagerPrefs)
|
||||
aManagerPrefs->mDisableAcceleration || safeMode;
|
||||
}
|
||||
|
||||
LayerManager*
|
||||
nsWindow::GetLayerManager(PLayersChild* aShadowManager,
|
||||
LayersBackend aBackendHint,
|
||||
LayerManagerPersistence aPersistence,
|
||||
bool* aAllowRetaining)
|
||||
mozilla::layers::LayerManager*
|
||||
nsWindow::GetLayerManager(LayerManagerPersistence aPersistence, bool* aAllowRetaining)
|
||||
{
|
||||
if (aAllowRetaining) {
|
||||
*aAllowRetaining = true;
|
||||
|
@ -159,10 +159,7 @@ public:
|
||||
PRBool aDoCapture, PRBool aConsumeRollupEvent);
|
||||
NS_IMETHOD GetAttention(PRInt32 aCycleCount);
|
||||
virtual PRBool HasPendingInputEvent();
|
||||
virtual LayerManager* GetLayerManager(PLayersChild* aShadowManager = nsnull,
|
||||
LayersBackend aBackendHint = LayerManager::LAYERS_NONE,
|
||||
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
|
||||
bool* aAllowRetaining = nsnull);
|
||||
virtual LayerManager* GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, bool* aAllowRetaining = nsnull);
|
||||
gfxASurface *GetThebesSurface();
|
||||
NS_IMETHOD OnDefaultButtonLoaded(const nsIntRect &aButtonRect);
|
||||
NS_IMETHOD OverrideSystemMouseScrollSpeed(PRInt32 aOriginalDelta, PRBool aIsHorizontal, PRInt32 &aOverriddenDelta);
|
||||
|
@ -97,10 +97,6 @@ ifdef MOZ_X11
|
||||
SHARED_LIBRARY_LIBS += ../shared/x11/$(LIB_PREFIX)widget_shared_x11.$(LIB_SUFFIX)
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_D3D10_LAYER
|
||||
DEFINES += -DMOZ_ENABLE_D3D10_LAYER
|
||||
endif
|
||||
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/../$(MOZ_WIDGET_TOOLKIT) \
|
||||
-I$(srcdir)/../shared \
|
||||
|
@ -40,9 +40,6 @@
|
||||
|
||||
#include "mozilla/dom/PBrowserChild.h"
|
||||
#include "BasicLayers.h"
|
||||
#if defined(MOZ_ENABLE_D3D10_LAYER)
|
||||
# include "LayerManagerD3D10.h"
|
||||
#endif
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "PuppetWidget.h"
|
||||
@ -333,27 +330,10 @@ PuppetWidget::DispatchEvent(nsGUIEvent* event, nsEventStatus& aStatus)
|
||||
}
|
||||
|
||||
LayerManager*
|
||||
PuppetWidget::GetLayerManager(PLayersChild* aShadowManager,
|
||||
LayersBackend aBackendHint,
|
||||
LayerManagerPersistence aPersistence,
|
||||
bool* aAllowRetaining)
|
||||
PuppetWidget::GetLayerManager(LayerManagerPersistence, bool* aAllowRetaining)
|
||||
{
|
||||
if (!mLayerManager) {
|
||||
// The backend hint is a temporary placeholder until Azure, when
|
||||
// all content-process layer managers will be BasicLayerManagers.
|
||||
#if defined(MOZ_ENABLE_D3D10_LAYER)
|
||||
if (LayerManager::LAYERS_D3D10 == aBackendHint) {
|
||||
nsRefPtr<LayerManagerD3D10> m = new LayerManagerD3D10(this);
|
||||
m->AsShadowForwarder()->SetShadowManager(aShadowManager);
|
||||
if (m->Initialize()) {
|
||||
mLayerManager = m;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!mLayerManager) {
|
||||
mLayerManager = new BasicShadowLayerManager(this);
|
||||
mLayerManager->AsShadowForwarder()->SetShadowManager(aShadowManager);
|
||||
}
|
||||
mLayerManager = new BasicShadowLayerManager(this);
|
||||
}
|
||||
if (aAllowRetaining) {
|
||||
*aAllowRetaining = true;
|
||||
@ -558,15 +538,10 @@ PuppetWidget::DispatchPaintEvent()
|
||||
nsCAutoString("PuppetWidget"), nsnull);
|
||||
#endif
|
||||
|
||||
LayerManager* lm = GetLayerManager();
|
||||
if (LayerManager::LAYERS_D3D10 == mLayerManager->GetBackendType()) {
|
||||
DispatchEvent(&event, status);
|
||||
} else {
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(mSurface);
|
||||
AutoLayerManagerSetup setupLayerManager(this, ctx,
|
||||
BasicLayerManager::BUFFER_NONE);
|
||||
DispatchEvent(&event, status);
|
||||
}
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(mSurface);
|
||||
AutoLayerManagerSetup setupLayerManager(this, ctx,
|
||||
BasicLayerManager::BUFFER_NONE);
|
||||
DispatchEvent(&event, status);
|
||||
}
|
||||
|
||||
nsPaintEvent didPaintEvent(PR_TRUE, NS_DID_PAINT, this);
|
||||
|
@ -164,11 +164,8 @@ public:
|
||||
//
|
||||
|
||||
//NS_IMETHOD CaptureMouse(PRBool aCapture);
|
||||
virtual LayerManager*
|
||||
GetLayerManager(PLayersChild* aShadowManager = nsnull,
|
||||
LayersBackend aBackendHint = LayerManager::LAYERS_NONE,
|
||||
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
|
||||
bool* aAllowRetaining = nsnull);
|
||||
virtual LayerManager* GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
|
||||
bool* aAllowRetaining = nsnull);
|
||||
// virtual nsDeviceContext* GetDeviceContext();
|
||||
virtual gfxASurface* GetThebesSurface();
|
||||
|
||||
|
@ -852,9 +852,7 @@ nsBaseWidget::GetShouldAccelerate()
|
||||
return mUseAcceleratedRendering;
|
||||
}
|
||||
|
||||
LayerManager* nsBaseWidget::GetLayerManager(PLayersChild* aShadowManager,
|
||||
LayersBackend aBackendHint,
|
||||
LayerManagerPersistence aPersistence,
|
||||
LayerManager* nsBaseWidget::GetLayerManager(LayerManagerPersistence,
|
||||
bool* aAllowRetaining)
|
||||
{
|
||||
if (!mLayerManager) {
|
||||
@ -862,7 +860,8 @@ LayerManager* nsBaseWidget::GetLayerManager(PLayersChild* aShadowManager,
|
||||
mUseAcceleratedRendering = GetShouldAccelerate();
|
||||
|
||||
if (mUseAcceleratedRendering) {
|
||||
nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(this);
|
||||
nsRefPtr<LayerManagerOGL> layerManager =
|
||||
new mozilla::layers::LayerManagerOGL(this);
|
||||
/**
|
||||
* XXX - On several OSes initialization is expected to fail for now.
|
||||
* If we'd get a none-basic layer manager they'd crash. This is ok though
|
||||
|
@ -115,9 +115,7 @@ public:
|
||||
NS_IMETHOD MakeFullScreen(PRBool aFullScreen);
|
||||
virtual nsDeviceContext* GetDeviceContext();
|
||||
virtual nsIToolkit* GetToolkit();
|
||||
virtual LayerManager* GetLayerManager(PLayersChild* aShadowManager,
|
||||
LayersBackend aBackendHint,
|
||||
LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
|
||||
virtual LayerManager* GetLayerManager(LayerManagerPersistence aPersistence,
|
||||
bool* aAllowRetaining = nsnull);
|
||||
using nsIWidget::GetLayerManager;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user