зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to inbound. a=merge CLOSED TREE
This commit is contained in:
Коммит
f4b7b652c4
|
@ -216,6 +216,10 @@ add_task(async function testBookmarkButtonPress() {
|
|||
forceFocus(button);
|
||||
let panel = document.getElementById("editBookmarkPanel");
|
||||
let focused = BrowserTestUtils.waitForEvent(panel, "focus", true);
|
||||
// The button ignores activation while the bookmarked status is being
|
||||
// updated. So, wait for it to finish updating.
|
||||
await TestUtils.waitForCondition(() =>
|
||||
BookmarkingUI.status != BookmarkingUI.STATUS_UPDATING);
|
||||
EventUtils.synthesizeKey(" ");
|
||||
await focused;
|
||||
ok(true, "Focus inside edit bookmark panel after Bookmark button pressed");
|
||||
|
|
|
@ -750,6 +750,7 @@ async function getAllPrincipals(progress) {
|
|||
progress.step = "principals-quota-manager";
|
||||
let principals = await new Promise(resolve => {
|
||||
quotaManagerService.getUsage(request => {
|
||||
progress.step = "principals-quota-manager-getUsage";
|
||||
if (request.resultCode != Cr.NS_OK) {
|
||||
// We are probably shutting down. We don't want to propagate the
|
||||
// error, rejecting the promise.
|
||||
|
@ -765,6 +766,8 @@ async function getAllPrincipals(progress) {
|
|||
list.push(principal);
|
||||
}
|
||||
}
|
||||
|
||||
progress.step = "principals-quota-manager-completed";
|
||||
resolve(list);
|
||||
});
|
||||
}).catch(() => []);
|
||||
|
|
|
@ -126,6 +126,7 @@ skip-if = (os == "linux") # Bug 1356214
|
|||
skip-if = (verify && debug && os == 'win')
|
||||
[browser_rules_edit-property-remove_02.js]
|
||||
[browser_rules_edit-property-remove_03.js]
|
||||
[browser_rules_edit-property-remove_04.js]
|
||||
[browser_rules_edit-property_01.js]
|
||||
[browser_rules_edit-property_02.js]
|
||||
[browser_rules_edit-property_03.js]
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tests that removing the only declaration from a rule and unselecting then re-selecting
|
||||
// the element will not restore the removed declaration. Bug 1512956
|
||||
|
||||
const TEST_URI = `
|
||||
<style type='text/css'>
|
||||
#testid {
|
||||
color: #00F;
|
||||
}
|
||||
</style>
|
||||
<div id='testid'>Styled Node</div>
|
||||
<div id='empty'></div>
|
||||
`;
|
||||
|
||||
add_task(async function() {
|
||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
const {inspector, view} = await openRuleView();
|
||||
|
||||
info("Select original node");
|
||||
await selectNode("#testid", inspector);
|
||||
|
||||
info("Get the first property in the #testid rule");
|
||||
const rule = getRuleViewRuleEditor(view, 1).rule;
|
||||
const prop = rule.textProps[0];
|
||||
|
||||
info("Delete the property name to remove the declaration");
|
||||
const onRuleViewChanged = view.once("ruleview-changed");
|
||||
await removeProperty(view, prop, false);
|
||||
info("Wait for Rule view to update");
|
||||
await onRuleViewChanged;
|
||||
|
||||
is(rule.textProps.length, 0, "No CSS properties left on the rule");
|
||||
|
||||
info("Select another node");
|
||||
await selectNode("#empty", inspector);
|
||||
|
||||
info("Select original node again");
|
||||
await selectNode("#testid", inspector);
|
||||
|
||||
is(rule.textProps.length, 0, "Still no CSS properties on the rule");
|
||||
});
|
|
@ -425,10 +425,6 @@ checkbox:-moz-focusring {
|
|||
background-image: url("chrome://devtools/skin/images/clear.svg");
|
||||
}
|
||||
|
||||
.devtools-button.devtools-filter-icon::before {
|
||||
background-image: url("chrome://devtools/skin/images/filter.svg");
|
||||
}
|
||||
|
||||
.devtools-toolbarbutton.devtools-clear-icon {
|
||||
list-style-image: url("chrome://devtools/skin/images/clear.svg");
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ class FilterBar extends Component {
|
|||
dispatch: PropTypes.func.isRequired,
|
||||
filter: PropTypes.object.isRequired,
|
||||
attachRefToWebConsoleUI: PropTypes.func.isRequired,
|
||||
filterBarVisible: PropTypes.bool.isRequired,
|
||||
persistLogs: PropTypes.bool.isRequired,
|
||||
hidePersistLogsCheckbox: PropTypes.bool.isRequired,
|
||||
filteredMessagesCount: PropTypes.object.isRequired,
|
||||
|
@ -64,7 +63,6 @@ class FilterBar extends Component {
|
|||
shouldComponentUpdate(nextProps, nextState) {
|
||||
const {
|
||||
filter,
|
||||
filterBarVisible,
|
||||
persistLogs,
|
||||
filteredMessagesCount,
|
||||
closeButtonVisible,
|
||||
|
@ -74,10 +72,6 @@ class FilterBar extends Component {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (nextProps.filterBarVisible !== filterBarVisible) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (nextProps.persistLogs !== persistLogs) {
|
||||
return true;
|
||||
}
|
||||
|
@ -306,7 +300,6 @@ function mapStateToProps(state) {
|
|||
const uiState = getAllUi(state);
|
||||
return {
|
||||
filter: getAllFilters(state),
|
||||
filterBarVisible: uiState.filterBarVisible,
|
||||
persistLogs: uiState.persistLogs,
|
||||
filteredMessagesCount: getFilteredMessagesCount(state),
|
||||
closeButtonVisible: uiState.closeButtonVisible,
|
||||
|
|
|
@ -47,14 +47,6 @@ add_task(async function() {
|
|||
|
||||
async function getFilterButtons(hud) {
|
||||
const outputNode = hud.ui.outputNode;
|
||||
info("Wait for console toolbar to appear");
|
||||
const toolbar = await waitFor(() => {
|
||||
return outputNode.querySelector(".webconsole-filterbar-primary");
|
||||
});
|
||||
// Show the filter bar if it is hidden
|
||||
if (!outputNode.querySelector(".webconsole-filterbar-secondary")) {
|
||||
toolbar.querySelector(".devtools-filter-icon").click();
|
||||
}
|
||||
|
||||
info("Wait for console filterbar to appear");
|
||||
const filterBar = await waitFor(() => {
|
||||
|
|
|
@ -1265,9 +1265,11 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
|
|||
// and so that we can safely determine if a declaration is valid rather than
|
||||
// have the client guess it.
|
||||
if (form.authoredText || form.cssText) {
|
||||
const declarations = parseNamedDeclarations(isCssPropertyKnown,
|
||||
form.authoredText || form.cssText,
|
||||
true);
|
||||
// authoredText may be an empty string when deleting all properties; it's ok to use.
|
||||
const cssText = (typeof form.authoredText === "string")
|
||||
? form.authoredText
|
||||
: form.cssText;
|
||||
const declarations = parseNamedDeclarations(isCssPropertyKnown, cssText, true);
|
||||
|
||||
// We need to grab CSS from the window, since calling supports() on the
|
||||
// one from the current global will fail due to not being an HTML global.
|
||||
|
|
|
@ -133,7 +133,9 @@ class StyleRuleFront extends FrontClassWithSpec(styleRuleSpec) {
|
|||
return this._form.cssText;
|
||||
}
|
||||
get authoredText() {
|
||||
return this._form.authoredText || this._form.cssText;
|
||||
return (typeof this._form.authoredText === "string")
|
||||
? this._form.authoredText
|
||||
: this._form.cssText;
|
||||
}
|
||||
get declarations() {
|
||||
return this._form.declarations || [];
|
||||
|
|
|
@ -85,6 +85,15 @@ nsresult WMFDecoderModule::Startup() {
|
|||
|
||||
already_AddRefed<MediaDataDecoder> WMFDecoderModule::CreateVideoDecoder(
|
||||
const CreateDecoderParams& aParams) {
|
||||
|
||||
// Temporary - forces use of VPXDecoder when alpha is present.
|
||||
// Bug 1263836 will handle alpha scenario once implemented. It will shift
|
||||
// the check for alpha to PDMFactory but not itself remove the need for a
|
||||
// check.
|
||||
if (aParams.VideoConfig().HasAlpha()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoPtr<WMFVideoMFTManager> manager(new WMFVideoMFTManager(
|
||||
aParams.VideoConfig(), aParams.mKnowsCompositor, aParams.mImageContainer,
|
||||
aParams.mRate.mValue, aParams.mOptions, sDXVAEnabled));
|
||||
|
|
|
@ -22,11 +22,15 @@
|
|||
let video = appendVideoToDoc(test.name, token);
|
||||
manager.started(token);
|
||||
|
||||
let visible = waitUntilVisible(video)
|
||||
let ended = nextVideoEnded(video);
|
||||
let playing = nextVideoPlaying(video);
|
||||
let resumes = nextVideoResumes(video);
|
||||
let suspends = nextVideoSuspends(video);
|
||||
|
||||
Log(token, "Waiting until video becomes visible");
|
||||
await visible;
|
||||
|
||||
Log(token, "Start playing");
|
||||
video.play();
|
||||
|
||||
|
|
|
@ -332,7 +332,9 @@ nsresult EditorBase::PostCreate() {
|
|||
// value first.
|
||||
mFlags = ~mFlags;
|
||||
nsresult rv = SetFlags(~mFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
// These operations only need to happen on the first PostCreate call
|
||||
if (!mDidPostCreate) {
|
||||
|
@ -341,7 +343,9 @@ nsresult EditorBase::PostCreate() {
|
|||
// Set up listeners
|
||||
CreateEventListeners();
|
||||
rv = InstallEventListeners();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
// nuke the modification count, so the doc appears unmodified
|
||||
// do this before we notify listeners
|
||||
|
@ -363,8 +367,9 @@ nsresult EditorBase::PostCreate() {
|
|||
mEventListener->SpellCheckIfNeeded();
|
||||
|
||||
IMEState newState;
|
||||
rv = GetPreferredIMEState(&newState);
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
if (NS_WARN_IF(NS_FAILED(GetPreferredIMEState(&newState)))) {
|
||||
return NS_OK;
|
||||
}
|
||||
// May be null in design mode
|
||||
nsCOMPtr<nsIContent> content = GetFocusedContentForIME();
|
||||
IMEStateManager::UpdateIMEState(newState, content, this);
|
||||
|
@ -710,7 +715,8 @@ EditorBase::DoTransaction(nsITransaction* aTxn) {
|
|||
if (NS_WARN_IF(!editActionData.CanHandle())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// This is a low level API. So, the caller might require raw error code.
|
||||
// Therefore, don't need to use EditorBase::ToGenericNSResult().
|
||||
return DoTransactionInternal(aTxn);
|
||||
}
|
||||
|
||||
|
@ -972,6 +978,8 @@ EditorBase::SelectAll() {
|
|||
|
||||
nsresult rv = SelectAllInternal();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// This is low level API for XUL applcation. So, we should return raw
|
||||
// error code here.
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -1005,7 +1013,9 @@ EditorBase::BeginningOfDocument() {
|
|||
|
||||
// get the root element
|
||||
dom::Element* rootElement = GetRoot();
|
||||
NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
|
||||
if (NS_WARN_IF(!rootElement)) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
// find first editable thingy
|
||||
nsCOMPtr<nsINode> firstNode = GetFirstEditableNode(rootElement);
|
||||
|
@ -1037,7 +1047,13 @@ EditorBase::EndOfDocument() {
|
|||
if (NS_WARN_IF(!editActionData.CanHandle())) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return CollapseSelectionToEnd();
|
||||
nsresult rv = CollapseSelectionToEnd();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// This is low level API for XUL applcation. So, we should return raw
|
||||
// error code here.
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditorBase::CollapseSelectionToEnd() {
|
||||
|
@ -1155,7 +1171,11 @@ EditorBase::SetAttribute(Element* aElement, const nsAString& aAttribute,
|
|||
}
|
||||
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
|
||||
return SetAttributeWithTransaction(*aElement, *attribute, aValue);
|
||||
nsresult rv = SetAttributeWithTransaction(*aElement, *attribute, aValue);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditorBase::SetAttributeWithTransaction(Element& aElement,
|
||||
|
@ -1198,7 +1218,11 @@ EditorBase::RemoveAttribute(Element* aElement, const nsAString& aAttribute) {
|
|||
}
|
||||
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
|
||||
return RemoveAttributeWithTransaction(*aElement, *attribute);
|
||||
nsresult rv = RemoveAttributeWithTransaction(*aElement, *attribute);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditorBase::RemoveAttributeWithTransaction(Element& aElement,
|
||||
|
@ -1367,8 +1391,12 @@ EditorBase::InsertNode(nsINode* aNodeToInsert, nsINode* aContainer,
|
|||
aOffset < 0
|
||||
? static_cast<int32_t>(aContainer->Length())
|
||||
: std::min(aOffset, static_cast<int32_t>(aContainer->Length()));
|
||||
return InsertNodeWithTransaction(*contentToInsert,
|
||||
EditorRawDOMPoint(aContainer, offset));
|
||||
nsresult rv = InsertNodeWithTransaction(
|
||||
*contentToInsert, EditorRawDOMPoint(aContainer, offset));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template <typename PT, typename CT>
|
||||
|
@ -1424,7 +1452,7 @@ EditorBase::SplitNode(nsINode* aNode, int32_t aOffset, nsINode** aNewLeftNode) {
|
|||
SplitNodeWithTransaction(EditorRawDOMPoint(aNode, offset), error);
|
||||
newNode.forget(aNewLeftNode);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1497,7 +1525,11 @@ EditorBase::JoinNodes(nsINode* aLeftNode, nsINode* aRightNode, nsINode*) {
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return JoinNodesWithTransaction(*aLeftNode, *aRightNode);
|
||||
nsresult rv = JoinNodesWithTransaction(*aLeftNode, *aRightNode);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditorBase::JoinNodesWithTransaction(nsINode& aLeftNode,
|
||||
|
@ -1569,7 +1601,11 @@ EditorBase::DeleteNode(nsINode* aNode) {
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return DeleteNodeWithTransaction(*aNode);
|
||||
nsresult rv = DeleteNodeWithTransaction(*aNode);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditorBase::DeleteNodeWithTransaction(nsINode& aNode) {
|
||||
|
@ -2262,8 +2298,12 @@ EditorBase::CloneAttribute(const nsAString& aAttribute, Element* aDestElement,
|
|||
}
|
||||
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
|
||||
return CloneAttributeWithTransaction(*attribute, *aDestElement,
|
||||
*aSourceElement);
|
||||
nsresult rv =
|
||||
CloneAttributeWithTransaction(*attribute, *aDestElement, *aSourceElement);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditorBase::CloneAttributeWithTransaction(nsAtom& aAttribute,
|
||||
|
@ -2977,6 +3017,22 @@ void EditorBase::DoSplitNode(const EditorDOMPoint& aStartOfRightNode,
|
|||
|
||||
// We don't need to set selection here because the caller should do that
|
||||
// in any case.
|
||||
|
||||
// If splitting the node causes running mutation event listener and we've
|
||||
// got unexpected result, we should return error because callers will
|
||||
// continue to do their work without complicated DOM tree result.
|
||||
// NOTE: Perhaps, we shouldn't do this immediately after each DOM tree change
|
||||
// because stopping handling it causes some data loss. E.g., user
|
||||
// may loose the text which is moved to the new text node.
|
||||
// XXX We cannot check all descendants in the right node and the new left
|
||||
// node for performance reason. I think that if caller needs to access
|
||||
// some of the descendants, they should check by themselves.
|
||||
if (NS_WARN_IF(parent != aStartOfRightNode.GetContainer()->GetParentNode()) ||
|
||||
NS_WARN_IF(parent != aNewLeftNode.GetParentNode()) ||
|
||||
NS_WARN_IF(aNewLeftNode.GetNextSibling() !=
|
||||
aStartOfRightNode.GetContainer())) {
|
||||
aError.Throw(NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult EditorBase::DoJoinNodes(nsINode* aNodeToKeep, nsINode* aNodeToJoin,
|
||||
|
@ -4218,8 +4274,12 @@ EditorBase::SetAttributeOrEquivalent(Element* aElement,
|
|||
}
|
||||
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
|
||||
return SetAttributeOrEquivalent(aElement, attribute, aValue,
|
||||
aSuppressTransaction);
|
||||
nsresult rv = SetAttributeOrEquivalent(aElement, attribute, aValue,
|
||||
aSuppressTransaction);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -4236,7 +4296,12 @@ EditorBase::RemoveAttributeOrEquivalent(Element* aElement,
|
|||
}
|
||||
|
||||
RefPtr<nsAtom> attribute = NS_Atomize(aAttribute);
|
||||
return RemoveAttributeOrEquivalent(aElement, attribute, aSuppressTransaction);
|
||||
nsresult rv =
|
||||
RemoveAttributeOrEquivalent(aElement, attribute, aSuppressTransaction);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EditorBase::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent) {
|
||||
|
@ -4416,7 +4481,9 @@ nsresult EditorBase::FinalizeSelection() {
|
|||
SelectionRefPtr()->SetAncestorLimiter(nullptr);
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_INITIALIZED);
|
||||
if (NS_WARN_IF(!presShell)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (RefPtr<nsCaret> caret = presShell->GetCaret()) {
|
||||
caret->SetIgnoreUserModify(true);
|
||||
|
@ -4425,7 +4492,9 @@ nsresult EditorBase::FinalizeSelection() {
|
|||
selectionController->SetCaretEnabled(false);
|
||||
|
||||
nsFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
NS_ENSURE_TRUE(fm, NS_ERROR_NOT_INITIALIZED);
|
||||
if (NS_WARN_IF(!fm)) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
fm->UpdateCaretForCaretBrowsingMode();
|
||||
|
||||
if (!HasIndependentSelection()) {
|
||||
|
@ -4537,20 +4606,20 @@ nsresult EditorBase::ToggleTextDirection() {
|
|||
|
||||
nsresult rv = DetermineCurrentDirection();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
if (IsRightToLeft()) {
|
||||
editActionData.SetData(NS_LITERAL_STRING("ltr"));
|
||||
nsresult rv = SetTextDirectionTo(TextDirection::eLTR);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
} else if (IsLeftToRight()) {
|
||||
editActionData.SetData(NS_LITERAL_STRING("rtl"));
|
||||
nsresult rv = SetTextDirectionTo(TextDirection::eRTL);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT_UNREACHABLE(
|
||||
|
|
|
@ -1838,6 +1838,29 @@ class EditorBase : public nsIEditor,
|
|||
*/
|
||||
virtual ~EditorBase();
|
||||
|
||||
/**
|
||||
* ToGenericNSResult() computes proper nsresult value for the editor users.
|
||||
* This should be used only when public methods return result of internal
|
||||
* methods.
|
||||
*/
|
||||
static inline nsresult ToGenericNSResult(nsresult aRv) {
|
||||
switch (aRv) {
|
||||
// If the editor is destroyed while handling an edit action, editor needs
|
||||
// to stop handling it. However, editor throw exception in this case
|
||||
// because Chrome does not throw exception even in this case.
|
||||
case NS_ERROR_EDITOR_DESTROYED:
|
||||
return NS_OK;
|
||||
// If editor meets unexpected DOM tree due to modified by mutation event
|
||||
// listener, editor needs to stop handling it. However, editor shouldn't
|
||||
// return error for the users because Chrome does not throw exception in
|
||||
// this case.
|
||||
case NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE:
|
||||
return NS_OK;
|
||||
default:
|
||||
return aRv;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GetDocumentCharsetInternal() returns charset of the document.
|
||||
*/
|
||||
|
|
|
@ -470,11 +470,6 @@ PasteTransferableCommand::DoCommandParams(const char* aCommandName,
|
|||
TextEditor* textEditor = editor->AsTextEditor();
|
||||
MOZ_ASSERT(textEditor);
|
||||
nsresult rv = textEditor->PasteTransferable(trans);
|
||||
if (rv == NS_ERROR_EDITOR_DESTROYED) {
|
||||
// Return NS_OK when editor is destroyed since it's expected by the
|
||||
// web app.
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1098,11 +1093,6 @@ PasteQuotationCommand::DoCommand(const char* aCommandName,
|
|||
MOZ_ASSERT(textEditor);
|
||||
nsresult rv = textEditor->PasteAsQuotationAsAction(
|
||||
nsIClipboard::kGlobalClipboard, true);
|
||||
if (rv == NS_ERROR_EDITOR_DESTROYED) {
|
||||
// Return NS_OK when editor is destroyed since it's expected by the
|
||||
// web app.
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -1121,11 +1111,6 @@ PasteQuotationCommand::DoCommandParams(const char* aCommandName,
|
|||
MOZ_ASSERT(textEditor);
|
||||
nsresult rv = textEditor->PasteAsQuotationAsAction(
|
||||
nsIClipboard::kGlobalClipboard, true);
|
||||
if (rv == NS_ERROR_EDITOR_DESTROYED) {
|
||||
// Return NS_OK when editor is destroyed since it's expected by the
|
||||
// web app.
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -805,11 +805,6 @@ nsresult EditorEventListener::Drop(DragEvent* aDragEvent) {
|
|||
|
||||
RefPtr<TextEditor> textEditor = mEditorBase->AsTextEditor();
|
||||
nsresult rv = textEditor->OnDrop(aDragEvent);
|
||||
if (rv == NS_ERROR_EDITOR_DESTROYED) {
|
||||
// If the editor has been destroyed, it means that this is handled as
|
||||
// expected by the web app. So, return NS_OK.
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -71,12 +71,12 @@ nsresult HTMLEditor::SetSelectionToAbsoluteOrStatic(bool aEnabled) {
|
|||
RefPtr<TextEditRules> rules(mRules);
|
||||
nsresult rv = rules->WillDoAction(subActionInfo, &cancel, &handled);
|
||||
if (NS_FAILED(rv) || cancel) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
rv = rules->DidDoAction(subActionInfo, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -167,12 +167,12 @@ nsresult HTMLEditor::AddZIndex(int32_t aChange) {
|
|||
RefPtr<TextEditRules> rules(mRules);
|
||||
nsresult rv = rules->WillDoAction(subActionInfo, &cancel, &handled);
|
||||
if (cancel || NS_FAILED(rv)) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
rv = rules->DidDoAction(subActionInfo, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ HTMLEditor::RefreshGrabber() {
|
|||
|
||||
nsresult rv = RefreshGrabberInternal();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ HTMLEditor::CheckSelectionStateForAnonymousButtons() {
|
|||
|
||||
nsresult rv = RefereshEditingUI();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -181,13 +181,8 @@ HTMLEditor::InsertHTML(const nsAString& aInString) {
|
|||
nsresult rv = DoInsertHTMLWithContext(aInString, EmptyString(), EmptyString(),
|
||||
EmptyString(), nullptr,
|
||||
EditorDOMPoint(), true, true, false);
|
||||
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
||||
// Return NS_OK when editor is destroyed since it's expected by the
|
||||
// web app.
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -983,19 +978,15 @@ nsresult HTMLEditor::BlobReader::OnResult(const nsACString& aResult) {
|
|||
nsAutoString stuffToPaste;
|
||||
nsresult rv = ImgFromData(type, aResult, stuffToPaste);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
AutoPlaceholderBatch treatAsOneTransaction(*mHTMLEditor);
|
||||
rv = mHTMLEditor->DoInsertHTMLWithContext(
|
||||
stuffToPaste, EmptyString(), EmptyString(), NS_LITERAL_STRING(kFileMime),
|
||||
mSourceDoc, mPointToInsert, mDoDeleteSelection, mIsSafe, false);
|
||||
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
||||
// Return NS_OK if the editor is destroyed since the web app expects it.
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1556,7 +1547,7 @@ nsresult HTMLEditor::PasteTransferable(nsITransferable* aTransferable) {
|
|||
nsresult rv = InsertFromTransferable(aTransferable, nullptr, contextStr,
|
||||
infoStr, false, true);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1583,14 +1574,16 @@ HTMLEditor::PasteNoFormatting(int32_t aSelectionType) {
|
|||
nsresult rv;
|
||||
nsCOMPtr<nsIClipboard> clipboard(
|
||||
do_GetService("@mozilla.org/widget/clipboard;1", &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Get the nsITransferable interface for getting the data from the clipboard.
|
||||
// use TextEditor::PrepareTransferable() to force unicode plaintext data.
|
||||
nsCOMPtr<nsITransferable> trans;
|
||||
rv = TextEditor::PrepareTransferable(getter_AddRefs(trans));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (!trans) {
|
||||
return NS_OK;
|
||||
|
@ -1608,13 +1601,8 @@ HTMLEditor::PasteNoFormatting(int32_t aSelectionType) {
|
|||
|
||||
const nsString& empty = EmptyString();
|
||||
rv = InsertFromTransferable(trans, nullptr, empty, empty, false, true);
|
||||
if (NS_WARN_IF(rv == NS_ERROR_EDITOR_DESTROYED)) {
|
||||
// Return NS_OK when editor is destroyed since it's expected by the
|
||||
// web app.
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1717,7 +1705,11 @@ nsresult HTMLEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
|
|||
|
||||
if (IsPlaintextEditor()) {
|
||||
// XXX In this case, we don't dispatch ePaste event. Why?
|
||||
return PasteAsPlaintextQuotation(aClipboardType);
|
||||
nsresult rv = PasteAsPlaintextQuotation(aClipboardType);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If it's not in plain text edit mode, paste text into new
|
||||
|
@ -1733,7 +1725,7 @@ nsresult HTMLEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
|
|||
RefPtr<TextEditRules> rules(mRules);
|
||||
nsresult rv = rules->WillDoAction(subActionInfo, &cancel, &handled);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (cancel || handled) {
|
||||
return NS_OK;
|
||||
|
@ -1763,7 +1755,7 @@ nsresult HTMLEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
|
|||
// will be dispatched by PasteInternal().
|
||||
rv = PasteInternal(aClipboardType, aDispatchPasteEvent);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1829,7 +1821,7 @@ nsresult HTMLEditor::InsertTextWithQuotations(
|
|||
|
||||
nsresult rv = InsertTextWithQuotationsInternal(aStringToInsert);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1936,7 +1928,7 @@ nsresult HTMLEditor::InsertAsQuotation(const nsAString& aQuotedText,
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this);
|
||||
nsresult rv = InsertAsPlaintextQuotation(aQuotedText, true, aNodeInserted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1952,7 +1944,7 @@ nsresult HTMLEditor::InsertAsQuotation(const nsAString& aQuotedText,
|
|||
nsresult rv = InsertAsCitedQuotationInternal(aQuotedText, citation, false,
|
||||
aNodeInserted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2078,7 +2070,7 @@ HTMLEditor::Rewrap(bool aRespectNewlines) {
|
|||
nsIDocumentEncoder::OutputLFLineBreak,
|
||||
&isCollapsed, current);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
nsString wrapped;
|
||||
|
@ -2087,7 +2079,7 @@ HTMLEditor::Rewrap(bool aRespectNewlines) {
|
|||
rv = InternetCiter::Rewrap(current, wrapWidth, firstLineOffset,
|
||||
aRespectNewlines, wrapped);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
if (isCollapsed) {
|
||||
|
@ -2102,7 +2094,7 @@ HTMLEditor::Rewrap(bool aRespectNewlines) {
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this);
|
||||
rv = InsertTextWithQuotationsInternal(wrapped);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2127,7 +2119,7 @@ HTMLEditor::InsertAsCitedQuotation(const nsAString& aQuotedText,
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this);
|
||||
nsresult rv = InsertAsPlaintextQuotation(aQuotedText, true, aNodeInserted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2142,7 +2134,7 @@ HTMLEditor::InsertAsCitedQuotation(const nsAString& aQuotedText,
|
|||
nsresult rv = InsertAsCitedQuotationInternal(aQuotedText, aCitation,
|
||||
aInsertHTML, aNodeInserted);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -195,7 +195,7 @@ HTMLEditor::RefreshResizers() {
|
|||
|
||||
nsresult rv = RefreshResizersInternal();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -435,7 +435,7 @@ HTMLEditor::HideResizers() {
|
|||
|
||||
nsresult rv = HideResizersInternal();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -622,7 +622,11 @@ nsresult HTMLEditor::OnMouseDown(int32_t aClientX, int32_t aClientY,
|
|||
aEvent->PreventDefault();
|
||||
mOriginalX = aClientX;
|
||||
mOriginalY = aClientY;
|
||||
return StartResizing(aTarget);
|
||||
nsresult rv = StartResizing(aTarget);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (anonclass.EqualsLiteral("mozGrabber")) {
|
||||
|
@ -635,7 +639,11 @@ nsresult HTMLEditor::OnMouseDown(int32_t aClientX, int32_t aClientY,
|
|||
// let's start moving the element!
|
||||
mOriginalX = aClientX;
|
||||
mOriginalY = aClientY;
|
||||
return GrabberClicked();
|
||||
nsresult rv = GrabberClicked();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -207,7 +207,9 @@ nsresult HTMLEditor::DoInlineTableEditingAction(const Element& aElement) {
|
|||
RefPtr<Element> tableElement = GetEnclosingTable(mInlineEditedCell);
|
||||
int32_t rowCount, colCount;
|
||||
nsresult rv = GetTableSize(tableElement, &rowCount, &colCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
bool hideUI = false;
|
||||
bool hideResizersWithInlineTableUI = (mResizedObject == tableElement);
|
||||
|
@ -315,7 +317,7 @@ HTMLEditor::RefreshInlineTableEditingUI() {
|
|||
|
||||
nsresult rv = RefreshInlineTableEditingUIInternal();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -87,18 +87,18 @@ nsresult HTMLEditor::SetInlinePropertyAsAction(nsAtom& aProperty,
|
|||
// Superscript and Subscript styles are mutually exclusive.
|
||||
nsresult rv = RemoveInlinePropertyInternal(nsGkAtoms::sub, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
} else if (&aProperty == nsGkAtoms::sub) {
|
||||
// Superscript and Subscript styles are mutually exclusive.
|
||||
nsresult rv = RemoveInlinePropertyInternal(nsGkAtoms::sup, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
}
|
||||
nsresult rv = SetInlinePropertyInternal(aProperty, aAttribute, aValue);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -131,7 +131,11 @@ HTMLEditor::SetInlineProperty(const nsAString& aProperty,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return SetInlinePropertyInternal(*property, attribute, aValue);
|
||||
nsresult rv = SetInlinePropertyInternal(*property, attribute, aValue);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::SetInlinePropertyInternal(nsAtom& aProperty,
|
||||
|
@ -1189,8 +1193,12 @@ nsresult HTMLEditor::GetInlineProperty(nsAtom* aProperty, nsAtom* aAttribute,
|
|||
|
||||
const nsAString* val = nullptr;
|
||||
if (!aValue.IsEmpty()) val = &aValue;
|
||||
return GetInlinePropertyBase(*aProperty, aAttribute, val, aFirst, aAny, aAll,
|
||||
nullptr);
|
||||
nsresult rv = GetInlinePropertyBase(*aProperty, aAttribute, val, aFirst, aAny,
|
||||
aAll, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1220,8 +1228,12 @@ nsresult HTMLEditor::GetInlinePropertyWithAttrValue(
|
|||
|
||||
const nsAString* val = nullptr;
|
||||
if (!aValue.IsEmpty()) val = &aValue;
|
||||
return GetInlinePropertyBase(*aProperty, aAttribute, val, aFirst, aAny, aAll,
|
||||
&outValue);
|
||||
nsresult rv = GetInlinePropertyBase(*aProperty, aAttribute, val, aFirst, aAny,
|
||||
aAll, &outValue);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1237,7 +1249,9 @@ HTMLEditor::RemoveAllInlineProperties() {
|
|||
*this, EditSubAction::eRemoveAllTextProperties, nsIEditor::eNext);
|
||||
|
||||
nsresult rv = RemoveInlinePropertyInternal(nullptr, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1263,7 +1277,7 @@ nsresult HTMLEditor::RemoveInlinePropertyAsAction(nsAtom& aProperty,
|
|||
}
|
||||
nsresult rv = RemoveInlinePropertyInternal(&aProperty, aAttribute);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1292,7 +1306,11 @@ HTMLEditor::RemoveInlineProperty(const nsAString& aProperty,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
return RemoveInlinePropertyInternal(property, attribute);
|
||||
nsresult rv = RemoveInlinePropertyInternal(property, attribute);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::RemoveInlinePropertyInternal(nsAtom* aProperty,
|
||||
|
@ -1455,7 +1473,11 @@ HTMLEditor::IncreaseFontSize() {
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return RelativeFontChange(FontSize::incr);
|
||||
nsresult rv = RelativeFontChange(FontSize::incr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1466,7 +1488,11 @@ HTMLEditor::DecreaseFontSize() {
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return RelativeFontChange(FontSize::decr);
|
||||
nsresult rv = RelativeFontChange(FontSize::decr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult HTMLEditor::RelativeFontChange(FontSize aDir) {
|
||||
|
@ -1809,7 +1835,9 @@ HTMLEditor::GetFontFaceState(bool* aMixed, nsAString& outFace) {
|
|||
|
||||
nsresult rv = GetInlinePropertyBase(*nsGkAtoms::font, nsGkAtoms::face,
|
||||
nullptr, &first, &any, &all, &outFace);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (any && !all) {
|
||||
return NS_OK; // mixed
|
||||
}
|
||||
|
@ -1821,9 +1849,11 @@ HTMLEditor::GetFontFaceState(bool* aMixed, nsAString& outFace) {
|
|||
// if there is no font face, check for tt
|
||||
rv = GetInlinePropertyBase(*nsGkAtoms::tt, nullptr, nullptr, &first, &any,
|
||||
&all, nullptr);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (any && !all) {
|
||||
return rv; // mixed
|
||||
return EditorBase::ToGenericNSResult(rv); // mixed
|
||||
}
|
||||
if (all) {
|
||||
*aMixed = false;
|
||||
|
@ -1855,7 +1885,7 @@ nsresult HTMLEditor::GetFontColorState(bool* aMixed, nsAString& aOutColor) {
|
|||
nsresult rv = GetInlinePropertyBase(*nsGkAtoms::font, nsGkAtoms::color,
|
||||
nullptr, &first, &any, &all, &aOutColor);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
if (any && !all) {
|
||||
|
|
|
@ -161,7 +161,7 @@ HTMLEditor::InsertTableCell(int32_t aNumberOfCellsToInsert,
|
|||
? InsertPosition::eAfterSelectedCell
|
||||
: InsertPosition::eBeforeSelectedCell);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ HTMLEditor::GetFirstRow(Element* aTableOrElementInTable,
|
|||
RefPtr<Element> firstRowElement =
|
||||
GetFirstTableRowElement(*aTableOrElementInTable, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
firstRowElement.forget(aFirstRowElement);
|
||||
return NS_OK;
|
||||
|
@ -578,7 +578,7 @@ HTMLEditor::InsertTableRow(int32_t aNumberOfRowsToInsert,
|
|||
? InsertPosition::eAfterSelectedCell
|
||||
: InsertPosition::eBeforeSelectedCell);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -837,7 +837,7 @@ HTMLEditor::DeleteTable() {
|
|||
nsresult rv = GetCellContext(getter_AddRefs(table), nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (NS_WARN_IF(!table)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -846,7 +846,7 @@ HTMLEditor::DeleteTable() {
|
|||
AutoPlaceholderBatch treateAsOneTransaction(*this);
|
||||
rv = DeleteTableElementAndChildrenWithTransaction(*table);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -861,7 +861,7 @@ HTMLEditor::DeleteTableCell(int32_t aNumberOfCellsToDelete) {
|
|||
|
||||
nsresult rv = DeleteTableCellWithTransaction(aNumberOfCellsToDelete);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1133,7 +1133,7 @@ HTMLEditor::DeleteTableCellContents() {
|
|||
|
||||
nsresult rv = DeleteTableCellContentsWithTransaction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1212,7 +1212,7 @@ HTMLEditor::DeleteTableColumn(int32_t aNumberOfColumnsToDelete) {
|
|||
nsresult rv =
|
||||
DeleteSelectedTableColumnsWithTransaction(aNumberOfColumnsToDelete);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1434,7 +1434,7 @@ HTMLEditor::DeleteTableRow(int32_t aNumberOfRowsToDelete) {
|
|||
|
||||
nsresult rv = DeleteSelectedTableRowsWithTransaction(aNumberOfRowsToDelete);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1688,10 +1688,14 @@ HTMLEditor::SelectTable() {
|
|||
}
|
||||
|
||||
nsresult rv = ClearSelection();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return AppendNodeToSelectionAsRange(table);
|
||||
rv = AppendNodeToSelectionAsRange(table);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1707,10 +1711,14 @@ HTMLEditor::SelectTableCell() {
|
|||
}
|
||||
|
||||
nsresult rv = ClearSelection();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return AppendNodeToSelectionAsRange(cell);
|
||||
rv = AppendNodeToSelectionAsRange(cell);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1745,11 +1753,11 @@ HTMLEditor::SelectBlockOfCells(Element* aStartCell, Element* aEndCell) {
|
|||
ErrorResult error;
|
||||
CellIndexes startCellIndexes(*aStartCell, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
CellIndexes endCellIndexes(*aEndCell, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
// Suppress nsISelectionListener notification
|
||||
|
@ -1767,7 +1775,7 @@ HTMLEditor::SelectBlockOfCells(Element* aStartCell, Element* aEndCell) {
|
|||
|
||||
RefPtr<Element> cell = GetFirstSelectedTableCellElement(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
if (!cell) {
|
||||
return NS_OK;
|
||||
|
@ -1777,7 +1785,7 @@ HTMLEditor::SelectBlockOfCells(Element* aStartCell, Element* aEndCell) {
|
|||
while (cell) {
|
||||
CellIndexes currentCellIndexes(*cell, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
if (currentCellIndexes.mRow < maxRow || currentCellIndexes.mRow > maxRow ||
|
||||
currentCellIndexes.mColumn < maxColumn ||
|
||||
|
@ -1789,7 +1797,7 @@ HTMLEditor::SelectBlockOfCells(Element* aStartCell, Element* aEndCell) {
|
|||
}
|
||||
cell = GetNextSelectedTableCellElement(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
if (cell) {
|
||||
MOZ_ASSERT(mSelectedCellIndex > 0);
|
||||
|
@ -1821,7 +1829,9 @@ HTMLEditor::SelectBlockOfCells(Element* aStartCell, Element* aEndCell) {
|
|||
MOZ_ASSERT(col < cellData.NextColumnIndex());
|
||||
}
|
||||
}
|
||||
// NS_OK, otherwise, the last failure of AppendNodeToSelectionAsRange().
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1850,7 +1860,7 @@ HTMLEditor::SelectAllTableCells() {
|
|||
ErrorResult error;
|
||||
TableSize tableSize(*this, *table, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
// Suppress nsISelectionListener notification
|
||||
|
@ -1889,11 +1899,17 @@ HTMLEditor::SelectAllTableCells() {
|
|||
}
|
||||
// Safety code to select starting cell if nothing else was selected
|
||||
if (!cellSelected) {
|
||||
return AppendNodeToSelectionAsRange(startCell);
|
||||
rv = AppendNodeToSelectionAsRange(startCell);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
// NS_OK, otherwise, the error of ClearSelection() when there is no column or
|
||||
// the last failure of CellData or AppendNodeToSelectionAsRange().
|
||||
return rv;
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1919,7 +1935,7 @@ HTMLEditor::SelectTableRow() {
|
|||
GetCellContext(getter_AddRefs(table), getter_AddRefs(cell), nullptr,
|
||||
nullptr, &startRowIndex, &startColIndex);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (NS_WARN_IF(!table)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -1928,7 +1944,7 @@ HTMLEditor::SelectTableRow() {
|
|||
ErrorResult error;
|
||||
TableSize tableSize(*this, *table, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
// Note: At this point, we could get first and last cells in row,
|
||||
|
@ -1971,9 +1987,10 @@ HTMLEditor::SelectTableRow() {
|
|||
if (!cellSelected) {
|
||||
return AppendNodeToSelectionAsRange(startCell);
|
||||
}
|
||||
// NS_OK, otherwise, the error of ClearSelection() when there is no column or
|
||||
// the last failure of CellData or AppendNodeToSelectionAsRange().
|
||||
return rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1999,7 +2016,7 @@ HTMLEditor::SelectTableColumn() {
|
|||
GetCellContext(getter_AddRefs(table), getter_AddRefs(cell), nullptr,
|
||||
nullptr, &startRowIndex, &startColIndex);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (NS_WARN_IF(!table)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -2008,7 +2025,7 @@ HTMLEditor::SelectTableColumn() {
|
|||
ErrorResult error;
|
||||
TableSize tableSize(*this, *table, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
// Suppress nsISelectionListener notification
|
||||
|
@ -2047,9 +2064,10 @@ HTMLEditor::SelectTableColumn() {
|
|||
if (!cellSelected) {
|
||||
return AppendNodeToSelectionAsRange(startCell);
|
||||
}
|
||||
// NS_OK, otherwise, the error of ClearSelection() when there is no row or
|
||||
// the last failure of CellData or AppendNodeToSelectionAsRange().
|
||||
return rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2067,7 +2085,9 @@ HTMLEditor::SplitTableCell() {
|
|||
nsresult rv =
|
||||
GetCellContext(getter_AddRefs(table), getter_AddRefs(cell), nullptr,
|
||||
nullptr, &startRowIndex, &startColIndex);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (!table || !cell) {
|
||||
return NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
@ -2075,7 +2095,9 @@ HTMLEditor::SplitTableCell() {
|
|||
// We need rowspan and colspan data
|
||||
rv = GetCellSpansAt(table, startRowIndex, startColIndex, actualRowSpan,
|
||||
actualColSpan);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
// Must have some span to split
|
||||
if (actualRowSpan <= 1 && actualColSpan <= 1) {
|
||||
|
@ -2104,7 +2126,9 @@ HTMLEditor::SplitTableCell() {
|
|||
if (rowSpanBelow > 0) {
|
||||
rv = SplitCellIntoRows(table, rowIndex, startColIndex, 1, rowSpanBelow,
|
||||
getter_AddRefs(newCell));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
CopyCellBackgroundColor(newCell, cell);
|
||||
}
|
||||
int32_t colIndex = startColIndex;
|
||||
|
@ -2112,7 +2136,9 @@ HTMLEditor::SplitTableCell() {
|
|||
for (colSpanAfter = actualColSpan - 1; colSpanAfter > 0; colSpanAfter--) {
|
||||
rv = SplitCellIntoColumns(table, rowIndex, colIndex, 1, colSpanAfter,
|
||||
getter_AddRefs(newCell));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
CopyCellBackgroundColor(newCell, cell);
|
||||
colIndex++;
|
||||
}
|
||||
|
@ -2376,7 +2402,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
GetCellContext(getter_AddRefs(table), getter_AddRefs(targetCell), nullptr,
|
||||
nullptr, &startRowIndex, &startColIndex);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (!table || !targetCell) {
|
||||
return NS_OK;
|
||||
|
@ -2393,14 +2419,14 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
ErrorResult error;
|
||||
CellAndIndexes firstSelectedCell(*this, *SelectionRefPtr(), error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
bool joinSelectedCells = false;
|
||||
if (firstSelectedCell.mElement) {
|
||||
RefPtr<Element> secondCell = GetNextSelectedTableCellElement(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
// If only one cell is selected, join with cell to the right
|
||||
|
@ -2412,7 +2438,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
// and just merge contents if not contiguous
|
||||
TableSize tableSize(*this, *table, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
// Get spans for cell we will merge into
|
||||
|
@ -2421,7 +2447,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
firstSelectedCell.mIndexes.mColumn, firstRowSpan,
|
||||
firstColSpan);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
// This defines the last indexes along the "edges"
|
||||
|
@ -2441,7 +2467,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
// Be sure each row doesn't have rowspan errors
|
||||
rv = FixBadRowSpan(table, rowIndex, tableSize.mRowCount);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
// Adjust rowcount by number of rows we removed
|
||||
lastRowIndex -= currentRowCount - tableSize.mRowCount;
|
||||
|
@ -2566,7 +2592,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
cellData.mEffectiveColSpan - extraColSpan, extraColSpan,
|
||||
nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2574,7 +2600,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
rv = MergeCells(firstSelectedCell.mElement, cellData.mElement,
|
||||
false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
// Add cell to list to delete
|
||||
|
@ -2602,7 +2628,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
if (nodeToBeRemoved) {
|
||||
rv = DeleteNodeWithTransaction(*nodeToBeRemoved);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2629,12 +2655,12 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
rv = SetRowSpan(firstSelectedCell.mElement,
|
||||
lastRowIndex - firstSelectedCell.mIndexes.mRow + 1);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
rv = SetColSpan(firstSelectedCell.mElement,
|
||||
lastColIndex - firstSelectedCell.mIndexes.mColumn + 1);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
// Fixup disturbances in table layout
|
||||
|
@ -2683,7 +2709,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
spanAboveMergedCell + leftCellData.mEffectiveRowSpan,
|
||||
effectiveRowSpan2 - leftCellData.mEffectiveRowSpan, nullptr);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2694,7 +2720,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
!rightCellData.IsSpannedFromOtherRow() &&
|
||||
effectiveRowSpan2 >= leftCellData.mEffectiveRowSpan);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
if (effectiveRowSpan2 < leftCellData.mEffectiveRowSpan) {
|
||||
|
@ -2710,7 +2736,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
// Reduce rowspan to give room where target cell will extend its colspan
|
||||
rv = SetRowSpan(rightCellData.mElement, spanAboveMergedCell);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2718,7 +2744,7 @@ HTMLEditor::JoinTableCells(bool aMergeNonContiguousContents) {
|
|||
rv = SetColSpan(leftCellData.mElement, leftCellData.mEffectiveColSpan +
|
||||
rightCellData.mEffectiveColSpan);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -2950,7 +2976,7 @@ HTMLEditor::NormalizeTable(Element* aTableOrElementInTable) {
|
|||
}
|
||||
nsresult rv = NormalizeTableInternal(*aTableOrElementInTable);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3067,7 +3093,7 @@ HTMLEditor::GetCellIndexes(Element* aCellElement, int32_t* aRowIndex,
|
|||
ErrorResult error;
|
||||
CellIndexes cellIndexes(*this, *SelectionRefPtr(), error);
|
||||
if (error.Failed()) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
*aRowIndex = cellIndexes.mRow;
|
||||
*aColumnIndex = cellIndexes.mColumn;
|
||||
|
@ -3077,7 +3103,7 @@ HTMLEditor::GetCellIndexes(Element* aCellElement, int32_t* aRowIndex,
|
|||
ErrorResult error;
|
||||
CellIndexes cellIndexes(*aCellElement, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
*aRowIndex = cellIndexes.mRow;
|
||||
*aColumnIndex = cellIndexes.mColumn;
|
||||
|
@ -3187,7 +3213,7 @@ HTMLEditor::GetTableSize(Element* aTableOrElementInTable, int32_t* aRowCount,
|
|||
ErrorResult error;
|
||||
TableSize tableSize(*this, *tableOrElementInTable, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
*aRowCount = tableSize.mRowCount;
|
||||
*aColumnCount = tableSize.mColumnCount;
|
||||
|
@ -3549,7 +3575,7 @@ HTMLEditor::GetFirstSelectedCell(nsRange** aFirstSelectedRange,
|
|||
RefPtr<Element> firstSelectedCellElement =
|
||||
GetFirstSelectedTableCellElement(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
if (!firstSelectedCellElement) {
|
||||
|
@ -3627,7 +3653,7 @@ HTMLEditor::GetNextSelectedCell(nsRange** aNextSelectedCellRange,
|
|||
RefPtr<Element> nextSelectedCellElement =
|
||||
GetNextSelectedTableCellElement(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
if (!nextSelectedCellElement) {
|
||||
|
@ -3706,7 +3732,7 @@ HTMLEditor::GetFirstSelectedCellInTable(int32_t* aRowIndex,
|
|||
ErrorResult error;
|
||||
CellAndIndexes result(*this, *SelectionRefPtr(), error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
result.mElement.forget(aCellElement);
|
||||
*aRowIndex = std::max(result.mIndexes.mRow, 0);
|
||||
|
@ -3835,7 +3861,7 @@ HTMLEditor::GetSelectedOrParentTableElement(
|
|||
RefPtr<Element> cellOrRowOrTableElement =
|
||||
GetSelectedOrParentTableElement(aRv, &isCellSelected);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return aRv.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(aRv.StealNSResult());
|
||||
}
|
||||
if (!cellOrRowOrTableElement) {
|
||||
return NS_OK;
|
||||
|
@ -3965,13 +3991,13 @@ HTMLEditor::GetSelectedCellsType(Element* aElement, uint32_t* aSelectionType) {
|
|||
ErrorResult error;
|
||||
TableSize tableSize(*this, *table, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
// Traverse all selected cells
|
||||
RefPtr<Element> selectedCell = GetFirstSelectedTableCellElement(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
if (!selectedCell) {
|
||||
return NS_OK;
|
||||
|
@ -3989,7 +4015,7 @@ HTMLEditor::GetSelectedCellsType(Element* aElement, uint32_t* aSelectionType) {
|
|||
while (selectedCell) {
|
||||
CellIndexes selectedCellIndexes(*selectedCell, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
if (!indexArray.Contains(selectedCellIndexes.mColumn)) {
|
||||
indexArray.AppendElement(selectedCellIndexes.mColumn);
|
||||
|
@ -4019,7 +4045,7 @@ HTMLEditor::GetSelectedCellsType(Element* aElement, uint32_t* aSelectionType) {
|
|||
while (selectedCell) {
|
||||
CellIndexes selectedCellIndexes(*selectedCell, error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
|
||||
if (!indexArray.Contains(selectedCellIndexes.mRow)) {
|
||||
|
|
|
@ -82,17 +82,14 @@ SplitNodeTransaction::DoTransaction() {
|
|||
// Insert the new node
|
||||
mEditorBase->DoSplitNode(EditorDOMPoint(mStartOfRightNode), *mNewLeftNode,
|
||||
error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
|
||||
if (!mEditorBase->AllowsTransactionsToChangeSelection()) {
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX Really odd. The result of DoSplitNode() is respected only when
|
||||
// we shouldn't set selection. Otherwise, it's overridden by the
|
||||
// result of Selection.Collapse().
|
||||
NS_WARNING_ASSERTION(
|
||||
!mEditorBase->Destroyed(),
|
||||
"The editor has gone but SplitNodeTransaction keeps trying to modify "
|
||||
|
@ -105,7 +102,6 @@ SplitNodeTransaction::DoTransaction() {
|
|||
// XXX This must be a bug.
|
||||
error.SuppressException();
|
||||
}
|
||||
MOZ_ASSERT(mStartOfRightNode.Offset() == mNewLeftNode->Length());
|
||||
EditorRawDOMPoint atEndOfLeftNode;
|
||||
atEndOfLeftNode.SetToEndOf(mNewLeftNode);
|
||||
selection->Collapse(atEndOfLeftNode, error);
|
||||
|
|
|
@ -198,8 +198,8 @@ nsresult TextEditor::EndEditorInit() {
|
|||
}
|
||||
|
||||
nsresult rv = InitRules();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
// Throw away the old transaction manager if this is not the first time that
|
||||
// we're initializing the editor.
|
||||
|
@ -216,7 +216,9 @@ TextEditor::SetDocumentCharacterSet(const nsACString& characterSet) {
|
|||
}
|
||||
|
||||
nsresult rv = EditorBase::SetDocumentCharacterSet(characterSet);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
// Update META charset element.
|
||||
RefPtr<Document> doc = GetDocument();
|
||||
|
@ -412,7 +414,7 @@ nsresult TextEditor::OnInputText(const nsAString& aStringToInsert) {
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName);
|
||||
nsresult rv = InsertTextAsSubAction(aStringToInsert);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -428,7 +430,7 @@ nsresult TextEditor::InsertLineBreakAsAction() {
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName);
|
||||
nsresult rv = InsertLineBreakAsSubAction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -696,7 +698,7 @@ nsresult TextEditor::DeleteSelectionAsAction(EDirection aDirection,
|
|||
ErrorResult error;
|
||||
SelectionRefPtr()->CollapseToStart(error);
|
||||
if (NS_WARN_IF(error.Failed())) {
|
||||
return error.StealNSResult();
|
||||
return EditorBase::ToGenericNSResult(error.StealNSResult());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -732,7 +734,7 @@ nsresult TextEditor::DeleteSelectionAsAction(EDirection aDirection,
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::DeleteTxnName);
|
||||
nsresult rv = DeleteSelectionAsSubAction(aDirection, aStripWrappers);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -992,7 +994,7 @@ nsresult TextEditor::InsertTextAsAction(const nsAString& aStringToInsert) {
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this);
|
||||
nsresult rv = InsertTextAsSubAction(aStringToInsert);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1057,7 +1059,7 @@ TextEditor::InsertLineBreak() {
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this);
|
||||
nsresult rv = InsertLineBreakAsSubAction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1104,7 +1106,7 @@ nsresult TextEditor::SetText(const nsAString& aString) {
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this);
|
||||
nsresult rv = SetTextAsSubAction(aString);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1130,7 +1132,7 @@ nsresult TextEditor::ReplaceTextAsAction(
|
|||
if (!aReplaceRange) {
|
||||
nsresult rv = SetTextAsSubAction(aString);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1158,7 +1160,7 @@ nsresult TextEditor::ReplaceTextAsAction(
|
|||
|
||||
rv = ReplaceSelectionAsSubAction(aString);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1367,7 +1369,10 @@ nsresult TextEditor::OnCompositionChange(
|
|||
NotifyEditorObservers(eNotifyEditorObserversOfEnd);
|
||||
}
|
||||
|
||||
return rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void TextEditor::OnCompositionEnd(
|
||||
|
@ -1663,7 +1668,10 @@ TextEditor::Undo(uint32_t aCount) {
|
|||
}
|
||||
|
||||
NotifyEditorObservers(eNotifyEditorObserversOfEnd);
|
||||
return rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1722,7 +1730,10 @@ TextEditor::Redo(uint32_t aCount) {
|
|||
}
|
||||
|
||||
NotifyEditorObservers(eNotifyEditorObserversOfEnd);
|
||||
return rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool TextEditor::CanCutOrCopy(PasswordFieldAllowed aPasswordFieldAllowed) {
|
||||
|
@ -1917,8 +1928,14 @@ TextEditor::OutputToString(const nsAString& aFormatType,
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return ComputeValueInternal(aFormatType, aDocumentEncoderFlags,
|
||||
aOutputString);
|
||||
nsresult rv =
|
||||
ComputeValueInternal(aFormatType, aDocumentEncoderFlags, aOutputString);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
// This is low level API for XUL applcation. So, we should return raw
|
||||
// error code here.
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult TextEditor::ComputeValueInternal(const nsAString& aFormatType,
|
||||
|
@ -1988,7 +2005,7 @@ nsresult TextEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
|
|||
nsCOMPtr<nsITransferable> trans;
|
||||
rv = PrepareTransferable(getter_AddRefs(trans));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (!trans) {
|
||||
return NS_OK;
|
||||
|
@ -2003,8 +2020,8 @@ nsresult TextEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
|
|||
nsCOMPtr<nsISupports> genericDataObj;
|
||||
nsAutoCString flav;
|
||||
rv = trans->GetAnyTransferData(flav, getter_AddRefs(genericDataObj));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
|
||||
if (!flav.EqualsLiteral(kUnicodeMime) &&
|
||||
|
@ -2020,7 +2037,7 @@ nsresult TextEditor::PasteAsQuotationAsAction(int32_t aClipboardType,
|
|||
AutoPlaceholderBatch treatAsOneTransaction(*this);
|
||||
rv = InsertWithQuotationsAsSubAction(stuffToPaste);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2184,7 +2201,11 @@ nsresult TextEditor::SetAttributeOrEquivalent(Element* aElement,
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return SetAttributeWithTransaction(*aElement, *aAttribute, aValue);
|
||||
nsresult rv = SetAttributeWithTransaction(*aElement, *aAttribute, aValue);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult TextEditor::RemoveAttributeOrEquivalent(Element* aElement,
|
||||
|
@ -2199,7 +2220,11 @@ nsresult TextEditor::RemoveAttributeOrEquivalent(Element* aElement,
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return RemoveAttributeWithTransaction(*aElement, *aAttribute);
|
||||
nsresult rv = RemoveAttributeWithTransaction(*aElement, *aAttribute);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult TextEditor::HideLastPasswordInput() {
|
||||
|
@ -2216,7 +2241,7 @@ nsresult TextEditor::HideLastPasswordInput() {
|
|||
RefPtr<TextEditRules> rules(mRules);
|
||||
nsresult rv = rules->HideLastPasswordInput();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -233,8 +233,12 @@ class TextEditor : public EditorBase, public nsIPlaintextEditor {
|
|||
if (NS_WARN_IF(!editActionData.CanHandle())) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
return ComputeValueInternal(NS_LITERAL_STRING("text/plain"),
|
||||
aDocumentEncoderFlags, aOutputString);
|
||||
nsresult rv = ComputeValueInternal(NS_LITERAL_STRING("text/plain"),
|
||||
aDocumentEncoderFlags, aOutputString);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected: // May be called by friends.
|
||||
|
|
|
@ -272,7 +272,7 @@ nsresult TextEditor::OnDrop(DragEvent* aDropEvent) {
|
|||
if (deleteSelection && !SelectionRefPtr()->IsCollapsed()) {
|
||||
nsresult rv = PrepareToInsertContent(droppedAt, true);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
// Now, Selection should be collapsed at dropped point. If somebody
|
||||
// changed Selection, we should think what should do it in such case
|
||||
|
@ -291,7 +291,7 @@ nsresult TextEditor::OnDrop(DragEvent* aDropEvent) {
|
|||
RefPtr<DataTransfer> dataTransfer; // Required due to bug 1506439
|
||||
FireInputEvent(EditAction::eDeleteByDrag, VoidString(), dataTransfer);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,7 +340,7 @@ nsresult TextEditor::OnDrop(DragEvent* aDropEvent) {
|
|||
nsContentUtils::PlatformToDOMLineBreaks(data);
|
||||
InsertTextAt(data, droppedAt, false);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
editActionData.InitializeDataTransfer(dataTransfer);
|
||||
|
@ -349,7 +349,7 @@ nsresult TextEditor::OnDrop(DragEvent* aDropEvent) {
|
|||
htmlEditor->InsertFromDataTransfer(dataTransfer, i, srcdoc, droppedAt,
|
||||
false);
|
||||
if (NS_WARN_IF(Destroyed())) {
|
||||
return NS_ERROR_EDITOR_DESTROYED;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -372,7 +372,7 @@ nsresult TextEditor::PasteAsAction(int32_t aClipboardType,
|
|||
nsresult rv =
|
||||
AsHTMLEditor()->PasteInternal(aClipboardType, aDispatchPasteEvent);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ nsresult TextEditor::PasteAsAction(int32_t aClipboardType,
|
|||
nsCOMPtr<nsITransferable> transferable;
|
||||
rv = PrepareTransferable(getter_AddRefs(transferable));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
if (NS_WARN_IF(!transferable)) {
|
||||
return NS_OK; // XXX Why?
|
||||
|
@ -409,7 +409,7 @@ nsresult TextEditor::PasteAsAction(int32_t aClipboardType,
|
|||
}
|
||||
rv = InsertTextFromTransferable(transferable);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -432,7 +432,11 @@ TextEditor::PasteTransferable(nsITransferable* aTransferable) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
return InsertTextFromTransferable(aTransferable);
|
||||
nsresult rv = InsertTextFromTransferable(aTransferable);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return EditorBase::ToGenericNSResult(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<script>
|
||||
function go() {
|
||||
document.execCommand("styleWithCSS", false, true)
|
||||
document.execCommand("delete", false)
|
||||
a.addEventListener("DOMNodeRemoved", function() {
|
||||
var c = window.getSelection()
|
||||
var d = document.createRange()
|
||||
d.setEndAfter(b)
|
||||
c.addRange(d)
|
||||
c.deleteFromDocument()
|
||||
})
|
||||
document.execCommand("outdent", false)
|
||||
}
|
||||
</script>
|
||||
<body onload=go()>
|
||||
<ul id="a" contenteditable="true" style="margin: -1px 0px 1px 6px">
|
||||
<dd></dd>
|
||||
<dd>
|
||||
<button id="b">
|
|
@ -107,3 +107,4 @@ skip-if(Android) needs-focus load 1444630.html
|
|||
load 1446451.html
|
||||
asserts(0-2) load 1464251.html # assertion is that mutation event listener modifies content
|
||||
pref(layout.accessiblecaret.enabled,true) load 1470926.html
|
||||
load 1525481.html
|
||||
|
|
|
@ -288,7 +288,8 @@ static bool PreprocessValue(JSContext* cx, HandleObject holder, KeyType key,
|
|||
RootedString keyStr(cx);
|
||||
|
||||
// Step 2. Modified by BigInt spec 6.1 to check for a toJSON method on the
|
||||
// BigInt prototype when the value is a BigInt.
|
||||
// BigInt prototype when the value is a BigInt, and to pass the BigInt
|
||||
// primitive value as receiver.
|
||||
if (vp.isObject() || vp.isBigInt()) {
|
||||
RootedValue toJSON(cx);
|
||||
RootedObject obj(cx, JS::ToObject(cx, vp));
|
||||
|
@ -296,7 +297,7 @@ static bool PreprocessValue(JSContext* cx, HandleObject holder, KeyType key,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!GetProperty(cx, obj, obj, cx->names().toJSON, &toJSON)) {
|
||||
if (!GetProperty(cx, obj, vp, cx->names().toJSON, &toJSON)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
// |reftest| skip-if(!this.hasOwnProperty('BigInt')) -- BigInt is not enabled unconditionally
|
||||
// Copyright 2019 Igalia, S.L. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
// Test case written by André Bargull.
|
||||
|
||||
/*---
|
||||
esid: sec-serializejsonproperty
|
||||
description: toJSON method called with BigInt as receiver
|
||||
features: [BigInt]
|
||||
---*/
|
||||
|
||||
assert.throws(TypeError, () => JSON.stringify(1n),
|
||||
"toString throws for BigInt object");
|
||||
|
||||
// The BigInt proposal changes the SerializeJSONProperty algorithm to
|
||||
// specifically allow passing BigInt objects as receivers for the toJSON
|
||||
// method.
|
||||
Object.defineProperty(BigInt.prototype, "toJSON", {
|
||||
get() {
|
||||
"use strict";
|
||||
return () => typeof this;
|
||||
}
|
||||
});
|
||||
|
||||
assert.sameValue(JSON.stringify(1n), "\"bigint\"",
|
||||
"BigInt toJSON method called with value as receiver");
|
||||
|
||||
reportCompare(0, 0);
|
|
@ -1556,10 +1556,41 @@ int32_t nsLayoutUtils::DoCompareTreePosition(
|
|||
|
||||
int32_t index1 = parent->ComputeIndexOf(content1Ancestor);
|
||||
int32_t index2 = parent->ComputeIndexOf(content2Ancestor);
|
||||
if (index1 < 0 || index2 < 0) {
|
||||
// one of them must be anonymous; we can't determine the order
|
||||
|
||||
// If either of the nodes are anonymous, then handle the relative ordering.
|
||||
// We consider all anonymous content to be behind regular siblings, with the
|
||||
// exception of ::after.
|
||||
if (index1 < 0) {
|
||||
if (content1Ancestor->IsContent() &&
|
||||
content1Ancestor->AsContent()->IsGeneratedContentContainerForAfter()) {
|
||||
// If content1 is ::after, then it must be after content2.
|
||||
MOZ_ASSERT(!content2Ancestor->IsContent() ||
|
||||
!content2Ancestor->AsContent()
|
||||
->IsGeneratedContentContainerForAfter());
|
||||
return 1;
|
||||
}
|
||||
if (index2 >= 0 || (content2Ancestor->IsContent() &&
|
||||
content2Ancestor->AsContent()
|
||||
->IsGeneratedContentContainerForAfter())) {
|
||||
// content1 is anonymous, so if content2 is a regular sibling or ::after,
|
||||
// then we must be before it.
|
||||
return -1;
|
||||
}
|
||||
// Both nodes are anonymous, so no relative ordering.
|
||||
return 0;
|
||||
}
|
||||
if (index2 < 0) {
|
||||
// content1 is a regular sibling, so if content2 is ::after, then
|
||||
// content1 comes first.
|
||||
if (content2Ancestor->IsContent() &&
|
||||
content2Ancestor->AsContent()->IsGeneratedContentContainerForAfter()) {
|
||||
MOZ_ASSERT(!content1Ancestor->IsContent() ||
|
||||
!content1Ancestor->AsContent()
|
||||
->IsGeneratedContentContainerForAfter());
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return index1 - index2;
|
||||
}
|
||||
|
|
|
@ -514,16 +514,6 @@ VARCACHE_PREF(
|
|||
bool, false
|
||||
)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Clear-Site-Data prefs
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
VARCACHE_PREF(
|
||||
"dom.clearSiteData.enabled",
|
||||
dom_clearSiteData_enabled,
|
||||
bool, true
|
||||
)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Extension prefs
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
prefs: [dom.clearSiteData.enabled:true]
|
|
@ -159,11 +159,6 @@ ClearSiteData::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
|
||||
MOZ_ASSERT(!strcmp(aTopic, NS_HTTP_ON_EXAMINE_RESPONSE_TOPIC));
|
||||
|
||||
// Pref disabled.
|
||||
if (!StaticPrefs::dom_clearSiteData_enabled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIHttpChannel> channel = do_QueryInterface(aSubject);
|
||||
if (NS_WARN_IF(!channel)) {
|
||||
return NS_OK;
|
||||
|
|
|
@ -2157,7 +2157,10 @@ class EventManager {
|
|||
|
||||
// Remove any primed listeners that were not re-registered.
|
||||
// This function is called after the background page has started.
|
||||
static clearPrimedListeners(extension) {
|
||||
// The removed listeners are removed from the set of saved listeners, unless
|
||||
// `clearPersistent` is false. If false, the listeners are cleared from
|
||||
// memory, but not removed from the extension's startup data.
|
||||
static clearPrimedListeners(extension, clearPersistent = true) {
|
||||
for (let [module, moduleEntry] of extension.persistentListeners) {
|
||||
for (let [event, listeners] of moduleEntry) {
|
||||
for (let [key, listener] of listeners) {
|
||||
|
@ -2170,7 +2173,9 @@ class EventManager {
|
|||
evt.reject(new Error("listener not re-registered"));
|
||||
}
|
||||
|
||||
EventManager.clearPersistentListener(extension, module, event, key);
|
||||
if (clearPersistent) {
|
||||
EventManager.clearPersistentListener(extension, module, event, key);
|
||||
}
|
||||
primed.unregister();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1057,6 +1057,7 @@ ParentAPIManager.init();
|
|||
class HiddenXULWindow {
|
||||
constructor() {
|
||||
this._windowlessBrowser = null;
|
||||
this.unloaded = false;
|
||||
this.waitInitialized = this.initWindowlessBrowser();
|
||||
}
|
||||
|
||||
|
@ -1067,9 +1068,14 @@ class HiddenXULWindow {
|
|||
|
||||
this.unloaded = true;
|
||||
|
||||
this.chromeShell = null;
|
||||
this.waitInitialized = null;
|
||||
|
||||
if (!this._windowlessBrowser) {
|
||||
Cu.reportError("HiddenXULWindow was shut down while it was loading.");
|
||||
// initWindowlessBrowser will close windowlessBrowser when possible.
|
||||
return;
|
||||
}
|
||||
|
||||
this._windowlessBrowser.close();
|
||||
this._windowlessBrowser = null;
|
||||
}
|
||||
|
@ -1081,8 +1087,8 @@ class HiddenXULWindow {
|
|||
/**
|
||||
* Private helper that create a XULDocument in a windowless browser.
|
||||
*
|
||||
* @returns {Promise<XULDocument>}
|
||||
* A promise which resolves to the newly created XULDocument.
|
||||
* @returns {Promise<void>}
|
||||
* A promise which resolves when the windowless browser is ready.
|
||||
*/
|
||||
async initWindowlessBrowser() {
|
||||
if (this.waitInitialized) {
|
||||
|
@ -1092,7 +1098,6 @@ class HiddenXULWindow {
|
|||
// The invisible page is currently wrapped in a XUL window to fix an issue
|
||||
// with using the canvas API from a background page (See Bug 1274775).
|
||||
let windowlessBrowser = Services.appShell.createWindowlessBrowser(true);
|
||||
this._windowlessBrowser = windowlessBrowser;
|
||||
|
||||
// The windowless browser is a thin wrapper around a docShell that keeps
|
||||
// its related resources alive. It implements nsIWebNavigation and
|
||||
|
@ -1102,26 +1107,31 @@ class HiddenXULWindow {
|
|||
// access to the webNav methods that are already available on the
|
||||
// windowless browser, but contrary to appearances, they are not the same
|
||||
// object.
|
||||
this.chromeShell = this._windowlessBrowser.docShell
|
||||
.QueryInterface(Ci.nsIWebNavigation);
|
||||
let chromeShell = windowlessBrowser.docShell
|
||||
.QueryInterface(Ci.nsIWebNavigation);
|
||||
|
||||
if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
|
||||
let attrs = this.chromeShell.getOriginAttributes();
|
||||
let attrs = chromeShell.getOriginAttributes();
|
||||
attrs.privateBrowsingId = 1;
|
||||
this.chromeShell.setOriginAttributes(attrs);
|
||||
chromeShell.setOriginAttributes(attrs);
|
||||
}
|
||||
|
||||
let system = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
this.chromeShell.createAboutBlankContentViewer(system);
|
||||
this.chromeShell.useGlobalHistory = false;
|
||||
chromeShell.createAboutBlankContentViewer(system);
|
||||
chromeShell.useGlobalHistory = false;
|
||||
let loadURIOptions = {
|
||||
triggeringPrincipal: system,
|
||||
};
|
||||
this.chromeShell.loadURI("chrome://extensions/content/dummy.xul", loadURIOptions);
|
||||
chromeShell.loadURI("chrome://extensions/content/dummy.xul", loadURIOptions);
|
||||
|
||||
await promiseObserved("chrome-document-global-created",
|
||||
win => win.document == this.chromeShell.document);
|
||||
return promiseDocumentLoaded(windowlessBrowser.document);
|
||||
win => win.document == chromeShell.document);
|
||||
await promiseDocumentLoaded(windowlessBrowser.document);
|
||||
if (this.unloaded) {
|
||||
windowlessBrowser.close();
|
||||
return;
|
||||
}
|
||||
this._windowlessBrowser = windowlessBrowser;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1223,6 +1233,7 @@ class HiddenExtensionPage {
|
|||
this.extension = extension;
|
||||
this.viewType = viewType;
|
||||
this.browser = null;
|
||||
this.unloaded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1233,13 +1244,19 @@ class HiddenExtensionPage {
|
|||
throw new Error("Unable to shutdown an unloaded HiddenExtensionPage instance");
|
||||
}
|
||||
|
||||
this.unloaded = true;
|
||||
|
||||
if (this.browser) {
|
||||
this.browser.remove();
|
||||
this.browser = null;
|
||||
SharedWindow.release();
|
||||
this._releaseBrowser();
|
||||
}
|
||||
}
|
||||
|
||||
_releaseBrowser() {
|
||||
this.browser.remove();
|
||||
this.browser = null;
|
||||
SharedWindow.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the browser XUL element that will contain the WebExtension Page.
|
||||
*
|
||||
|
@ -1252,12 +1269,22 @@ class HiddenExtensionPage {
|
|||
}
|
||||
|
||||
let window = SharedWindow.acquire();
|
||||
this.browser = await window.createBrowserElement({
|
||||
"webextension-view-type": this.viewType,
|
||||
"remote": this.extension.remote ? "true" : null,
|
||||
"remoteType": this.extension.remote ?
|
||||
E10SUtils.EXTENSION_REMOTE_TYPE : null,
|
||||
}, this.extension.groupFrameLoader);
|
||||
try {
|
||||
this.browser = await window.createBrowserElement({
|
||||
"webextension-view-type": this.viewType,
|
||||
"remote": this.extension.remote ? "true" : null,
|
||||
"remoteType": this.extension.remote ?
|
||||
E10SUtils.EXTENSION_REMOTE_TYPE : null,
|
||||
}, this.extension.groupFrameLoader);
|
||||
} catch (e) {
|
||||
SharedWindow.release();
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (this.unloaded) {
|
||||
this._releaseBrowser();
|
||||
throw new Error("Extension shut down before browser element was created");
|
||||
}
|
||||
|
||||
return this.browser;
|
||||
}
|
||||
|
@ -1403,15 +1430,47 @@ const DebugUtils = {
|
|||
};
|
||||
|
||||
|
||||
function promiseExtensionViewLoaded(browser) {
|
||||
return new Promise(resolve => {
|
||||
browser.messageManager.addMessageListener("Extension:ExtensionViewLoaded", function onLoad({data}) {
|
||||
browser.messageManager.removeMessageListener("Extension:ExtensionViewLoaded", onLoad);
|
||||
resolve(data.childId && ParentAPIManager.getContextById(data.childId));
|
||||
});
|
||||
/**
|
||||
* Returns a Promise which resolves with the message data when the given message
|
||||
* was received by the message manager. The promise is rejected if the message
|
||||
* manager was closed before a message was received.
|
||||
*
|
||||
* @param {MessageListenerManager} messageManager
|
||||
* The message manager on which to listen for messages.
|
||||
* @param {string} messageName
|
||||
* The message to listen for.
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
function promiseMessageFromChild(messageManager, messageName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let unregister;
|
||||
function listener(message) {
|
||||
unregister();
|
||||
resolve(message.data);
|
||||
}
|
||||
function observer(subject, topic, data) {
|
||||
if (subject === messageManager) {
|
||||
unregister();
|
||||
reject(new Error(`Message manager was disconnected before receiving ${messageName}`));
|
||||
}
|
||||
}
|
||||
unregister = () => {
|
||||
Services.obs.removeObserver(observer, "message-manager-close");
|
||||
messageManager.removeMessageListener(messageName, listener);
|
||||
};
|
||||
messageManager.addMessageListener(messageName, listener);
|
||||
Services.obs.addObserver(observer, "message-manager-close");
|
||||
});
|
||||
}
|
||||
|
||||
// This should be called before browser.loadURI is invoked.
|
||||
async function promiseExtensionViewLoaded(browser) {
|
||||
let {childId} = await promiseMessageFromChild(browser.messageManager, "Extension:ExtensionViewLoaded");
|
||||
if (childId) {
|
||||
return ParentAPIManager.getContextById(childId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper is used to subscribe a listener (e.g. in the ext-devtools API implementation)
|
||||
* to be called for every ExtensionProxyContext created for an extension page given
|
||||
|
|
|
@ -33,14 +33,27 @@ class BackgroundPage extends HiddenExtensionPage {
|
|||
|
||||
ExtensionTelemetry.backgroundPageLoad.stopwatchStart(extension, this);
|
||||
|
||||
await this.createBrowserElement();
|
||||
extension._backgroundPageFrameLoader = this.browser.frameLoader;
|
||||
let context;
|
||||
try {
|
||||
await this.createBrowserElement();
|
||||
if (!this.browser) {
|
||||
throw new Error("Extension shut down before the background page was created");
|
||||
}
|
||||
extension._backgroundPageFrameLoader = this.browser.frameLoader;
|
||||
|
||||
extensions.emit("extension-browser-inserted", this.browser);
|
||||
extensions.emit("extension-browser-inserted", this.browser);
|
||||
|
||||
this.browser.loadURI(this.url, {triggeringPrincipal: extension.principal});
|
||||
let contextPromise = promiseExtensionViewLoaded(this.browser);
|
||||
this.browser.loadURI(this.url, {triggeringPrincipal: extension.principal});
|
||||
|
||||
let context = await promiseExtensionViewLoaded(this.browser);
|
||||
context = await contextPromise;
|
||||
} catch (e) {
|
||||
// Extension was down before the background page has loaded.
|
||||
Cu.reportError(e);
|
||||
ExtensionTelemetry.backgroundPageLoad.stopwatchCancel(extension, this);
|
||||
extension.emit("background-page-aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
ExtensionTelemetry.backgroundPageLoad.stopwatchFinish(extension, this);
|
||||
|
||||
|
@ -85,8 +98,16 @@ this.backgroundPage = class extends ExtensionAPI {
|
|||
EventManager.primeListeners(extension);
|
||||
|
||||
extension.once("start-background-page", async () => {
|
||||
if (!this.extension) {
|
||||
// Extension was shut down. Don't build the background page.
|
||||
// Primed listeners have been cleared in onShutdown.
|
||||
return;
|
||||
}
|
||||
await this.build();
|
||||
EventManager.clearPrimedListeners(extension);
|
||||
// |this.extension| may be null if the extension was shut down.
|
||||
// In that case, we still want to clear the primed listeners,
|
||||
// but not update the persistent listeners in the startupData.
|
||||
EventManager.clearPrimedListeners(extension, !!this.extension);
|
||||
});
|
||||
|
||||
// There are two ways to start the background page:
|
||||
|
@ -109,6 +130,8 @@ this.backgroundPage = class extends ExtensionAPI {
|
|||
onShutdown() {
|
||||
if (this.bgPage) {
|
||||
this.bgPage.shutdown();
|
||||
} else {
|
||||
EventManager.clearPrimedListeners(this.extension, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set sts=2 sw=2 et tw=80: */
|
||||
"use strict";
|
||||
|
||||
AddonTestUtils.init(this);
|
||||
AddonTestUtils.overrideCertDB();
|
||||
AddonTestUtils.createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "43");
|
||||
|
||||
let {
|
||||
promiseRestartManager,
|
||||
promiseShutdownManager,
|
||||
promiseStartupManager,
|
||||
} = AddonTestUtils;
|
||||
|
||||
Services.prefs.setBoolPref("extensions.webextensions.background-delayed-startup", true);
|
||||
|
||||
let {Management} = ChromeUtils.import("resource://gre/modules/Extension.jsm", null);
|
||||
|
||||
// Crashes a <browser>'s remote process.
|
||||
// Based on BrowserTestUtils.crashBrowser.
|
||||
function crashBrowser(browser) {
|
||||
if (!browser.isRemoteBrowser) {
|
||||
// The browser should be remote, or the test runner would be killed.
|
||||
throw new Error("<browser> must be remote");
|
||||
}
|
||||
|
||||
let frameScript = () => {
|
||||
const {ctypes} = ChromeUtils.import("resource://gre/modules/ctypes.jsm");
|
||||
privateNoteIntentionalCrash(); /* eslint-disable-line no-undef */
|
||||
let zero = new ctypes.intptr_t(8);
|
||||
let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
|
||||
dump("Intentionally crashing extension process...\n");
|
||||
badptr.contents; /* eslint-disable-line no-unused-expressions */
|
||||
};
|
||||
browser.messageManager.loadFrameScript(`data:,(${frameScript})();`, false);
|
||||
}
|
||||
|
||||
// Verifies that a delayed background page is not loaded when an extension is
|
||||
// shut down during startup.
|
||||
add_task(async function test_unload_extension_before_background_page_startup() {
|
||||
await promiseStartupManager();
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
useAddonManager: "permanent",
|
||||
background() {
|
||||
browser.test.sendMessage("background_startup_observed");
|
||||
},
|
||||
});
|
||||
|
||||
// Delayed startup are only enabled for browser (re)starts, so we need to
|
||||
// install the extension first, and then unload it.
|
||||
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("background_startup_observed");
|
||||
|
||||
// Now the actual test: Unloading an extension before the startup has
|
||||
// finished should interrupt the start-up and abort pending delayed loads.
|
||||
info("Starting extension whose startup will be interrupted");
|
||||
ExtensionParent._resetStartupPromises();
|
||||
await promiseRestartManager();
|
||||
await extension.awaitStartup();
|
||||
|
||||
let extensionBrowserInsertions = 0;
|
||||
let onExtensionBrowserInserted = () => ++extensionBrowserInsertions;
|
||||
Management.on("extension-browser-inserted", onExtensionBrowserInserted);
|
||||
|
||||
info("Unloading extension before the delayed background page starts loading");
|
||||
await extension.addon.disable();
|
||||
|
||||
// Re-enable the add-on to let enough time pass to load a whole background
|
||||
// page. If at the end of this the original background page hasn't loaded,
|
||||
// we can consider the test successful.
|
||||
await extension.addon.enable();
|
||||
|
||||
// Trigger the notification that would load a background page.
|
||||
info("Forcing pending delayed background page to load");
|
||||
Services.obs.notifyObservers(null, "sessionstore-windows-restored");
|
||||
|
||||
// This is the expected message from the re-enabled add-on.
|
||||
await extension.awaitMessage("background_startup_observed");
|
||||
await extension.unload();
|
||||
|
||||
await promiseShutdownManager();
|
||||
ExtensionParent._resetStartupPromises();
|
||||
|
||||
Management.off("extension-browser-inserted", onExtensionBrowserInserted);
|
||||
Assert.equal(extensionBrowserInsertions, 1,
|
||||
"Extension browser should have been inserted only once");
|
||||
});
|
||||
|
||||
// Verifies that the "build" method of BackgroundPage in ext-backgroundPage.js
|
||||
// does not deadlock when startup is interrupted by extension shutdown.
|
||||
add_task(async function test_unload_extension_during_background_page_startup() {
|
||||
await promiseStartupManager();
|
||||
|
||||
let extension = ExtensionTestUtils.loadExtension({
|
||||
useAddonManager: "permanent",
|
||||
background() {
|
||||
browser.test.sendMessage("background_starting");
|
||||
},
|
||||
});
|
||||
|
||||
// Delayed startup are only enabled for browser (re)starts, so we need to
|
||||
// install the extension first, and then reload it.
|
||||
await extension.startup();
|
||||
await extension.awaitMessage("background_starting");
|
||||
|
||||
ExtensionParent._resetStartupPromises();
|
||||
await promiseRestartManager();
|
||||
await extension.awaitStartup();
|
||||
|
||||
let bgStartupPromise = new Promise(resolve => {
|
||||
function onBackgroundPageDone(eventName) {
|
||||
extension.extension.off("startup", onBackgroundPageDone);
|
||||
extension.extension.off("background-page-aborted", onBackgroundPageDone);
|
||||
|
||||
if (eventName === "background-page-aborted") {
|
||||
info("Background page startup was interrupted");
|
||||
resolve("bg_aborted");
|
||||
} else {
|
||||
info("Background page startup finished normally");
|
||||
resolve("bg_fully_loaded");
|
||||
}
|
||||
}
|
||||
extension.extension.on("startup", onBackgroundPageDone);
|
||||
extension.extension.on("background-page-aborted", onBackgroundPageDone);
|
||||
});
|
||||
|
||||
let bgStartingPromise = new Promise(resolve => {
|
||||
let backgroundLoadCount = 0;
|
||||
let backgroundPageUrl = extension.extension.baseURI.resolve("_generated_background_page.html");
|
||||
|
||||
// Prevent the background page from actually loading.
|
||||
Management.once("extension-browser-inserted", (eventName, browser) => {
|
||||
// Intercept background page load.
|
||||
let browserLoadURI = browser.loadURI;
|
||||
browser.loadURI = function() {
|
||||
Assert.equal(++backgroundLoadCount, 1, "loadURI should be called once");
|
||||
Assert.equal(arguments[0], backgroundPageUrl, "Expected background page");
|
||||
// Reset to "about:blank" to not load the actual background page.
|
||||
arguments[0] = "about:blank";
|
||||
browserLoadURI.apply(this, arguments);
|
||||
|
||||
// And force the extension process to crash.
|
||||
if (browser.isRemote) {
|
||||
crashBrowser(browser);
|
||||
} else {
|
||||
// If extensions are not running in out-of-process mode, then the
|
||||
// non-remote process should not be killed (or the test runner dies).
|
||||
// Remove <browser> instead, to simulate the immediate disconnection
|
||||
// of the message manager (that would happen if the process crashed).
|
||||
browser.remove();
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// Force background page to initialize.
|
||||
Services.obs.notifyObservers(null, "sessionstore-windows-restored");
|
||||
await bgStartingPromise;
|
||||
|
||||
await extension.unload();
|
||||
await promiseShutdownManager();
|
||||
|
||||
// This part is the regression test for bug 1501375. It verifies that the
|
||||
// background building completes eventually.
|
||||
// If it does not, then the next line will cause a timeout.
|
||||
info("Waiting for background builder to finish");
|
||||
let bgLoadState = await bgStartupPromise;
|
||||
Assert.equal(bgLoadState, "bg_aborted", "Startup should be interrupted");
|
||||
|
||||
ExtensionParent._resetStartupPromises();
|
||||
});
|
|
@ -4,6 +4,7 @@
|
|||
[test_ext_alarms_replaces.js]
|
||||
[test_ext_api_permissions.js]
|
||||
[test_ext_background_api_injection.js]
|
||||
[test_ext_background_early_shutdown.js]
|
||||
[test_ext_background_generated_load_events.js]
|
||||
[test_ext_background_generated_reload.js]
|
||||
[test_ext_background_global_history.js]
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
/* Notification overrides for Heartbeat UI */
|
||||
|
||||
notification.heartbeat {
|
||||
background-color: #F1F1F1 !important;
|
||||
border-bottom: 1px solid #C1C1C1 !important;
|
||||
height: 40px;
|
||||
}
|
||||
|
@ -49,10 +48,8 @@ notification.heartbeat {
|
|||
}
|
||||
|
||||
.messageText.heartbeat {
|
||||
color: #333 !important;
|
||||
margin-inline-end: 12px !important; /* The !important is required to override OSX default style. */
|
||||
margin-inline-start: 0;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.messageImage.heartbeat {
|
||||
|
@ -78,19 +75,13 @@ notification.heartbeat {
|
|||
|
||||
/* Learn More link styles */
|
||||
.heartbeat > hbox > .text-link {
|
||||
color: #0095DD !important;
|
||||
margin-inline-start: 0 !important;
|
||||
}
|
||||
|
||||
.heartbeat > hbox > .text-link:hover {
|
||||
color: #008ACB !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.heartbeat > hbox > .text-link:hover:active {
|
||||
color: #006B9D !important;
|
||||
}
|
||||
|
||||
/* Heartbeat UI Rating Star Classes */
|
||||
#star-rating-container {
|
||||
display: -moz-box;
|
||||
|
|
|
@ -9,6 +9,17 @@ const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|||
const DEFAULT_THEME_ID = "default-theme@mozilla.org";
|
||||
const ICONS = Services.prefs.getStringPref("extensions.webextensions.themes.icons.buttons", "").split(",");
|
||||
|
||||
ChromeUtils.defineModuleGetter(this, "AppConstants",
|
||||
"resource://gre/modules/AppConstants.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "LightweightThemeImageOptimizer",
|
||||
"resource://gre/modules/addons/LightweightThemeImageOptimizer.jsm");
|
||||
// Get the theme variables from the app resource directory.
|
||||
// This allows per-app variables.
|
||||
ChromeUtils.defineModuleGetter(this, "ThemeContentPropertyList",
|
||||
"resource:///modules/ThemeVariableMap.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "ThemeVariableMap",
|
||||
"resource:///modules/ThemeVariableMap.jsm");
|
||||
|
||||
const toolkitVariableMap = [
|
||||
["--lwt-accent-color", {
|
||||
lwtProperty: "accentcolor",
|
||||
|
@ -113,15 +124,6 @@ const toolkitVariableMap = [
|
|||
}],
|
||||
];
|
||||
|
||||
// Get the theme variables from the app resource directory.
|
||||
// This allows per-app variables.
|
||||
ChromeUtils.defineModuleGetter(this, "ThemeContentPropertyList",
|
||||
"resource:///modules/ThemeVariableMap.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "ThemeVariableMap",
|
||||
"resource:///modules/ThemeVariableMap.jsm");
|
||||
ChromeUtils.defineModuleGetter(this, "LightweightThemeImageOptimizer",
|
||||
"resource://gre/modules/addons/LightweightThemeImageOptimizer.jsm");
|
||||
|
||||
function LightweightThemeConsumer(aDocument) {
|
||||
this._doc = aDocument;
|
||||
this._win = aDocument.defaultView;
|
||||
|
@ -131,9 +133,14 @@ function LightweightThemeConsumer(aDocument) {
|
|||
|
||||
ChromeUtils.import("resource://gre/modules/LightweightThemeManager.jsm", this);
|
||||
|
||||
this._darkThemeMediaQuery = this._win.matchMedia("(-moz-system-dark-theme)");
|
||||
this._darkThemeMediaQuery.addListener(this.LightweightThemeManager);
|
||||
this.LightweightThemeManager.systemThemeChanged(this._darkThemeMediaQuery);
|
||||
// We're responsible for notifying LightweightThemeManager when the OS is in
|
||||
// dark mode so it can activate the dark theme. We don't want this on Linux
|
||||
// as default theme picks up the right colors from dark GTK themes.
|
||||
if (AppConstants.platform != "linux") {
|
||||
this._darkThemeMediaQuery = this._win.matchMedia("(-moz-system-dark-theme)");
|
||||
this._darkThemeMediaQuery.addListener(this.LightweightThemeManager);
|
||||
this.LightweightThemeManager.systemThemeChanged(this._darkThemeMediaQuery);
|
||||
}
|
||||
|
||||
this._update(this.LightweightThemeManager.currentThemeWithPersistedData);
|
||||
|
||||
|
@ -173,8 +180,11 @@ LightweightThemeConsumer.prototype = {
|
|||
Services.obs.removeObserver(this, "lightweight-theme-styling-update");
|
||||
Services.ppmm.sharedData.delete(`theme/${this._winId}`);
|
||||
this._win.removeEventListener("resolutionchange", this);
|
||||
this._darkThemeMediaQuery.removeListener(this.LightweightThemeManager);
|
||||
this._win = this._doc = this._darkThemeMediaQuery = null;
|
||||
this._win = this._doc = null;
|
||||
if (this._darkThemeMediaQuery) {
|
||||
this._darkThemeMediaQuery.removeListener(this.LightweightThemeManager);
|
||||
this._darkThemeMediaQuery = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
@ -198,6 +208,7 @@ LightweightThemeConsumer.prototype = {
|
|||
let isDefaultThemeInDarkMode =
|
||||
theme.id == this.LightweightThemeManager.defaultDarkThemeID &&
|
||||
this.LightweightThemeManager.selectedThemeID == DEFAULT_THEME_ID &&
|
||||
this._darkThemeMediaQuery &&
|
||||
this._darkThemeMediaQuery.matches;
|
||||
|
||||
let root = this._doc.documentElement;
|
||||
|
|
|
@ -2603,10 +2603,12 @@ bool TextInputHandler::HandleCommand(Command aCommand) {
|
|||
// editor may behave differently if some of them are active.
|
||||
bool dispatchFakeKeyPress = !(currentKeyEvent && currentKeyEvent->IsProperKeyEvent(aCommand));
|
||||
|
||||
WidgetKeyboardEvent keydownEvent(true, eKeyDown, widget);
|
||||
WidgetKeyboardEvent keypressEvent(true, eKeyPress, widget);
|
||||
if (!dispatchFakeKeyPress) {
|
||||
// If we're acutally handling a key press, we should dispatch
|
||||
// the keypress event as-is.
|
||||
currentKeyEvent->InitKeyEvent(this, keydownEvent, false);
|
||||
currentKeyEvent->InitKeyEvent(this, keypressEvent, false);
|
||||
} else {
|
||||
// Otherwise, we should dispatch "fake" keypress event.
|
||||
|
@ -2615,7 +2617,7 @@ bool TextInputHandler::HandleCommand(Command aCommand) {
|
|||
// not same as what we expect since the native keyboard event caused
|
||||
// this command.
|
||||
NSEvent* keyEvent = currentKeyEvent ? currentKeyEvent->mKeyEvent : nullptr;
|
||||
keypressEvent.mNativeKeyEvent = keyEvent;
|
||||
keydownEvent.mNativeKeyEvent = keypressEvent.mNativeKeyEvent = keyEvent;
|
||||
NS_WARNING_ASSERTION(keypressEvent.mNativeKeyEvent,
|
||||
"Without native key event, NativeKeyBindings cannot compute aCommand");
|
||||
switch (aCommand) {
|
||||
|
@ -2640,6 +2642,16 @@ bool TextInputHandler::HandleCommand(Command aCommand) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CommandInsertTab:
|
||||
case CommandInsertBacktab:
|
||||
nsCocoaUtils::InitInputEvent(keypressEvent, keyEvent);
|
||||
keypressEvent.mKeyCode = NS_VK_TAB;
|
||||
keypressEvent.mKeyNameIndex = KEY_NAME_INDEX_Tab;
|
||||
keypressEvent.mModifiers &= ~(MODIFIER_CONTROL | MODIFIER_ALT | MODIFIER_META);
|
||||
if (aCommand == CommandInsertBacktab) {
|
||||
keypressEvent.mModifiers |= MODIFIER_SHIFT;
|
||||
}
|
||||
break;
|
||||
case CommandDeleteCharBackward:
|
||||
case CommandDeleteToBeginningOfLine:
|
||||
case CommandDeleteWordBackward: {
|
||||
|
@ -2790,9 +2802,36 @@ bool TextInputHandler::HandleCommand(Command aCommand) {
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCocoaUtils::InitInputEvent(keydownEvent, keyEvent);
|
||||
keydownEvent.mKeyCode = keypressEvent.mKeyCode;
|
||||
keydownEvent.mKeyNameIndex = keypressEvent.mKeyNameIndex;
|
||||
keydownEvent.mModifiers = keypressEvent.mModifiers;
|
||||
}
|
||||
|
||||
// We've stopped dispatching "keypress" events of non-printable keys on
|
||||
// the web. Therefore, we need to dispatch eKeyDown event here for web
|
||||
// apps. This is non-standard behavior if we've already dispatched a
|
||||
// "keydown" event. However, Chrome also dispatches such fake "keydown"
|
||||
// (and "keypress") event for making same behavior as Safari.
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
if (mDispatcher->DispatchKeyboardEvent(eKeyDown, keydownEvent, status, nullptr)) {
|
||||
bool keydownHandled = status == nsEventStatus_eConsumeNoDefault;
|
||||
if (currentKeyEvent) {
|
||||
currentKeyEvent->mKeyDownDispatched = true;
|
||||
currentKeyEvent->mKeyDownHandled |= keydownHandled;
|
||||
}
|
||||
if (keydownHandled) {
|
||||
// Don't dispatch eKeyPress event if preceding eKeyDown event is
|
||||
// consumed for conforming to UI Events.
|
||||
// XXX Perhaps, we should ignore previous eKeyDown event result
|
||||
// even if we've already dispatched because it may notify web apps
|
||||
// of different key information, e.g., it's handled by IME, but
|
||||
// web apps want to handle only this key.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool keyPressDispatched =
|
||||
mDispatcher->MaybeDispatchKeypressEvents(keypressEvent, status, currentKeyEvent);
|
||||
bool keyPressHandled = (status == nsEventStatus_eConsumeNoDefault);
|
||||
|
|
|
@ -674,6 +674,12 @@ with modules["IMGLIB"]:
|
|||
with modules["EDITOR"]:
|
||||
errors["NS_ERROR_EDITOR_DESTROYED"] = FAILURE(1)
|
||||
|
||||
# A error code that indicates that the DOM tree has been modified by
|
||||
# web app or add-on while the editor modifying the tree. However,
|
||||
# this shouldn't be exposed to the web because the result should've
|
||||
# been expected by the web app.
|
||||
errors["NS_ERROR_EDITOR_UNEXPECTED_DOM_TREE"] = FAILURE(2)
|
||||
|
||||
errors["NS_SUCCESS_EDITOR_ELEMENT_NOT_FOUND"] = SUCCESS(1)
|
||||
errors["NS_SUCCESS_EDITOR_FOUND_TARGET"] = SUCCESS(2)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче