editor/libeditor/base/SetDocTitleTxn.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "SetDocTitleTxn.h"
michael@0 7 #include "mozilla/dom/Element.h" // for Element
michael@0 8 #include "nsAString.h"
michael@0 9 #include "nsCOMPtr.h" // for nsCOMPtr, getter_AddRefs, etc
michael@0 10 #include "nsDebug.h" // for NS_ENSURE_SUCCESS, etc
michael@0 11 #include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc
michael@0 12 #include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
michael@0 13 #include "nsIDOMDocument.h" // for nsIDOMDocument
michael@0 14 #include "nsIDOMElement.h" // for nsIDOMElement
michael@0 15 #include "nsIDOMNode.h" // for nsIDOMNode
michael@0 16 #include "nsIDOMNodeList.h" // for nsIDOMNodeList
michael@0 17 #include "nsIDOMText.h" // for nsIDOMText
michael@0 18 #include "nsIDocument.h" // for nsIDocument
michael@0 19 #include "nsIEditor.h" // for nsIEditor
michael@0 20 #include "nsIHTMLEditor.h" // for nsIHTMLEditor
michael@0 21 #include "nsLiteralString.h" // for NS_LITERAL_STRING
michael@0 22
michael@0 23 using namespace mozilla;
michael@0 24
michael@0 25 // note that aEditor is not refcounted
michael@0 26 SetDocTitleTxn::SetDocTitleTxn()
michael@0 27 : EditTxn()
michael@0 28 , mIsTransient(false)
michael@0 29 {
michael@0 30 }
michael@0 31
michael@0 32 NS_IMETHODIMP SetDocTitleTxn::Init(nsIHTMLEditor *aEditor,
michael@0 33 const nsAString *aValue)
michael@0 34
michael@0 35 {
michael@0 36 NS_ASSERTION(aEditor && aValue, "null args");
michael@0 37 if (!aEditor || !aValue) { return NS_ERROR_NULL_POINTER; }
michael@0 38
michael@0 39 mEditor = aEditor;
michael@0 40 mValue = *aValue;
michael@0 41
michael@0 42 return NS_OK;
michael@0 43 }
michael@0 44
michael@0 45 NS_IMETHODIMP SetDocTitleTxn::DoTransaction(void)
michael@0 46 {
michael@0 47 return SetDomTitle(mValue);
michael@0 48 }
michael@0 49
michael@0 50 NS_IMETHODIMP SetDocTitleTxn::UndoTransaction(void)
michael@0 51 {
michael@0 52 // No extra work required; the DOM changes alone are enough
michael@0 53 return NS_OK;
michael@0 54 }
michael@0 55
michael@0 56 NS_IMETHODIMP SetDocTitleTxn::RedoTransaction(void)
michael@0 57 {
michael@0 58 // No extra work required; the DOM changes alone are enough
michael@0 59 return NS_OK;
michael@0 60 }
michael@0 61
michael@0 62 nsresult SetDocTitleTxn::SetDomTitle(const nsAString& aTitle)
michael@0 63 {
michael@0 64 nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor);
michael@0 65 NS_ENSURE_TRUE(editor, NS_ERROR_FAILURE);
michael@0 66 nsCOMPtr<nsIDOMDocument> domDoc;
michael@0 67 nsresult res = editor->GetDocument(getter_AddRefs(domDoc));
michael@0 68 NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
michael@0 69
michael@0 70 nsCOMPtr<nsIDOMNodeList> titleList;
michael@0 71 res = domDoc->GetElementsByTagName(NS_LITERAL_STRING("title"), getter_AddRefs(titleList));
michael@0 72 NS_ENSURE_SUCCESS(res, res);
michael@0 73
michael@0 74 // First assume we will NOT really do anything
michael@0 75 // (transaction will not be pushed on stack)
michael@0 76 mIsTransient = true;
michael@0 77
michael@0 78 nsCOMPtr<nsIDOMNode>titleNode;
michael@0 79 if(titleList)
michael@0 80 {
michael@0 81 res = titleList->Item(0, getter_AddRefs(titleNode));
michael@0 82 NS_ENSURE_SUCCESS(res, res);
michael@0 83 if (titleNode)
michael@0 84 {
michael@0 85 // Delete existing child textnode of title node
michael@0 86 // (Note: all contents under a TITLE node are always in a single text node)
michael@0 87 nsCOMPtr<nsIDOMNode> child;
michael@0 88 res = titleNode->GetFirstChild(getter_AddRefs(child));
michael@0 89 if(NS_FAILED(res)) return res;
michael@0 90 if(child)
michael@0 91 {
michael@0 92 // Save current text as the undo value
michael@0 93 nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(child);
michael@0 94 if(textNode)
michael@0 95 {
michael@0 96 textNode->GetData(mUndoValue);
michael@0 97
michael@0 98 // If title text is identical to what already exists,
michael@0 99 // quit now (mIsTransient is now TRUE)
michael@0 100 if (mUndoValue == aTitle)
michael@0 101 return NS_OK;
michael@0 102 }
michael@0 103 res = editor->DeleteNode(child);
michael@0 104 if(NS_FAILED(res)) return res;
michael@0 105 }
michael@0 106 }
michael@0 107 }
michael@0 108
michael@0 109 // We didn't return above, thus we really will be changing the title
michael@0 110 mIsTransient = false;
michael@0 111
michael@0 112 // Get the <HEAD> node, create a <TITLE> and insert it under the HEAD
michael@0 113 nsCOMPtr<nsIDocument> document = do_QueryInterface(domDoc);
michael@0 114 NS_ENSURE_STATE(document);
michael@0 115
michael@0 116 dom::Element* head = document->GetHeadElement();
michael@0 117 NS_ENSURE_STATE(head);
michael@0 118
michael@0 119 bool newTitleNode = false;
michael@0 120 uint32_t newTitleIndex = 0;
michael@0 121
michael@0 122 if (!titleNode)
michael@0 123 {
michael@0 124 // Didn't find one above: Create a new one
michael@0 125 nsCOMPtr<nsIDOMElement>titleElement;
michael@0 126 res = domDoc->CreateElement(NS_LITERAL_STRING("title"), getter_AddRefs(titleElement));
michael@0 127 NS_ENSURE_SUCCESS(res, res);
michael@0 128 NS_ENSURE_TRUE(titleElement, NS_ERROR_FAILURE);
michael@0 129
michael@0 130 titleNode = do_QueryInterface(titleElement);
michael@0 131 newTitleNode = true;
michael@0 132
michael@0 133 // Get index so we append new title node after all existing HEAD children.
michael@0 134 newTitleIndex = head->GetChildCount();
michael@0 135 }
michael@0 136
michael@0 137 // Append a text node under the TITLE
michael@0 138 // only if the title text isn't empty
michael@0 139 if (titleNode && !aTitle.IsEmpty())
michael@0 140 {
michael@0 141 nsCOMPtr<nsIDOMText> textNode;
michael@0 142 res = domDoc->CreateTextNode(aTitle, getter_AddRefs(textNode));
michael@0 143 NS_ENSURE_SUCCESS(res, res);
michael@0 144 nsCOMPtr<nsIDOMNode> newNode = do_QueryInterface(textNode);
michael@0 145 NS_ENSURE_TRUE(newNode, NS_ERROR_FAILURE);
michael@0 146
michael@0 147 if (newTitleNode)
michael@0 148 {
michael@0 149 // Not undoable: We will insert newTitleNode below
michael@0 150 nsCOMPtr<nsIDOMNode> resultNode;
michael@0 151 res = titleNode->AppendChild(newNode, getter_AddRefs(resultNode));
michael@0 152 }
michael@0 153 else
michael@0 154 {
michael@0 155 // This is an undoable transaction
michael@0 156 res = editor->InsertNode(newNode, titleNode, 0);
michael@0 157 }
michael@0 158 NS_ENSURE_SUCCESS(res, res);
michael@0 159 }
michael@0 160
michael@0 161 if (newTitleNode)
michael@0 162 {
michael@0 163 // Undoable transaction to insert title+text together
michael@0 164 res = editor->InsertNode(titleNode, head->AsDOMNode(), newTitleIndex);
michael@0 165 }
michael@0 166 return res;
michael@0 167 }
michael@0 168
michael@0 169 NS_IMETHODIMP SetDocTitleTxn::GetTxnDescription(nsAString& aString)
michael@0 170 {
michael@0 171 aString.AssignLiteral("SetDocTitleTxn: ");
michael@0 172 aString += mValue;
michael@0 173 return NS_OK;
michael@0 174 }
michael@0 175
michael@0 176 NS_IMETHODIMP SetDocTitleTxn::GetIsTransient(bool *aIsTransient)
michael@0 177 {
michael@0 178 NS_ENSURE_TRUE(aIsTransient, NS_ERROR_NULL_POINTER);
michael@0 179 *aIsTransient = mIsTransient;
michael@0 180 return NS_OK;
michael@0 181 }
michael@0 182

mercurial