michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:expandtab:shiftwidth=2:tabstop=2: michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "HyperTextAccessibleWrap.h" michael@0: #include "Accessible-inl.h" michael@0: michael@0: #include "nsEventShell.h" michael@0: michael@0: #include "mozilla/StaticPtr.h" michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::a11y; michael@0: michael@0: StaticRefPtr HyperTextAccessibleWrap::sLastTextChangeAcc; michael@0: StaticAutoPtr HyperTextAccessibleWrap::sLastTextChangeString; michael@0: uint32_t HyperTextAccessibleWrap::sLastTextChangeStart = 0; michael@0: uint32_t HyperTextAccessibleWrap::sLastTextChangeEnd = 0; michael@0: bool HyperTextAccessibleWrap::sLastTextChangeWasInsert = false; michael@0: michael@0: NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAccessibleWrap, michael@0: HyperTextAccessible) michael@0: michael@0: STDMETHODIMP michael@0: HyperTextAccessibleWrap::QueryInterface(REFIID aIID, void** aInstancePtr) michael@0: { michael@0: if (!aInstancePtr) michael@0: return E_FAIL; michael@0: michael@0: *aInstancePtr = nullptr; michael@0: michael@0: if (IsTextRole()) { michael@0: if (aIID == IID_IAccessibleText) michael@0: *aInstancePtr = michael@0: static_cast(static_cast(this)); michael@0: else if (aIID == IID_IAccessibleHypertext) michael@0: *aInstancePtr = static_cast(this); michael@0: else if (aIID == IID_IAccessibleEditableText) michael@0: *aInstancePtr = static_cast(this); michael@0: michael@0: if (*aInstancePtr) { michael@0: AddRef(); michael@0: return S_OK; michael@0: } michael@0: } michael@0: michael@0: return AccessibleWrap::QueryInterface(aIID, aInstancePtr); michael@0: } michael@0: michael@0: nsresult michael@0: HyperTextAccessibleWrap::HandleAccEvent(AccEvent* aEvent) michael@0: { michael@0: uint32_t eventType = aEvent->GetEventType(); michael@0: michael@0: if (eventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED || michael@0: eventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) { michael@0: Accessible* accessible = aEvent->GetAccessible(); michael@0: if (accessible && accessible->IsHyperText()) { michael@0: sLastTextChangeAcc = accessible; michael@0: if (!sLastTextChangeString) michael@0: sLastTextChangeString = new nsString(); michael@0: michael@0: AccTextChangeEvent* event = downcast_accEvent(aEvent); michael@0: event->GetModifiedText(*sLastTextChangeString); michael@0: sLastTextChangeStart = event->GetStartOffset(); michael@0: sLastTextChangeEnd = sLastTextChangeStart + event->GetLength(); michael@0: sLastTextChangeWasInsert = event->IsTextInserted(); michael@0: } michael@0: } michael@0: michael@0: return HyperTextAccessible::HandleAccEvent(aEvent); michael@0: } michael@0: michael@0: nsresult michael@0: HyperTextAccessibleWrap::GetModifiedText(bool aGetInsertedText, michael@0: nsAString& aText, michael@0: uint32_t* aStartOffset, michael@0: uint32_t* aEndOffset) michael@0: { michael@0: aText.Truncate(); michael@0: *aStartOffset = 0; michael@0: *aEndOffset = 0; michael@0: michael@0: if (!sLastTextChangeAcc) michael@0: return NS_OK; michael@0: michael@0: if (aGetInsertedText != sLastTextChangeWasInsert) michael@0: return NS_OK; michael@0: michael@0: if (sLastTextChangeAcc != this) michael@0: return NS_OK; michael@0: michael@0: *aStartOffset = sLastTextChangeStart; michael@0: *aEndOffset = sLastTextChangeEnd; michael@0: aText.Append(*sLastTextChangeString); michael@0: michael@0: return NS_OK; michael@0: } michael@0: