dom/base/CompositionStringSynthesizer.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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 "CompositionStringSynthesizer.h"
michael@0 7 #include "nsContentUtils.h"
michael@0 8 #include "nsIDocShell.h"
michael@0 9 #include "nsIFrame.h"
michael@0 10 #include "nsIPresShell.h"
michael@0 11 #include "nsIWidget.h"
michael@0 12 #include "nsPIDOMWindow.h"
michael@0 13 #include "nsView.h"
michael@0 14 #include "mozilla/TextEvents.h"
michael@0 15
michael@0 16 namespace mozilla {
michael@0 17 namespace dom {
michael@0 18
michael@0 19 NS_IMPL_ISUPPORTS(CompositionStringSynthesizer,
michael@0 20 nsICompositionStringSynthesizer)
michael@0 21
michael@0 22 CompositionStringSynthesizer::CompositionStringSynthesizer(
michael@0 23 nsPIDOMWindow* aWindow)
michael@0 24 {
michael@0 25 mWindow = do_GetWeakReference(aWindow);
michael@0 26 mClauses = new TextRangeArray();
michael@0 27 ClearInternal();
michael@0 28 }
michael@0 29
michael@0 30 CompositionStringSynthesizer::~CompositionStringSynthesizer()
michael@0 31 {
michael@0 32 }
michael@0 33
michael@0 34 void
michael@0 35 CompositionStringSynthesizer::ClearInternal()
michael@0 36 {
michael@0 37 mString.Truncate();
michael@0 38 mClauses->Clear();
michael@0 39 mCaret.mRangeType = 0;
michael@0 40 }
michael@0 41
michael@0 42 nsIWidget*
michael@0 43 CompositionStringSynthesizer::GetWidget()
michael@0 44 {
michael@0 45 nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
michael@0 46 if (!window) {
michael@0 47 return nullptr;
michael@0 48 }
michael@0 49 nsIDocShell *docShell = window->GetDocShell();
michael@0 50 if (!docShell) {
michael@0 51 return nullptr;
michael@0 52 }
michael@0 53 nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
michael@0 54 if (!presShell) {
michael@0 55 return nullptr;
michael@0 56 }
michael@0 57 nsIFrame* frame = presShell->GetRootFrame();
michael@0 58 if (!frame) {
michael@0 59 return nullptr;
michael@0 60 }
michael@0 61 return frame->GetView()->GetNearestWidget(nullptr);
michael@0 62 }
michael@0 63
michael@0 64 NS_IMETHODIMP
michael@0 65 CompositionStringSynthesizer::SetString(const nsAString& aString)
michael@0 66 {
michael@0 67 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 68 NS_ENSURE_TRUE(widget && !widget->Destroyed(), NS_ERROR_NOT_AVAILABLE);
michael@0 69
michael@0 70 mString = aString;
michael@0 71 return NS_OK;
michael@0 72 }
michael@0 73
michael@0 74 NS_IMETHODIMP
michael@0 75 CompositionStringSynthesizer::AppendClause(uint32_t aLength,
michael@0 76 uint32_t aAttribute)
michael@0 77 {
michael@0 78 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 79 NS_ENSURE_TRUE(widget && !widget->Destroyed(), NS_ERROR_NOT_AVAILABLE);
michael@0 80
michael@0 81 switch (aAttribute) {
michael@0 82 case ATTR_RAWINPUT:
michael@0 83 case ATTR_SELECTEDRAWTEXT:
michael@0 84 case ATTR_CONVERTEDTEXT:
michael@0 85 case ATTR_SELECTEDCONVERTEDTEXT: {
michael@0 86 TextRange textRange;
michael@0 87 textRange.mStartOffset =
michael@0 88 mClauses->IsEmpty() ? 0 : mClauses->LastElement().mEndOffset;
michael@0 89 textRange.mEndOffset = textRange.mStartOffset + aLength;
michael@0 90 textRange.mRangeType = aAttribute;
michael@0 91 mClauses->AppendElement(textRange);
michael@0 92 return NS_OK;
michael@0 93 }
michael@0 94 default:
michael@0 95 return NS_ERROR_INVALID_ARG;
michael@0 96 }
michael@0 97 }
michael@0 98
michael@0 99 NS_IMETHODIMP
michael@0 100 CompositionStringSynthesizer::SetCaret(uint32_t aOffset, uint32_t aLength)
michael@0 101 {
michael@0 102 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 103 NS_ENSURE_TRUE(widget && !widget->Destroyed(), NS_ERROR_NOT_AVAILABLE);
michael@0 104
michael@0 105 mCaret.mStartOffset = aOffset;
michael@0 106 mCaret.mEndOffset = mCaret.mStartOffset + aLength;
michael@0 107 mCaret.mRangeType = NS_TEXTRANGE_CARETPOSITION;
michael@0 108 return NS_OK;
michael@0 109 }
michael@0 110
michael@0 111 NS_IMETHODIMP
michael@0 112 CompositionStringSynthesizer::DispatchEvent(bool* aDefaultPrevented)
michael@0 113 {
michael@0 114 NS_ENSURE_ARG_POINTER(aDefaultPrevented);
michael@0 115 nsCOMPtr<nsIWidget> widget = GetWidget();
michael@0 116 NS_ENSURE_TRUE(widget && !widget->Destroyed(), NS_ERROR_NOT_AVAILABLE);
michael@0 117
michael@0 118 if (!nsContentUtils::IsCallerChrome()) {
michael@0 119 return NS_ERROR_DOM_SECURITY_ERR;
michael@0 120 }
michael@0 121
michael@0 122 if (!mClauses->IsEmpty() &&
michael@0 123 mClauses->LastElement().mEndOffset != mString.Length()) {
michael@0 124 NS_WARNING("Sum of length of the all clauses must be same as the string "
michael@0 125 "length");
michael@0 126 ClearInternal();
michael@0 127 return NS_ERROR_ILLEGAL_VALUE;
michael@0 128 }
michael@0 129 if (mCaret.mRangeType == NS_TEXTRANGE_CARETPOSITION) {
michael@0 130 if (mCaret.mEndOffset > mString.Length()) {
michael@0 131 NS_WARNING("Caret position is out of the composition string");
michael@0 132 ClearInternal();
michael@0 133 return NS_ERROR_ILLEGAL_VALUE;
michael@0 134 }
michael@0 135 mClauses->AppendElement(mCaret);
michael@0 136 }
michael@0 137
michael@0 138 WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
michael@0 139 textEvent.time = PR_IntervalNow();
michael@0 140 textEvent.theText = mString;
michael@0 141 if (!mClauses->IsEmpty()) {
michael@0 142 textEvent.mRanges = mClauses;
michael@0 143 }
michael@0 144
michael@0 145 // XXX How should we set false for this on b2g?
michael@0 146 textEvent.mFlags.mIsSynthesizedForTests = true;
michael@0 147
michael@0 148 nsEventStatus status = nsEventStatus_eIgnore;
michael@0 149 nsresult rv = widget->DispatchEvent(&textEvent, status);
michael@0 150 *aDefaultPrevented = (status == nsEventStatus_eConsumeNoDefault);
michael@0 151
michael@0 152 ClearInternal();
michael@0 153
michael@0 154 NS_ENSURE_SUCCESS(rv, rv);
michael@0 155
michael@0 156 return NS_OK;
michael@0 157 }
michael@0 158
michael@0 159 } // namespace dom
michael@0 160 } // namespace mozilla

mercurial