mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to b2g-inbound. a=merge
CLOSED TREE
This commit is contained in:
commit
87d1f4f2e8
@ -1089,6 +1089,16 @@ window.addEventListener('ContentStart', function update_onContentStart() {
|
||||
})();
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
try {
|
||||
let gmpService = Cc["@mozilla.org/gecko-media-plugin-service;1"]
|
||||
.getService(Ci.mozIGeckoMediaPluginChromeService);
|
||||
gmpService.addPluginDirectory("/system/b2g/gmp-clearkey/0.1");
|
||||
} catch(e) {
|
||||
dump("Failed to add clearkey path! " + e + "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Calling this observer will cause a shutdown an a profile reset.
|
||||
// Use eg. : Services.obs.notifyObservers(null, 'b2g-reset-profile', null);
|
||||
Services.obs.addObserver(function resetProfile(subject, topic, data) {
|
||||
|
@ -159,6 +159,7 @@
|
||||
@BINPATH@/components/commandlines.xpt
|
||||
@BINPATH@/components/composer.xpt
|
||||
@BINPATH@/components/content_events.xpt
|
||||
@BINPATH@/components/content_geckomediaplugins.xpt
|
||||
@BINPATH@/components/content_html.xpt
|
||||
@BINPATH@/components/content_xslt.xpt
|
||||
@BINPATH@/components/cookie.xpt
|
||||
|
@ -41,3 +41,5 @@ if [ -d "$topsrcdir/gtk3" ]; then
|
||||
mk_add_options "export LD_LIBRARY_PATH=$topsrcdir/gtk3/usr/local/lib"
|
||||
ac_add_options --enable-default-toolkit=cairo-gtk3
|
||||
fi
|
||||
|
||||
export SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE=/builds/crash-stats-api.token
|
||||
|
@ -2607,6 +2607,5 @@ nsMessageManagerSH<Super>::Enumerate(nsIXPConnectWrappedNative* wrapper,
|
||||
|
||||
// Don't call up to our superclass, since neither nsDOMGenericSH nor
|
||||
// nsEventTargetSH have WANT_ENUMERATE.
|
||||
MOZ_ASSERT(!(this->GetScriptableFlags() & nsIXPCScriptable::WANT_ENUMERATE));
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -4080,13 +4080,12 @@ ArrayBufferBuilder::mapToFileInPackage(const nsCString& aFile,
|
||||
uint32_t offset = zip->GetDataOffset(zipItem);
|
||||
uint32_t size = zipItem->RealSize();
|
||||
mozilla::AutoFDClose pr_fd;
|
||||
mozilla::ScopedClose fd;
|
||||
rv = aJarFile->OpenNSPRFileDesc(PR_RDONLY, 0, &pr_fd.rwget());
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
fd.rwget() = PR_FileDesc2NativeHandle(pr_fd);
|
||||
mMapPtr = JS_CreateMappedArrayBufferContents(fd, offset, size);
|
||||
mMapPtr = JS_CreateMappedArrayBufferContents(PR_FileDesc2NativeHandle(pr_fd),
|
||||
offset, size);
|
||||
if (mMapPtr) {
|
||||
mLength = size;
|
||||
return NS_OK;
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
template<class U>
|
||||
MOZ_IMPLICIT OwningNonNull(already_AddRefed<U>&& aValue)
|
||||
{
|
||||
init(aValue.take());
|
||||
init(aValue);
|
||||
}
|
||||
|
||||
// This is no worse than get() in terms of const handling.
|
||||
@ -106,7 +106,7 @@ public:
|
||||
|
||||
protected:
|
||||
template<typename U>
|
||||
void init(U aValue)
|
||||
void init(U&& aValue)
|
||||
{
|
||||
mPtr = aValue;
|
||||
MOZ_ASSERT(mPtr);
|
||||
|
@ -92,47 +92,6 @@ private:
|
||||
bool mEnabled;
|
||||
bool mShutdown;
|
||||
nsRefPtr<ContentParent> mPreallocatedAppProcess;
|
||||
|
||||
#if defined(MOZ_NUWA_PROCESS) && defined(ENABLE_TESTS)
|
||||
// For testing NS_NewUnmonitoredThread().
|
||||
|
||||
void CreateUnmonitoredThread();
|
||||
void DestroyUnmonitoredThread();
|
||||
|
||||
class UnmonitoredThreadRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
UnmonitoredThreadRunnable()
|
||||
: mMonitor("UnmonitoredThreadRunnable")
|
||||
, mEnabled(true)
|
||||
{ }
|
||||
|
||||
NS_IMETHODIMP Run() override
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
while (mEnabled) {
|
||||
mMonitor.Wait();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void Disable()
|
||||
{
|
||||
MonitorAutoLock mon(mMonitor);
|
||||
mEnabled = false;
|
||||
mMonitor.NotifyAll();
|
||||
}
|
||||
|
||||
private:
|
||||
~UnmonitoredThreadRunnable() { }
|
||||
|
||||
Monitor mMonitor;
|
||||
bool mEnabled;
|
||||
};
|
||||
|
||||
nsCOMPtr<nsIThread> mUnmonitoredThread;
|
||||
nsRefPtr<UnmonitoredThreadRunnable> mUnmonitoredThreadRunnable;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* static */ StaticRefPtr<PreallocatedProcessManagerImpl>
|
||||
@ -196,40 +155,6 @@ PreallocatedProcessManagerImpl::Observe(nsISupports* aSubject,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(MOZ_NUWA_PROCESS) && defined(ENABLE_TESTS)
|
||||
void
|
||||
PreallocatedProcessManagerImpl::CreateUnmonitoredThread()
|
||||
{
|
||||
if (Preferences::GetBool("dom.ipc.newUnmonitoredThread.testMode")) {
|
||||
// Create an unmonitored thread and dispatch a blocking runnable in test
|
||||
// case startup.
|
||||
nsresult rv = NS_NewUnmonitoredThread(getter_AddRefs(mUnmonitoredThread),
|
||||
nullptr);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
mUnmonitoredThreadRunnable = new UnmonitoredThreadRunnable();
|
||||
mUnmonitoredThread->Dispatch(mUnmonitoredThreadRunnable,
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::DestroyUnmonitoredThread()
|
||||
{
|
||||
// Cleanup after the test case finishes.
|
||||
if (mUnmonitoredThreadRunnable) {
|
||||
mUnmonitoredThreadRunnable->Disable();
|
||||
}
|
||||
|
||||
if (mUnmonitoredThread) {
|
||||
mUnmonitoredThread->Shutdown();
|
||||
}
|
||||
|
||||
mUnmonitoredThreadRunnable = nullptr;
|
||||
mUnmonitoredThread = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
PreallocatedProcessManagerImpl::RereadPrefs()
|
||||
{
|
||||
@ -255,11 +180,6 @@ PreallocatedProcessManagerImpl::Enable()
|
||||
|
||||
mEnabled = true;
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#ifdef ENABLE_TESTS
|
||||
// For testing New_UnmonitoredThread().
|
||||
CreateUnmonitoredThread();
|
||||
#endif
|
||||
|
||||
ScheduleDelayedNuwaFork();
|
||||
#else
|
||||
AllocateAfterDelay();
|
||||
@ -452,11 +372,6 @@ PreallocatedProcessManagerImpl::Disable()
|
||||
mEnabled = false;
|
||||
|
||||
#ifdef MOZ_NUWA_PROCESS
|
||||
#ifdef ENABLE_TESTS
|
||||
// Shut down the test-only unmonitored thread.
|
||||
DestroyUnmonitoredThread();
|
||||
#endif
|
||||
|
||||
// Cancel pending fork.
|
||||
if (mPreallocateAppProcessTask) {
|
||||
mPreallocateAppProcessTask->Cancel();
|
||||
|
@ -17,8 +17,6 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet'
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_NuwaProcessDeadlock.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_NewUnmonitoredThread.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_child_docshell.html]
|
||||
skip-if = toolkit == 'cocoa' # disabled due to hangs, see changeset 6852e7c47edf
|
||||
[test_CrashService_crash.html]
|
||||
|
@ -1,80 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test if Nuwa process created successfully.
|
||||
-->
|
||||
<head>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="setup()">
|
||||
|
||||
<script type="application/javascript;version=1.7">
|
||||
"use strict";
|
||||
|
||||
function runTest()
|
||||
{
|
||||
info("Launch the Nuwa process");
|
||||
let cpmm = SpecialPowers.Cc["@mozilla.org/childprocessmessagemanager;1"]
|
||||
.getService(SpecialPowers.Ci.nsISyncMessageSender);
|
||||
let seenNuwaReady = false;
|
||||
let msgHandler = {
|
||||
receiveMessage: function receiveMessage(msg) {
|
||||
msg = SpecialPowers.wrap(msg);
|
||||
if (msg.name == 'TEST-ONLY:nuwa-ready') {
|
||||
ok(true, "Got nuwa-ready");
|
||||
is(seenNuwaReady, false, "Already received nuwa ready");
|
||||
seenNuwaReady = true;
|
||||
} else if (msg.name == 'TEST-ONLY:nuwa-add-new-process') {
|
||||
ok(true, "Got nuwa-add-new-process");
|
||||
is(seenNuwaReady, true, "Receive nuwa-add-new-process before nuwa-ready");
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function shutdown() {
|
||||
info("Shut down the test case");
|
||||
cpmm.removeMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
|
||||
cpmm.removeMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
cpmm.addMessageListener("TEST-ONLY:nuwa-ready", msgHandler);
|
||||
cpmm.addMessageListener("TEST-ONLY:nuwa-add-new-process", msgHandler);
|
||||
|
||||
|
||||
// Setting this pref to true should cause us to prelaunch a process.
|
||||
SpecialPowers.setBoolPref('dom.ipc.processPrelaunch.enabled', true);
|
||||
}
|
||||
|
||||
function setup2()
|
||||
{
|
||||
info("Enable the Nuwa process to test the unmonitored thread");
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
['dom.ipc.processPrelaunch.enabled', false],
|
||||
['dom.ipc.preallocatedProcessManager.testMode', true]
|
||||
]
|
||||
}, runTest);
|
||||
}
|
||||
|
||||
function setup()
|
||||
{
|
||||
info("Create an unmonitored thread.");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [
|
||||
// For testing NS_NewUnmonitoredThread()
|
||||
['dom.ipc.newUnmonitoredThread.testMode', true],
|
||||
]
|
||||
}, setup2);
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1353,9 +1353,9 @@ nsEditor::CreateNode(nsIAtom* aTag,
|
||||
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext);
|
||||
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->WillCreateNode(nsDependentAtomString(aTag),
|
||||
GetAsDOMNode(aParent), aPosition);
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillCreateNode(nsDependentAtomString(aTag),
|
||||
GetAsDOMNode(aParent), aPosition);
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> ret;
|
||||
@ -1370,11 +1370,9 @@ nsEditor::CreateNode(nsIAtom* aTag,
|
||||
|
||||
mRangeUpdater.SelAdjCreateNode(aParent, aPosition);
|
||||
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->DidCreateNode(nsDependentAtomString(aTag),
|
||||
GetAsDOMNode(ret),
|
||||
GetAsDOMNode(aParent), aPosition,
|
||||
res);
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidCreateNode(nsDependentAtomString(aTag), GetAsDOMNode(ret),
|
||||
GetAsDOMNode(aParent), aPosition, res);
|
||||
}
|
||||
|
||||
return ret.forget();
|
||||
@ -1396,9 +1394,9 @@ nsEditor::InsertNode(nsIContent& aNode, nsINode& aParent, int32_t aPosition)
|
||||
{
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::insertNode, nsIEditor::eNext);
|
||||
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(),
|
||||
aPosition);
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(),
|
||||
aPosition);
|
||||
}
|
||||
|
||||
nsRefPtr<InsertNodeTxn> txn = CreateTxnForInsertNode(aNode, aParent,
|
||||
@ -1407,9 +1405,9 @@ nsEditor::InsertNode(nsIContent& aNode, nsINode& aParent, int32_t aPosition)
|
||||
|
||||
mRangeUpdater.SelAdjInsertNode(aParent.AsDOMNode(), aPosition);
|
||||
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(),
|
||||
aPosition, res);
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidInsertNode(aNode.AsDOMNode(), aParent.AsDOMNode(), aPosition,
|
||||
res);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -1435,8 +1433,8 @@ nsEditor::SplitNode(nsIContent& aNode, int32_t aOffset, ErrorResult& aResult)
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::splitNode,
|
||||
nsIEditor::eNext);
|
||||
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->WillSplitNode(aNode.AsDOMNode(), aOffset);
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillSplitNode(aNode.AsDOMNode(), aOffset);
|
||||
}
|
||||
|
||||
nsRefPtr<SplitNodeTxn> txn = CreateTxnForSplitNode(aNode, aOffset);
|
||||
@ -1447,10 +1445,9 @@ nsEditor::SplitNode(nsIContent& aNode, int32_t aOffset, ErrorResult& aResult)
|
||||
|
||||
mRangeUpdater.SelAdjSplitNode(aNode, aOffset, newNode);
|
||||
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->DidSplitNode(aNode.AsDOMNode(), aOffset,
|
||||
GetAsDOMNode(newNode),
|
||||
aResult.ErrorCode());
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidSplitNode(aNode.AsDOMNode(), aOffset, GetAsDOMNode(newNode),
|
||||
aResult.ErrorCode());
|
||||
}
|
||||
|
||||
return newNode;
|
||||
@ -1483,10 +1480,9 @@ nsEditor::JoinNodes(nsINode& aLeftNode, nsINode& aRightNode)
|
||||
// Find the number of children of the lefthand node
|
||||
uint32_t oldLeftNodeLen = aLeftNode.Length();
|
||||
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->WillJoinNodes(aLeftNode.AsDOMNode(),
|
||||
aRightNode.AsDOMNode(),
|
||||
parent->AsDOMNode());
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(),
|
||||
parent->AsDOMNode());
|
||||
}
|
||||
|
||||
nsresult result;
|
||||
@ -1498,10 +1494,9 @@ nsEditor::JoinNodes(nsINode& aLeftNode, nsINode& aRightNode)
|
||||
mRangeUpdater.SelAdjJoinNodes(aLeftNode, aRightNode, *parent, offset,
|
||||
(int32_t)oldLeftNodeLen);
|
||||
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->DidJoinNodes(aLeftNode.AsDOMNode(),
|
||||
aRightNode.AsDOMNode(),
|
||||
parent->AsDOMNode(), result);
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidJoinNodes(aLeftNode.AsDOMNode(), aRightNode.AsDOMNode(),
|
||||
parent->AsDOMNode(), result);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -1522,8 +1517,8 @@ nsEditor::DeleteNode(nsINode* aNode)
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::ePrevious);
|
||||
|
||||
// save node location for selection updating code.
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->WillDeleteNode(aNode->AsDOMNode());
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillDeleteNode(aNode->AsDOMNode());
|
||||
}
|
||||
|
||||
nsRefPtr<DeleteNodeTxn> txn;
|
||||
@ -1532,8 +1527,8 @@ nsEditor::DeleteNode(nsINode* aNode)
|
||||
res = DoTransaction(txn);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->DidDeleteNode(aNode->AsDOMNode(), res);
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidDeleteNode(aNode->AsDOMNode(), res);
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
@ -1738,10 +1733,8 @@ nsEditor::AddEditorObserver(nsIEditorObserver *aObserver)
|
||||
NS_ENSURE_TRUE(aObserver, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// Make sure the listener isn't already on the list
|
||||
if (mEditorObservers.IndexOf(aObserver) == -1)
|
||||
{
|
||||
if (!mEditorObservers.AppendObject(aObserver))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!mEditorObservers.Contains(aObserver)) {
|
||||
mEditorObservers.AppendElement(*aObserver);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1753,8 +1746,7 @@ nsEditor::RemoveEditorObserver(nsIEditorObserver *aObserver)
|
||||
{
|
||||
NS_ENSURE_TRUE(aObserver, NS_ERROR_FAILURE);
|
||||
|
||||
if (!mEditorObservers.RemoveObject(aObserver))
|
||||
return NS_ERROR_FAILURE;
|
||||
mEditorObservers.RemoveElement(aObserver);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1814,8 +1806,8 @@ nsEditor::NotifyEditorObservers(NotificationForEditorObservers aNotification)
|
||||
switch (aNotification) {
|
||||
case eNotifyEditorObserversOfEnd:
|
||||
mIsInEditAction = false;
|
||||
for (int32_t i = 0; i < mEditorObservers.Count(); i++) {
|
||||
mEditorObservers[i]->EditAction();
|
||||
for (auto& observer : mEditorObservers) {
|
||||
observer->EditAction();
|
||||
}
|
||||
|
||||
if (!mDispatchInputEvent) {
|
||||
@ -1826,14 +1818,14 @@ nsEditor::NotifyEditorObservers(NotificationForEditorObservers aNotification)
|
||||
break;
|
||||
case eNotifyEditorObserversOfBefore:
|
||||
mIsInEditAction = true;
|
||||
for (int32_t i = 0; i < mEditorObservers.Count(); i++) {
|
||||
mEditorObservers[i]->BeforeEditAction();
|
||||
for (auto& observer : mEditorObservers) {
|
||||
observer->BeforeEditAction();
|
||||
}
|
||||
break;
|
||||
case eNotifyEditorObserversOfCancel:
|
||||
mIsInEditAction = false;
|
||||
for (int32_t i = 0; i < mEditorObservers.Count(); i++) {
|
||||
mEditorObservers[i]->CancelEditAction();
|
||||
for (auto& observer : mEditorObservers) {
|
||||
observer->CancelEditAction();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1866,10 +1858,8 @@ nsEditor::AddEditActionListener(nsIEditActionListener *aListener)
|
||||
NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// Make sure the listener isn't already on the list
|
||||
if (mActionListeners.IndexOf(aListener) == -1)
|
||||
{
|
||||
if (!mActionListeners.AppendObject(aListener))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!mActionListeners.Contains(aListener)) {
|
||||
mActionListeners.AppendElement(*aListener);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1881,8 +1871,7 @@ nsEditor::RemoveEditActionListener(nsIEditActionListener *aListener)
|
||||
{
|
||||
NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE);
|
||||
|
||||
if (!mActionListeners.RemoveObject(aListener))
|
||||
return NS_ERROR_FAILURE;
|
||||
mActionListeners.RemoveElement(aListener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1893,10 +1882,8 @@ nsEditor::AddDocumentStateListener(nsIDocumentStateListener *aListener)
|
||||
{
|
||||
NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (mDocStateListeners.IndexOf(aListener) == -1)
|
||||
{
|
||||
if (!mDocStateListeners.AppendObject(aListener))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (!mDocStateListeners.Contains(aListener)) {
|
||||
mDocStateListeners.AppendElement(*aListener);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1908,8 +1895,7 @@ nsEditor::RemoveDocumentStateListener(nsIDocumentStateListener *aListener)
|
||||
{
|
||||
NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (!mDocStateListeners.RemoveObject(aListener))
|
||||
return NS_ERROR_FAILURE;
|
||||
mDocStateListeners.RemoveElement(aListener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2392,8 +2378,8 @@ nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
}
|
||||
|
||||
// Let listeners know what's up
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->WillInsertText(
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillInsertText(
|
||||
static_cast<nsIDOMCharacterData*>(aTextNode.AsDOMNode()), aOffset,
|
||||
aStringToInsert);
|
||||
}
|
||||
@ -2407,8 +2393,8 @@ nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
mRangeUpdater.SelAdjInsertText(aTextNode, aOffset, aStringToInsert);
|
||||
|
||||
// let listeners know what happened
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->DidInsertText(
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidInsertText(
|
||||
static_cast<nsIDOMCharacterData*>(aTextNode.AsDOMNode()),
|
||||
aOffset, aStringToInsert, res);
|
||||
}
|
||||
@ -2465,29 +2451,28 @@ nsEditor::GetFirstEditableNode(nsINode* aRoot)
|
||||
NS_IMETHODIMP
|
||||
nsEditor::NotifyDocumentListeners(TDocumentListenerNotification aNotificationType)
|
||||
{
|
||||
int32_t numListeners = mDocStateListeners.Count();
|
||||
if (!numListeners) // maybe there just aren't any.
|
||||
if (!mDocStateListeners.Length()) {
|
||||
// Maybe there just aren't any.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMArray<nsIDocumentStateListener> listeners(mDocStateListeners);
|
||||
nsTArray<OwningNonNull<nsIDocumentStateListener>>
|
||||
listeners(mDocStateListeners);
|
||||
nsresult rv = NS_OK;
|
||||
int32_t i;
|
||||
|
||||
switch (aNotificationType)
|
||||
{
|
||||
case eDocumentCreated:
|
||||
for (i = 0; i < numListeners;i++)
|
||||
{
|
||||
rv = listeners[i]->NotifyDocumentCreated();
|
||||
for (auto& listener : listeners) {
|
||||
rv = listener->NotifyDocumentCreated();
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eDocumentToBeDestroyed:
|
||||
for (i = 0; i < numListeners;i++)
|
||||
{
|
||||
rv = listeners[i]->NotifyDocumentWillBeDestroyed();
|
||||
for (auto& listener : listeners) {
|
||||
rv = listener->NotifyDocumentWillBeDestroyed();
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
@ -2504,9 +2489,8 @@ nsEditor::NotifyDocumentListeners(TDocumentListenerNotification aNotificationTyp
|
||||
|
||||
mDocDirtyState = docIsDirty;
|
||||
|
||||
for (i = 0; i < numListeners;i++)
|
||||
{
|
||||
rv = listeners[i]->NotifyDocumentStateChanged(mDocDirtyState);
|
||||
for (auto& listener : listeners) {
|
||||
rv = listener->NotifyDocumentStateChanged(mDocDirtyState);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
@ -2542,8 +2526,8 @@ nsEditor::DeleteText(nsGenericDOMDataNode& aCharData, uint32_t aOffset,
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::deleteText, nsIEditor::ePrevious);
|
||||
|
||||
// Let listeners know what's up
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->WillDeleteText(
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillDeleteText(
|
||||
static_cast<nsIDOMCharacterData*>(GetAsDOMNode(&aCharData)), aOffset,
|
||||
aLength);
|
||||
}
|
||||
@ -2551,8 +2535,8 @@ nsEditor::DeleteText(nsGenericDOMDataNode& aCharData, uint32_t aOffset,
|
||||
nsresult res = DoTransaction(txn);
|
||||
|
||||
// Let listeners know what happened
|
||||
for (int32_t i = 0; i < mActionListeners.Count(); i++) {
|
||||
mActionListeners[i]->DidDeleteText(
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidDeleteText(
|
||||
static_cast<nsIDOMCharacterData*>(GetAsDOMNode(&aCharData)), aOffset,
|
||||
aLength, res);
|
||||
}
|
||||
@ -3960,31 +3944,38 @@ nsEditor::DeleteSelectionImpl(EDirection aAction,
|
||||
if (NS_SUCCEEDED(res))
|
||||
{
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::deleteSelection, aAction);
|
||||
int32_t i;
|
||||
// Notify nsIEditActionListener::WillDelete[Selection|Text|Node]
|
||||
if (!deleteNode)
|
||||
for (i = 0; i < mActionListeners.Count(); i++)
|
||||
mActionListeners[i]->WillDeleteSelection(selection);
|
||||
else if (deleteCharData)
|
||||
for (i = 0; i < mActionListeners.Count(); i++)
|
||||
mActionListeners[i]->WillDeleteText(deleteCharData, deleteCharOffset, 1);
|
||||
else
|
||||
for (i = 0; i < mActionListeners.Count(); i++)
|
||||
mActionListeners[i]->WillDeleteNode(deleteNode->AsDOMNode());
|
||||
if (!deleteNode) {
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillDeleteSelection(selection);
|
||||
}
|
||||
} else if (deleteCharData) {
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillDeleteText(deleteCharData, deleteCharOffset, 1);
|
||||
}
|
||||
} else {
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->WillDeleteNode(deleteNode->AsDOMNode());
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the specified amount
|
||||
res = DoTransaction(txn);
|
||||
|
||||
// Notify nsIEditActionListener::DidDelete[Selection|Text|Node]
|
||||
if (!deleteNode)
|
||||
for (i = 0; i < mActionListeners.Count(); i++)
|
||||
mActionListeners[i]->DidDeleteSelection(selection);
|
||||
else if (deleteCharData)
|
||||
for (i = 0; i < mActionListeners.Count(); i++)
|
||||
mActionListeners[i]->DidDeleteText(deleteCharData, deleteCharOffset, 1, res);
|
||||
else
|
||||
for (i = 0; i < mActionListeners.Count(); i++)
|
||||
mActionListeners[i]->DidDeleteNode(deleteNode->AsDOMNode(), res);
|
||||
if (!deleteNode) {
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidDeleteSelection(selection);
|
||||
}
|
||||
} else if (deleteCharData) {
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidDeleteText(deleteCharData, deleteCharOffset, 1, res);
|
||||
}
|
||||
} else {
|
||||
for (auto& listener : mActionListeners) {
|
||||
listener->DidDeleteNode(deleteNode->AsDOMNode(), res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -7,9 +7,9 @@
|
||||
#define __editor_h__
|
||||
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc.
|
||||
#include "mozilla/dom/OwningNonNull.h" // for OwningNonNull
|
||||
#include "mozilla/dom/Text.h"
|
||||
#include "nsAutoPtr.h" // for nsRefPtr
|
||||
#include "nsCOMArray.h" // for nsCOMArray
|
||||
#include "nsCOMPtr.h" // for already_AddRefed, nsCOMPtr
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@ -830,9 +830,12 @@ protected:
|
||||
nsRefPtr<mozilla::TextComposition> mComposition;
|
||||
|
||||
// various listeners
|
||||
nsCOMArray<nsIEditActionListener> mActionListeners; // listens to all low level actions on the doc
|
||||
nsCOMArray<nsIEditorObserver> mEditorObservers; // just notify once per high level change
|
||||
nsCOMArray<nsIDocumentStateListener> mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc)
|
||||
// Listens to all low level actions on the doc
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsIEditActionListener>> mActionListeners;
|
||||
// Just notify once per high level change
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsIEditorObserver>> mEditorObservers;
|
||||
// Listen to overall doc state (dirty or not, just created, etc)
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsIDocumentStateListener>> mDocStateListeners;
|
||||
|
||||
nsSelectionState mSavedSel; // cached selection for nsAutoSelectionReset
|
||||
nsRangeUpdater mRangeUpdater; // utility class object for maintaining preserved ranges
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
#include "nsEditorUtils.h"
|
||||
|
||||
#include "mozilla/dom/OwningNonNull.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIClipboardDragDropHookList.h"
|
||||
@ -66,91 +66,53 @@ nsAutoSelectionReset::Abort()
|
||||
* some helper classes for iterating the dom tree
|
||||
*****************************************************************************/
|
||||
|
||||
nsDOMIterator::nsDOMIterator() :
|
||||
mIter(nullptr)
|
||||
nsDOMIterator::nsDOMIterator(nsRange& aRange)
|
||||
{
|
||||
MOZ_ASSERT(aRange.GetStartParent(), "Invalid range");
|
||||
mIter = NS_NewContentIterator();
|
||||
DebugOnly<nsresult> res = mIter->Init(&aRange);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(res));
|
||||
}
|
||||
|
||||
nsDOMIterator::nsDOMIterator(nsINode& aNode)
|
||||
{
|
||||
mIter = NS_NewContentIterator();
|
||||
DebugOnly<nsresult> res = mIter->Init(&aNode);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(res));
|
||||
}
|
||||
|
||||
nsDOMIterator::nsDOMIterator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
nsDOMIterator::~nsDOMIterator()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMIterator::Init(nsRange* aRange)
|
||||
{
|
||||
nsresult res;
|
||||
mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE);
|
||||
return mIter->Init(aRange);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMIterator::Init(nsIDOMNode* aNode)
|
||||
{
|
||||
nsresult res;
|
||||
mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
|
||||
return mIter->Init(content);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor,
|
||||
nsTArray<nsCOMPtr<nsINode>>& arrayOfNodes) const
|
||||
void
|
||||
nsDOMIterator::AppendList(const nsBoolDomIterFunctor& functor,
|
||||
nsTArray<OwningNonNull<nsINode>>& arrayOfNodes) const
|
||||
{
|
||||
// Iterate through dom and build list
|
||||
while (!mIter->IsDone()) {
|
||||
for (; !mIter->IsDone(); mIter->Next()) {
|
||||
nsCOMPtr<nsINode> node = mIter->GetCurrentNode();
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (functor(node)) {
|
||||
arrayOfNodes.AppendElement(node);
|
||||
arrayOfNodes.AppendElement(*node);
|
||||
}
|
||||
mIter->Next();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor,
|
||||
nsCOMArray<nsIDOMNode>& arrayOfNodes) const
|
||||
nsDOMSubtreeIterator::nsDOMSubtreeIterator(nsRange& aRange)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
|
||||
// iterate through dom and build list
|
||||
while (!mIter->IsDone())
|
||||
{
|
||||
node = do_QueryInterface(mIter->GetCurrentNode());
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (functor(node))
|
||||
{
|
||||
arrayOfNodes.AppendObject(node);
|
||||
}
|
||||
mIter->Next();
|
||||
}
|
||||
return NS_OK;
|
||||
mIter = NS_NewContentSubtreeIterator();
|
||||
DebugOnly<nsresult> res = mIter->Init(&aRange);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(res));
|
||||
}
|
||||
|
||||
nsDOMSubtreeIterator::nsDOMSubtreeIterator()
|
||||
{
|
||||
}
|
||||
|
||||
nsDOMSubtreeIterator::~nsDOMSubtreeIterator()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMSubtreeIterator::Init(nsRange* aRange)
|
||||
{
|
||||
nsresult res;
|
||||
mIter = do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(mIter, NS_ERROR_FAILURE);
|
||||
return mIter->Init(aRange);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* some general purpose editor utils
|
||||
|
@ -19,9 +19,9 @@ class nsIAtom;
|
||||
class nsIContentIterator;
|
||||
class nsIDOMDocument;
|
||||
class nsRange;
|
||||
template <class E> class nsCOMArray;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
template <class T> class OwningNonNull;
|
||||
class Selection;
|
||||
}
|
||||
}
|
||||
@ -167,42 +167,37 @@ class MOZ_STACK_CLASS nsAutoUpdateViewBatch
|
||||
class nsBoolDomIterFunctor
|
||||
{
|
||||
public:
|
||||
virtual bool operator()(nsIDOMNode* aNode)=0;
|
||||
bool operator()(nsINode* aNode)
|
||||
{
|
||||
return operator()(GetAsDOMNode(aNode));
|
||||
}
|
||||
virtual bool operator()(nsINode* aNode) const = 0;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS nsDOMIterator
|
||||
{
|
||||
public:
|
||||
nsDOMIterator();
|
||||
explicit nsDOMIterator(nsRange& aRange);
|
||||
explicit nsDOMIterator(nsINode& aNode);
|
||||
virtual ~nsDOMIterator();
|
||||
|
||||
nsresult Init(nsRange* aRange);
|
||||
nsresult Init(nsIDOMNode* aNode);
|
||||
nsresult AppendList(nsBoolDomIterFunctor& functor,
|
||||
nsTArray<nsCOMPtr<nsINode>>& arrayOfNodes) const;
|
||||
nsresult AppendList(nsBoolDomIterFunctor& functor,
|
||||
nsCOMArray<nsIDOMNode>& arrayOfNodes) const;
|
||||
|
||||
void AppendList(const nsBoolDomIterFunctor& functor,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& arrayOfNodes) const;
|
||||
protected:
|
||||
nsCOMPtr<nsIContentIterator> mIter;
|
||||
|
||||
// For nsDOMSubtreeIterator
|
||||
nsDOMIterator();
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS nsDOMSubtreeIterator : public nsDOMIterator
|
||||
{
|
||||
public:
|
||||
nsDOMSubtreeIterator();
|
||||
explicit nsDOMSubtreeIterator(nsRange& aRange);
|
||||
virtual ~nsDOMSubtreeIterator();
|
||||
|
||||
nsresult Init(nsRange* aRange);
|
||||
};
|
||||
|
||||
class nsTrivialFunctor : public nsBoolDomIterFunctor
|
||||
{
|
||||
public:
|
||||
virtual bool operator()(nsIDOMNode* aNode) // used to build list of all nodes iterator covers
|
||||
// Used to build list of all nodes iterator covers
|
||||
virtual bool operator()(nsINode* aNode) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "mozilla/dom/OwningNonNull.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
@ -14,7 +15,6 @@
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsCRTGlue.h"
|
||||
@ -102,39 +102,6 @@ static nsresult RemoveFragComments(nsCString &theStr);
|
||||
static void RemoveBodyAndHead(nsIDOMNode *aNode);
|
||||
static nsresult FindTargetNode(nsIDOMNode *aStart, nsCOMPtr<nsIDOMNode> &aResult);
|
||||
|
||||
static nsCOMPtr<nsIDOMNode> GetListParent(nsIDOMNode* aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode, nullptr);
|
||||
nsCOMPtr<nsIDOMNode> parent, tmp;
|
||||
aNode->GetParentNode(getter_AddRefs(parent));
|
||||
while (parent)
|
||||
{
|
||||
if (nsHTMLEditUtils::IsList(parent)) {
|
||||
return parent;
|
||||
}
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
parent = tmp;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static nsCOMPtr<nsIDOMNode> GetTableParent(nsIDOMNode* aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode, nullptr);
|
||||
nsCOMPtr<nsIDOMNode> parent, tmp;
|
||||
aNode->GetParentNode(getter_AddRefs(parent));
|
||||
while (parent)
|
||||
{
|
||||
if (nsHTMLEditUtils::IsTable(parent)) {
|
||||
return parent;
|
||||
}
|
||||
parent->GetParentNode(getter_AddRefs(tmp));
|
||||
parent = tmp;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::LoadHTML(const nsAString & aInputString)
|
||||
{
|
||||
@ -321,13 +288,21 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
// this is work to be completed at a later date (probably by jfrancis)
|
||||
|
||||
// make a list of what nodes in docFrag we need to move
|
||||
nsCOMArray<nsIDOMNode> nodeList;
|
||||
rv = CreateListOfNodesToPaste(fragmentAsNode, nodeList,
|
||||
streamStartParent, streamStartOffset,
|
||||
streamEndParent, streamEndOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsTArray<OwningNonNull<nsINode>> nodeList;
|
||||
nsCOMPtr<nsINode> fragmentAsNodeNode = do_QueryInterface(fragmentAsNode);
|
||||
NS_ENSURE_STATE(fragmentAsNodeNode || !fragmentAsNode);
|
||||
nsCOMPtr<nsINode> streamStartParentNode =
|
||||
do_QueryInterface(streamStartParent);
|
||||
NS_ENSURE_STATE(streamStartParentNode || !streamStartParent);
|
||||
nsCOMPtr<nsINode> streamEndParentNode =
|
||||
do_QueryInterface(streamEndParent);
|
||||
NS_ENSURE_STATE(streamEndParentNode || !streamEndParent);
|
||||
CreateListOfNodesToPaste(*static_cast<DocumentFragment*>(fragmentAsNodeNode.get()),
|
||||
nodeList,
|
||||
streamStartParentNode, streamStartOffset,
|
||||
streamEndParentNode, streamEndOffset);
|
||||
|
||||
if (nodeList.Count() == 0) {
|
||||
if (nodeList.Length() == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -352,9 +327,9 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
// but if not we want to delete _contents_ of cells and replace
|
||||
// with non-table elements. Use cellSelectionMode bool to
|
||||
// indicate results.
|
||||
nsIDOMNode* firstNode = nodeList[0];
|
||||
if (!nsHTMLEditUtils::IsTableElement(firstNode))
|
||||
if (!nsHTMLEditUtils::IsTableElement(nodeList[0])) {
|
||||
cellSelectionMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cellSelectionMode)
|
||||
@ -402,7 +377,8 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
NS_ENSURE_TRUE(parentNode, NS_ERROR_FAILURE);
|
||||
|
||||
// Adjust position based on the first node we are going to insert.
|
||||
NormalizeEOLInsertPosition(nodeList[0], address_of(parentNode), &offsetOfNewNode);
|
||||
NormalizeEOLInsertPosition(GetAsDOMNode(nodeList[0]),
|
||||
address_of(parentNode), &offsetOfNewNode);
|
||||
|
||||
// if there are any invisible br's after our insertion point, remove them.
|
||||
// this is because if there is a br at end of what we paste, it will make
|
||||
@ -431,16 +407,15 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
|
||||
// build up list of parents of first node in list that are either
|
||||
// lists or tables. First examine front of paste node list.
|
||||
nsCOMArray<nsIDOMNode> startListAndTableArray;
|
||||
rv = GetListAndTableParents(false, nodeList, startListAndTableArray);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsTArray<OwningNonNull<Element>> startListAndTableArray;
|
||||
GetListAndTableParents(StartOrEnd::start, nodeList,
|
||||
startListAndTableArray);
|
||||
|
||||
// remember number of lists and tables above us
|
||||
int32_t highWaterMark = -1;
|
||||
if (startListAndTableArray.Count() > 0)
|
||||
{
|
||||
rv = DiscoverPartialListsAndTables(nodeList, startListAndTableArray, &highWaterMark);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (startListAndTableArray.Length() > 0) {
|
||||
highWaterMark = DiscoverPartialListsAndTables(nodeList,
|
||||
startListAndTableArray);
|
||||
}
|
||||
|
||||
// if we have pieces of tables or lists to be inserted, let's force the paste
|
||||
@ -448,33 +423,31 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
// table or list contents outside the table or list.
|
||||
if (highWaterMark >= 0)
|
||||
{
|
||||
rv = ReplaceOrphanedStructure(false, nodeList, startListAndTableArray, highWaterMark);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ReplaceOrphanedStructure(StartOrEnd::start, nodeList,
|
||||
startListAndTableArray, highWaterMark);
|
||||
}
|
||||
|
||||
// Now go through the same process again for the end of the paste node list.
|
||||
nsCOMArray<nsIDOMNode> endListAndTableArray;
|
||||
rv = GetListAndTableParents(true, nodeList, endListAndTableArray);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsTArray<OwningNonNull<Element>> endListAndTableArray;
|
||||
GetListAndTableParents(StartOrEnd::end, nodeList, endListAndTableArray);
|
||||
highWaterMark = -1;
|
||||
|
||||
// remember number of lists and tables above us
|
||||
if (endListAndTableArray.Count() > 0)
|
||||
{
|
||||
rv = DiscoverPartialListsAndTables(nodeList, endListAndTableArray, &highWaterMark);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (endListAndTableArray.Length() > 0) {
|
||||
highWaterMark = DiscoverPartialListsAndTables(nodeList,
|
||||
endListAndTableArray);
|
||||
}
|
||||
|
||||
// don't orphan partial list or table structure
|
||||
if (highWaterMark >= 0)
|
||||
{
|
||||
rv = ReplaceOrphanedStructure(true, nodeList, endListAndTableArray, highWaterMark);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ReplaceOrphanedStructure(StartOrEnd::end, nodeList,
|
||||
endListAndTableArray, highWaterMark);
|
||||
}
|
||||
|
||||
// Loop over the node list and paste the nodes:
|
||||
nsCOMPtr<nsIDOMNode> parentBlock, lastInsertNode, insertedContextParent;
|
||||
int32_t listCount = nodeList.Count();
|
||||
int32_t listCount = nodeList.Length();
|
||||
int32_t j;
|
||||
if (IsBlockNode(parentNode))
|
||||
parentBlock = parentNode;
|
||||
@ -484,7 +457,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
for (j=0; j<listCount; j++)
|
||||
{
|
||||
bool bDidInsert = false;
|
||||
nsCOMPtr<nsIDOMNode> curNode = nodeList[j];
|
||||
nsCOMPtr<nsIDOMNode> curNode = nodeList[j]->AsDOMNode();
|
||||
|
||||
NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(curNode != fragmentAsNode, NS_ERROR_FAILURE);
|
||||
@ -721,26 +694,25 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
return mRules->DidDoAction(selection, &ruleInfo, rv);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::AddInsertionListener(nsIContentFilter *aListener)
|
||||
{
|
||||
NS_ENSURE_TRUE(aListener, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// don't let a listener be added more than once
|
||||
if (mContentFilters.IndexOfObject(aListener) == -1)
|
||||
{
|
||||
NS_ENSURE_TRUE(mContentFilters.AppendObject(aListener), NS_ERROR_FAILURE);
|
||||
if (!mContentFilters.Contains(aListener)) {
|
||||
mContentFilters.AppendElement(*aListener);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::RemoveInsertionListener(nsIContentFilter *aListener)
|
||||
{
|
||||
NS_ENSURE_TRUE(aListener, NS_ERROR_FAILURE);
|
||||
|
||||
NS_ENSURE_TRUE(mContentFilters.RemoveObject(aListener), NS_ERROR_FAILURE);
|
||||
mContentFilters.RemoveElement(aListener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -760,17 +732,15 @@ nsHTMLEditor::DoContentFilterCallback(const nsAString &aFlavor,
|
||||
{
|
||||
*aDoContinue = true;
|
||||
|
||||
int32_t i;
|
||||
nsIContentFilter *listener;
|
||||
for (i=0; i < mContentFilters.Count() && *aDoContinue; i++)
|
||||
{
|
||||
listener = (nsIContentFilter *)mContentFilters[i];
|
||||
if (listener)
|
||||
listener->NotifyOfInsertion(aFlavor, nullptr, sourceDoc,
|
||||
aWillDeleteSelection, aFragmentAsNode,
|
||||
aFragStartNode, aFragStartOffset,
|
||||
aFragEndNode, aFragEndOffset,
|
||||
aTargetNode, aTargetOffset, aDoContinue);
|
||||
for (auto& listener : mContentFilters) {
|
||||
if (!*aDoContinue) {
|
||||
break;
|
||||
}
|
||||
listener->NotifyOfInsertion(aFlavor, nullptr, sourceDoc,
|
||||
aWillDeleteSelection, aFragmentAsNode,
|
||||
aFragStartNode, aFragStartOffset,
|
||||
aFragEndNode, aFragEndOffset, aTargetNode,
|
||||
aTargetOffset, aDoContinue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -2166,219 +2136,170 @@ nsresult nsHTMLEditor::ParseFragment(const nsAString & aFragStr,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsHTMLEditor::CreateListOfNodesToPaste(nsIDOMNode *aFragmentAsNode,
|
||||
nsCOMArray<nsIDOMNode>& outNodeList,
|
||||
nsIDOMNode *aStartNode,
|
||||
int32_t aStartOffset,
|
||||
nsIDOMNode *aEndNode,
|
||||
int32_t aEndOffset)
|
||||
void
|
||||
nsHTMLEditor::CreateListOfNodesToPaste(DocumentFragment& aFragment,
|
||||
nsTArray<OwningNonNull<nsINode>>& outNodeList,
|
||||
nsINode* aStartNode,
|
||||
int32_t aStartOffset,
|
||||
nsINode* aEndNode,
|
||||
int32_t aEndOffset)
|
||||
{
|
||||
NS_ENSURE_TRUE(aFragmentAsNode, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// if no info was provided about the boundary between context and stream,
|
||||
// If no info was provided about the boundary between context and stream,
|
||||
// then assume all is stream.
|
||||
if (!aStartNode)
|
||||
{
|
||||
int32_t fragLen;
|
||||
rv = GetLengthOfDOMNode(aFragmentAsNode, (uint32_t&)fragLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
aStartNode = aFragmentAsNode;
|
||||
if (!aStartNode) {
|
||||
aStartNode = &aFragment;
|
||||
aStartOffset = 0;
|
||||
aEndNode = aFragmentAsNode;
|
||||
aEndOffset = fragLen;
|
||||
aEndNode = &aFragment;
|
||||
aEndOffset = aFragment.Length();
|
||||
}
|
||||
|
||||
nsRefPtr<nsRange> docFragRange;
|
||||
rv = nsRange::CreateRange(aStartNode, aStartOffset, aEndNode, aEndOffset, getter_AddRefs(docFragRange));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult rv = nsRange::CreateRange(aStartNode, aStartOffset,
|
||||
aEndNode, aEndOffset,
|
||||
getter_AddRefs(docFragRange));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
NS_ENSURE_SUCCESS(rv, );
|
||||
|
||||
// now use a subtree iterator over the range to create a list of nodes
|
||||
// Now use a subtree iterator over the range to create a list of nodes
|
||||
nsTrivialFunctor functor;
|
||||
nsDOMSubtreeIterator iter;
|
||||
rv = iter.Init(docFragRange);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return iter.AppendList(functor, outNodeList);
|
||||
nsDOMSubtreeIterator iter(*docFragRange);
|
||||
iter.AppendList(functor, outNodeList);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::GetListAndTableParents(bool aEnd,
|
||||
nsCOMArray<nsIDOMNode>& aListOfNodes,
|
||||
nsCOMArray<nsIDOMNode>& outArray)
|
||||
void
|
||||
nsHTMLEditor::GetListAndTableParents(StartOrEnd aStartOrEnd,
|
||||
nsTArray<OwningNonNull<nsINode>>& aNodeList,
|
||||
nsTArray<OwningNonNull<Element>>& outArray)
|
||||
{
|
||||
int32_t listCount = aListOfNodes.Count();
|
||||
NS_ENSURE_TRUE(listCount > 0, NS_ERROR_FAILURE); // no empty lists, please
|
||||
MOZ_ASSERT(aNodeList.Length());
|
||||
|
||||
// build up list of parents of first (or last) node in list
|
||||
// that are either lists, or tables.
|
||||
int32_t idx = 0;
|
||||
if (aEnd) idx = listCount-1;
|
||||
// Build up list of parents of first (or last) node in list that are either
|
||||
// lists, or tables.
|
||||
int32_t idx = aStartOrEnd == StartOrEnd::end ? aNodeList.Length() - 1 : 0;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> pNode = aListOfNodes[idx];
|
||||
while (pNode)
|
||||
{
|
||||
if (nsHTMLEditUtils::IsList(pNode) || nsHTMLEditUtils::IsTable(pNode))
|
||||
{
|
||||
NS_ENSURE_TRUE(outArray.AppendObject(pNode), NS_ERROR_FAILURE);
|
||||
for (nsCOMPtr<nsINode> node = aNodeList[idx]; node;
|
||||
node = node->GetParentNode()) {
|
||||
if (nsHTMLEditUtils::IsList(node) || nsHTMLEditUtils::IsTable(node)) {
|
||||
outArray.AppendElement(*node->AsElement());
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
pNode->GetParentNode(getter_AddRefs(parent));
|
||||
pNode = parent;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::DiscoverPartialListsAndTables(nsCOMArray<nsIDOMNode>& aPasteNodes,
|
||||
nsCOMArray<nsIDOMNode>& aListsAndTables,
|
||||
int32_t *outHighWaterMark)
|
||||
int32_t
|
||||
nsHTMLEditor::DiscoverPartialListsAndTables(nsTArray<OwningNonNull<nsINode>>& aPasteNodes,
|
||||
nsTArray<OwningNonNull<Element>>& aListsAndTables)
|
||||
{
|
||||
NS_ENSURE_TRUE(outHighWaterMark, NS_ERROR_NULL_POINTER);
|
||||
int32_t ret = -1;
|
||||
int32_t listAndTableParents = aListsAndTables.Length();
|
||||
|
||||
*outHighWaterMark = -1;
|
||||
int32_t listAndTableParents = aListsAndTables.Count();
|
||||
|
||||
// scan insertion list for table elements (other than table).
|
||||
int32_t listCount = aPasteNodes.Count();
|
||||
int32_t j;
|
||||
for (j=0; j<listCount; j++)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> curNode = aPasteNodes[j];
|
||||
|
||||
NS_ENSURE_TRUE(curNode, NS_ERROR_FAILURE);
|
||||
if (nsHTMLEditUtils::IsTableElement(curNode) && !nsHTMLEditUtils::IsTable(curNode))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> theTable = GetTableParent(curNode);
|
||||
if (theTable)
|
||||
{
|
||||
int32_t indexT = aListsAndTables.IndexOf(theTable);
|
||||
if (indexT >= 0)
|
||||
{
|
||||
*outHighWaterMark = indexT;
|
||||
if (*outHighWaterMark == listAndTableParents-1) break;
|
||||
// Scan insertion list for table elements (other than table).
|
||||
for (auto& curNode : aPasteNodes) {
|
||||
if (nsHTMLEditUtils::IsTableElement(curNode) &&
|
||||
!curNode->IsHTMLElement(nsGkAtoms::table)) {
|
||||
nsCOMPtr<Element> table = curNode->GetParentElement();
|
||||
while (table && !table->IsHTMLElement(nsGkAtoms::table)) {
|
||||
table = table->GetParentElement();
|
||||
}
|
||||
if (table) {
|
||||
int32_t idx = aListsAndTables.IndexOf(table);
|
||||
if (idx == -1) {
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
ret = idx;
|
||||
if (ret == listAndTableParents - 1) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nsHTMLEditUtils::IsListItem(curNode))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> theList = GetListParent(curNode);
|
||||
if (theList)
|
||||
{
|
||||
int32_t indexL = aListsAndTables.IndexOf(theList);
|
||||
if (indexL >= 0)
|
||||
{
|
||||
*outHighWaterMark = indexL;
|
||||
if (*outHighWaterMark == listAndTableParents-1) break;
|
||||
if (nsHTMLEditUtils::IsListItem(curNode)) {
|
||||
nsCOMPtr<Element> list = curNode->GetParentElement();
|
||||
while (list && !nsHTMLEditUtils::IsList(list)) {
|
||||
list = list->GetParentElement();
|
||||
}
|
||||
if (list) {
|
||||
int32_t idx = aListsAndTables.IndexOf(list);
|
||||
if (idx == -1) {
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
ret = idx;
|
||||
if (ret == listAndTableParents - 1) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::ScanForListAndTableStructure( bool aEnd,
|
||||
nsCOMArray<nsIDOMNode>& aNodes,
|
||||
nsIDOMNode *aListOrTable,
|
||||
nsCOMPtr<nsIDOMNode> *outReplaceNode)
|
||||
nsINode*
|
||||
nsHTMLEditor::ScanForListAndTableStructure(StartOrEnd aStartOrEnd,
|
||||
nsTArray<OwningNonNull<nsINode>>& aNodes,
|
||||
Element& aListOrTable)
|
||||
{
|
||||
NS_ENSURE_TRUE(aListOrTable, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(outReplaceNode, NS_ERROR_NULL_POINTER);
|
||||
|
||||
*outReplaceNode = 0;
|
||||
// Look upward from first/last paste node for a piece of this list/table
|
||||
int32_t idx = aStartOrEnd == StartOrEnd::end ? aNodes.Length() - 1 : 0;
|
||||
bool isList = nsHTMLEditUtils::IsList(&aListOrTable);
|
||||
|
||||
// look upward from first/last paste node for a piece of this list/table
|
||||
int32_t listCount = aNodes.Count(), idx = 0;
|
||||
if (aEnd) idx = listCount-1;
|
||||
bool bList = nsHTMLEditUtils::IsList(aListOrTable);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> pNode = aNodes[idx];
|
||||
nsCOMPtr<nsIDOMNode> originalNode = pNode;
|
||||
while (pNode)
|
||||
{
|
||||
if ((bList && nsHTMLEditUtils::IsListItem(pNode)) ||
|
||||
(!bList && (nsHTMLEditUtils::IsTableElement(pNode) && !nsHTMLEditUtils::IsTable(pNode))))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> structureNode;
|
||||
if (bList) structureNode = GetListParent(pNode);
|
||||
else structureNode = GetTableParent(pNode);
|
||||
if (structureNode == aListOrTable)
|
||||
{
|
||||
if (bList)
|
||||
*outReplaceNode = structureNode;
|
||||
else
|
||||
*outReplaceNode = pNode;
|
||||
break;
|
||||
for (nsCOMPtr<nsINode> node = aNodes[idx]; node;
|
||||
node = node->GetParentNode()) {
|
||||
if ((isList && nsHTMLEditUtils::IsListItem(node)) ||
|
||||
(!isList && nsHTMLEditUtils::IsTableElement(node) &&
|
||||
!node->IsHTMLElement(nsGkAtoms::table))) {
|
||||
nsCOMPtr<Element> structureNode = node->GetParentElement();
|
||||
if (isList) {
|
||||
while (structureNode && !nsHTMLEditUtils::IsList(structureNode)) {
|
||||
structureNode = structureNode->GetParentElement();
|
||||
}
|
||||
} else {
|
||||
while (structureNode &&
|
||||
!structureNode->IsHTMLElement(nsGkAtoms::table)) {
|
||||
structureNode = structureNode->GetParentElement();
|
||||
}
|
||||
}
|
||||
if (structureNode == &aListOrTable) {
|
||||
if (isList) {
|
||||
return structureNode;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
pNode->GetParentNode(getter_AddRefs(parent));
|
||||
pNode = parent;
|
||||
}
|
||||
return NS_OK;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::ReplaceOrphanedStructure(bool aEnd,
|
||||
nsCOMArray<nsIDOMNode>& aNodeArray,
|
||||
nsCOMArray<nsIDOMNode>& aListAndTableArray,
|
||||
void
|
||||
nsHTMLEditor::ReplaceOrphanedStructure(StartOrEnd aStartOrEnd,
|
||||
nsTArray<OwningNonNull<nsINode>>& aNodeArray,
|
||||
nsTArray<OwningNonNull<Element>>& aListAndTableArray,
|
||||
int32_t aHighWaterMark)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> curNode = aListAndTableArray[aHighWaterMark];
|
||||
NS_ENSURE_TRUE(curNode, NS_ERROR_NULL_POINTER);
|
||||
OwningNonNull<Element> curNode = aListAndTableArray[aHighWaterMark];
|
||||
|
||||
nsCOMPtr<nsIDOMNode> replaceNode, originalNode;
|
||||
// Find substructure of list or table that must be included in paste.
|
||||
nsCOMPtr<nsINode> replaceNode =
|
||||
ScanForListAndTableStructure(aStartOrEnd, aNodeArray, curNode);
|
||||
|
||||
// find substructure of list or table that must be included in paste.
|
||||
nsresult rv = ScanForListAndTableStructure(aEnd, aNodeArray,
|
||||
curNode, address_of(replaceNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// if we found substructure, paste it instead of its descendants
|
||||
if (replaceNode)
|
||||
{
|
||||
// postprocess list to remove any descendants of this node
|
||||
// so that we don't insert them twice.
|
||||
nsCOMPtr<nsIDOMNode> endpoint;
|
||||
do
|
||||
{
|
||||
endpoint = GetArrayEndpoint(aEnd, aNodeArray);
|
||||
if (!endpoint) break;
|
||||
if (nsEditorUtils::IsDescendantOf(endpoint, replaceNode))
|
||||
aNodeArray.RemoveObject(endpoint);
|
||||
else
|
||||
break;
|
||||
} while(endpoint);
|
||||
|
||||
// now replace the removed nodes with the structural parent
|
||||
if (aEnd) aNodeArray.AppendObject(replaceNode);
|
||||
else aNodeArray.InsertObjectAt(replaceNode, 0);
|
||||
if (!replaceNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we found substructure, paste it instead of its descendants.
|
||||
// Postprocess list to remove any descendants of this node so that we don't
|
||||
// insert them twice.
|
||||
while (aNodeArray.Length()) {
|
||||
int32_t idx = aStartOrEnd == StartOrEnd::start ? 0
|
||||
: aNodeArray.Length() - 1;
|
||||
OwningNonNull<nsINode> endpoint = aNodeArray[idx];
|
||||
if (!nsEditorUtils::IsDescendantOf(endpoint, replaceNode)) {
|
||||
break;
|
||||
}
|
||||
aNodeArray.RemoveElementAt(idx);
|
||||
}
|
||||
|
||||
// Now replace the removed nodes with the structural parent
|
||||
if (aStartOrEnd == StartOrEnd::end) {
|
||||
aNodeArray.AppendElement(*replaceNode);
|
||||
} else {
|
||||
aNodeArray.InsertElementAt(0, *replaceNode);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDOMNode* nsHTMLEditor::GetArrayEndpoint(bool aEnd,
|
||||
nsCOMArray<nsIDOMNode>& aNodeArray)
|
||||
{
|
||||
int32_t listCount = aNodeArray.Count();
|
||||
if (listCount <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aEnd) {
|
||||
return aNodeArray[listCount-1];
|
||||
}
|
||||
|
||||
return aNodeArray[0];
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,6 @@ class Selection;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
struct DOMPoint;
|
||||
template <class E> class nsCOMArray;
|
||||
|
||||
struct StyleCache : public PropItem
|
||||
{
|
||||
@ -191,14 +190,17 @@ protected:
|
||||
nsresult DidMakeBasicBlock(mozilla::dom::Selection* aSelection,
|
||||
nsRulesInfo* aInfo, nsresult aResult);
|
||||
nsresult DidAbsolutePosition();
|
||||
nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);
|
||||
nsresult AlignInnerBlocks(nsINode& aNode, const nsAString* alignType);
|
||||
nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType);
|
||||
nsresult AppendInnerFormatNodes(nsCOMArray<nsIDOMNode>& aArray,
|
||||
nsresult AppendInnerFormatNodes(nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aArray,
|
||||
nsINode* aNode);
|
||||
nsresult AppendInnerFormatNodes(nsCOMArray<nsIDOMNode>& aArray,
|
||||
nsIDOMNode *aNode);
|
||||
nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat);
|
||||
nsresult GetInnerContent(nsIDOMNode *aNode, nsCOMArray<nsIDOMNode>& outArrayOfNodes, int32_t *aIndex, bool aList = true, bool aTble = true);
|
||||
enum class Lists { no, yes };
|
||||
enum class Tables { no, yes };
|
||||
void GetInnerContent(nsINode& aNode,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aOutArrayOfNodes,
|
||||
int32_t* aIndex, Lists aLists = Lists::yes,
|
||||
Tables aTables = Tables::yes);
|
||||
already_AddRefed<nsIDOMNode> IsInListItem(nsIDOMNode* aNode);
|
||||
mozilla::dom::Element* IsInListItem(nsINode* aNode);
|
||||
nsresult ReturnInHeader(mozilla::dom::Selection* aSelection,
|
||||
@ -217,11 +219,9 @@ protected:
|
||||
int32_t aOffset);
|
||||
nsresult AfterEditInner(EditAction action,
|
||||
nsIEditor::EDirection aDirection);
|
||||
nsresult RemovePartOfBlock(nsIDOMNode *aBlock,
|
||||
nsIDOMNode *aStartChild,
|
||||
nsIDOMNode *aEndChild,
|
||||
nsCOMPtr<nsIDOMNode> *aLeftNode = 0,
|
||||
nsCOMPtr<nsIDOMNode> *aRightNode = 0);
|
||||
nsresult RemovePartOfBlock(mozilla::dom::Element& aBlock,
|
||||
nsIContent& aStartChild,
|
||||
nsIContent& aEndChild);
|
||||
nsresult SplitBlock(nsIDOMNode *aBlock,
|
||||
nsIDOMNode *aStartChild,
|
||||
nsIDOMNode *aEndChild,
|
||||
@ -263,37 +263,44 @@ protected:
|
||||
void GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode,
|
||||
int32_t aOffset, EditAction actionID,
|
||||
nsCOMPtr<nsIDOMNode>* outNode, int32_t* outOffset);
|
||||
nsresult GetPromotedRanges(mozilla::dom::Selection* aSelection,
|
||||
nsTArray<nsRefPtr<nsRange>>& outArrayOfRanges,
|
||||
EditAction inOperationType);
|
||||
nsresult PromoteRange(nsRange* inRange, EditAction inOperationType);
|
||||
nsresult GetNodesForOperation(nsTArray<nsRefPtr<nsRange>>& inArrayOfRanges,
|
||||
nsCOMArray<nsIDOMNode>& outArrayOfNodes,
|
||||
EditAction inOperationType,
|
||||
bool aDontTouchContent=false);
|
||||
nsresult GetChildNodesForOperation(nsIDOMNode *inNode,
|
||||
nsCOMArray<nsIDOMNode>& outArrayOfNodes);
|
||||
nsresult GetNodesFromPoint(::DOMPoint point,
|
||||
EditAction operation,
|
||||
nsCOMArray<nsIDOMNode>& arrayOfNodes,
|
||||
bool dontTouchContent);
|
||||
nsresult GetNodesFromSelection(mozilla::dom::Selection* selection,
|
||||
EditAction operation,
|
||||
nsCOMArray<nsIDOMNode>& arrayOfNodes,
|
||||
bool aDontTouchContent=false);
|
||||
nsresult GetListActionNodes(nsCOMArray<nsIDOMNode> &outArrayOfNodes, bool aEntireList, bool aDontTouchContent=false);
|
||||
void GetPromotedRanges(mozilla::dom::Selection& aSelection,
|
||||
nsTArray<nsRefPtr<nsRange>>& outArrayOfRanges,
|
||||
EditAction inOperationType);
|
||||
void PromoteRange(nsRange& aRange, EditAction inOperationType);
|
||||
enum class TouchContent { no, yes };
|
||||
nsresult GetNodesForOperation(nsTArray<nsRefPtr<nsRange>>& aArrayOfRanges,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aOutArrayOfNodes,
|
||||
EditAction aOperationType,
|
||||
TouchContent aTouchContent = TouchContent::yes);
|
||||
void GetChildNodesForOperation(nsINode& aNode,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& outArrayOfNodes);
|
||||
nsresult GetNodesFromPoint(::DOMPoint aPoint,
|
||||
EditAction aOperation,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& outArrayOfNodes,
|
||||
TouchContent aTouchContent);
|
||||
nsresult GetNodesFromSelection(mozilla::dom::Selection& aSelection,
|
||||
EditAction aOperation,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& outArrayOfNodes,
|
||||
TouchContent aTouchContent = TouchContent::yes);
|
||||
enum class EntireList { no, yes };
|
||||
nsresult GetListActionNodes(nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aOutArrayOfNodes,
|
||||
EntireList aEntireList,
|
||||
TouchContent aTouchContent = TouchContent::yes);
|
||||
void GetDefinitionListItemTypes(mozilla::dom::Element* aElement, bool* aDT, bool* aDD);
|
||||
nsresult GetParagraphFormatNodes(nsCOMArray<nsIDOMNode>& outArrayOfNodes, bool aDontTouchContent=false);
|
||||
nsresult LookInsideDivBQandList(nsCOMArray<nsIDOMNode>& aNodeArray);
|
||||
nsresult GetParagraphFormatNodes(
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& outArrayOfNodes,
|
||||
TouchContent aTouchContent = TouchContent::yes);
|
||||
void LookInsideDivBQandList(nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aNodeArray);
|
||||
nsresult BustUpInlinesAtRangeEndpoints(nsRangeStore &inRange);
|
||||
nsresult BustUpInlinesAtBRs(nsIDOMNode *inNode,
|
||||
nsCOMArray<nsIDOMNode>& outArrayOfNodes);
|
||||
nsresult BustUpInlinesAtBRs(nsINode& aNode,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aOutArrayOfNodes);
|
||||
nsCOMPtr<nsIDOMNode> GetHighestInlineParent(nsIDOMNode* aNode);
|
||||
nsresult MakeTransitionList(nsCOMArray<nsIDOMNode>& inArrayOfNodes,
|
||||
nsTArray<bool> &inTransitionArray);
|
||||
nsresult RemoveBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes);
|
||||
nsresult ApplyBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes, const nsAString *aBlockTag);
|
||||
nsresult MakeBlockquote(nsCOMArray<nsIDOMNode>& arrayOfNodes);
|
||||
void MakeTransitionList(nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aNodeArray,
|
||||
nsTArray<bool>& aTransitionArray);
|
||||
nsresult RemoveBlockStyle(nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aNodeArray);
|
||||
nsresult ApplyBlockStyle(nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aNodeArray,
|
||||
nsIAtom& aBlockTag);
|
||||
nsresult MakeBlockquote(nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aNodeArray);
|
||||
nsresult SplitAsNeeded(nsIAtom& aTag, nsCOMPtr<nsINode>& inOutParent,
|
||||
int32_t& inOutOffset);
|
||||
nsresult AddTerminatingBR(nsIDOMNode *aBlock);
|
||||
@ -304,7 +311,7 @@ protected:
|
||||
nsresult CacheInlineStyles(nsIDOMNode *aNode);
|
||||
nsresult ReapplyCachedStyles();
|
||||
void ClearCachedStyles();
|
||||
nsresult AdjustSpecialBreaks(bool aSafeToAskFrames = false);
|
||||
void AdjustSpecialBreaks();
|
||||
nsresult AdjustWhitespace(mozilla::dom::Selection* aSelection);
|
||||
nsresult PinSelectionToNewBlock(mozilla::dom::Selection* aSelection);
|
||||
nsresult CheckInterlinePosition(mozilla::dom::Selection* aSelection);
|
||||
@ -329,7 +336,7 @@ protected:
|
||||
nsresult ConfirmSelectionInBody();
|
||||
nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode);
|
||||
bool IsEmptyInline(nsIDOMNode *aNode);
|
||||
bool ListIsEmptyLine(nsCOMArray<nsIDOMNode> &arrayOfNodes);
|
||||
bool ListIsEmptyLine(nsTArray<mozilla::dom::OwningNonNull<nsINode>>& arrayOfNodes);
|
||||
nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, bool aChildrenOnly);
|
||||
nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, bool aStarts);
|
||||
nsresult AlignBlock(nsIDOMElement * aElement, const nsAString * aAlignType, bool aContentsOnly);
|
||||
|
@ -195,7 +195,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLEditor, nsPlaintextEdito
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMouseMotionListenerP)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelectionListenerP)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResizeEventListenerP)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(objectResizeEventListeners)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObjectResizeEventListeners)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAbsolutelyPositionedObject)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGrabber)
|
||||
@ -2988,8 +2988,6 @@ nsHTMLEditor::GetURLForStyleSheet(CSSStyleSheet* aStyleSheet,
|
||||
int32_t foundIndex = mStyleSheets.IndexOf(aStyleSheet);
|
||||
|
||||
// Don't fail if we don't find it in our list
|
||||
// Note: mStyleSheets is nsCOMArray, so its IndexOf() method
|
||||
// returns -1 on failure.
|
||||
if (foundIndex == -1)
|
||||
return NS_OK;
|
||||
|
||||
@ -4503,196 +4501,156 @@ nsHTMLEditor::SetIsCSSEnabled(bool aIsCSSPrefChecked)
|
||||
nsresult
|
||||
nsHTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
|
||||
{
|
||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
||||
NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
|
||||
ForceCompositionEnd();
|
||||
|
||||
// Protect the edit rules object from dying
|
||||
nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
|
||||
|
||||
nsRefPtr<Selection> selection = GetSelection();
|
||||
NS_ENSURE_STATE(selection);
|
||||
|
||||
bool isCollapsed = selection->Collapsed();
|
||||
|
||||
nsAutoEditBatch batchIt(this);
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::insertElement, nsIEditor::eNext);
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::insertElement,
|
||||
nsIEditor::eNext);
|
||||
nsAutoSelectionReset selectionResetter(selection, this);
|
||||
nsAutoTxnsConserveSelection dontSpazMySelection(this);
|
||||
|
||||
|
||||
bool cancel, handled;
|
||||
nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
|
||||
nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (!cancel && !handled)
|
||||
{
|
||||
// loop thru the ranges in the selection
|
||||
nsAutoString bgcolor; bgcolor.AssignLiteral("bgcolor");
|
||||
uint32_t rangeCount = selection->RangeCount();
|
||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
|
||||
nsCOMPtr<nsIDOMNode> cachedBlockParent = nullptr;
|
||||
nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
|
||||
if (!cancel && !handled) {
|
||||
// Loop through the ranges in the selection
|
||||
NS_NAMED_LITERAL_STRING(bgcolor, "bgcolor");
|
||||
for (uint32_t i = 0; i < selection->RangeCount(); i++) {
|
||||
nsRefPtr<nsRange> range = selection->GetRangeAt(i);
|
||||
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
|
||||
|
||||
// check for easy case: both range endpoints in same text node
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
||||
int32_t startOffset, endOffset;
|
||||
res = range->GetStartContainer(getter_AddRefs(startNode));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = range->GetEndContainer(getter_AddRefs(endNode));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = range->GetStartOffset(&startOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = range->GetEndOffset(&endOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if ((startNode == endNode) && IsTextNode(startNode))
|
||||
{
|
||||
// let's find the block container of the text node
|
||||
nsCOMPtr<nsIDOMNode> blockParent;
|
||||
blockParent = GetBlockNodeParent(startNode);
|
||||
// and apply the background color to that block container
|
||||
|
||||
nsCOMPtr<Element> cachedBlockParent;
|
||||
|
||||
// Check for easy case: both range endpoints in same text node
|
||||
nsCOMPtr<nsINode> startNode = range->GetStartParent();
|
||||
int32_t startOffset = range->StartOffset();
|
||||
nsCOMPtr<nsINode> endNode = range->GetEndParent();
|
||||
int32_t endOffset = range->EndOffset();
|
||||
if (startNode == endNode && IsTextNode(startNode)) {
|
||||
// Let's find the block container of the text node
|
||||
nsCOMPtr<Element> blockParent = GetBlockNodeParent(startNode);
|
||||
// And apply the background color to that block container
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
||||
int32_t count;
|
||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor, false);
|
||||
}
|
||||
}
|
||||
else if ((startNode == endNode) && nsTextEditUtils::IsBody(startNode) && isCollapsed)
|
||||
{
|
||||
// we have no block in the document, let's apply the background to the body
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(startNode);
|
||||
int32_t count;
|
||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
else if ((startNode == endNode) && (((endOffset-startOffset) == 1) || (!startOffset && !endOffset)))
|
||||
{
|
||||
// a unique node is selected, let's also apply the background color
|
||||
// to the containing block, possibly the node itself
|
||||
nsCOMPtr<nsIDOMNode> selectedNode = GetChildAt(startNode, startOffset);
|
||||
bool isBlock =false;
|
||||
res = NodeIsBlockStatic(selectedNode, &isBlock);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
nsCOMPtr<nsIDOMNode> blockParent = selectedNode;
|
||||
if (!isBlock) {
|
||||
} else if (startNode == endNode &&
|
||||
startNode->IsHTMLElement(nsGkAtoms::body) && isCollapsed) {
|
||||
// No block in the document, let's apply the background to the body
|
||||
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(startNode->AsElement(),
|
||||
nullptr, &bgcolor, &aColor,
|
||||
false);
|
||||
} else if (startNode == endNode && (endOffset - startOffset == 1 ||
|
||||
(!startOffset && !endOffset))) {
|
||||
// A unique node is selected, let's also apply the background color to
|
||||
// the containing block, possibly the node itself
|
||||
nsCOMPtr<nsIContent> selectedNode = startNode->GetChildAt(startOffset);
|
||||
nsCOMPtr<Element> blockParent;
|
||||
if (NodeIsBlockStatic(selectedNode)) {
|
||||
blockParent = selectedNode->AsElement();
|
||||
} else {
|
||||
blockParent = GetBlockNodeParent(selectedNode);
|
||||
}
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
||||
int32_t count;
|
||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not the easy case. range not contained in single text node.
|
||||
// there are up to three phases here. There are all the nodes
|
||||
// reported by the subtree iterator to be processed. And there
|
||||
// are potentially a starting textnode and an ending textnode
|
||||
// which are only partially contained by the range.
|
||||
|
||||
// lets handle the nodes reported by the iterator. These nodes
|
||||
// are entirely contained in the selection range. We build up
|
||||
// a list of them (since doing operations on the document during
|
||||
// iteration would perturb the iterator).
|
||||
} else {
|
||||
// Not the easy case. Range not contained in single text node. There
|
||||
// are up to three phases here. There are all the nodes reported by
|
||||
// the subtree iterator to be processed. And there are potentially a
|
||||
// starting textnode and an ending textnode which are only partially
|
||||
// contained by the range.
|
||||
|
||||
nsCOMPtr<nsIContentIterator> iter =
|
||||
do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE);
|
||||
// Let's handle the nodes reported by the iterator. These nodes are
|
||||
// entirely contained in the selection range. We build up a list of
|
||||
// them (since doing operations on the document during iteration would
|
||||
// perturb the iterator).
|
||||
|
||||
nsCOMArray<nsIDOMNode> arrayOfNodes;
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
|
||||
// iterate range and build up array
|
||||
OwningNonNull<nsIContentIterator> iter =
|
||||
NS_NewContentSubtreeIterator();
|
||||
|
||||
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
|
||||
nsCOMPtr<nsINode> node;
|
||||
|
||||
// Iterate range and build up array
|
||||
res = iter->Init(range);
|
||||
// init returns an error if no nodes in range.
|
||||
// this can easily happen with the subtree
|
||||
// iterator if the selection doesn't contain
|
||||
// any *whole* nodes.
|
||||
if (NS_SUCCEEDED(res))
|
||||
{
|
||||
while (!iter->IsDone())
|
||||
{
|
||||
// Init returns an error if no nodes in range. This can easily happen
|
||||
// with the subtree iterator if the selection doesn't contain any
|
||||
// *whole* nodes.
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
for (; !iter->IsDone(); iter->Next()) {
|
||||
node = do_QueryInterface(iter->GetCurrentNode());
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
|
||||
if (IsEditable(node))
|
||||
{
|
||||
arrayOfNodes.AppendObject(node);
|
||||
if (IsEditable(node)) {
|
||||
arrayOfNodes.AppendElement(*node);
|
||||
}
|
||||
|
||||
iter->Next();
|
||||
}
|
||||
}
|
||||
// first check the start parent of the range to see if it needs to
|
||||
// be separately handled (it does if it's a text node, due to how the
|
||||
// First check the start parent of the range to see if it needs to be
|
||||
// separately handled (it does if it's a text node, due to how the
|
||||
// subtree iterator works - it will not have reported it).
|
||||
if (IsTextNode(startNode) && IsEditable(startNode))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> blockParent;
|
||||
blockParent = GetBlockNodeParent(startNode);
|
||||
if (IsTextNode(startNode) && IsEditable(startNode)) {
|
||||
nsCOMPtr<Element> blockParent = GetBlockNodeParent(startNode);
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
||||
int32_t count;
|
||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
// then loop through the list, set the property on each node
|
||||
int32_t listCount = arrayOfNodes.Count();
|
||||
int32_t j;
|
||||
for (j = 0; j < listCount; j++)
|
||||
{
|
||||
node = arrayOfNodes[j];
|
||||
// do we have a block here ?
|
||||
bool isBlock =false;
|
||||
res = NodeIsBlockStatic(node, &isBlock);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
nsCOMPtr<nsIDOMNode> blockParent = node;
|
||||
if (!isBlock) {
|
||||
// no we don't, let's find the block ancestor
|
||||
|
||||
// Then loop through the list, set the property on each node
|
||||
for (auto& node : arrayOfNodes) {
|
||||
nsCOMPtr<Element> blockParent;
|
||||
if (NodeIsBlockStatic(node)) {
|
||||
blockParent = node->AsElement();
|
||||
} else {
|
||||
blockParent = GetBlockNodeParent(node);
|
||||
}
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
||||
int32_t count;
|
||||
// and set the property on it
|
||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor,
|
||||
false);
|
||||
}
|
||||
}
|
||||
arrayOfNodes.Clear();
|
||||
|
||||
// last check the end parent of the range to see if it needs to
|
||||
// be separately handled (it does if it's a text node, due to how the
|
||||
|
||||
// Last, check the end parent of the range to see if it needs to be
|
||||
// separately handled (it does if it's a text node, due to how the
|
||||
// subtree iterator works - it will not have reported it).
|
||||
if (IsTextNode(endNode) && IsEditable(endNode))
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> blockParent;
|
||||
blockParent = GetBlockNodeParent(endNode);
|
||||
if (IsTextNode(endNode) && IsEditable(endNode)) {
|
||||
nsCOMPtr<Element> blockParent = GetBlockNodeParent(endNode);
|
||||
if (blockParent && cachedBlockParent != blockParent) {
|
||||
cachedBlockParent = blockParent;
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
||||
int32_t count;
|
||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||
&bgcolor, &aColor,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cancel)
|
||||
{
|
||||
// post-process
|
||||
if (!cancel) {
|
||||
// Post-process
|
||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
return res;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -7,7 +7,6 @@
|
||||
#define nsHTMLEditor_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsPlaintextEditor.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
@ -41,6 +40,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
class nsDocumentFragment;
|
||||
class nsIDOMKeyEvent;
|
||||
class nsITransferable;
|
||||
class nsIClipboard;
|
||||
@ -53,6 +53,9 @@ class nsRange;
|
||||
struct PropItem;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
template<class T> class OwningNonNull;
|
||||
}
|
||||
namespace widget {
|
||||
struct IMEState;
|
||||
} // namespace widget
|
||||
@ -591,29 +594,27 @@ protected:
|
||||
nsIDocument* aTargetDoc,
|
||||
nsCOMPtr<nsIDOMNode> *outNode,
|
||||
bool aTrustedInput);
|
||||
nsresult CreateListOfNodesToPaste(nsIDOMNode *aFragmentAsNode,
|
||||
nsCOMArray<nsIDOMNode>& outNodeList,
|
||||
nsIDOMNode *aStartNode,
|
||||
void CreateListOfNodesToPaste(mozilla::dom::DocumentFragment& aFragment,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& outNodeList,
|
||||
nsINode* aStartNode,
|
||||
int32_t aStartOffset,
|
||||
nsIDOMNode *aEndNode,
|
||||
nsINode* aEndNode,
|
||||
int32_t aEndOffset);
|
||||
nsresult CreateTagStack(nsTArray<nsString> &aTagStack,
|
||||
nsIDOMNode *aNode);
|
||||
nsresult GetListAndTableParents( bool aEnd,
|
||||
nsCOMArray<nsIDOMNode>& aListOfNodes,
|
||||
nsCOMArray<nsIDOMNode>& outArray);
|
||||
nsresult DiscoverPartialListsAndTables(nsCOMArray<nsIDOMNode>& aPasteNodes,
|
||||
nsCOMArray<nsIDOMNode>& aListsAndTables,
|
||||
int32_t *outHighWaterMark);
|
||||
nsresult ScanForListAndTableStructure(bool aEnd,
|
||||
nsCOMArray<nsIDOMNode>& aNodes,
|
||||
nsIDOMNode *aListOrTable,
|
||||
nsCOMPtr<nsIDOMNode> *outReplaceNode);
|
||||
nsresult ReplaceOrphanedStructure( bool aEnd,
|
||||
nsCOMArray<nsIDOMNode>& aNodeArray,
|
||||
nsCOMArray<nsIDOMNode>& aListAndTableArray,
|
||||
int32_t aHighWaterMark);
|
||||
nsIDOMNode* GetArrayEndpoint(bool aEnd, nsCOMArray<nsIDOMNode>& aNodeArray);
|
||||
enum class StartOrEnd { start, end };
|
||||
void GetListAndTableParents(StartOrEnd aStartOrEnd,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aNodeList,
|
||||
nsTArray<mozilla::dom::OwningNonNull<mozilla::dom::Element>>& outArray);
|
||||
int32_t DiscoverPartialListsAndTables(nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aPasteNodes,
|
||||
nsTArray<mozilla::dom::OwningNonNull<mozilla::dom::Element>>& aListsAndTables);
|
||||
nsINode* ScanForListAndTableStructure(StartOrEnd aStartOrEnd,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aNodes,
|
||||
mozilla::dom::Element& aListOrTable);
|
||||
void ReplaceOrphanedStructure(StartOrEnd aStartOrEnd,
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsINode>>& aNodeArray,
|
||||
nsTArray<mozilla::dom::OwningNonNull<mozilla::dom::Element>>& aListAndTableArray,
|
||||
int32_t aHighWaterMark);
|
||||
|
||||
/* small utility routine to test if a break node is visible to user */
|
||||
bool IsVisBreak(nsINode* aNode);
|
||||
@ -633,7 +634,8 @@ protected:
|
||||
nsresult InsertBasicBlock(const nsAString & aBlockType);
|
||||
|
||||
/* increase/decrease the font size of selection */
|
||||
nsresult RelativeFontChange( int32_t aSizeChange);
|
||||
enum class FontSize { incr, decr };
|
||||
nsresult RelativeFontChange(FontSize aDir);
|
||||
|
||||
/* helper routines for font size changing */
|
||||
nsresult RelativeFontChangeOnTextNode( int32_t aSizeChange,
|
||||
@ -650,14 +652,10 @@ protected:
|
||||
nsIAtom& aProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString& aValue);
|
||||
nsresult SetInlinePropertyOnNode( nsIDOMNode *aNode,
|
||||
nsIAtom *aProperty,
|
||||
const nsAString *aAttribute,
|
||||
const nsAString *aValue);
|
||||
nsresult SetInlinePropertyOnNode(nsIContent* aNode,
|
||||
nsIAtom* aProperty,
|
||||
nsresult SetInlinePropertyOnNode(nsIContent& aNode,
|
||||
nsIAtom& aProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue);
|
||||
const nsAString& aValue);
|
||||
|
||||
nsresult PromoteInlineRange(nsRange* aRange);
|
||||
nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsRange* aRange);
|
||||
@ -758,7 +756,7 @@ protected:
|
||||
// Data members
|
||||
protected:
|
||||
|
||||
nsCOMArray<nsIContentFilter> mContentFilters;
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsIContentFilter>> mContentFilters;
|
||||
|
||||
nsRefPtr<TypeInState> mTypeInState;
|
||||
|
||||
@ -848,7 +846,7 @@ protected:
|
||||
nsCOMPtr<nsISelectionListener> mSelectionListenerP;
|
||||
nsCOMPtr<nsIDOMEventListener> mResizeEventListenerP;
|
||||
|
||||
nsCOMArray<nsIHTMLObjectResizeListener> objectResizeEventListeners;
|
||||
nsTArray<mozilla::dom::OwningNonNull<nsIHTMLObjectResizeListener>> mObjectResizeEventListeners;
|
||||
|
||||
int32_t mOriginalX;
|
||||
int32_t mOriginalY;
|
||||
@ -959,10 +957,10 @@ private:
|
||||
nsIAtom* aProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue);
|
||||
nsresult SetInlinePropertyOnNodeImpl(nsIContent* aNode,
|
||||
nsIAtom* aProperty,
|
||||
nsresult SetInlinePropertyOnNodeImpl(nsIContent& aNode,
|
||||
nsIAtom& aProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue);
|
||||
const nsAString& aValue);
|
||||
typedef enum { eInserted, eAppended } InsertedOrAppended;
|
||||
void DoContentInserted(nsIDocument* aDocument, nsIContent* aContainer,
|
||||
nsIContent* aChild, int32_t aIndexInContainer,
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "nsAString.h"
|
||||
#include "nsAttrName.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCaseTreatment.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
@ -109,23 +108,20 @@ NS_IMETHODIMP nsHTMLEditor::RemoveAllDefaultProperties()
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
|
||||
nsHTMLEditor::SetInlineProperty(nsIAtom* aProperty,
|
||||
const nsAString& aAttribute,
|
||||
const nsAString& aValue)
|
||||
{
|
||||
if (!aProperty) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (!mRules) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
NS_ENSURE_TRUE(aProperty, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
|
||||
nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
|
||||
ForceCompositionEnd();
|
||||
|
||||
nsRefPtr<Selection> selection = GetSelection();
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (selection->Collapsed()) {
|
||||
// manipulating text attributes on a collapsed selection only sets state
|
||||
// Manipulating text attributes on a collapsed selection only sets state
|
||||
// for the next text insertion
|
||||
mTypeInState->SetProp(aProperty, aAttribute, aValue);
|
||||
return NS_OK;
|
||||
@ -139,21 +135,20 @@ nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
|
||||
bool cancel, handled;
|
||||
nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
|
||||
// Protect the edit rules object from dying
|
||||
nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
|
||||
nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (!cancel && !handled) {
|
||||
// loop thru the ranges in the selection
|
||||
// Loop through the ranges in the selection
|
||||
uint32_t rangeCount = selection->RangeCount();
|
||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
|
||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; rangeIdx++) {
|
||||
nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
|
||||
|
||||
// adjust range to include any ancestors whose children are entirely
|
||||
// Adjust range to include any ancestors whose children are entirely
|
||||
// selected
|
||||
res = PromoteInlineRange(range);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// check for easy case: both range endpoints in same text node
|
||||
// Check for easy case: both range endpoints in same text node
|
||||
nsCOMPtr<nsINode> startNode = range->GetStartParent();
|
||||
nsCOMPtr<nsINode> endNode = range->GetEndParent();
|
||||
if (startNode && startNode == endNode && startNode->GetAsText()) {
|
||||
@ -176,31 +171,26 @@ nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
|
||||
// (since doing operations on the document during iteration would perturb
|
||||
// the iterator).
|
||||
|
||||
nsCOMPtr<nsIContentIterator> iter =
|
||||
do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE);
|
||||
OwningNonNull<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
|
||||
|
||||
nsCOMArray<nsIDOMNode> arrayOfNodes;
|
||||
nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
|
||||
|
||||
// iterate range and build up array
|
||||
// Iterate range and build up array
|
||||
res = iter->Init(range);
|
||||
// Init returns an error if there are no nodes in range. This can easily
|
||||
// happen with the subtree iterator if the selection doesn't contain any
|
||||
// *whole* nodes.
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
for (; !iter->IsDone(); iter->Next()) {
|
||||
node = do_QueryInterface(iter->GetCurrentNode());
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||
OwningNonNull<nsINode> node = *iter->GetCurrentNode();
|
||||
|
||||
if (IsEditable(node)) {
|
||||
arrayOfNodes.AppendObject(node);
|
||||
if (node->IsContent() && IsEditable(node)) {
|
||||
arrayOfNodes.AppendElement(*node->AsContent());
|
||||
}
|
||||
}
|
||||
}
|
||||
// first check the start parent of the range to see if it needs to
|
||||
// be separately handled (it does if it's a text node, due to how the
|
||||
// First check the start parent of the range to see if it needs to be
|
||||
// separately handled (it does if it's a text node, due to how the
|
||||
// subtree iterator works - it will not have reported it).
|
||||
if (startNode && startNode->GetAsText() && IsEditable(startNode)) {
|
||||
res = SetInlinePropertyOnTextNode(*startNode->GetAsText(),
|
||||
@ -210,17 +200,14 @@ nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
|
||||
// then loop through the list, set the property on each node
|
||||
int32_t listCount = arrayOfNodes.Count();
|
||||
int32_t j;
|
||||
for (j = 0; j < listCount; j++) {
|
||||
res = SetInlinePropertyOnNode(arrayOfNodes[j], aProperty,
|
||||
&aAttribute, &aValue);
|
||||
// Then loop through the list, set the property on each node
|
||||
for (auto& node : arrayOfNodes) {
|
||||
res = SetInlinePropertyOnNode(*node, *aProperty, &aAttribute, aValue);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
|
||||
// last check the end parent of the range to see if it needs to
|
||||
// be separately handled (it does if it's a text node, due to how the
|
||||
// Last check the end parent of the range to see if it needs to be
|
||||
// separately handled (it does if it's a text node, due to how the
|
||||
// subtree iterator works - it will not have reported it).
|
||||
if (endNode && endNode->GetAsText() && IsEditable(endNode)) {
|
||||
res = SetInlinePropertyOnTextNode(*endNode->GetAsText(), 0,
|
||||
@ -231,7 +218,7 @@ nsHTMLEditor::SetInlineProperty(nsIAtom *aProperty,
|
||||
}
|
||||
}
|
||||
if (!cancel) {
|
||||
// post-process
|
||||
// Post-process
|
||||
return mRules->DidDoAction(selection, &ruleInfo, res);
|
||||
}
|
||||
return NS_OK;
|
||||
@ -376,41 +363,37 @@ nsHTMLEditor::SetInlinePropertyOnTextNode(Text& aText,
|
||||
}
|
||||
|
||||
// Reparent the node inside inline node with appropriate {attribute,value}
|
||||
return SetInlinePropertyOnNode(text, &aProperty, aAttribute, &aValue);
|
||||
return SetInlinePropertyOnNode(*text, aProperty, aAttribute, aValue);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode,
|
||||
nsIAtom* aProperty,
|
||||
nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent& aNode,
|
||||
nsIAtom& aProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue)
|
||||
const nsAString& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aNode && aProperty);
|
||||
MOZ_ASSERT(aValue);
|
||||
|
||||
nsCOMPtr<nsIAtom> attrAtom = aAttribute ? do_GetAtom(*aAttribute) : nullptr;
|
||||
|
||||
// If this is an element that can't be contained in a span, we have to
|
||||
// recurse to its children.
|
||||
if (!TagCanContain(*nsGkAtoms::span, *aNode)) {
|
||||
if (aNode->HasChildren()) {
|
||||
nsCOMArray<nsIContent> arrayOfNodes;
|
||||
if (!TagCanContain(*nsGkAtoms::span, aNode)) {
|
||||
if (aNode.HasChildren()) {
|
||||
nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
|
||||
|
||||
// Populate the list.
|
||||
for (nsIContent* child = aNode->GetFirstChild();
|
||||
for (nsCOMPtr<nsIContent> child = aNode.GetFirstChild();
|
||||
child;
|
||||
child = child->GetNextSibling()) {
|
||||
if (IsEditable(child) && !IsEmptyTextNode(this, child)) {
|
||||
arrayOfNodes.AppendObject(child);
|
||||
arrayOfNodes.AppendElement(*child);
|
||||
}
|
||||
}
|
||||
|
||||
// Then loop through the list, set the property on each node.
|
||||
int32_t listCount = arrayOfNodes.Count();
|
||||
for (int32_t j = 0; j < listCount; ++j) {
|
||||
nsresult rv = SetInlinePropertyOnNode(arrayOfNodes[j], aProperty,
|
||||
aAttribute, aValue);
|
||||
for (auto& node : arrayOfNodes) {
|
||||
nsresult rv = SetInlinePropertyOnNode(node, aProperty, aAttribute,
|
||||
aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
@ -419,36 +402,36 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode,
|
||||
|
||||
// First check if there's an adjacent sibling we can put our node into.
|
||||
nsresult res;
|
||||
nsCOMPtr<nsIContent> previousSibling = GetPriorHTMLSibling(aNode);
|
||||
nsCOMPtr<nsIContent> nextSibling = GetNextHTMLSibling(aNode);
|
||||
if (IsSimpleModifiableNode(previousSibling, aProperty, aAttribute, aValue)) {
|
||||
res = MoveNode(aNode, previousSibling, -1);
|
||||
nsCOMPtr<nsIContent> previousSibling = GetPriorHTMLSibling(&aNode);
|
||||
nsCOMPtr<nsIContent> nextSibling = GetNextHTMLSibling(&aNode);
|
||||
if (IsSimpleModifiableNode(previousSibling, &aProperty, aAttribute, &aValue)) {
|
||||
res = MoveNode(&aNode, previousSibling, -1);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (IsSimpleModifiableNode(nextSibling, aProperty, aAttribute, aValue)) {
|
||||
if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) {
|
||||
res = JoinNodes(*previousSibling, *nextSibling);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
if (IsSimpleModifiableNode(nextSibling, aProperty, aAttribute, aValue)) {
|
||||
res = MoveNode(aNode, nextSibling, 0);
|
||||
if (IsSimpleModifiableNode(nextSibling, &aProperty, aAttribute, &aValue)) {
|
||||
res = MoveNode(&aNode, nextSibling, 0);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// don't need to do anything if property already set on node
|
||||
if (mHTMLCSSUtils->IsCSSEditableProperty(aNode, aProperty, aAttribute)) {
|
||||
// Don't need to do anything if property already set on node
|
||||
if (mHTMLCSSUtils->IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) {
|
||||
if (mHTMLCSSUtils->IsCSSEquivalentToHTMLInlineStyleSet(
|
||||
aNode, aProperty, aAttribute, *aValue, nsHTMLCSSUtils::eComputed)) {
|
||||
&aNode, &aProperty, aAttribute, aValue, nsHTMLCSSUtils::eComputed)) {
|
||||
return NS_OK;
|
||||
}
|
||||
} else if (IsTextPropertySetByContent(aNode, aProperty,
|
||||
aAttribute, aValue)) {
|
||||
} else if (IsTextPropertySetByContent(&aNode, &aProperty,
|
||||
aAttribute, &aValue)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool useCSS = (IsCSSEnabled() &&
|
||||
mHTMLCSSUtils->IsCSSEditableProperty(aNode, aProperty, aAttribute)) ||
|
||||
mHTMLCSSUtils->IsCSSEditableProperty(&aNode, &aProperty, aAttribute)) ||
|
||||
// bgcolor is always done using CSS
|
||||
aAttribute->EqualsLiteral("bgcolor");
|
||||
|
||||
@ -456,33 +439,33 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode,
|
||||
nsCOMPtr<dom::Element> tmp;
|
||||
// We only add style="" to <span>s with no attributes (bug 746515). If we
|
||||
// don't have one, we need to make one.
|
||||
if (aNode->IsHTMLElement(nsGkAtoms::span) &&
|
||||
!aNode->AsElement()->GetAttrCount()) {
|
||||
tmp = aNode->AsElement();
|
||||
if (aNode.IsHTMLElement(nsGkAtoms::span) &&
|
||||
!aNode.AsElement()->GetAttrCount()) {
|
||||
tmp = aNode.AsElement();
|
||||
} else {
|
||||
tmp = InsertContainerAbove(aNode, nsGkAtoms::span);
|
||||
tmp = InsertContainerAbove(&aNode, nsGkAtoms::span);
|
||||
NS_ENSURE_STATE(tmp);
|
||||
}
|
||||
|
||||
// Add the CSS styles corresponding to the HTML style request
|
||||
int32_t count;
|
||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(tmp->AsDOMNode(),
|
||||
aProperty, aAttribute,
|
||||
aValue, &count, false);
|
||||
&aProperty, aAttribute,
|
||||
&aValue, &count, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// is it already the right kind of node, but with wrong attribute?
|
||||
if (aNode->IsHTMLElement(aProperty)) {
|
||||
if (aNode.IsHTMLElement(&aProperty)) {
|
||||
// Just set the attribute on it.
|
||||
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(aNode);
|
||||
return SetAttribute(elem, *aAttribute, *aValue);
|
||||
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(&aNode);
|
||||
return SetAttribute(elem, *aAttribute, aValue);
|
||||
}
|
||||
|
||||
// ok, chuck it in its very own container
|
||||
nsCOMPtr<Element> tmp = InsertContainerAbove(aNode, aProperty, attrAtom,
|
||||
aValue);
|
||||
nsCOMPtr<Element> tmp = InsertContainerAbove(&aNode, &aProperty, attrAtom,
|
||||
&aValue);
|
||||
NS_ENSURE_STATE(tmp);
|
||||
|
||||
return NS_OK;
|
||||
@ -490,42 +473,20 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode,
|
||||
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::SetInlinePropertyOnNode(nsIDOMNode *aNode,
|
||||
nsIAtom *aProperty,
|
||||
const nsAString *aAttribute,
|
||||
const nsAString *aValue)
|
||||
{
|
||||
// Before setting the property, we remove it if it's already set.
|
||||
// RemoveStyleInside might remove the node we're looking at or some of its
|
||||
// descendants, however, in which case we want to set the property on
|
||||
// whatever wound up in its place. We have to save the original siblings and
|
||||
// parent to figure this out.
|
||||
NS_ENSURE_TRUE(aNode && aProperty, NS_ERROR_NULL_POINTER);
|
||||
|
||||
nsCOMPtr<nsIContent> node = do_QueryInterface(aNode);
|
||||
NS_ENSURE_STATE(node);
|
||||
|
||||
return SetInlinePropertyOnNode(node, aProperty, aAttribute, aValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::SetInlinePropertyOnNode(nsIContent* aNode,
|
||||
nsIAtom* aProperty,
|
||||
nsHTMLEditor::SetInlinePropertyOnNode(nsIContent& aNode,
|
||||
nsIAtom& aProperty,
|
||||
const nsAString* aAttribute,
|
||||
const nsAString* aValue)
|
||||
const nsAString& aValue)
|
||||
{
|
||||
MOZ_ASSERT(aNode);
|
||||
MOZ_ASSERT(aProperty);
|
||||
nsCOMPtr<nsIContent> previousSibling = aNode.GetPreviousSibling(),
|
||||
nextSibling = aNode.GetNextSibling();
|
||||
NS_ENSURE_STATE(aNode.GetParentNode());
|
||||
OwningNonNull<nsINode> parent = *aNode.GetParentNode();
|
||||
|
||||
nsCOMPtr<nsIContent> previousSibling = aNode->GetPreviousSibling(),
|
||||
nextSibling = aNode->GetNextSibling();
|
||||
nsCOMPtr<nsINode> parent = aNode->GetParentNode();
|
||||
NS_ENSURE_STATE(parent);
|
||||
|
||||
nsresult res = RemoveStyleInside(aNode->AsDOMNode(), aProperty, aAttribute);
|
||||
nsresult res = RemoveStyleInside(aNode.AsDOMNode(), &aProperty, aAttribute);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
if (aNode->GetParentNode()) {
|
||||
if (aNode.GetParentNode()) {
|
||||
// The node is still where it was
|
||||
return SetInlinePropertyOnNodeImpl(aNode, aProperty,
|
||||
aAttribute, aValue);
|
||||
@ -538,20 +499,17 @@ nsHTMLEditor::SetInlinePropertyOnNode(nsIContent* aNode,
|
||||
(nextSibling && nextSibling->GetParentNode() != parent)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
nsCOMArray<nsIContent> nodesToSet;
|
||||
nsTArray<OwningNonNull<nsIContent>> nodesToSet;
|
||||
nsCOMPtr<nsIContent> cur = previousSibling
|
||||
? previousSibling->GetNextSibling() : parent->GetFirstChild();
|
||||
while (cur && cur != nextSibling) {
|
||||
for (; cur && cur != nextSibling; cur = cur->GetNextSibling()) {
|
||||
if (IsEditable(cur)) {
|
||||
nodesToSet.AppendObject(cur);
|
||||
nodesToSet.AppendElement(*cur);
|
||||
}
|
||||
cur = cur->GetNextSibling();
|
||||
}
|
||||
|
||||
int32_t nodesToSetCount = nodesToSet.Count();
|
||||
for (int32_t k = 0; k < nodesToSetCount; k++) {
|
||||
res = SetInlinePropertyOnNodeImpl(nodesToSet[k], aProperty,
|
||||
aAttribute, aValue);
|
||||
for (auto& node : nodesToSet) {
|
||||
res = SetInlinePropertyOnNodeImpl(node, aProperty, aAttribute, aValue);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
|
||||
@ -1416,8 +1374,8 @@ nsHTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty,
|
||||
// "inverting" the style
|
||||
mHTMLCSSUtils->IsCSSInvertible(*aProperty, aAttribute)) {
|
||||
NS_NAMED_LITERAL_STRING(value, "-moz-editor-invert-value");
|
||||
SetInlinePropertyOnNode(node->AsContent(), aProperty,
|
||||
aAttribute, &value);
|
||||
SetInlinePropertyOnNode(*node->AsContent(), *aProperty,
|
||||
aAttribute, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1433,150 +1391,126 @@ nsHTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty,
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::IncreaseFontSize()
|
||||
{
|
||||
return RelativeFontChange(1);
|
||||
return RelativeFontChange(FontSize::incr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::DecreaseFontSize()
|
||||
{
|
||||
return RelativeFontChange(-1);
|
||||
return RelativeFontChange(FontSize::decr);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLEditor::RelativeFontChange( int32_t aSizeChange)
|
||||
nsHTMLEditor::RelativeFontChange(FontSize aDir)
|
||||
{
|
||||
// Can only change font size by + or - 1
|
||||
if ( !( (aSizeChange==1) || (aSizeChange==-1) ) )
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
ForceCompositionEnd();
|
||||
|
||||
// Get the selection
|
||||
// Get the selection
|
||||
nsRefPtr<Selection> selection = GetSelection();
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
||||
// Is the selection collapsed?
|
||||
// if it's collapsed set typing state
|
||||
// If selection is collapsed, set typing state
|
||||
if (selection->Collapsed()) {
|
||||
nsCOMPtr<nsIAtom> atom;
|
||||
if (aSizeChange == 1) {
|
||||
atom = nsGkAtoms::big;
|
||||
} else {
|
||||
atom = nsGkAtoms::small;
|
||||
}
|
||||
nsIAtom& atom = aDir == FontSize::incr ? *nsGkAtoms::big :
|
||||
*nsGkAtoms::small;
|
||||
|
||||
// Let's see in what kind of element the selection is
|
||||
int32_t offset;
|
||||
nsCOMPtr<nsINode> selectedNode;
|
||||
GetStartNodeAndOffset(selection, getter_AddRefs(selectedNode), &offset);
|
||||
if (selectedNode && IsTextNode(selectedNode)) {
|
||||
selectedNode = selectedNode->GetParentNode();
|
||||
NS_ENSURE_TRUE(selection->RangeCount() &&
|
||||
selection->GetRangeAt(0)->GetStartParent(), NS_OK);
|
||||
OwningNonNull<nsINode> selectedNode =
|
||||
*selection->GetRangeAt(0)->GetStartParent();
|
||||
if (IsTextNode(selectedNode)) {
|
||||
NS_ENSURE_TRUE(selectedNode->GetParentNode(), NS_OK);
|
||||
selectedNode = *selectedNode->GetParentNode();
|
||||
}
|
||||
NS_ENSURE_TRUE(selectedNode, NS_OK);
|
||||
if (!CanContainTag(*selectedNode, *atom)) {
|
||||
if (!CanContainTag(selectedNode, atom)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// manipulating text attributes on a collapsed selection only sets state for the next text insertion
|
||||
mTypeInState->SetProp(atom, EmptyString(), EmptyString());
|
||||
// Manipulating text attributes on a collapsed selection only sets state
|
||||
// for the next text insertion
|
||||
mTypeInState->SetProp(&atom, EmptyString(), EmptyString());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// wrap with txn batching, rules sniffing, and selection preservation code
|
||||
|
||||
// Wrap with txn batching, rules sniffing, and selection preservation code
|
||||
nsAutoEditBatch batchIt(this);
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::setTextProperty, nsIEditor::eNext);
|
||||
nsAutoRules beginRulesSniffing(this, EditAction::setTextProperty,
|
||||
nsIEditor::eNext);
|
||||
nsAutoSelectionReset selectionResetter(selection, this);
|
||||
nsAutoTxnsConserveSelection dontSpazMySelection(this);
|
||||
|
||||
// loop thru the ranges in the selection
|
||||
// Loop through the ranges in the selection
|
||||
uint32_t rangeCount = selection->RangeCount();
|
||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
|
||||
nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
|
||||
|
||||
// adjust range to include any ancestors who's children are entirely selected
|
||||
// Adjust range to include any ancestors with entirely selected children
|
||||
nsresult res = PromoteInlineRange(range);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// check for easy case: both range endpoints in same text node
|
||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
||||
res = range->GetStartContainer(getter_AddRefs(startNode));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = range->GetEndContainer(getter_AddRefs(endNode));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if ((startNode == endNode) && IsTextNode(startNode))
|
||||
{
|
||||
int32_t startOffset, endOffset;
|
||||
range->GetStartOffset(&startOffset);
|
||||
range->GetEndOffset(&endOffset);
|
||||
nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(startNode);
|
||||
res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, startOffset, endOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
else
|
||||
{
|
||||
// not the easy case. range not contained in single text node.
|
||||
// there are up to three phases here. There are all the nodes
|
||||
// reported by the subtree iterator to be processed. And there
|
||||
// are potentially a starting textnode and an ending textnode
|
||||
// which are only partially contained by the range.
|
||||
|
||||
// lets handle the nodes reported by the iterator. These nodes
|
||||
// are entirely contained in the selection range. We build up
|
||||
// a list of them (since doing operations on the document during
|
||||
// iteration would perturb the iterator).
|
||||
|
||||
nsCOMPtr<nsIContentIterator> iter =
|
||||
do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
|
||||
// Check for easy case: both range endpoints in same text node
|
||||
nsCOMPtr<nsINode> startNode = range->GetStartParent();
|
||||
nsCOMPtr<nsINode> endNode = range->GetEndParent();
|
||||
if (startNode == endNode && IsTextNode(startNode)) {
|
||||
res = RelativeFontChangeOnTextNode(aDir == FontSize::incr ? +1 : -1,
|
||||
static_cast<nsIDOMCharacterData*>(startNode->AsDOMNode()),
|
||||
range->StartOffset(), range->EndOffset());
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE);
|
||||
} else {
|
||||
// Not the easy case. Range not contained in single text node. There
|
||||
// are up to three phases here. There are all the nodes reported by the
|
||||
// subtree iterator to be processed. And there are potentially a
|
||||
// starting textnode and an ending textnode which are only partially
|
||||
// contained by the range.
|
||||
|
||||
// iterate range and build up array
|
||||
// Let's handle the nodes reported by the iterator. These nodes are
|
||||
// entirely contained in the selection range. We build up a list of them
|
||||
// (since doing operations on the document during iteration would perturb
|
||||
// the iterator).
|
||||
|
||||
OwningNonNull<nsIContentIterator> iter = NS_NewContentSubtreeIterator();
|
||||
|
||||
// Iterate range and build up array
|
||||
res = iter->Init(range);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
nsCOMArray<nsIContent> arrayOfNodes;
|
||||
while (!iter->IsDone()) {
|
||||
nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
|
||||
for (; !iter->IsDone(); iter->Next()) {
|
||||
NS_ENSURE_TRUE(iter->GetCurrentNode()->IsContent(), NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIContent> node = iter->GetCurrentNode()->AsContent();
|
||||
OwningNonNull<nsIContent> node = *iter->GetCurrentNode()->AsContent();
|
||||
|
||||
if (IsEditable(node)) {
|
||||
arrayOfNodes.AppendObject(node);
|
||||
arrayOfNodes.AppendElement(node);
|
||||
}
|
||||
|
||||
iter->Next();
|
||||
}
|
||||
|
||||
// now that we have the list, do the font size change on each node
|
||||
int32_t listCount = arrayOfNodes.Count();
|
||||
for (int32_t j = 0; j < listCount; ++j) {
|
||||
nsIContent* node = arrayOfNodes[j];
|
||||
res = RelativeFontChangeOnNode(aSizeChange, node);
|
||||
|
||||
// Now that we have the list, do the font size change on each node
|
||||
for (auto& node : arrayOfNodes) {
|
||||
res = RelativeFontChangeOnNode(aDir == FontSize::incr ? +1 : -1,
|
||||
node);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
arrayOfNodes.Clear();
|
||||
}
|
||||
// now check the start and end parents of the range to see if they need to
|
||||
// be separately handled (they do if they are text nodes, due to how the
|
||||
// subtree iterator works - it will not have reported them).
|
||||
if (IsTextNode(startNode) && IsEditable(startNode))
|
||||
{
|
||||
nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(startNode);
|
||||
int32_t startOffset;
|
||||
uint32_t textLen;
|
||||
range->GetStartOffset(&startOffset);
|
||||
nodeAsText->GetLength(&textLen);
|
||||
res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, startOffset, textLen);
|
||||
// Now check the start and end parents of the range to see if they need
|
||||
// to be separately handled (they do if they are text nodes, due to how
|
||||
// the subtree iterator works - it will not have reported them).
|
||||
if (IsTextNode(startNode) && IsEditable(startNode)) {
|
||||
res = RelativeFontChangeOnTextNode(aDir == FontSize::incr ? +1 : -1,
|
||||
static_cast<nsIDOMCharacterData*>(startNode->AsDOMNode()),
|
||||
range->StartOffset(), startNode->Length());
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
if (IsTextNode(endNode) && IsEditable(endNode))
|
||||
{
|
||||
if (IsTextNode(endNode) && IsEditable(endNode)) {
|
||||
nsCOMPtr<nsIDOMCharacterData> nodeAsText = do_QueryInterface(endNode);
|
||||
int32_t endOffset;
|
||||
range->GetEndOffset(&endOffset);
|
||||
res = RelativeFontChangeOnTextNode(aSizeChange, nodeAsText, 0, endOffset);
|
||||
res = RelativeFontChangeOnTextNode(aDir == FontSize::incr ? +1 : -1,
|
||||
static_cast<nsIDOMCharacterData*>(startNode->AsDOMNode()),
|
||||
0, range->EndOffset());
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "nsAString.h"
|
||||
#include "nsAlgorithm.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsEditorUtils.h"
|
||||
@ -499,14 +498,8 @@ nsresult
|
||||
nsHTMLEditor::StartResizing(nsIDOMElement *aHandle)
|
||||
{
|
||||
// First notify the listeners if any
|
||||
int32_t listenersCount = objectResizeEventListeners.Count();
|
||||
if (listenersCount) {
|
||||
nsCOMPtr<nsIHTMLObjectResizeListener> listener;
|
||||
int32_t index;
|
||||
for (index = 0; index < listenersCount; index++) {
|
||||
listener = objectResizeEventListeners[index];
|
||||
listener->OnStartResizing(static_cast<nsIDOMElement*>(GetAsDOMNode(mResizedObject)));
|
||||
}
|
||||
for (auto& listener : mObjectResizeEventListeners) {
|
||||
listener->OnStartResizing(static_cast<nsIDOMElement*>(GetAsDOMNode(mResizedObject)));
|
||||
}
|
||||
|
||||
mIsResizing = true;
|
||||
@ -976,16 +969,10 @@ nsHTMLEditor::SetFinalSize(int32_t aX, int32_t aY)
|
||||
EmptyString());
|
||||
}
|
||||
// finally notify the listeners if any
|
||||
int32_t listenersCount = objectResizeEventListeners.Count();
|
||||
if (listenersCount) {
|
||||
nsCOMPtr<nsIHTMLObjectResizeListener> listener;
|
||||
int32_t index;
|
||||
for (index = 0; index < listenersCount; index++) {
|
||||
listener = objectResizeEventListeners[index];
|
||||
listener->OnEndResizing(static_cast<nsIDOMElement*>(GetAsDOMNode(mResizedObject)),
|
||||
mResizedObjectWidth, mResizedObjectHeight,
|
||||
width, height);
|
||||
}
|
||||
for (auto& listener : mObjectResizeEventListeners) {
|
||||
listener->OnEndResizing(static_cast<nsIDOMElement*>(GetAsDOMNode(mResizedObject)),
|
||||
mResizedObjectWidth, mResizedObjectHeight, width,
|
||||
height);
|
||||
}
|
||||
|
||||
// keep track of that size
|
||||
@ -1021,14 +1008,13 @@ NS_IMETHODIMP
|
||||
nsHTMLEditor::AddObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aListener);
|
||||
if (objectResizeEventListeners.Count() &&
|
||||
objectResizeEventListeners.IndexOf(aListener) != -1) {
|
||||
if (mObjectResizeEventListeners.Contains(aListener)) {
|
||||
/* listener already registered */
|
||||
NS_ASSERTION(false,
|
||||
"trying to register an already registered object resize event listener");
|
||||
return NS_OK;
|
||||
}
|
||||
objectResizeEventListeners.AppendObject(aListener);
|
||||
mObjectResizeEventListeners.AppendElement(*aListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1036,14 +1022,13 @@ NS_IMETHODIMP
|
||||
nsHTMLEditor::RemoveObjectResizeEventListener(nsIHTMLObjectResizeListener * aListener)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aListener);
|
||||
if (!objectResizeEventListeners.Count() ||
|
||||
objectResizeEventListeners.IndexOf(aListener) == -1) {
|
||||
if (!mObjectResizeEventListeners.Contains(aListener)) {
|
||||
/* listener was not registered */
|
||||
NS_ASSERTION(false,
|
||||
"trying to remove an object resize event listener that was not already registered");
|
||||
return NS_OK;
|
||||
}
|
||||
objectResizeEventListeners.RemoveObject(aListener);
|
||||
mObjectResizeEventListeners.RemoveElement(aListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ skip-if(B2G||Mulet) fails-if(Android) needs-focus != spellcheck-hyphen-multiple-
|
||||
== unneeded_scroll.html unneeded_scroll-ref.html
|
||||
skip-if(B2G||Mulet) == caret_on_presshell_reinit.html caret_on_presshell_reinit-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) == caret_on_presshell_reinit-2.html caret_on_presshell_reinit-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) == 642800.html 642800-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,2824) == 642800.html 642800-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
== selection_visibility_after_reframe.html selection_visibility_after_reframe-ref.html
|
||||
!= selection_visibility_after_reframe-2.html selection_visibility_after_reframe-ref.html
|
||||
!= selection_visibility_after_reframe-3.html selection_visibility_after_reframe-ref.html
|
||||
|
@ -1014,6 +1014,10 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
hr = mutex->AcquireSync(0, 20000);
|
||||
|
||||
if (hr == WAIT_TIMEOUT) {
|
||||
if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
|
||||
gfxWarning() << "AcquireSync timed out because of device reset.";
|
||||
return;
|
||||
}
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
@ -1038,6 +1042,10 @@ SyncObjectD3D11::FinalizeFrame()
|
||||
hr = mutex->AcquireSync(0, 20000);
|
||||
|
||||
if (hr == WAIT_TIMEOUT) {
|
||||
if (gfxWindowsPlatform::GetPlatform()->DidRenderingDeviceReset()) {
|
||||
gfxWarning() << "AcquireSync timed out because of device reset.";
|
||||
return;
|
||||
}
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,6 @@ CheckProgressConsistency(Progress aProgress)
|
||||
void
|
||||
ProgressTracker::SetImage(Image* aImage)
|
||||
{
|
||||
MutexAutoLock lock(mImageMutex);
|
||||
MOZ_ASSERT(aImage, "Setting null image");
|
||||
MOZ_ASSERT(!mImage, "Setting image when we already have one");
|
||||
mImage = aImage;
|
||||
@ -96,7 +95,6 @@ ProgressTracker::SetImage(Image* aImage)
|
||||
void
|
||||
ProgressTracker::ResetImage()
|
||||
{
|
||||
MutexAutoLock lock(mImageMutex);
|
||||
MOZ_ASSERT(mImage, "Resetting image when it's already null!");
|
||||
mImage = nullptr;
|
||||
}
|
||||
@ -185,9 +183,8 @@ ProgressTracker::Notify(IProgressObserver* aObserver)
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
nsRefPtr<Image> image = GetImage();
|
||||
if (image && image->GetURI()) {
|
||||
nsRefPtr<ImageURL> uri(image->GetURI());
|
||||
if (mImage && mImage->GetURI()) {
|
||||
nsRefPtr<ImageURL> uri(mImage->GetURI());
|
||||
nsAutoCString spec;
|
||||
uri->GetSpec(spec);
|
||||
LOG_FUNC_WITH_PARAM(GetImgLog(),
|
||||
@ -254,10 +251,9 @@ ProgressTracker::NotifyCurrentState(IProgressObserver* aObserver)
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
nsRefPtr<Image> image = GetImage();
|
||||
nsAutoCString spec;
|
||||
if (image && image->GetURI()) {
|
||||
image->GetURI()->GetSpec(spec);
|
||||
if (mImage && mImage->GetURI()) {
|
||||
mImage->GetURI()->GetSpec(spec);
|
||||
}
|
||||
LOG_FUNC_WITH_PARAM(GetImgLog(),
|
||||
"ProgressTracker::NotifyCurrentState", "uri", spec.get());
|
||||
@ -371,7 +367,7 @@ ProgressTracker::SyncNotifyProgress(Progress aProgress,
|
||||
CheckProgressConsistency(mProgress);
|
||||
|
||||
// Send notifications.
|
||||
SyncNotifyInternal(mObservers, HasImage(), progress, aInvalidRect);
|
||||
SyncNotifyInternal(mObservers, !!mImage, progress, aInvalidRect);
|
||||
|
||||
if (progress & FLAG_HAS_ERROR) {
|
||||
FireFailureNotification();
|
||||
@ -383,21 +379,19 @@ ProgressTracker::SyncNotify(IProgressObserver* aObserver)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsRefPtr<Image> image = GetImage();
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
nsAutoCString spec;
|
||||
if (image && image->GetURI()) {
|
||||
image->GetURI()->GetSpec(spec);
|
||||
if (mImage && mImage->GetURI()) {
|
||||
mImage->GetURI()->GetSpec(spec);
|
||||
}
|
||||
LOG_SCOPE_WITH_PARAM(GetImgLog(),
|
||||
"ProgressTracker::SyncNotify", "uri", spec.get());
|
||||
#endif
|
||||
|
||||
nsIntRect rect;
|
||||
if (image) {
|
||||
if (NS_FAILED(image->GetWidth(&rect.width)) ||
|
||||
NS_FAILED(image->GetHeight(&rect.height))) {
|
||||
if (mImage) {
|
||||
if (NS_FAILED(mImage->GetWidth(&rect.width)) ||
|
||||
NS_FAILED(mImage->GetHeight(&rect.height))) {
|
||||
// Either the image has no intrinsic size, or it has an error.
|
||||
rect = GetMaxSizedIntRect();
|
||||
}
|
||||
@ -405,7 +399,7 @@ ProgressTracker::SyncNotify(IProgressObserver* aObserver)
|
||||
|
||||
ObserverArray array;
|
||||
array.AppendElement(aObserver);
|
||||
SyncNotifyInternal(array, !!image, mProgress, rect);
|
||||
SyncNotifyInternal(array, !!mImage, mProgress, rect);
|
||||
}
|
||||
|
||||
void
|
||||
@ -517,12 +511,11 @@ ProgressTracker::FireFailureNotification()
|
||||
|
||||
// Some kind of problem has happened with image decoding.
|
||||
// Report the URI to net:failed-to-process-uri-conent observers.
|
||||
nsRefPtr<Image> image = GetImage();
|
||||
if (image) {
|
||||
if (mImage) {
|
||||
// Should be on main thread, so ok to create a new nsIURI.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
{
|
||||
nsRefPtr<ImageURL> threadsafeUriData = image->GetURI();
|
||||
nsRefPtr<ImageURL> threadsafeUriData = mImage->GetURI();
|
||||
uri = threadsafeUriData ? threadsafeUriData->ToIURI() : nullptr;
|
||||
}
|
||||
if (uri) {
|
||||
|
@ -7,7 +7,6 @@
|
||||
#ifndef mozilla_image_src_ProgressTracker_h
|
||||
#define mozilla_image_src_ProgressTracker_h
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -77,15 +76,13 @@ public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProgressTracker)
|
||||
|
||||
ProgressTracker()
|
||||
: mImageMutex("ProgressTracker::mImage")
|
||||
, mImage(nullptr)
|
||||
: mImage(nullptr)
|
||||
, mProgress(NoProgress)
|
||||
{ }
|
||||
|
||||
bool HasImage() const { MutexAutoLock lock(mImageMutex); return mImage; }
|
||||
bool HasImage() const { return mImage; }
|
||||
already_AddRefed<Image> GetImage() const
|
||||
{
|
||||
MutexAutoLock lock(mImageMutex);
|
||||
nsRefPtr<Image> image = mImage;
|
||||
return image.forget();
|
||||
}
|
||||
@ -193,9 +190,7 @@ private:
|
||||
|
||||
nsCOMPtr<nsIRunnable> mRunnable;
|
||||
|
||||
// mImage is a weak ref; it should be set to null when the image goes out of
|
||||
// scope. mImageMutex protects mImage.
|
||||
mutable Mutex mImageMutex;
|
||||
// This weak ref should be set null when the image goes out of scope.
|
||||
Image* mImage;
|
||||
|
||||
// List of observers attached to the image. Each observer represents a
|
||||
|
@ -537,8 +537,28 @@ MOZ_ALWAYS_INLINE void
|
||||
js::Nursery::traceObject(MinorCollectionTracer* trc, JSObject* obj)
|
||||
{
|
||||
const Class* clasp = obj->getClass();
|
||||
if (clasp->trace)
|
||||
if (clasp->trace) {
|
||||
if (clasp->trace == InlineTypedObject::obj_trace) {
|
||||
TypeDescr* descr = &obj->as<InlineTypedObject>().typeDescr();
|
||||
if (descr->hasTraceList()) {
|
||||
markTraceList(trc, descr->traceList(),
|
||||
obj->as<InlineTypedObject>().inlineTypedMem());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (clasp == &UnboxedPlainObject::class_) {
|
||||
JSObject** pexpando = obj->as<UnboxedPlainObject>().addressOfExpando();
|
||||
if (*pexpando)
|
||||
markObject(trc, pexpando);
|
||||
const UnboxedLayout& layout = obj->as<UnboxedPlainObject>().layout();
|
||||
if (layout.traceList()) {
|
||||
markTraceList(trc, layout.traceList(),
|
||||
obj->as<UnboxedPlainObject>().data());
|
||||
}
|
||||
return;
|
||||
}
|
||||
clasp->trace(trc, obj);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(obj->isNative() == clasp->isNative());
|
||||
if (!clasp->isNative())
|
||||
@ -579,16 +599,42 @@ js::Nursery::markSlot(MinorCollectionTracer* trc, HeapSlot* slotp)
|
||||
return;
|
||||
|
||||
JSObject* obj = &slotp->toObject();
|
||||
if (!IsInsideNursery(obj))
|
||||
return;
|
||||
|
||||
if (getForwardedPointer(&obj)) {
|
||||
if (markObject(trc, &obj))
|
||||
slotp->unsafeGet()->setObject(*obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JSObject* tenured = static_cast<JSObject*>(moveToTenured(trc, obj));
|
||||
slotp->unsafeGet()->setObject(*tenured);
|
||||
MOZ_ALWAYS_INLINE void
|
||||
js::Nursery::markTraceList(MinorCollectionTracer* trc, const int32_t* traceList, uint8_t* memory)
|
||||
{
|
||||
while (*traceList != -1) {
|
||||
// Strings are not in the nursery and do not need tracing.
|
||||
traceList++;
|
||||
}
|
||||
traceList++;
|
||||
while (*traceList != -1) {
|
||||
JSObject** pobj = reinterpret_cast<JSObject **>(memory + *traceList);
|
||||
markObject(trc, pobj);
|
||||
traceList++;
|
||||
}
|
||||
traceList++;
|
||||
while (*traceList != -1) {
|
||||
HeapSlot* pslot = reinterpret_cast<HeapSlot *>(memory + *traceList);
|
||||
markSlot(trc, pslot);
|
||||
traceList++;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
js::Nursery::markObject(MinorCollectionTracer* trc, JSObject** pobj)
|
||||
{
|
||||
if (!IsInsideNursery(*pobj))
|
||||
return false;
|
||||
|
||||
if (getForwardedPointer(pobj))
|
||||
return true;
|
||||
|
||||
*pobj = static_cast<JSObject*>(moveToTenured(trc, *pobj));
|
||||
return true;
|
||||
}
|
||||
|
||||
void*
|
||||
|
@ -313,6 +313,9 @@ class Nursery
|
||||
MOZ_ALWAYS_INLINE void markSlots(gc::MinorCollectionTracer* trc, HeapSlot* vp, uint32_t nslots);
|
||||
MOZ_ALWAYS_INLINE void markSlots(gc::MinorCollectionTracer* trc, HeapSlot* vp, HeapSlot* end);
|
||||
MOZ_ALWAYS_INLINE void markSlot(gc::MinorCollectionTracer* trc, HeapSlot* slotp);
|
||||
MOZ_ALWAYS_INLINE void markTraceList(gc::MinorCollectionTracer* trc,
|
||||
const int32_t* traceList, uint8_t* memory);
|
||||
MOZ_ALWAYS_INLINE bool markObject(gc::MinorCollectionTracer* trc, JSObject** pobj);
|
||||
void* moveToTenured(gc::MinorCollectionTracer* trc, JSObject* src);
|
||||
size_t moveObjectToTenured(gc::MinorCollectionTracer* trc, JSObject* dst, JSObject* src,
|
||||
gc::AllocKind dstKind);
|
||||
|
@ -10130,6 +10130,17 @@ TryAttachStringSplit(JSContext* cx, ICCall_Fallback* stub, HandleScript script,
|
||||
if (!CopyArray(cx, obj, &arr))
|
||||
return false;
|
||||
|
||||
// Atomize all elements of the array.
|
||||
RootedArrayObject arrObj(cx, &arr.toObject().as<ArrayObject>());
|
||||
uint32_t initLength = arrObj->length();
|
||||
for (uint32_t i = 0; i < initLength; i++) {
|
||||
JSAtom* str = js::AtomizeString(cx, arrObj->getDenseElement(i).toString());
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
arrObj->setDenseElement(i, StringValue(str));
|
||||
}
|
||||
|
||||
ICCall_StringSplit::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(),
|
||||
script->pcToOffset(pc), thisString, argString,
|
||||
arr);
|
||||
|
@ -12873,17 +12873,8 @@ IonBuilder::storeReferenceTypedObjectValue(MDefinition* typedObj,
|
||||
MConstant*
|
||||
IonBuilder::constant(const Value& v)
|
||||
{
|
||||
// For performance reason (TLS) and error code handling (AtomizeString), we
|
||||
// should prefer the specialized frunction constantMaybeAtomize instead of
|
||||
// constant.
|
||||
MOZ_ASSERT(!v.isString() || v.toString()->isAtom(),
|
||||
"To handle non-atomized strings, you should use constantMaybeAtomize instead of constant.");
|
||||
if (v.isString() && MOZ_UNLIKELY(!v.toString()->isAtom())) {
|
||||
MConstant* cst = constantMaybeAtomize(v);
|
||||
if (!cst)
|
||||
js::CrashAtUnhandlableOOM("Use constantMaybeAtomize.");
|
||||
return cst;
|
||||
}
|
||||
"Handle non-atomized strings outside IonBuilder.");
|
||||
|
||||
MConstant* c = MConstant::New(alloc(), v, constraints());
|
||||
current->add(c);
|
||||
@ -12896,19 +12887,6 @@ IonBuilder::constantInt(int32_t i)
|
||||
return constant(Int32Value(i));
|
||||
}
|
||||
|
||||
MConstant*
|
||||
IonBuilder::constantMaybeAtomize(const Value& v)
|
||||
{
|
||||
if (!v.isString() || v.toString()->isAtom())
|
||||
return constant(v);
|
||||
|
||||
JSContext* cx = GetJitContext()->cx;
|
||||
JSAtom* atom = js::AtomizeString(cx, v.toString());
|
||||
if (!atom)
|
||||
return nullptr;
|
||||
return constant(StringValue(atom));
|
||||
}
|
||||
|
||||
MDefinition*
|
||||
IonBuilder::getCallee()
|
||||
{
|
||||
|
@ -353,9 +353,6 @@ class IonBuilder
|
||||
MConstant* constant(const Value& v);
|
||||
MConstant* constantInt(int32_t i);
|
||||
|
||||
// Note: This function might return nullptr in case of failure.
|
||||
MConstant* constantMaybeAtomize(const Value& v);
|
||||
|
||||
// Improve the type information at tests
|
||||
bool improveTypesAtTest(MDefinition* ins, bool trueBranch, MTest* test);
|
||||
bool improveTypesAtCompare(MCompare* ins, bool trueBranch, MTest* test);
|
||||
|
@ -1567,14 +1567,11 @@ IonBuilder::inlineConstantStringSplit(CallInfo& callInfo)
|
||||
if (templateObject->getDenseInitializedLength() != initLength)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
JSContext* cx = GetJitContext()->cx;
|
||||
Vector<MConstant*, 0, SystemAllocPolicy> arrayValues;
|
||||
for (uint32_t i = 0; i < initLength; i++) {
|
||||
JSAtom* str = js::AtomizeString(cx, templateObject->getDenseElement(i).toString());
|
||||
if (!str)
|
||||
return InliningStatus_Error;
|
||||
|
||||
MConstant* value = MConstant::New(alloc(), StringValue(str), constraints());
|
||||
Value str = templateObject->getDenseElement(i);
|
||||
MOZ_ASSERT(str.toString()->isAtom());
|
||||
MConstant* value = MConstant::New(alloc(), str, constraints());
|
||||
if (!TypeSetIncludes(key.maybeTypes(), value->type(), value->resultTypeSet()))
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
@ -2772,11 +2769,15 @@ IonBuilder::inlineBoundFunction(CallInfo& nativeCallInfo, JSFunction* target)
|
||||
const Value val = target->getBoundFunctionArgument(i);
|
||||
if (val.isObject() && gc::IsInsideNursery(&val.toObject()))
|
||||
return InliningStatus_NotInlined;
|
||||
if (val.isString() && !val.toString()->isAtom())
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
const Value thisVal = target->getBoundFunctionThis();
|
||||
if (thisVal.isObject() && gc::IsInsideNursery(&thisVal.toObject()))
|
||||
return InliningStatus_NotInlined;
|
||||
if (thisVal.isString() && !thisVal.toString()->isAtom())
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
size_t argc = target->getBoundFunctionArgumentCount() + nativeCallInfo.argc();
|
||||
if (argc > ARGS_LENGTH_MAX)
|
||||
@ -2786,18 +2787,13 @@ IonBuilder::inlineBoundFunction(CallInfo& nativeCallInfo, JSFunction* target)
|
||||
|
||||
CallInfo callInfo(alloc(), nativeCallInfo.constructing());
|
||||
callInfo.setFun(constant(ObjectValue(*scriptedTarget)));
|
||||
MConstant* thisConst = constantMaybeAtomize(thisVal);
|
||||
if (!thisConst)
|
||||
return InliningStatus_Error;
|
||||
callInfo.setThis(thisConst);
|
||||
callInfo.setThis(constant(thisVal));
|
||||
|
||||
if (!callInfo.argv().reserve(argc))
|
||||
return InliningStatus_Error;
|
||||
|
||||
for (size_t i = 0; i < target->getBoundFunctionArgumentCount(); i++) {
|
||||
MConstant* argConst = constantMaybeAtomize(target->getBoundFunctionArgument(i));
|
||||
if (!argConst)
|
||||
return InliningStatus_Error;
|
||||
MConstant* argConst = constant(target->getBoundFunctionArgument(i));
|
||||
callInfo.argv().infallibleAppend(argConst);
|
||||
}
|
||||
for (size_t i = 0; i < nativeCallInfo.argc(); i++)
|
||||
|
@ -904,7 +904,7 @@ TypeSet::intersectSets(TemporaryTypeSet* a, TemporaryTypeSet* b, LifoAlloc* allo
|
||||
|
||||
if (b->unknownObject()) {
|
||||
for (size_t i = 0; i < a->getObjectCount(); i++) {
|
||||
if (b->getObject(i))
|
||||
if (a->getObject(i))
|
||||
res->addType(ObjectType(a->getObject(i)), alloc);
|
||||
}
|
||||
return res;
|
||||
|
@ -233,6 +233,11 @@ class UnboxedPlainObject : public JSObject
|
||||
expando_ = nullptr;
|
||||
}
|
||||
|
||||
// For use during GC.
|
||||
JSObject** addressOfExpando() {
|
||||
return reinterpret_cast<JSObject**>(&expando_);
|
||||
}
|
||||
|
||||
bool containsUnboxedOrExpandoProperty(ExclusiveContext* cx, jsid id) const;
|
||||
|
||||
static UnboxedExpandoObject* ensureExpando(JSContext* cx, Handle<UnboxedPlainObject*> obj);
|
||||
|
@ -49,11 +49,11 @@ skip-if((B2G&&browserIsRemote)||Mulet) != table-cell-8.html table-print-1-ref.ht
|
||||
== continuation-positioned-inline-1.html continuation-positioned-inline-ref.html
|
||||
== continuation-positioned-inline-2.html continuation-positioned-inline-ref.html
|
||||
== scrollframe-1.html scrollframe-1-ref.html
|
||||
skip-if(B2G||Mulet) fuzzy-if(Android,9,185) == scrollframe-2.html scrollframe-2-ref.html #bug 756530 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fuzzy-if(Android,9,185) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,107) == scrollframe-2.html scrollframe-2-ref.html #bug 756530 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fuzzy-if(gtk2Widget,1,8) == select-1.html select-1-ref.html
|
||||
fuzzy-if(gtk2Widget,1,8) == select-1-dynamic.html select-1-ref.html
|
||||
== select-2.html select-2-ref.html
|
||||
fuzzy-if(gtk2Widget,1,19) fuzzy-if(Android||B2G,17,726) == select-3.html select-3-ref.html
|
||||
fuzzy-if(gtk2Widget,1,19) fuzzy-if(Android||B2G,17,726) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,98) == select-3.html select-3-ref.html
|
||||
== multi-column-1.html multi-column-1-ref.html
|
||||
== button-1.html button-1-ref.html
|
||||
== button-2.html button-2-ref.html
|
||||
|
@ -36,7 +36,7 @@ fails-if(Android||B2G) == center-scaling-3.html center-scaling-3-ref.html # Andr
|
||||
== border-image-outset-1c.html border-image-outset-1-ref.html
|
||||
== border-image-nofill-1.html border-image-nofill-1-ref.html
|
||||
== border-image-outset-resize-1.html border-image-outset-resize-1-ref.html
|
||||
== border-image-outset-move-1.html border-image-outset-move-1-ref.html
|
||||
fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,445) == border-image-outset-move-1.html border-image-outset-move-1-ref.html
|
||||
== border-image-style-none.html border-image-style-none-ref.html
|
||||
== border-image-style-none-length.html border-image-style-none-length-ref.html
|
||||
== border-image-style-none-auto.html border-image-style-none-auto-ref.html
|
||||
|
@ -71,7 +71,7 @@ fuzzy-if(azureQuartz,1,3) skip-if(B2G||Mulet) == invalidate-1a.html invalidate-1
|
||||
fuzzy-if(azureQuartz,1,3) skip-if(B2G||Mulet) == invalidate-1b.html invalidate-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
||||
# test that border-radius is reduced for scrollbars
|
||||
skip-if(B2G||Mulet) fails-if(Android) == scrollbar-clamping-1.html scrollbar-clamping-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fails-if(Android) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,12,12) == scrollbar-clamping-1.html scrollbar-clamping-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fails-if(Android) == scrollbar-clamping-2.html scrollbar-clamping-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
||||
# Test for bad corner joins.
|
||||
|
@ -1575,7 +1575,7 @@ random-if(!winWidget) fails-if(winWidget&&!d2d) random-if(winWidget&&d2d) != 574
|
||||
skip-if(!haveTestPlugin) skip-if(B2G||Mulet) fails-if(Android) == 579808-1.html 579808-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fails-if(Android) random-if(layersGPUAccelerated) == 579985-1.html 579985-1-ref.html # bug 623452 for WinXP; this bug was only for a regression in BasicLayers anyway # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) skip-if(Android) == 580160-1.html 580160-1-ref.html # bug 920927 for Android; issues without the test-plugin # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
HTTP(..) == 580863-1.html 580863-1-ref.html
|
||||
fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,255,13) HTTP(..) == 580863-1.html 580863-1-ref.html
|
||||
skip-if(B2G||Mulet) fails-if(Android) random-if(layersGPUAccelerated) == 581317-1.html 581317-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
== 581579-1.html 581579-1-ref.html
|
||||
== 582037-1a.html 582037-1-ref.html
|
||||
@ -1671,7 +1671,7 @@ skip-if(B2G||Mulet) == 641770-1.html 641770-1-ref.html # Initial mulet triage: p
|
||||
== 641856-1.html 641856-1-ref.html
|
||||
== 645491-1.html 645491-1-ref.html
|
||||
== 645768-1.html 645768-1-ref.html
|
||||
fails-if(layersGPUAccelerated&&cocoaWidget) fails-if(Android&&AndroidVersion<15&&AndroidVersion!=10) == 650228-1.html 650228-1-ref.html # Quartz alpha blending doesn't match GL alpha blending
|
||||
fails-if(layersGPUAccelerated&&cocoaWidget) fails-if(Android&&AndroidVersion<15&&AndroidVersion!=10) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,41,260) == 650228-1.html 650228-1-ref.html # Quartz alpha blending doesn't match GL alpha blending
|
||||
needs-focus == 652301-1a.html 652301-1-ref.html
|
||||
needs-focus == 652301-1b.html 652301-1-ref.html
|
||||
== 652775-1.html 652775-1-ref.html
|
||||
@ -1756,7 +1756,7 @@ skip-if(B2G||Mulet) fuzzy-if(Android,4,400) == 815593-1.html 815593-1-ref.html #
|
||||
== 816948-1.html 816948-1-ref.html
|
||||
== 817019-1.html about:blank
|
||||
skip-if(B2G||Mulet) == 818276-1.html 818276-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fuzzy-if(asyncPanZoom,190,27) == 825999.html 825999-ref.html
|
||||
fuzzy-if(asyncPanZoom,190,510) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,510) == 825999.html 825999-ref.html
|
||||
== 827577-1a.html 827577-1-ref.html
|
||||
== 827577-1b.html 827577-1-ref.html
|
||||
== 827799-1.html about:blank
|
||||
@ -1806,7 +1806,7 @@ fuzzy-if(B2G,1,7) == 942672-1.html 942672-1-ref.html
|
||||
== 961887-1.html 961887-1-ref.html
|
||||
== 961887-2.html 961887-2-ref.html
|
||||
== 961887-3.html 961887-3-ref.html
|
||||
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,145) == 966992-1.html 966992-1-ref.html
|
||||
pref(layout.css.overflow-clip-box.enabled,true) fuzzy(50,145) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,3712) == 966992-1.html 966992-1-ref.html
|
||||
skip-if(Android) == 966510-1.html 966510-1-ref.html # scrollable elements other than the root probably won't work well on android until bug 776030 is fixed
|
||||
skip-if(Android) == 966510-2.html 966510-2-ref.html # same as above
|
||||
== 978911-1.svg 978911-1-ref.svg
|
||||
|
@ -10,7 +10,7 @@ needs-focus == select-required-invalid-changed-1.html select-required-ref.html
|
||||
needs-focus == select-required-invalid-changed-2.html select-required-ref.html
|
||||
needs-focus == select-required-valid.html select-required-ref.html
|
||||
needs-focus == select-required-multiple-invalid.html select-required-multiple-ref.html
|
||||
needs-focus == select-required-multiple-invalid-changed.html select-required-multiple-ref.html
|
||||
fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,84,77) needs-focus == select-required-multiple-invalid-changed.html select-required-multiple-ref.html
|
||||
needs-focus == select-required-multiple-valid.html select-required-multiple-ref.html
|
||||
skip-if(B2G||Mulet) fails-if(Android) needs-focus == select-disabled-fieldset-1.html select-fieldset-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fails-if(Android) needs-focus == select-disabled-fieldset-2.html select-fieldset-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
@ -11,7 +11,7 @@ needs-focus == select-required-valid-changed-1.html select-required-ref.html
|
||||
needs-focus == select-required-valid-changed-2.html select-required-ref.html
|
||||
needs-focus == select-required-multiple-invalid.html select-required-multiple-ref.html
|
||||
needs-focus == select-required-multiple-valid.html select-required-multiple-ref.html
|
||||
fuzzy(64,4) needs-focus == select-required-multiple-valid-changed.html select-required-multiple-ref.html
|
||||
fuzzy(64,4) fuzzy-if(asyncPanZoom&&layersGPUAccelerated,84,77) needs-focus == select-required-multiple-valid-changed.html select-required-multiple-ref.html
|
||||
fails-if(Android||B2G||Mulet) needs-focus == select-disabled-fieldset-1.html select-fieldset-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fails-if(Android||B2G||Mulet) needs-focus == select-disabled-fieldset-2.html select-fieldset-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
needs-focus == select-fieldset-legend.html select-fieldset-legend-ref.html
|
||||
|
@ -37,7 +37,7 @@ test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceE
|
||||
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == textarea-3.html textarea-3-ref.html
|
||||
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == css-transform-1.html css-transform-1-ref.html
|
||||
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == css-transform-2.html css-transform-2-ref.html
|
||||
skip-if(B2G||Mulet) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == container-with-clamping.html container-with-clamping-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,1764) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) == container-with-clamping.html container-with-clamping-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) load video-1.html
|
||||
test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-min-1.html intrinsic-min-1-ref.html
|
||||
skip-if(B2G||Mulet) test-pref(font.size.inflation.emPerLine,15) test-pref(font.size.inflation.forceEnabled,true) test-pref(font.size.inflation.lineThreshold,0) HTTP(..) == intrinsic-max-1.html intrinsic-max-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
@ -5,7 +5,7 @@
|
||||
== fieldset-scroll-1.html fieldset-scroll-1-ref.html
|
||||
== fieldset-scrolled-1.html fieldset-scrolled-1-ref.html
|
||||
random-if(B2G||Mulet) == fieldset-overflow-auto-1.html fieldset-overflow-auto-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,102,205) == positioned-container-1.html positioned-container-1-ref.html
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,102,221) == positioned-container-1.html positioned-container-1-ref.html
|
||||
== relpos-legend-1.html relpos-legend-1-ref.html
|
||||
== relpos-legend-2.html relpos-legend-2-ref.html
|
||||
test-pref(layout.css.sticky.enabled,true) skip-if((B2G&&browserIsRemote)||Mulet) == sticky-legend-1.html sticky-legend-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
@ -1,5 +1,5 @@
|
||||
== bounds-1.html bounds-1-ref.html
|
||||
== size-1.html size-1-ref.html
|
||||
fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,84) == size-1.html size-1-ref.html
|
||||
skip-if(B2G||Mulet) == size-2.html size-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
HTTP(..) == baseline-1.html baseline-1-ref.html
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) HTTP(..) == centering-1.xul centering-1-ref.xul # bug 974780 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
|
@ -16,7 +16,7 @@
|
||||
== placeholder-3.html placeholder-overridden-ref.html
|
||||
== placeholder-4.html placeholder-overridden-ref.html
|
||||
== placeholder-5.html placeholder-visible-ref.html
|
||||
fuzzy-if(winWidget,160,7) == placeholder-6.html placeholder-overflow-ref.html
|
||||
fuzzy-if(winWidget,160,7) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,146,299) == placeholder-6.html placeholder-overflow-ref.html
|
||||
skip-if(B2G||Mulet) == placeholder-6-textarea.html placeholder-overflow-textarea-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
# needs-focus == placeholder-7.html placeholder-focus-ref.html
|
||||
# needs-focus == placeholder-8.html placeholder-focus-ref.html
|
||||
|
@ -10,5 +10,5 @@ skip-if(B2G||Mulet) fails-if(Android) fails-if(gtk2Widget) != rtl.html no-resize
|
||||
== rtl.html rtl-dynamic-style.html
|
||||
== rtl.html in-dynamic-rtl-doc.html
|
||||
== setvalue-framereconstruction-1.html setvalue-framereconstruction-ref.html
|
||||
== padding-scrollbar-placement.html padding-scrollbar-placement-ref.html
|
||||
fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,4168) == padding-scrollbar-placement.html padding-scrollbar-placement-ref.html
|
||||
== various-cols.html various-cols-ref.html
|
||||
|
@ -1,5 +1,5 @@
|
||||
fuzzy-if(cocoaWidget,1,2) fuzzy-if(d2d,47,26) == move-right-bottom.html move-right-bottom-ref.html
|
||||
fuzzy-if(cocoaWidget,1,2) == move-top-left.html move-top-left-ref.html # Bug 688545
|
||||
fuzzy-if(cocoaWidget,1,3) == move-right-bottom-table.html move-right-bottom-table-ref.html
|
||||
fuzzy-if(cocoaWidget,1,3) == move-top-left-table.html move-top-left-table-ref.html # Bug 688545
|
||||
fuzzy-if(cocoaWidget,1,2) fuzzy-if(d2d,47,26) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,492) == move-right-bottom.html move-right-bottom-ref.html
|
||||
fuzzy-if(cocoaWidget,1,2) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,492) == move-top-left.html move-top-left-ref.html # Bug 688545
|
||||
fuzzy-if(cocoaWidget,1,3) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,492) == move-right-bottom-table.html move-right-bottom-table-ref.html
|
||||
fuzzy-if(cocoaWidget,1,3) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,492) == move-top-left-table.html move-top-left-table-ref.html # Bug 688545
|
||||
== percent.html percent-ref.html
|
||||
|
@ -27,11 +27,11 @@ skip-if(B2G||Mulet) fuzzy-if(Android&&AndroidVersion<15,251,722) fuzzy-if(d2d,1,
|
||||
HTTP == transformed-1.html?up transformed-1.html?ref
|
||||
fuzzy-if(Android,5,20000) == uncovering-1.html uncovering-1-ref.html
|
||||
fuzzy-if(Android,5,20000) == uncovering-2.html uncovering-2-ref.html
|
||||
skip-if(B2G||Mulet) == less-than-scrollbar-height.html less-than-scrollbar-height-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,3721) == less-than-scrollbar-height.html less-than-scrollbar-height-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) == huge-horizontal-overflow.html huge-horizontal-overflow-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) == huge-vertical-overflow.html huge-vertical-overflow-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
== iframe-scrolling-attr-1.html iframe-scrolling-attr-ref.html
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) == iframe-scrolling-attr-2.html iframe-scrolling-attr-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,6818) == iframe-scrolling-attr-1.html iframe-scrolling-attr-ref.html
|
||||
skip-if((B2G&&browserIsRemote)||Mulet) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,6818) == iframe-scrolling-attr-2.html iframe-scrolling-attr-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
== frame-scrolling-attr-1.html frame-scrolling-attr-ref.html
|
||||
== frame-scrolling-attr-2.html frame-scrolling-attr-ref.html
|
||||
fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,2420) == frame-scrolling-attr-2.html frame-scrolling-attr-ref.html
|
||||
== move-item.html move-item-ref.html # bug 1125750
|
||||
|
@ -4,11 +4,11 @@ fuzzy-if(Android,16,244) skip-if(B2G||Mulet) HTTP(..) == marker-basic.html marke
|
||||
skip-if(B2G||Mulet) HTTP(..) == marker-string.html marker-string-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(Android||B2G) HTTP(..) == bidi-simple.html bidi-simple-ref.html # Fails on Android due to anti-aliasing
|
||||
skip-if(!gtk2Widget) fuzzy-if(gtk2Widget,1,104) HTTP(..) == bidi-simple-scrolled.html bidi-simple-scrolled-ref.html # Fails on Windows and OSX due to anti-aliasing
|
||||
skip-if(B2G||Mulet) fuzzy-if(Android&&AndroidVersion<15,9,2545) fuzzy-if(Android&&AndroidVersion>=15,24,4000) fuzzy-if(cocoaWidget,1,40) HTTP(..) == scroll-rounding.html scroll-rounding-ref.html # bug 760264 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fuzzy-if(Android&&AndroidVersion<15,9,2545) fuzzy-if(Android&&AndroidVersion>=15,24,4000) fuzzy-if(cocoaWidget,1,40) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,1770) HTTP(..) == scroll-rounding.html scroll-rounding-ref.html # bug 760264 # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fuzzy-if(OSX==1008,1,1) HTTP(..) == anonymous-block.html anonymous-block-ref.html
|
||||
skip-if(B2G||Mulet) HTTP(..) == false-marker-overlap.html false-marker-overlap-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
HTTP(..) == visibility-hidden.html visibility-hidden-ref.html
|
||||
skip-if(B2G||Mulet) HTTP(..) == block-padding.html block-padding-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,1724) HTTP(..) == block-padding.html block-padding-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
HTTP(..) == quirks-decorations.html quirks-decorations-ref.html
|
||||
HTTP(..) == quirks-line-height.html quirks-line-height-ref.html
|
||||
HTTP(..) == standards-decorations.html standards-decorations-ref.html
|
||||
@ -22,5 +22,5 @@ skip-if(B2G||Mulet) HTTP(..) == table-cell.html table-cell-ref.html # Initial mu
|
||||
skip-if(Mulet) HTTP(..) == two-value-syntax.html two-value-syntax-ref.html # MULET: Bug 1144079: Re-enable Mulet mochitests and reftests taskcluster-specific disables
|
||||
skip-if(B2G||Mulet) HTTP(..) == single-value.html single-value-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
skip-if(B2G||Mulet) HTTP(..) == atomic-under-marker.html atomic-under-marker-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fuzzy(1,702) skip-if(Android||B2G||Mulet) HTTP(..) == xulscroll.html xulscroll-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
fuzzy(1,702) skip-if(Android||B2G||Mulet) fuzzy-if(asyncPanZoom&&!layersGPUAccelerated,102,12352) HTTP(..) == xulscroll.html xulscroll-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
|
||||
HTTP(..) == combobox-zoom.html combobox-zoom-ref.html
|
||||
|
@ -328,7 +328,7 @@ platform_files = [
|
||||
]
|
||||
|
||||
def prepare_upstream(prefix, commit=None):
|
||||
upstream_url = 'https://gerrit.chromium.org/gerrit/webm/libvpx'
|
||||
upstream_url = 'https://chromium.googlesource.com/webm/libvpx'
|
||||
if os.path.exists(prefix):
|
||||
print "Using existing repo in '%s'" % prefix
|
||||
os.chdir(prefix)
|
||||
|
@ -172,6 +172,9 @@ static DllBlockInfo sWindowsDllBlocklist[] = {
|
||||
// Crashes with CyberLink YouCam, bug 1136968
|
||||
{ "ycwebcamerasource.ax", MAKE_VERSION(2, 0, 0, 1611) },
|
||||
|
||||
// Old version of WebcamMax crashes WebRTC, bug 1130061
|
||||
{ "vwcsource.ax", MAKE_VERSION(1, 5, 0, 0) },
|
||||
|
||||
{ nullptr, 0 }
|
||||
};
|
||||
|
||||
|
@ -2308,7 +2308,7 @@ GeckoDriver.prototype.sendKeysToElement = function(cmd, resp) {
|
||||
let {id, value} = cmd.parameters;
|
||||
|
||||
if (!value) {
|
||||
throw new IllegalArgumentError(`Expected character sequence: ${value}`);
|
||||
throw new InvalidArgumentError(`Expected character sequence: ${value}`);
|
||||
}
|
||||
|
||||
switch (this.context) {
|
||||
@ -2341,7 +2341,7 @@ GeckoDriver.prototype.sendKeysToElement = function(cmd, resp) {
|
||||
try {
|
||||
file = new File(val);
|
||||
} catch (e) {
|
||||
err = new IllegalArgumentError(`File not found: ${val}`);
|
||||
err = new InvalidArgumentError(`File not found: ${val}`);
|
||||
}
|
||||
fs.push(file);
|
||||
el.mozSetFileArray(fs);
|
||||
|
@ -1 +1,2 @@
|
||||
marionette-transport == 0.4
|
||||
marionette-transport == 0.4
|
||||
mozrunner >= 6.2
|
||||
|
@ -1,6 +1,6 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
version = '0.4'
|
||||
version = '0.5'
|
||||
|
||||
# dependencies
|
||||
with open('requirements.txt') as f:
|
||||
|
@ -11,7 +11,7 @@ const errors = [
|
||||
"ElementNotVisibleError",
|
||||
"FrameSendFailureError",
|
||||
"FrameSendNotInitializedError",
|
||||
"IllegalArgumentError",
|
||||
"InvalidArgumentError",
|
||||
"InvalidElementStateError",
|
||||
"InvalidSelectorError",
|
||||
"InvalidSessionIdError",
|
||||
@ -171,12 +171,12 @@ this.FrameSendNotInitializedError = function(frame) {
|
||||
};
|
||||
FrameSendNotInitializedError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
this.IllegalArgumentError = function(msg) {
|
||||
this.InvalidArgumentError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "IllegalArgumentError";
|
||||
this.status = "illegal argument";
|
||||
this.name = "InvalidArgumentError";
|
||||
this.status = "invalid argument";
|
||||
};
|
||||
IllegalArgumentError.prototype = Object.create(WebDriverError.prototype);
|
||||
InvalidArgumentError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
this.InvalidElementStateError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
@ -196,7 +196,6 @@ this.InvalidSessionIdError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "InvalidSessionIdError";
|
||||
this.status = "invalid session id";
|
||||
this.code = 13;
|
||||
};
|
||||
InvalidSessionIdError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
@ -307,7 +306,6 @@ this.UnableToSetCookieError = function(msg) {
|
||||
WebDriverError.call(this, msg);
|
||||
this.name = "UnableToSetCookieError";
|
||||
this.status = "unable to set cookie";
|
||||
this.code = 25;
|
||||
};
|
||||
UnableToSetCookieError.prototype = Object.create(WebDriverError.prototype);
|
||||
|
||||
|
@ -1562,7 +1562,7 @@ function sendKeysToElement(msg) {
|
||||
try {
|
||||
file = new File(p);
|
||||
} catch (e) {
|
||||
let err = new IllegalArgumentError(`File not found: ${val}`);
|
||||
let err = new InvalidArgumentError(`File not found: ${val}`);
|
||||
sendError(err, command_id);
|
||||
return;
|
||||
}
|
||||
|
@ -437,6 +437,7 @@ STUB(gtk_widget_realize)
|
||||
STUB(gtk_widget_reparent)
|
||||
STUB(gtk_widget_set_allocation)
|
||||
STUB(gtk_widget_set_app_paintable)
|
||||
STUB(gtk_window_set_auto_startup_notification)
|
||||
STUB(gtk_widget_set_can_focus)
|
||||
STUB(gtk_widget_set_direction)
|
||||
STUB(gtk_widget_set_double_buffered)
|
||||
|
@ -93,67 +93,6 @@ NS_NewThread(nsIThread** aResult, nsIRunnable* aEvent, uint32_t aStackSize)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(MOZ_NUWA_PROCESS) && !defined(XPCOM_GLUE_AVOID_NSPR)
|
||||
|
||||
namespace {
|
||||
class IgnoreThreadStatusRunnable : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
private:
|
||||
virtual ~IgnoreThreadStatusRunnable() = default;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(IgnoreThreadStatusRunnable, nsIRunnable)
|
||||
|
||||
NS_IMETHODIMP IgnoreThreadStatusRunnable::Run(void)
|
||||
{
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
nsThreadManager::get()->SetIgnoreThreadStatus();
|
||||
return NS_OK;
|
||||
#endif
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
} // Anonymous namespace.
|
||||
#endif // defined(MOZ_NUWA_PROCESS) && !defined(XPCOM_GLUE_AVOID_NSPR)
|
||||
|
||||
NS_METHOD
|
||||
NS_NewUnmonitoredThread(nsIThread** aResult,
|
||||
nsIRunnable* aEvent,
|
||||
uint32_t aStackSize)
|
||||
{
|
||||
#if defined(MOZ_NUWA_PROCESS) && !defined(XPCOM_GLUE_AVOID_NSPR)
|
||||
// Hold a ref while dispatching the initial event to match NS_NewThread()
|
||||
nsCOMPtr<nsIThread> thread;
|
||||
nsresult rv = NS_NewThread(getter_AddRefs(thread), nullptr, aStackSize);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> ignoreme = new IgnoreThreadStatusRunnable();
|
||||
rv = thread->Dispatch(ignoreme, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aEvent) {
|
||||
rv = thread->Dispatch(aEvent, NS_DISPATCH_NORMAL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
*aResult = nullptr;
|
||||
thread.swap(*aResult);
|
||||
return rv;
|
||||
#else
|
||||
return NS_NewThread(aResult, aEvent, aStackSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
NS_GetCurrentThread(nsIThread** aResult)
|
||||
{
|
||||
|
@ -61,17 +61,6 @@ NS_NewThread(nsIThread** aResult,
|
||||
nsIRunnable* aInitialEvent = nullptr,
|
||||
uint32_t aStackSize = nsIThreadManager::DEFAULT_STACK_SIZE);
|
||||
|
||||
/**
|
||||
* Create a new thread that is ignored in thread status monitoring by default on
|
||||
* platforms with Nuwa process enabled. On non-Nuwa platforms, this function is
|
||||
* identical to NS_NewThread().
|
||||
*/
|
||||
extern NS_METHOD
|
||||
NS_NewUnmonitoredThread(nsIThread** aResult,
|
||||
nsIRunnable* aInitialEvent = nullptr,
|
||||
uint32_t aStackSize =
|
||||
nsIThreadManager::DEFAULT_STACK_SIZE);
|
||||
|
||||
/**
|
||||
* Creates a named thread, otherwise the same as NS_NewThread
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user