mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1154701 part 13 - Clean up nsHTMLEditor::SetCSSBackgroundColor; r=ehsan
This commit is contained in:
parent
be20af1451
commit
bfb3f9c688
@ -4503,196 +4503,156 @@ nsHTMLEditor::SetIsCSSEnabled(bool aIsCSSPrefChecked)
|
|||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
|
nsHTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
|
||||||
{
|
{
|
||||||
if (!mRules) { return NS_ERROR_NOT_INITIALIZED; }
|
NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
|
||||||
ForceCompositionEnd();
|
ForceCompositionEnd();
|
||||||
|
|
||||||
// Protect the edit rules object from dying
|
// Protect the edit rules object from dying
|
||||||
nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
|
nsCOMPtr<nsIEditRules> kungFuDeathGrip(mRules);
|
||||||
|
|
||||||
nsRefPtr<Selection> selection = GetSelection();
|
nsRefPtr<Selection> selection = GetSelection();
|
||||||
|
NS_ENSURE_STATE(selection);
|
||||||
|
|
||||||
bool isCollapsed = selection->Collapsed();
|
bool isCollapsed = selection->Collapsed();
|
||||||
|
|
||||||
nsAutoEditBatch batchIt(this);
|
nsAutoEditBatch batchIt(this);
|
||||||
nsAutoRules beginRulesSniffing(this, EditAction::insertElement, nsIEditor::eNext);
|
nsAutoRules beginRulesSniffing(this, EditAction::insertElement,
|
||||||
|
nsIEditor::eNext);
|
||||||
nsAutoSelectionReset selectionResetter(selection, this);
|
nsAutoSelectionReset selectionResetter(selection, this);
|
||||||
nsAutoTxnsConserveSelection dontSpazMySelection(this);
|
nsAutoTxnsConserveSelection dontSpazMySelection(this);
|
||||||
|
|
||||||
bool cancel, handled;
|
bool cancel, handled;
|
||||||
nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
|
nsTextRulesInfo ruleInfo(EditAction::setTextProperty);
|
||||||
nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
if (!cancel && !handled)
|
if (!cancel && !handled) {
|
||||||
{
|
// Loop through the ranges in the selection
|
||||||
// loop thru the ranges in the selection
|
NS_NAMED_LITERAL_STRING(bgcolor, "bgcolor");
|
||||||
nsAutoString bgcolor; bgcolor.AssignLiteral("bgcolor");
|
for (uint32_t i = 0; i < selection->RangeCount(); i++) {
|
||||||
uint32_t rangeCount = selection->RangeCount();
|
nsRefPtr<nsRange> range = selection->GetRangeAt(i);
|
||||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
|
|
||||||
nsCOMPtr<nsIDOMNode> cachedBlockParent = nullptr;
|
|
||||||
nsRefPtr<nsRange> range = selection->GetRangeAt(rangeIdx);
|
|
||||||
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
// check for easy case: both range endpoints in same text node
|
nsCOMPtr<Element> cachedBlockParent;
|
||||||
nsCOMPtr<nsIDOMNode> startNode, endNode;
|
|
||||||
int32_t startOffset, endOffset;
|
// Check for easy case: both range endpoints in same text node
|
||||||
res = range->GetStartContainer(getter_AddRefs(startNode));
|
nsCOMPtr<nsINode> startNode = range->GetStartParent();
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
int32_t startOffset = range->StartOffset();
|
||||||
res = range->GetEndContainer(getter_AddRefs(endNode));
|
nsCOMPtr<nsINode> endNode = range->GetEndParent();
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
int32_t endOffset = range->EndOffset();
|
||||||
res = range->GetStartOffset(&startOffset);
|
if (startNode == endNode && IsTextNode(startNode)) {
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
// Let's find the block container of the text node
|
||||||
res = range->GetEndOffset(&endOffset);
|
nsCOMPtr<Element> blockParent = GetBlockNodeParent(startNode);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
// And apply the background color to that block container
|
||||||
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
|
|
||||||
if (blockParent && cachedBlockParent != blockParent) {
|
if (blockParent && cachedBlockParent != blockParent) {
|
||||||
cachedBlockParent = blockParent;
|
cachedBlockParent = blockParent;
|
||||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||||
int32_t count;
|
&bgcolor, &aColor, false);
|
||||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
}
|
}
|
||||||
}
|
} else if (startNode == endNode &&
|
||||||
else if ((startNode == endNode) && nsTextEditUtils::IsBody(startNode) && isCollapsed)
|
startNode->IsHTMLElement(nsGkAtoms::body) && isCollapsed) {
|
||||||
{
|
// No block in the document, let's apply the background to the body
|
||||||
// we have no block in the document, let's apply the background to the body
|
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(startNode->AsElement(),
|
||||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(startNode);
|
nullptr, &bgcolor, &aColor,
|
||||||
int32_t count;
|
false);
|
||||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
} else if (startNode == endNode && (endOffset - startOffset == 1 ||
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
(!startOffset && !endOffset))) {
|
||||||
}
|
// A unique node is selected, let's also apply the background color to
|
||||||
else if ((startNode == endNode) && (((endOffset-startOffset) == 1) || (!startOffset && !endOffset)))
|
// the containing block, possibly the node itself
|
||||||
{
|
nsCOMPtr<nsIContent> selectedNode = startNode->GetChildAt(startOffset);
|
||||||
// a unique node is selected, let's also apply the background color
|
nsCOMPtr<Element> blockParent;
|
||||||
// to the containing block, possibly the node itself
|
if (NodeIsBlockStatic(selectedNode)) {
|
||||||
nsCOMPtr<nsIDOMNode> selectedNode = GetChildAt(startNode, startOffset);
|
blockParent = selectedNode->AsElement();
|
||||||
bool isBlock =false;
|
} else {
|
||||||
res = NodeIsBlockStatic(selectedNode, &isBlock);
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
nsCOMPtr<nsIDOMNode> blockParent = selectedNode;
|
|
||||||
if (!isBlock) {
|
|
||||||
blockParent = GetBlockNodeParent(selectedNode);
|
blockParent = GetBlockNodeParent(selectedNode);
|
||||||
}
|
}
|
||||||
if (blockParent && cachedBlockParent != blockParent) {
|
if (blockParent && cachedBlockParent != blockParent) {
|
||||||
cachedBlockParent = blockParent;
|
cachedBlockParent = blockParent;
|
||||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||||
int32_t count;
|
&bgcolor, &aColor, false);
|
||||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
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
|
||||||
// not the easy case. range not contained in single text node.
|
// the subtree iterator to be processed. And there are potentially a
|
||||||
// there are up to three phases here. There are all the nodes
|
// starting textnode and an ending textnode which are only partially
|
||||||
// reported by the subtree iterator to be processed. And there
|
// contained by the range.
|
||||||
// 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 =
|
// Let's handle the nodes reported by the iterator. These nodes are
|
||||||
do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);
|
// entirely contained in the selection range. We build up a list of
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
// them (since doing operations on the document during iteration would
|
||||||
NS_ENSURE_TRUE(iter, NS_ERROR_FAILURE);
|
// perturb the iterator).
|
||||||
|
|
||||||
nsCOMArray<nsIDOMNode> arrayOfNodes;
|
OwningNonNull<nsIContentIterator> iter =
|
||||||
nsCOMPtr<nsIDOMNode> node;
|
NS_NewContentSubtreeIterator();
|
||||||
|
|
||||||
// iterate range and build up array
|
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
|
||||||
|
nsCOMPtr<nsINode> node;
|
||||||
|
|
||||||
|
// Iterate range and build up array
|
||||||
res = iter->Init(range);
|
res = iter->Init(range);
|
||||||
// init returns an error if no nodes in range.
|
// Init returns an error if no nodes in range. This can easily happen
|
||||||
// this can easily happen with the subtree
|
// with the subtree iterator if the selection doesn't contain any
|
||||||
// iterator if the selection doesn't contain
|
// *whole* nodes.
|
||||||
// any *whole* nodes.
|
if (NS_SUCCEEDED(res)) {
|
||||||
if (NS_SUCCEEDED(res))
|
for (; !iter->IsDone(); iter->Next()) {
|
||||||
{
|
|
||||||
while (!iter->IsDone())
|
|
||||||
{
|
|
||||||
node = do_QueryInterface(iter->GetCurrentNode());
|
node = do_QueryInterface(iter->GetCurrentNode());
|
||||||
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
if (IsEditable(node))
|
if (IsEditable(node)) {
|
||||||
{
|
arrayOfNodes.AppendElement(*node);
|
||||||
arrayOfNodes.AppendObject(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iter->Next();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// first check the start parent of the range to see if it needs to
|
// First check the start parent of the range to see if it needs to be
|
||||||
// be separately handled (it does if it's a text node, due to how the
|
// separately handled (it does if it's a text node, due to how the
|
||||||
// subtree iterator works - it will not have reported it).
|
// subtree iterator works - it will not have reported it).
|
||||||
if (IsTextNode(startNode) && IsEditable(startNode))
|
if (IsTextNode(startNode) && IsEditable(startNode)) {
|
||||||
{
|
nsCOMPtr<Element> blockParent = GetBlockNodeParent(startNode);
|
||||||
nsCOMPtr<nsIDOMNode> blockParent;
|
|
||||||
blockParent = GetBlockNodeParent(startNode);
|
|
||||||
if (blockParent && cachedBlockParent != blockParent) {
|
if (blockParent && cachedBlockParent != blockParent) {
|
||||||
cachedBlockParent = blockParent;
|
cachedBlockParent = blockParent;
|
||||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||||
int32_t count;
|
&bgcolor, &aColor,
|
||||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
false);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// then loop through the list, set the property on each node
|
// Then loop through the list, set the property on each node
|
||||||
int32_t listCount = arrayOfNodes.Count();
|
for (auto& node : arrayOfNodes) {
|
||||||
int32_t j;
|
nsCOMPtr<Element> blockParent;
|
||||||
for (j = 0; j < listCount; j++)
|
if (NodeIsBlockStatic(node)) {
|
||||||
{
|
blockParent = node->AsElement();
|
||||||
node = arrayOfNodes[j];
|
} else {
|
||||||
// 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
|
|
||||||
blockParent = GetBlockNodeParent(node);
|
blockParent = GetBlockNodeParent(node);
|
||||||
}
|
}
|
||||||
if (blockParent && cachedBlockParent != blockParent) {
|
if (blockParent && cachedBlockParent != blockParent) {
|
||||||
cachedBlockParent = blockParent;
|
cachedBlockParent = blockParent;
|
||||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||||
int32_t count;
|
&bgcolor, &aColor,
|
||||||
// and set the property on it
|
false);
|
||||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
arrayOfNodes.Clear();
|
arrayOfNodes.Clear();
|
||||||
|
|
||||||
// last check the end parent of the range to see if it needs to
|
// Last, check the end parent of the range to see if it needs to be
|
||||||
// be separately handled (it does if it's a text node, due to how the
|
// separately handled (it does if it's a text node, due to how the
|
||||||
// subtree iterator works - it will not have reported it).
|
// subtree iterator works - it will not have reported it).
|
||||||
if (IsTextNode(endNode) && IsEditable(endNode))
|
if (IsTextNode(endNode) && IsEditable(endNode)) {
|
||||||
{
|
nsCOMPtr<Element> blockParent = GetBlockNodeParent(endNode);
|
||||||
nsCOMPtr<nsIDOMNode> blockParent;
|
|
||||||
blockParent = GetBlockNodeParent(endNode);
|
|
||||||
if (blockParent && cachedBlockParent != blockParent) {
|
if (blockParent && cachedBlockParent != blockParent) {
|
||||||
cachedBlockParent = blockParent;
|
cachedBlockParent = blockParent;
|
||||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(blockParent);
|
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(blockParent, nullptr,
|
||||||
int32_t count;
|
&bgcolor, &aColor,
|
||||||
res = mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(element, nullptr, &bgcolor, &aColor, &count, false);
|
false);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!cancel)
|
if (!cancel) {
|
||||||
{
|
// Post-process
|
||||||
// post-process
|
|
||||||
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
res = mRules->DidDoAction(selection, &ruleInfo, res);
|
||||||
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
}
|
}
|
||||||
return res;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
Loading…
Reference in New Issue
Block a user