зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1312991 Get rid of nsIHTMLEditor::SetDocumentTitle() and mozilla::SetDocumentTitleTransaction r=smaug
Now, nobody (including add-ons) uses nsIHTMLEditor::SetDocumentTitle(), so, we can remove it. Additionally, mozilla::SetDocumentTitleTransaction is created only when nsIHMLEditor::SetDocumentTitle(), so, we can remove this class too. MozReview-Commit-ID: HK7G9u7HUlh --HG-- extra : rebase_source : da68cabbf929a684d26f6316fdc7f58b8e32ab02
This commit is contained in:
Родитель
fedd79ebdb
Коммит
c20fedebf4
|
@ -17,7 +17,6 @@
|
|||
#include "HTMLEditRules.h"
|
||||
#include "HTMLEditUtils.h"
|
||||
#include "HTMLURIRefObject.h"
|
||||
#include "SetDocumentTitleTransaction.h"
|
||||
#include "StyleSheetTransactions.h"
|
||||
#include "TextEditUtils.h"
|
||||
#include "TypeInState.h"
|
||||
|
@ -811,22 +810,6 @@ HTMLEditor::IsBlockNode(nsINode* aNode)
|
|||
return aNode && NodeIsBlockStatic(aNode);
|
||||
}
|
||||
|
||||
// Non-static version for the nsIEditor interface and JavaScript
|
||||
NS_IMETHODIMP
|
||||
HTMLEditor::SetDocumentTitle(const nsAString& aTitle)
|
||||
{
|
||||
RefPtr<SetDocumentTitleTransaction> transaction =
|
||||
new SetDocumentTitleTransaction();
|
||||
NS_ENSURE_TRUE(transaction, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsresult rv = transaction->Init(this, &aTitle);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
//Don't let Rules System change the selection
|
||||
AutoTransactionsConserveSelection dontChangeSelection(this);
|
||||
return EditorBase::DoTransaction(transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* GetBlockNodeParent returns enclosing block level ancestor, if any.
|
||||
*/
|
||||
|
|
|
@ -1,230 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "SetDocumentTitleTransaction.h"
|
||||
#include "mozilla/dom/Element.h" // for Element
|
||||
#include "nsAString.h"
|
||||
#include "nsCOMPtr.h" // for nsCOMPtr, getter_AddRefs, etc.
|
||||
#include "nsDebug.h" // for NS_ENSURE_SUCCESS, etc.
|
||||
#include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc.
|
||||
#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
|
||||
#include "nsIDOMDocument.h" // for nsIDOMDocument
|
||||
#include "nsIDOMElement.h" // for nsIDOMElement
|
||||
#include "nsIDOMNode.h" // for nsIDOMNode
|
||||
#include "nsIDOMNodeList.h" // for nsIDOMNodeList
|
||||
#include "nsIDOMText.h" // for nsIDOMText
|
||||
#include "nsIDocument.h" // for nsIDocument
|
||||
#include "nsIEditor.h" // for nsIEditor
|
||||
#include "nsIHTMLEditor.h" // for nsIHTMLEditor
|
||||
#include "nsLiteralString.h" // for NS_LITERAL_STRING
|
||||
#include "nsTextNode.h" // for nsTextNode
|
||||
#include "nsQueryObject.h" // for do_QueryObject
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Note that aEditor is not refcounted.
|
||||
SetDocumentTitleTransaction::SetDocumentTitleTransaction()
|
||||
: mEditor(nullptr)
|
||||
, mIsTransient(false)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SetDocumentTitleTransaction::Init(nsIHTMLEditor* aEditor,
|
||||
const nsAString* aValue)
|
||||
|
||||
{
|
||||
NS_ASSERTION(aEditor && aValue, "null args");
|
||||
if (!aEditor || !aValue) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
mEditor = aEditor;
|
||||
mValue = *aValue;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SetDocumentTitleTransaction::DoTransaction()
|
||||
{
|
||||
return SetDomTitle(mValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SetDocumentTitleTransaction::UndoTransaction()
|
||||
{
|
||||
// No extra work required; the DOM changes alone are enough
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SetDocumentTitleTransaction::RedoTransaction()
|
||||
{
|
||||
// No extra work required; the DOM changes alone are enough
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
SetDocumentTitleTransaction::SetDomTitle(const nsAString& aTitle)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor);
|
||||
if (NS_WARN_IF(!editor)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
nsresult rv = editor->GetDocument(getter_AddRefs(domDoc));
|
||||
if (NS_WARN_IF(!domDoc)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> titleList;
|
||||
rv = domDoc->GetElementsByTagName(NS_LITERAL_STRING("title"),
|
||||
getter_AddRefs(titleList));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// First assume we will NOT really do anything
|
||||
// (transaction will not be pushed on stack)
|
||||
mIsTransient = true;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> titleNode;
|
||||
if(titleList) {
|
||||
rv = titleList->Item(0, getter_AddRefs(titleNode));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (titleNode) {
|
||||
// Delete existing child textnode of title node
|
||||
// (Note: all contents under a TITLE node are always in a single text node)
|
||||
nsCOMPtr<nsIDOMNode> child;
|
||||
rv = titleNode->GetFirstChild(getter_AddRefs(child));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if(child) {
|
||||
// Save current text as the undo value
|
||||
nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(child);
|
||||
if(textNode) {
|
||||
textNode->GetData(mUndoValue);
|
||||
|
||||
// If title text is identical to what already exists,
|
||||
// quit now (mIsTransient is now TRUE)
|
||||
if (mUndoValue == aTitle) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
rv = editor->DeleteNode(child);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't return above, thus we really will be changing the title
|
||||
mIsTransient = false;
|
||||
|
||||
// Get the <HEAD> node, create a <TITLE> and insert it under the HEAD
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
|
||||
if (NS_WARN_IF(!document)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
RefPtr<dom::Element> headElement = document->GetHeadElement();
|
||||
if (NS_WARN_IF(!headElement)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
bool newTitleNode = false;
|
||||
uint32_t newTitleIndex = 0;
|
||||
|
||||
if (!titleNode) {
|
||||
// Didn't find one above: Create a new one
|
||||
nsCOMPtr<nsIDOMElement>titleElement;
|
||||
rv = domDoc->CreateElement(NS_LITERAL_STRING("title"),
|
||||
getter_AddRefs(titleElement));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
if (NS_WARN_IF(!titleElement)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
titleNode = do_QueryInterface(titleElement);
|
||||
newTitleNode = true;
|
||||
|
||||
// Get index so we append new title node after all existing HEAD children.
|
||||
newTitleIndex = headElement->GetChildCount();
|
||||
}
|
||||
|
||||
// Append a text node under the TITLE only if the title text isn't empty.
|
||||
if (titleNode && !aTitle.IsEmpty()) {
|
||||
RefPtr<nsTextNode> textNode = document->CreateTextNode(aTitle);
|
||||
|
||||
if (newTitleNode) {
|
||||
// Not undoable: We will insert newTitleNode below
|
||||
nsCOMPtr<nsINode> title = do_QueryInterface(titleNode);
|
||||
MOZ_ASSERT(title);
|
||||
|
||||
ErrorResult result;
|
||||
title->AppendChild(*textNode, result);
|
||||
if (NS_WARN_IF(result.Failed())) {
|
||||
return result.StealNSResult();
|
||||
}
|
||||
} else {
|
||||
// This is an undoable transaction
|
||||
nsCOMPtr<nsIDOMNode> newNode = do_QueryObject(textNode);
|
||||
if (NS_WARN_IF(!newNode)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = editor->InsertNode(newNode, titleNode, 0);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
// Calling AppendChild() or InsertNode() could cause removing the head
|
||||
// element. So, let's mark it dirty.
|
||||
headElement = nullptr;
|
||||
}
|
||||
|
||||
if (newTitleNode) {
|
||||
if (!headElement) {
|
||||
headElement = document->GetHeadElement();
|
||||
if (NS_WARN_IF(!headElement)) {
|
||||
// XXX Can we return NS_OK when there is no head element?
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
// Undoable transaction to insert title+text together
|
||||
rv = editor->InsertNode(titleNode, headElement->AsDOMNode(), newTitleIndex);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SetDocumentTitleTransaction::GetTxnDescription(nsAString& aString)
|
||||
{
|
||||
aString.AssignLiteral("SetDocumentTitleTransaction: ");
|
||||
aString += mValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SetDocumentTitleTransaction::GetIsTransient(bool* aIsTransient)
|
||||
{
|
||||
if (NS_WARN_IF(!aIsTransient)) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
*aIsTransient = mIsTransient;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -1,60 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef SetDocumentTitleTransaction_h
|
||||
#define SetDocumentTitleTransaction_h
|
||||
|
||||
#include "mozilla/EditTransactionBase.h" // for EditTransactionBase, etc.
|
||||
#include "nsString.h" // for nsString
|
||||
#include "nscore.h" // for NS_IMETHOD, nsAString, etc.
|
||||
|
||||
class nsIHTMLEditor;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* A transaction that changes the document's title,
|
||||
* which is a text node under the <title> tag in a page's <head> section
|
||||
* provides default concrete behavior for all nsITransaction methods.
|
||||
*/
|
||||
class SetDocumentTitleTransaction final : public EditTransactionBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Initialize the transaction.
|
||||
* @param aEditor The object providing core editing operations.
|
||||
* @param aValue The new value for document title.
|
||||
*/
|
||||
NS_IMETHOD Init(nsIHTMLEditor* aEditor,
|
||||
const nsAString* aValue);
|
||||
SetDocumentTitleTransaction();
|
||||
|
||||
private:
|
||||
nsresult SetDomTitle(const nsAString& aTitle);
|
||||
|
||||
public:
|
||||
NS_DECL_EDITTRANSACTIONBASE
|
||||
|
||||
NS_IMETHOD RedoTransaction() override;
|
||||
NS_IMETHOD GetIsTransient(bool *aIsTransient) override;
|
||||
|
||||
protected:
|
||||
|
||||
// The editor that created this transaction.
|
||||
nsIHTMLEditor* mEditor;
|
||||
|
||||
// The new title string.
|
||||
nsString mValue;
|
||||
|
||||
// The previous title string to use for undo.
|
||||
nsString mUndoValue;
|
||||
|
||||
// Set true if we dont' really change the title during Do().
|
||||
bool mIsTransient;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // #ifndef SetDocumentTitleTransaction_h
|
|
@ -64,7 +64,6 @@ UNIFIED_SOURCES += [
|
|||
'JoinNodeTransaction.cpp',
|
||||
'PlaceholderTransaction.cpp',
|
||||
'SelectionState.cpp',
|
||||
'SetDocumentTitleTransaction.cpp',
|
||||
'SplitNodeTransaction.cpp',
|
||||
'StyleSheetTransactions.cpp',
|
||||
'TextEditor.cpp',
|
||||
|
|
|
@ -9,6 +9,5 @@ support-files = green.png
|
|||
[test_bug780908.xul]
|
||||
[test_contenteditable_text_input_handling.html]
|
||||
[test_htmleditor_keyevent_handling.html]
|
||||
[test_set_document_title_transaction.html]
|
||||
[test_texteditor_keyevent_handling.html]
|
||||
skip-if = (debug && os=='win') || (os == 'linux') # Bug 1116205, leaks on windows debug, fails delete key on linux
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for SetDocumentTitleTransaction</title>
|
||||
<script type="text/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="runTests()">
|
||||
<div id="display">
|
||||
<iframe src="data:text/html,<!DOCTYPE html><html><head><title>first title</title></head><body></body></html>"></iframe>
|
||||
</div>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
function runTests() {
|
||||
var iframe = document.getElementsByTagName("iframe")[0];
|
||||
function isDocumentTitleEquals(aDescription, aExpectedTitle) {
|
||||
is(iframe.contentDocument.title, aExpectedTitle, aDescription + ": document.title should be " + aExpectedTitle);
|
||||
is(iframe.contentDocument.getElementsByTagName("title")[0].textContent, aExpectedTitle, aDescription + ": The text in the title element should be " + aExpectedTitle);
|
||||
}
|
||||
|
||||
isDocumentTitleEquals("Checking isDocumentTitleEquals()", "first title");
|
||||
|
||||
const kTests = [
|
||||
{ description: "designMode=\"on\"",
|
||||
init: function () {
|
||||
iframe.contentDocument.designMode = "on";
|
||||
},
|
||||
cleanUp: function () {
|
||||
iframe.contentDocument.designMode = "off";
|
||||
}
|
||||
},
|
||||
{ description: "html element has contenteditable attribute",
|
||||
init: function () {
|
||||
iframe.contentDocument.documentElement.setAttribute("contenteditable", "true");
|
||||
},
|
||||
cleanUp: function () {
|
||||
iframe.contentDocument.documentElement.removeAttribute("contenteditable");
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
for (var i = 0; i < kTests.length; i++) {
|
||||
const kTest = kTests[i];
|
||||
kTest.init();
|
||||
|
||||
var editor = SpecialPowers.wrap(iframe.contentWindow).
|
||||
QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor).
|
||||
getInterface(SpecialPowers.Ci.nsIWebNavigation).
|
||||
QueryInterface(SpecialPowers.Ci.nsIDocShell).editor;
|
||||
ok(editor, kTest.description + ": The docshell should have editor");
|
||||
var htmlEditor = editor.QueryInterface(SpecialPowers.Ci.nsIHTMLEditor);
|
||||
ok(htmlEditor, kTest.description + ": The editor should have nsIHTMLEditor interface");
|
||||
|
||||
// Replace existing title.
|
||||
htmlEditor.setDocumentTitle("Modified title");
|
||||
isDocumentTitleEquals(kTest.description, "Modified title");
|
||||
|
||||
// When the document doesn't have <title> element, title element should be created automatically.
|
||||
iframe.contentDocument.head.removeChild(iframe.contentDocument.getElementsByTagName("title")[0]);
|
||||
is(iframe.contentDocument.getElementsByTagName("title").length, 0, kTest.description + ": There should be no title element");
|
||||
htmlEditor.setDocumentTitle("new title");
|
||||
is(iframe.contentDocument.getElementsByTagName("title").length, 1, kTest.description + ": There should be a title element");
|
||||
isDocumentTitleEquals(kTest.description, "new title");
|
||||
|
||||
kTest.cleanUp();
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -236,11 +236,6 @@ interface nsIHTMLEditor : nsISupports
|
|||
void insertElementAtSelection(in nsIDOMElement aElement,
|
||||
in boolean aDeleteSelection);
|
||||
|
||||
/**
|
||||
* Set the documents title.
|
||||
*/
|
||||
void setDocumentTitle(in AString aTitle);
|
||||
|
||||
/**
|
||||
* Set the BaseURL for the document to the current URL
|
||||
* but only if the page doesn't have a <base> tag
|
||||
|
|
Загрузка…
Ссылка в новой задаче