зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1540029 - part 8: Replace `HTMLEditRules::GetParagraphState()` with new stack only class r=m_kato
Differential Revision: https://phabricator.services.mozilla.com/D45790 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
75e563c076
Коммит
8b7e7ba3d1
|
@ -84,6 +84,7 @@ class InsertTextTransaction;
|
|||
class JoinNodeTransaction;
|
||||
class ListElementSelectionState;
|
||||
class ListItemElementSelectionState;
|
||||
class ParagraphStateAtSelection;
|
||||
class PlaceholderTransaction;
|
||||
class PresShell;
|
||||
class SplitNodeResult;
|
||||
|
@ -2675,6 +2676,7 @@ class EditorBase : public nsIEditor,
|
|||
friend class JoinNodeTransaction;
|
||||
friend class ListElementSelectionState;
|
||||
friend class ListItemElementSelectionState;
|
||||
friend class ParagraphStateAtSelection;
|
||||
friend class SplitNodeTransaction;
|
||||
friend class TextEditRules;
|
||||
friend class TypeInState;
|
||||
|
|
|
@ -1064,142 +1064,185 @@ static nsStaticAtom& MarginPropertyAtomForIndent(nsINode& aNode) {
|
|||
: *nsGkAtoms::marginLeft;
|
||||
}
|
||||
|
||||
nsresult HTMLEditRules::GetParagraphState(bool* aMixed, nsAString& outFormat) {
|
||||
if (NS_WARN_IF(!aMixed)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
ParagraphStateAtSelection::ParagraphStateAtSelection(HTMLEditor& aHTMLEditor,
|
||||
ErrorResult& aRv) {
|
||||
if (NS_WARN_IF(aHTMLEditor.Destroyed())) {
|
||||
aRv = EditorBase::ToGenericNSResult(NS_ERROR_EDITOR_DESTROYED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!CanHandleEditAction())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
// XXX Should we create another constructor which won't create
|
||||
// AutoEditActionDataSetter? Or should we create another
|
||||
// AutoEditActionDataSetter which won't nest edit action?
|
||||
EditorBase::AutoEditActionDataSetter editActionData(aHTMLEditor,
|
||||
EditAction::eNotEditing);
|
||||
if (NS_WARN_IF(!editActionData.CanHandle())) {
|
||||
aRv = EditorBase::ToGenericNSResult(NS_ERROR_EDITOR_DESTROYED);
|
||||
return;
|
||||
}
|
||||
|
||||
// This routine is *heavily* tied to our ui choices in the paragraph
|
||||
// style popup. I can't see a way around that.
|
||||
*aMixed = true;
|
||||
outFormat.Truncate(0);
|
||||
|
||||
AutoSafeEditorData setData(*this, *mHTMLEditor);
|
||||
|
||||
bool bMixed = false;
|
||||
// using "x" as an uninitialized value, since "" is meaningful
|
||||
nsAutoString formatStr(NS_LITERAL_STRING("x"));
|
||||
|
||||
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
|
||||
nsresult rv = GetParagraphFormatNodes(arrayOfNodes);
|
||||
AutoTArray<OwningNonNull<nsINode>, 64> arrayOfNodes;
|
||||
nsresult rv =
|
||||
CollectEditableFormatNodesInSelection(aHTMLEditor, arrayOfNodes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
// post process list. We need to replace any block nodes that are not format
|
||||
// nodes with their content. This is so we only have to look "up" the
|
||||
// hierarchy to find format nodes, instead of both up and down.
|
||||
// We need to append descendant format block if block nodes are not format
|
||||
// block. This is so we only have to look "up" the hierarchy to find
|
||||
// format nodes, instead of both up and down.
|
||||
for (int32_t i = arrayOfNodes.Length() - 1; i >= 0; i--) {
|
||||
auto& curNode = arrayOfNodes[i];
|
||||
auto& node = arrayOfNodes[i];
|
||||
nsAutoString format;
|
||||
// if it is a known format node we have it easy
|
||||
if (HTMLEditor::NodeIsBlockStatic(curNode) &&
|
||||
!HTMLEditUtils::IsFormatNode(curNode)) {
|
||||
// arrayOfNodes.RemoveObject(curNode);
|
||||
rv = AppendInnerFormatNodes(arrayOfNodes, curNode);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (HTMLEditor::NodeIsBlockStatic(node) &&
|
||||
!HTMLEditUtils::IsFormatNode(node)) {
|
||||
// XXX This RemoveObject() call has already been commented out and
|
||||
// the above comment explained we're trying to replace non-format
|
||||
// block nodes in the array. According to the following blocks and
|
||||
// `AppendDescendantFormatNodesAndFirstInlineNode()`, replacing
|
||||
// non-format block with descendants format blocks makes sense.
|
||||
// arrayOfNodes.RemoveObject(node);
|
||||
ParagraphStateAtSelection::AppendDescendantFormatNodesAndFirstInlineNode(
|
||||
arrayOfNodes, *node->AsElement());
|
||||
}
|
||||
}
|
||||
|
||||
// we might have an empty node list. if so, find selection parent
|
||||
// We might have an empty node list. if so, find selection parent
|
||||
// and put that on the list
|
||||
if (arrayOfNodes.IsEmpty()) {
|
||||
EditorRawDOMPoint atCaret(EditorBase::GetStartPoint(*SelectionRefPtr()));
|
||||
EditorRawDOMPoint atCaret(
|
||||
EditorBase::GetStartPoint(*aHTMLEditor.SelectionRefPtr()));
|
||||
if (NS_WARN_IF(!atCaret.IsSet())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
arrayOfNodes.AppendElement(*atCaret.GetContainer());
|
||||
}
|
||||
|
||||
// remember root node
|
||||
Element* rootElement = HTMLEditorRef().GetRoot();
|
||||
if (NS_WARN_IF(!rootElement)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
Element* bodyOrDocumentElement = aHTMLEditor.GetRoot();
|
||||
if (NS_WARN_IF(!bodyOrDocumentElement)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
// loop through the nodes in selection and examine their paragraph format
|
||||
for (auto& curNode : Reversed(arrayOfNodes)) {
|
||||
nsAutoString format;
|
||||
// if it is a known format node we have it easy
|
||||
if (HTMLEditUtils::IsFormatNode(curNode)) {
|
||||
GetFormatString(curNode, format);
|
||||
} else if (HTMLEditor::NodeIsBlockStatic(curNode)) {
|
||||
// this is a div or some other non-format block.
|
||||
// we should ignore it. Its children were appended to this list
|
||||
// by AppendInnerFormatNodes() call above. We will get needed
|
||||
// info when we examine them instead.
|
||||
for (auto& node : Reversed(arrayOfNodes)) {
|
||||
nsAtom* paragraphStateOfNode = nsGkAtoms::_empty;
|
||||
if (HTMLEditUtils::IsFormatNode(node)) {
|
||||
MOZ_ASSERT(node->NodeInfo()->NameAtom());
|
||||
paragraphStateOfNode = node->NodeInfo()->NameAtom();
|
||||
}
|
||||
// Ignore non-format block node since its children have been appended
|
||||
// the list above so that we'll handle this descendants later.
|
||||
else if (HTMLEditor::NodeIsBlockStatic(node)) {
|
||||
continue;
|
||||
} else {
|
||||
nsINode* node = curNode->GetParentNode();
|
||||
while (node) {
|
||||
if (node == rootElement) {
|
||||
format.Truncate(0);
|
||||
break;
|
||||
} else if (HTMLEditUtils::IsFormatNode(node)) {
|
||||
GetFormatString(node, format);
|
||||
}
|
||||
// If we meet an inline node, let's get its parent format.
|
||||
else {
|
||||
for (nsINode* parentNode = node->GetParentNode(); parentNode;
|
||||
parentNode = parentNode->GetParentNode()) {
|
||||
// If we reach `HTMLDocument.body` or `Document.documentElement`,
|
||||
// there is no format.
|
||||
if (parentNode == bodyOrDocumentElement) {
|
||||
break;
|
||||
}
|
||||
if (HTMLEditUtils::IsFormatNode(parentNode)) {
|
||||
MOZ_ASSERT(parentNode->NodeInfo()->NameAtom());
|
||||
paragraphStateOfNode = parentNode->NodeInfo()->NameAtom();
|
||||
break;
|
||||
}
|
||||
// else keep looking up
|
||||
node = node->GetParentNode();
|
||||
}
|
||||
}
|
||||
|
||||
// if this is the first node, we've found, remember it as the format
|
||||
if (formatStr.EqualsLiteral("x")) {
|
||||
formatStr = format;
|
||||
if (!mFirstParagraphState) {
|
||||
mFirstParagraphState = paragraphStateOfNode;
|
||||
continue;
|
||||
}
|
||||
// else make sure it matches previously found format
|
||||
else if (format != formatStr) {
|
||||
bMixed = true;
|
||||
if (mFirstParagraphState != paragraphStateOfNode) {
|
||||
mIsMixed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*aMixed = bMixed;
|
||||
outFormat = formatStr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditRules::AppendInnerFormatNodes(
|
||||
nsTArray<OwningNonNull<nsINode>>& aArray, nsINode* aNode) {
|
||||
MOZ_ASSERT(aNode);
|
||||
// static
|
||||
void ParagraphStateAtSelection::AppendDescendantFormatNodesAndFirstInlineNode(
|
||||
nsTArray<OwningNonNull<nsINode>>& aArrayOfNodes,
|
||||
Element& aNonFormatBlockElement) {
|
||||
MOZ_ASSERT(HTMLEditor::NodeIsBlockStatic(aNonFormatBlockElement));
|
||||
MOZ_ASSERT(!HTMLEditUtils::IsFormatNode(&aNonFormatBlockElement));
|
||||
|
||||
// we only need to place any one inline inside this node onto
|
||||
// We only need to place any one inline inside this node onto
|
||||
// the list. They are all the same for purposes of determining
|
||||
// paragraph style. We use foundInline to track this as we are
|
||||
// going through the children in the loop below.
|
||||
bool foundInline = false;
|
||||
for (nsIContent* child = aNode->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
bool isBlock = HTMLEditor::NodeIsBlockStatic(*child);
|
||||
bool isFormat = HTMLEditUtils::IsFormatNode(child);
|
||||
for (nsIContent* childContent = aNonFormatBlockElement.GetFirstChild();
|
||||
childContent; childContent = childContent->GetNextSibling()) {
|
||||
bool isBlock = HTMLEditor::NodeIsBlockStatic(*childContent);
|
||||
bool isFormat = HTMLEditUtils::IsFormatNode(childContent);
|
||||
// If the child is a non-format block element, let's check its children
|
||||
// recursively.
|
||||
if (isBlock && !isFormat) {
|
||||
// if it's a div, etc., recurse
|
||||
AppendInnerFormatNodes(aArray, child);
|
||||
} else if (isFormat) {
|
||||
aArray.AppendElement(*child);
|
||||
} else if (!foundInline) {
|
||||
// if this is the first inline we've found, use it
|
||||
ParagraphStateAtSelection::AppendDescendantFormatNodesAndFirstInlineNode(
|
||||
aArrayOfNodes, *childContent->AsElement());
|
||||
continue;
|
||||
}
|
||||
|
||||
// If it's a format block, append it.
|
||||
if (isFormat) {
|
||||
aArrayOfNodes.AppendElement(*childContent);
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!isBlock);
|
||||
|
||||
// If we haven't found inline node, append only this first inline node.
|
||||
// XXX I think that this makes sense if caller of this removes
|
||||
// aNonFormatBlockElement from aArrayOfNodes because the last loop of
|
||||
// the constructor can check parent format block with
|
||||
// aNonFormatBlockElement.
|
||||
if (!foundInline) {
|
||||
foundInline = true;
|
||||
aArray.AppendElement(*child);
|
||||
aArrayOfNodes.AppendElement(*childContent);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditRules::GetFormatString(nsINode* aNode, nsAString& outFormat) {
|
||||
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
|
||||
// static
|
||||
nsresult ParagraphStateAtSelection::CollectEditableFormatNodesInSelection(
|
||||
HTMLEditor& aHTMLEditor, nsTArray<OwningNonNull<nsINode>>& aArrayOfNodes) {
|
||||
nsresult rv = aHTMLEditor.CollectEditTargetNodesInExtendedSelectionRanges(
|
||||
aArrayOfNodes, EditSubAction::eCreateOrRemoveBlock,
|
||||
HTMLEditor::CollectNonEditableNodes::Yes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (HTMLEditUtils::IsFormatNode(aNode)) {
|
||||
aNode->NodeInfo()->NameAtom()->ToString(outFormat);
|
||||
} else {
|
||||
outFormat.Truncate();
|
||||
// Pre-process our list of nodes
|
||||
for (int32_t i = aArrayOfNodes.Length() - 1; i >= 0; i--) {
|
||||
OwningNonNull<nsINode> node = aArrayOfNodes[i];
|
||||
|
||||
// Remove all non-editable nodes. Leave them be.
|
||||
if (!aHTMLEditor.IsEditable(node)) {
|
||||
aArrayOfNodes.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Scan for table elements. If we find table elements other than table,
|
||||
// replace it with a list of any editable non-table content. Ditto for
|
||||
// list elements.
|
||||
if (HTMLEditUtils::IsTableElement(node) || HTMLEditUtils::IsList(node) ||
|
||||
HTMLEditUtils::IsListItem(node)) {
|
||||
aArrayOfNodes.RemoveElementAt(i);
|
||||
aHTMLEditor.CollectChildren(node, aArrayOfNodes, i,
|
||||
HTMLEditor::CollectListChildren::Yes,
|
||||
HTMLEditor::CollectTableChildren::Yes,
|
||||
HTMLEditor::CollectNonEditableNodes::Yes);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -7962,43 +8005,6 @@ Element* HTMLEditor::GetDeepestEditableOnlyChildDivBlockquoteOrListElement(
|
|||
return parentElement;
|
||||
}
|
||||
|
||||
nsresult HTMLEditRules::GetParagraphFormatNodes(
|
||||
nsTArray<OwningNonNull<nsINode>>& outArrayOfNodes) {
|
||||
MOZ_ASSERT(IsEditorDataAvailable());
|
||||
|
||||
nsresult rv = HTMLEditorRef().CollectEditTargetNodesInExtendedSelectionRanges(
|
||||
outArrayOfNodes, EditSubAction::eCreateOrRemoveBlock,
|
||||
HTMLEditor::CollectNonEditableNodes::Yes);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Pre-process our list of nodes
|
||||
for (int32_t i = outArrayOfNodes.Length() - 1; i >= 0; i--) {
|
||||
OwningNonNull<nsINode> testNode = outArrayOfNodes[i];
|
||||
|
||||
// Remove all non-editable nodes. Leave them be.
|
||||
if (!HTMLEditorRef().IsEditable(testNode)) {
|
||||
outArrayOfNodes.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Scan for table elements. If we find table elements other than table,
|
||||
// replace it with a list of any editable non-table content. Ditto for
|
||||
// list elements.
|
||||
if (HTMLEditUtils::IsTableElement(testNode) ||
|
||||
HTMLEditUtils::IsList(testNode) ||
|
||||
HTMLEditUtils::IsListItem(testNode)) {
|
||||
outArrayOfNodes.RemoveElementAt(i);
|
||||
HTMLEditorRef().CollectChildren(testNode, outArrayOfNodes, i,
|
||||
HTMLEditor::CollectListChildren::Yes,
|
||||
HTMLEditor::CollectTableChildren::Yes,
|
||||
HTMLEditor::CollectNonEditableNodes::Yes);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::SplitParentInlineElementsAtRangeEdges(
|
||||
RangeItem& aRangeItem) {
|
||||
MOZ_ASSERT(IsEditActionDataAvailable());
|
||||
|
|
|
@ -59,9 +59,6 @@ class HTMLEditRules : public TextEditRules {
|
|||
virtual nsresult Init(TextEditor* aTextEditor) override;
|
||||
virtual nsresult DetachEditor() override;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult GetParagraphState(bool* aMixed, nsAString& outFormat);
|
||||
|
||||
protected:
|
||||
virtual ~HTMLEditRules() = default;
|
||||
|
||||
|
@ -70,14 +67,6 @@ class HTMLEditRules : public TextEditRules {
|
|||
return mData->HTMLEditorRef();
|
||||
}
|
||||
|
||||
nsresult AppendInnerFormatNodes(nsTArray<OwningNonNull<nsINode>>& aArray,
|
||||
nsINode* aNode);
|
||||
nsresult GetFormatString(nsINode* aNode, nsAString& outFormat);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult GetParagraphFormatNodes(
|
||||
nsTArray<OwningNonNull<nsINode>>& outArrayOfNodes);
|
||||
|
||||
protected:
|
||||
HTMLEditor* mHTMLEditor;
|
||||
bool mInitialized;
|
||||
|
|
|
@ -1832,21 +1832,28 @@ nsresult HTMLEditor::SetParagraphFormatAsAction(
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLEditor::GetParagraphState(bool* aMixed, nsAString& outFormat) {
|
||||
HTMLEditor::GetParagraphState(bool* aMixed, nsAString& aFirstParagraphState) {
|
||||
if (NS_WARN_IF(!aMixed)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
if (!mRules) {
|
||||
if (!mInitSucceeded) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
|
||||
if (NS_WARN_IF(!editActionData.CanHandle())) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
ErrorResult error;
|
||||
ParagraphStateAtSelection state(*this, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
RefPtr<HTMLEditRules> htmlRules(mRules->AsHTMLEditRules());
|
||||
return htmlRules->GetParagraphState(aMixed, outFormat);
|
||||
*aMixed = state.IsMixed();
|
||||
if (NS_WARN_IF(!state.GetFirstParagraphStateAtSelection())) {
|
||||
// XXX Odd result, but keep this behavior for now...
|
||||
aFirstParagraphState.AssignASCII("x");
|
||||
} else {
|
||||
state.GetFirstParagraphStateAtSelection()->ToString(aFirstParagraphState);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -48,6 +48,7 @@ class EmptyEditableFunctor;
|
|||
class ListElementSelectionState;
|
||||
class ListItemElementSelectionState;
|
||||
class MoveNodeResult;
|
||||
class ParagraphStateAtSelection;
|
||||
class ResizerSelectionListener;
|
||||
class SplitRangeOffFromNodeResult;
|
||||
class WSRunObject;
|
||||
|
@ -4370,6 +4371,7 @@ class HTMLEditor final : public TextEditor,
|
|||
friend class HTMLEditRules;
|
||||
friend class ListElementSelectionState;
|
||||
friend class ListItemElementSelectionState;
|
||||
friend class ParagraphStateAtSelection;
|
||||
friend class SlurpBlobEventListener;
|
||||
friend class TextEditor;
|
||||
friend class WSRunObject;
|
||||
|
@ -4441,6 +4443,63 @@ class MOZ_STACK_CLASS AlignStateAtSelection final {
|
|||
nsIHTMLEditor::EAlignment mFirstAlign = nsIHTMLEditor::eLeft;
|
||||
};
|
||||
|
||||
/**
|
||||
* ParagraphStateAtSelection class gets format block types around selection.
|
||||
*/
|
||||
class MOZ_STACK_CLASS ParagraphStateAtSelection final {
|
||||
public:
|
||||
ParagraphStateAtSelection() = delete;
|
||||
ParagraphStateAtSelection(HTMLEditor& aHTMLEditor, ErrorResult& aRv);
|
||||
|
||||
/**
|
||||
* GetFirstParagraphStateAtSelection() returns:
|
||||
* - nullptr if there is no format blocks nor inline nodes.
|
||||
* - nsGkAtoms::_empty if first node is not in any format block.
|
||||
* - a tag name of format block at first node.
|
||||
* XXX See the private method explanations. If selection ranges contains
|
||||
* non-format block first, it'll be check after its siblings. Therefore,
|
||||
* this may return non-first paragraph state.
|
||||
*/
|
||||
nsAtom* GetFirstParagraphStateAtSelection() const {
|
||||
return mFirstParagraphState;
|
||||
}
|
||||
|
||||
/**
|
||||
* If selected nodes are not in same format node nor only in no-format blocks,
|
||||
* this returns true.
|
||||
*/
|
||||
bool IsMixed() const { return mIsMixed; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* AppendDescendantFormatNodesAndFirstInlineNode() appends descendant
|
||||
* format blocks and first inline child node in aNonFormatBlockElement to
|
||||
* the last of the array (not inserting where aNonFormatBlockElement is,
|
||||
* so that the node order becomes randomly).
|
||||
*
|
||||
* @param aArrayOfNodes [in/out] Found descendant format blocks
|
||||
* and first inline node in each non-format
|
||||
* block will be appended to this.
|
||||
* @param aNonFormatBlockElement Must be a non-format block element.
|
||||
*/
|
||||
static void AppendDescendantFormatNodesAndFirstInlineNode(
|
||||
nsTArray<OwningNonNull<nsINode>>& aArrayOfNodes,
|
||||
Element& aNonFormatBlockElement);
|
||||
|
||||
/**
|
||||
* CollectEditableFormatNodesInSelection() collects only editable nodes
|
||||
* around selection ranges (with
|
||||
* `HTMLEditor::CollectEditTargetNodesInExtendedSelectionRanges()`, see its
|
||||
* document for the detail). If it includes list, list item or table
|
||||
* related elements, they will be replaced their children.
|
||||
*/
|
||||
static nsresult CollectEditableFormatNodesInSelection(
|
||||
HTMLEditor& aHTMLEditor, nsTArray<OwningNonNull<nsINode>>& aArrayOfNodes);
|
||||
|
||||
RefPtr<nsAtom> mFirstParagraphState;
|
||||
bool mIsMixed = false;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
mozilla::HTMLEditor* nsIEditor::AsHTMLEditor() {
|
||||
|
|
|
@ -558,16 +558,21 @@ nsresult ParagraphStateCommand::GetCurrentState(
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
bool outMixed;
|
||||
nsAutoString outStateString;
|
||||
nsresult rv = aHTMLEditor->GetParagraphState(&outMixed, outStateString);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoCString tOutStateString;
|
||||
LossyCopyUTF16toASCII(outStateString, tOutStateString);
|
||||
aParams.SetBool(STATE_MIXED, outMixed);
|
||||
aParams.SetCString(STATE_ATTRIBUTE, tOutStateString);
|
||||
ErrorResult error;
|
||||
ParagraphStateAtSelection state(*aHTMLEditor, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
return rv;
|
||||
aParams.SetBool(STATE_MIXED, state.IsMixed());
|
||||
if (NS_WARN_IF(!state.GetFirstParagraphStateAtSelection())) {
|
||||
// XXX This is odd behavior, we should fix this later.
|
||||
aParams.SetCString(STATE_ATTRIBUTE, NS_LITERAL_CSTRING("x"));
|
||||
} else {
|
||||
nsCString paragraphState; // Don't use `nsAutoCString` for avoiding copy.
|
||||
state.GetFirstParagraphStateAtSelection()->ToUTF8String(paragraphState);
|
||||
aParams.SetCString(STATE_ATTRIBUTE, paragraphState);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult ParagraphStateCommand::SetState(HTMLEditor* aHTMLEditor,
|
||||
|
|
|
@ -219,7 +219,6 @@ interface nsIHTMLEditor : nsISupports
|
|||
* @param aMixed True if there is more than one format
|
||||
* @return Name of block tag. "" is returned for none.
|
||||
*/
|
||||
[can_run_script]
|
||||
AString getParagraphState(out boolean aMixed);
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче