Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp
Warning:line 100, column 9
Value stored to 'end' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_editor_libeditor0.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/editor/libeditor -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/editor/libeditor -resource-dir /usr/lib/llvm-19/lib/clang/19 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/editor/libeditor -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/html -I /var/lib/jenkins/workspace/firefox-scan-build/extensions/spellcheck/src -I /var/lib/jenkins/workspace/firefox-scan-build/layout/generic -I /var/lib/jenkins/workspace/firefox-scan-build/layout/style -I /var/lib/jenkins/workspace/firefox-scan-build/layout/tables -I /var/lib/jenkins/workspace/firefox-scan-build/layout/xul -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-09-22-115206-3586786-1 -x c++ Unified_cpp_editor_libeditor0.cpp
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6#include "ChangeStyleTransaction.h"
7
8#include "HTMLEditUtils.h"
9#include "mozilla/Logging.h"
10#include "mozilla/ToString.h"
11#include "mozilla/dom/Element.h" // for Element
12#include "nsAString.h" // for nsAString::Append, etc.
13#include "nsCRT.h" // for nsCRT::IsAsciiSpace
14#include "nsDebug.h" // for NS_WARNING, etc.
15#include "nsError.h" // for NS_ERROR_NULL_POINTER, etc.
16#include "nsGkAtoms.h" // for nsGkAtoms, etc.
17#include "nsICSSDeclaration.h" // for nsICSSDeclaration.
18#include "nsLiteralString.h" // for NS_LITERAL_STRING, etc.
19#include "nsReadableUtils.h" // for ToNewUnicode
20#include "nsString.h" // for nsAutoString, nsString, etc.
21#include "nsStyledElement.h" // for nsStyledElement.
22#include "nsUnicharUtils.h" // for nsCaseInsensitiveStringComparator
23
24namespace mozilla {
25
26using namespace dom;
27
28// static
29already_AddRefed<ChangeStyleTransaction> ChangeStyleTransaction::Create(
30 nsStyledElement& aStyledElement, nsAtom& aProperty,
31 const nsAString& aValue) {
32 RefPtr<ChangeStyleTransaction> transaction =
33 new ChangeStyleTransaction(aStyledElement, aProperty, aValue, false);
34 return transaction.forget();
35}
36
37// static
38already_AddRefed<ChangeStyleTransaction> ChangeStyleTransaction::CreateToRemove(
39 nsStyledElement& aStyledElement, nsAtom& aProperty,
40 const nsAString& aValue) {
41 RefPtr<ChangeStyleTransaction> transaction =
42 new ChangeStyleTransaction(aStyledElement, aProperty, aValue, true);
43 return transaction.forget();
44}
45
46ChangeStyleTransaction::ChangeStyleTransaction(nsStyledElement& aStyledElement,
47 nsAtom& aProperty,
48 const nsAString& aValue,
49 bool aRemove)
50 : EditTransactionBase(),
51 mStyledElement(&aStyledElement),
52 mProperty(&aProperty),
53 mRemoveProperty(aRemove),
54 mUndoAttributeWasSet(false),
55 mRedoAttributeWasSet(false) {
56 CopyUTF16toUTF8(aValue, mValue);
57}
58
59std::ostream& operator<<(std::ostream& aStream,
60 const ChangeStyleTransaction& aTransaction) {
61 aStream << "{ mStyledElement=" << aTransaction.mStyledElement.get();
62 if (aTransaction.mStyledElement) {
63 aStream << " (" << *aTransaction.mStyledElement << ")";
64 }
65 aStream << ", mProperty=" << nsAtomCString(aTransaction.mProperty).get()
66 << ", mValue=\"" << aTransaction.mValue.get() << "\", mUndoValue=\""
67 << aTransaction.mUndoValue.get()
68 << "\", mRedoValue=" << aTransaction.mRedoValue.get()
69 << ", mRemoveProperty="
70 << (aTransaction.mRemoveProperty ? "true" : "false")
71 << ", mUndoAttributeWasSet="
72 << (aTransaction.mUndoAttributeWasSet ? "true" : "false")
73 << ", mRedoAttributeWasSet="
74 << (aTransaction.mRedoAttributeWasSet ? "true" : "false") << " }";
75 return aStream;
76}
77
78#define kNullCh('\0') ('\0')
79
80NS_IMPL_CYCLE_COLLECTION_INHERITED(ChangeStyleTransaction, EditTransactionBase,ChangeStyleTransaction::cycleCollection ChangeStyleTransaction
::_cycleCollectorGlobal; void ChangeStyleTransaction::cycleCollection
::Unlink(void* p) { ChangeStyleTransaction* tmp = DowncastCCParticipant
<ChangeStyleTransaction>(p); nsISupports* s = static_cast
<nsISupports*>(p); EditTransactionBase::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mStyledElement
); (void)tmp; } nsresult ChangeStyleTransaction::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { ChangeStyleTransaction* tmp = DowncastCCParticipant
<ChangeStyleTransaction>(p); nsISupports* s = static_cast
<nsISupports*>(p); if (EditTransactionBase::cycleCollection
::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mStyledElement, "mStyledElement", 0); (void)tmp;
return NS_OK; }
81 mStyledElement)ChangeStyleTransaction::cycleCollection ChangeStyleTransaction
::_cycleCollectorGlobal; void ChangeStyleTransaction::cycleCollection
::Unlink(void* p) { ChangeStyleTransaction* tmp = DowncastCCParticipant
<ChangeStyleTransaction>(p); nsISupports* s = static_cast
<nsISupports*>(p); EditTransactionBase::cycleCollection
::Unlink(s); ImplCycleCollectionUnlink(tmp->mStyledElement
); (void)tmp; } nsresult ChangeStyleTransaction::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { ChangeStyleTransaction* tmp = DowncastCCParticipant
<ChangeStyleTransaction>(p); nsISupports* s = static_cast
<nsISupports*>(p); if (EditTransactionBase::cycleCollection
::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE; } ImplCycleCollectionTraverse
(cb, tmp->mStyledElement, "mStyledElement", 0); (void)tmp;
return NS_OK; }
82
83NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ChangeStyleTransaction)nsresult ChangeStyleTransaction::QueryInterface(const nsIID&
aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 83); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>::
kIID), (nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports
, void>::kIID)) && (LowWordEquals(aIID, (nsXPCOMCycleCollectionParticipant
::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>::
kIID)) || LowWordEquals(aIID, (nsCycleCollectionISupports::COMTypeInfo
<nsCycleCollectionISupports, void>::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::COMTypeInfo<nsXPCOMCycleCollectionParticipant
, void>::kIID))) { *aInstancePtr = ChangeStyleTransaction::
cycleCollection::GetParticipant(); return NS_OK; } if (LowWordEquals
(aIID, (nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports
, void>::kIID))) { *aInstancePtr = ChangeStyleTransaction::
cycleCollection::Upcast(this); return NS_OK; } foundInterface
= nullptr; } else
84NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase)foundInterface = 0; nsresult status; if (!foundInterface) status
= EditTransactionBase::QueryInterface(aIID, (void**)&foundInterface
); else { (foundInterface)->AddRef(); status = NS_OK; } *aInstancePtr
= foundInterface; return status; }
85
86NS_IMPL_ADDREF_INHERITED(ChangeStyleTransaction, EditTransactionBase)MozExternalRefCountType ChangeStyleTransaction::AddRef(void) {
static_assert(!std::is_destructible_v<ChangeStyleTransaction
>, "Reference-counted class " "ChangeStyleTransaction" " should not have a public destructor. "
"Make this class's destructor non-public"); nsrefcnt r = EditTransactionBase
::AddRef(); if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt
<ChangeStyleTransaction>) { NS_LogAddRef((this), (r), (
"ChangeStyleTransaction"), (uint32_t)(sizeof(*this))); } return
r; }
87NS_IMPL_RELEASE_INHERITED(ChangeStyleTransaction, EditTransactionBase)MozExternalRefCountType ChangeStyleTransaction::Release(void)
{ nsrefcnt r = EditTransactionBase::Release(); if constexpr (
::mozilla::detail::ShouldLogInheritedRefcnt<ChangeStyleTransaction
>) { NS_LogRelease((this), (r), ("ChangeStyleTransaction")
); } return r; }
88
89// Answers true if aValue is in the string list of white-space separated values
90// aValueList.
91bool ChangeStyleTransaction::ValueIncludes(const nsACString& aValueList,
92 const nsACString& aValue) {
93 nsAutoCString valueList(aValueList);
94 bool result = false;
95
96 // put an extra null at the end
97 valueList.Append(kNullCh('\0'));
98
99 char* start = valueList.BeginWriting();
100 char* end = start;
Value stored to 'end' during its initialization is never read
101
102 while (kNullCh('\0') != *start) {
103 while (kNullCh('\0') != *start && nsCRT::IsAsciiSpace(*start)) {
104 // skip leading space
105 start++;
106 }
107 end = start;
108
109 while (kNullCh('\0') != *end && !nsCRT::IsAsciiSpace(*end)) {
110 // look for space or end
111 end++;
112 }
113 // end string here
114 *end = kNullCh('\0');
115
116 if (start < end) {
117 if (aValue.Equals(nsDependentCString(start),
118 nsCaseInsensitiveCStringComparator)) {
119 result = true;
120 break;
121 }
122 }
123 start = ++end;
124 }
125 return result;
126}
127
128NS_IMETHODIMPnsresult ChangeStyleTransaction::DoTransaction() {
129 MOZ_LOG(GetLogModule(), LogLevel::Info,do { const ::mozilla::LogModule* moz_real_module = GetLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "%p ChangeStyleTransaction::%s this=%s", this
, __FUNCTION__, ToString(*this).c_str()); } } while (0)
130 ("%p ChangeStyleTransaction::%s this=%s", this, __FUNCTION__,do { const ::mozilla::LogModule* moz_real_module = GetLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "%p ChangeStyleTransaction::%s this=%s", this
, __FUNCTION__, ToString(*this).c_str()); } } while (0)
131 ToString(*this).c_str()))do { const ::mozilla::LogModule* moz_real_module = GetLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "%p ChangeStyleTransaction::%s this=%s", this
, __FUNCTION__, ToString(*this).c_str()); } } while (0)
;
132
133 if (NS_WARN_IF(!mStyledElement)NS_warn_if_impl(!mStyledElement, "!mStyledElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 133)
) {
134 return NS_ERROR_NOT_AVAILABLE;
135 }
136
137 OwningNonNull<nsStyledElement> styledElement = *mStyledElement;
138 nsCOMPtr<nsICSSDeclaration> cssDecl = styledElement->Style();
139
140 // FIXME(bug 1606994): Using atoms forces a string copy here which is not
141 // great.
142 nsAutoCString propertyNameString;
143 mProperty->ToUTF8String(propertyNameString);
144
145 mUndoAttributeWasSet = mStyledElement->HasAttr(nsGkAtoms::style);
146
147 nsAutoCString values;
148 cssDecl->GetPropertyValue(propertyNameString, values);
149 mUndoValue.Assign(values);
150
151 if (mRemoveProperty) {
152 nsAutoCString returnString;
153 if (mProperty == nsGkAtoms::text_decoration) {
154 BuildTextDecorationValueToRemove(values, mValue, values);
155 if (values.IsEmpty()) {
156 ErrorResult error;
157 cssDecl->RemoveProperty(propertyNameString, returnString, error);
158 if (MOZ_UNLIKELY(error.Failed())(__builtin_expect(!!(error.Failed()), 0))) {
159 NS_WARNING("nsICSSDeclaration::RemoveProperty() failed")NS_DebugBreak(NS_DEBUG_WARNING, "nsICSSDeclaration::RemoveProperty() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 159)
;
160 return error.StealNSResult();
161 }
162 } else {
163 ErrorResult error;
164 nsAutoCString priority;
165 cssDecl->GetPropertyPriority(propertyNameString, priority);
166 cssDecl->SetProperty(propertyNameString, values, priority, error);
167 if (MOZ_UNLIKELY(error.Failed())(__builtin_expect(!!(error.Failed()), 0))) {
168 NS_WARNING("nsICSSDeclaration::SetProperty() failed")NS_DebugBreak(NS_DEBUG_WARNING, "nsICSSDeclaration::SetProperty() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 168)
;
169 return error.StealNSResult();
170 }
171 }
172 } else {
173 ErrorResult error;
174 cssDecl->RemoveProperty(propertyNameString, returnString, error);
175 if (MOZ_UNLIKELY(error.Failed())(__builtin_expect(!!(error.Failed()), 0))) {
176 NS_WARNING("nsICSSDeclaration::RemoveProperty() failed")NS_DebugBreak(NS_DEBUG_WARNING, "nsICSSDeclaration::RemoveProperty() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 176)
;
177 return error.StealNSResult();
178 }
179 }
180 } else {
181 nsAutoCString priority;
182 cssDecl->GetPropertyPriority(propertyNameString, priority);
183 if (mProperty == nsGkAtoms::text_decoration) {
184 BuildTextDecorationValueToSet(values, mValue, values);
185 } else {
186 values.Assign(mValue);
187 }
188 ErrorResult error;
189 cssDecl->SetProperty(propertyNameString, values, priority, error);
190 if (MOZ_UNLIKELY(error.Failed())(__builtin_expect(!!(error.Failed()), 0))) {
191 NS_WARNING("nsICSSDeclaration::SetProperty() failed")NS_DebugBreak(NS_DEBUG_WARNING, "nsICSSDeclaration::SetProperty() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 191)
;
192 return error.StealNSResult();
193 }
194 }
195
196 // Let's be sure we don't keep an empty style attribute
197 uint32_t length = cssDecl->Length();
198 if (!length) {
199 nsresult rv =
200 styledElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::style, true);
201 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
202 NS_WARNING("Element::UnsetAttr(nsGkAtoms::style) failed")NS_DebugBreak(NS_DEBUG_WARNING, "Element::UnsetAttr(nsGkAtoms::style) failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 202)
;
203 return rv;
204 }
205 } else {
206 mRedoAttributeWasSet = true;
207 }
208
209 cssDecl->GetPropertyValue(propertyNameString, mRedoValue);
210 return NS_OK;
211}
212
213nsresult ChangeStyleTransaction::SetStyle(bool aAttributeWasSet,
214 nsACString& aValue) {
215 if (NS_WARN_IF(!mStyledElement)NS_warn_if_impl(!mStyledElement, "!mStyledElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 215)
) {
216 return NS_ERROR_NOT_AVAILABLE;
217 }
218
219 if (aAttributeWasSet) {
220 OwningNonNull<nsStyledElement> styledElement = *mStyledElement;
221
222 // The style attribute was not empty, let's recreate the declaration
223 nsAutoCString propertyNameString;
224 mProperty->ToUTF8String(propertyNameString);
225
226 nsCOMPtr<nsICSSDeclaration> cssDecl = styledElement->Style();
227
228 ErrorResult error;
229 if (aValue.IsEmpty()) {
230 // An empty value means we have to remove the property
231 nsAutoCString returnString;
232 cssDecl->RemoveProperty(propertyNameString, returnString, error);
233 if (MOZ_UNLIKELY(error.Failed())(__builtin_expect(!!(error.Failed()), 0))) {
234 NS_WARNING("nsICSSDeclaration::RemoveProperty() failed")NS_DebugBreak(NS_DEBUG_WARNING, "nsICSSDeclaration::RemoveProperty() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 234)
;
235 return error.StealNSResult();
236 }
237 }
238 // Let's recreate the declaration as it was
239 nsAutoCString priority;
240 cssDecl->GetPropertyPriority(propertyNameString, priority);
241 cssDecl->SetProperty(propertyNameString, aValue, priority, error);
242 NS_WARNING_ASSERTION(!error.Failed(),do { if (!(!error.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING
, "nsICSSDeclaration::SetProperty() failed", "!error.Failed()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 243); } } while (false)
243 "nsICSSDeclaration::SetProperty() failed")do { if (!(!error.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING
, "nsICSSDeclaration::SetProperty() failed", "!error.Failed()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 243); } } while (false)
;
244 return error.StealNSResult();
245 }
246
247 OwningNonNull<nsStyledElement> styledElement = *mStyledElement;
248 nsresult rv =
249 styledElement->UnsetAttr(kNameSpaceID_None, nsGkAtoms::style, true);
250 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "Element::UnsetAttr(nsGkAtoms::style) failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 251); } } while (false)
251 "Element::UnsetAttr(nsGkAtoms::style) failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "Element::UnsetAttr(nsGkAtoms::style) failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 251); } } while (false)
;
252 return rv;
253}
254
255NS_IMETHODIMPnsresult ChangeStyleTransaction::UndoTransaction() {
256 MOZ_LOG(GetLogModule(), LogLevel::Info,do { const ::mozilla::LogModule* moz_real_module = GetLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "%p ChangeStyleTransaction::%s this=%s", this
, __FUNCTION__, ToString(*this).c_str()); } } while (0)
257 ("%p ChangeStyleTransaction::%s this=%s", this, __FUNCTION__,do { const ::mozilla::LogModule* moz_real_module = GetLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "%p ChangeStyleTransaction::%s this=%s", this
, __FUNCTION__, ToString(*this).c_str()); } } while (0)
258 ToString(*this).c_str()))do { const ::mozilla::LogModule* moz_real_module = GetLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "%p ChangeStyleTransaction::%s this=%s", this
, __FUNCTION__, ToString(*this).c_str()); } } while (0)
;
259
260 nsresult rv = SetStyle(mUndoAttributeWasSet, mUndoValue);
261 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "ChangeStyleTransaction::SetStyle() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 262); } } while (false)
262 "ChangeStyleTransaction::SetStyle() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "ChangeStyleTransaction::SetStyle() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 262); } } while (false)
;
263 return rv;
264}
265
266NS_IMETHODIMPnsresult ChangeStyleTransaction::RedoTransaction() {
267 MOZ_LOG(GetLogModule(), LogLevel::Info,do { const ::mozilla::LogModule* moz_real_module = GetLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "%p ChangeStyleTransaction::%s this=%s", this
, __FUNCTION__, ToString(*this).c_str()); } } while (0)
268 ("%p ChangeStyleTransaction::%s this=%s", this, __FUNCTION__,do { const ::mozilla::LogModule* moz_real_module = GetLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "%p ChangeStyleTransaction::%s this=%s", this
, __FUNCTION__, ToString(*this).c_str()); } } while (0)
269 ToString(*this).c_str()))do { const ::mozilla::LogModule* moz_real_module = GetLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Info)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Info, "%p ChangeStyleTransaction::%s this=%s", this
, __FUNCTION__, ToString(*this).c_str()); } } while (0)
;
270
271 nsresult rv = SetStyle(mRedoAttributeWasSet, mRedoValue);
272 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "ChangeStyleTransaction::SetStyle() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 273); } } while (false)
273 "ChangeStyleTransaction::SetStyle() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "ChangeStyleTransaction::SetStyle() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/ChangeStyleTransaction.cpp"
, 273); } } while (false)
;
274 return rv;
275}
276
277// static
278void ChangeStyleTransaction::BuildTextDecorationValueToSet(
279 const nsACString& aCurrentValues, const nsACString& aAddingValues,
280 nsACString& aOutValues) {
281 const bool underline = ValueIncludes(aCurrentValues, "underline"_ns) ||
282 ValueIncludes(aAddingValues, "underline"_ns);
283 const bool overline = ValueIncludes(aCurrentValues, "overline"_ns) ||
284 ValueIncludes(aAddingValues, "overline"_ns);
285 const bool lineThrough = ValueIncludes(aCurrentValues, "line-through"_ns) ||
286 ValueIncludes(aAddingValues, "line-through"_ns);
287 // FYI: Don't refer aCurrentValues which may refer same instance as
288 // aOutValues.
289 BuildTextDecorationValue(underline, overline, lineThrough, aOutValues);
290}
291
292// static
293void ChangeStyleTransaction::BuildTextDecorationValueToRemove(
294 const nsACString& aCurrentValues, const nsACString& aRemovingValues,
295 nsACString& aOutValues) {
296 const bool underline = ValueIncludes(aCurrentValues, "underline"_ns) &&
297 !ValueIncludes(aRemovingValues, "underline"_ns);
298 const bool overline = ValueIncludes(aCurrentValues, "overline"_ns) &&
299 !ValueIncludes(aRemovingValues, "overline"_ns);
300 const bool lineThrough = ValueIncludes(aCurrentValues, "line-through"_ns) &&
301 !ValueIncludes(aRemovingValues, "line-through"_ns);
302 // FYI: Don't refer aCurrentValues which may refer same instance as
303 // aOutValues.
304 BuildTextDecorationValue(underline, overline, lineThrough, aOutValues);
305}
306
307void ChangeStyleTransaction::BuildTextDecorationValue(bool aUnderline,
308 bool aOverline,
309 bool aLineThrough,
310 nsACString& aOutValues) {
311 // We should build text-decoration(-line) value as same as Blink for
312 // compatibility. Blink sets text-decoration-line to the values in the
313 // following order. Blink drops `blink` and other styles like color and
314 // style. For keeping the code simple, let's use the lossy behavior.
315 aOutValues.Truncate();
316 if (aUnderline) {
317 aOutValues.AssignLiteral("underline");
318 }
319 if (aOverline) {
320 if (!aOutValues.IsEmpty()) {
321 aOutValues.Append(HTMLEditUtils::kSpace);
322 }
323 aOutValues.AppendLiteral("overline");
324 }
325 if (aLineThrough) {
326 if (!aOutValues.IsEmpty()) {
327 aOutValues.Append(HTMLEditUtils::kSpace);
328 }
329 aOutValues.AppendLiteral("line-through");
330 }
331}
332
333} // namespace mozilla