accessible/src/windows/sdn/sdnTextAccessible.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "sdnTextAccessible.h"
     9 #include "ISimpleDOMText_i.c"
    11 #include "nsCoreUtils.h"
    12 #include "DocAccessible.h"
    14 #include "nsIFrame.h"
    15 #include "nsFontMetrics.h"
    16 #include "nsPresContext.h"
    17 #include "nsLayoutUtils.h"
    18 #include "gfxFont.h"
    19 #include "nsIAccessibleTypes.h"
    20 #include "mozilla/gfx/2D.h"
    22 using namespace mozilla::a11y;
    24 ////////////////////////////////////////////////////////////////////////////////
    25 // sdnTextAccessible
    26 ////////////////////////////////////////////////////////////////////////////////
    28 IMPL_IUNKNOWN_QUERY_HEAD(sdnTextAccessible)
    29   IMPL_IUNKNOWN_QUERY_IFACE(ISimpleDOMText)
    30 IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mAccessible)
    32 STDMETHODIMP
    33 sdnTextAccessible::get_domText(BSTR __RPC_FAR* aText)
    34 {
    35   A11Y_TRYBLOCK_BEGIN
    37   if (!aText)
    38     return E_INVALIDARG;
    39   *aText = nullptr;
    41   if (mAccessible->IsDefunct())
    42     return CO_E_OBJNOTCONNECTED;
    44   nsAutoString nodeValue;
    46   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mAccessible->GetContent()));
    47   DOMNode->GetNodeValue(nodeValue);
    48   if (nodeValue.IsEmpty())
    49     return S_FALSE;
    51   *aText = ::SysAllocStringLen(nodeValue.get(), nodeValue.Length());
    52   return *aText ? S_OK : E_OUTOFMEMORY;
    54   A11Y_TRYBLOCK_END
    55 }
    57 STDMETHODIMP
    58 sdnTextAccessible::get_clippedSubstringBounds(unsigned int aStartIndex,
    59                                               unsigned int aEndIndex,
    60                                               int __RPC_FAR* aX,
    61                                               int __RPC_FAR* aY,
    62                                               int __RPC_FAR* aWidth,
    63                                               int __RPC_FAR* aHeight)
    64 {
    65   A11Y_TRYBLOCK_BEGIN
    67   nscoord x = 0, y = 0, width = 0, height = 0;
    68   HRESULT rv = get_unclippedSubstringBounds(aStartIndex, aEndIndex,
    69                                             &x, &y, &width, &height);
    70   if (FAILED(rv))
    71     return rv;
    73   DocAccessible* document = mAccessible->Document();
    74   NS_ASSERTION(document,
    75                "There must always be a doc accessible, but there isn't. Crash!");
    77   nscoord docX = 0, docY = 0, docWidth = 0, docHeight = 0;
    78   document->GetBounds(&docX, &docY, &docWidth, &docHeight);
    80   nsIntRect unclippedRect(x, y, width, height);
    81   nsIntRect docRect(docX, docY, docWidth, docHeight);
    83   nsIntRect clippedRect;
    84   clippedRect.IntersectRect(unclippedRect, docRect);
    86   *aX = clippedRect.x;
    87   *aY = clippedRect.y;
    88   *aWidth = clippedRect.width;
    89   *aHeight = clippedRect.height;
    90   return S_OK;
    92   A11Y_TRYBLOCK_END
    93 }
    95 STDMETHODIMP
    96 sdnTextAccessible::get_unclippedSubstringBounds(unsigned int aStartIndex,
    97                                                 unsigned int aEndIndex,
    98                                                 int __RPC_FAR* aX,
    99                                                 int __RPC_FAR* aY,
   100                                                 int __RPC_FAR* aWidth,
   101                                                 int __RPC_FAR* aHeight)
   102 {
   103   A11Y_TRYBLOCK_BEGIN
   105   if (!aX || !aY || !aWidth || !aHeight)
   106     return E_INVALIDARG;
   107   *aX = *aY = *aWidth = *aHeight = 0;
   109   if (mAccessible->IsDefunct())
   110     return CO_E_OBJNOTCONNECTED;
   112   nsIFrame *frame = mAccessible->GetFrame();
   113   NS_ENSURE_TRUE(frame, E_FAIL);
   115   nsPoint startPoint, endPoint;
   116   nsIFrame* startFrame = GetPointFromOffset(frame, aStartIndex, true, startPoint);
   117   nsIFrame* endFrame = GetPointFromOffset(frame, aEndIndex, false, endPoint);
   118   if (!startFrame || !endFrame)
   119     return E_FAIL;
   121   nsRect sum;
   122   nsIFrame* iter = startFrame;
   123   nsIFrame* stopLoopFrame = endFrame->GetNextContinuation();
   124   for (; iter != stopLoopFrame; iter = iter->GetNextContinuation()) {
   125     nsRect rect = iter->GetScreenRectInAppUnits();
   126     nscoord start = (iter == startFrame) ? startPoint.x : 0;
   127     nscoord end = (iter == endFrame) ? endPoint.x : rect.width;
   128     rect.x += start;
   129     rect.width = end - start;
   130     sum.UnionRect(sum, rect);
   131   }
   133   nsPresContext* presContext = mAccessible->Document()->PresContext();
   134   *aX = presContext->AppUnitsToDevPixels(sum.x);
   135   *aY = presContext->AppUnitsToDevPixels(sum.y);
   136   *aWidth = presContext->AppUnitsToDevPixels(sum.width);
   137   *aHeight = presContext->AppUnitsToDevPixels(sum.height);
   139   return S_OK;
   141   A11Y_TRYBLOCK_END
   142 }
   144 STDMETHODIMP
   145 sdnTextAccessible::scrollToSubstring(unsigned int aStartIndex,
   146                                      unsigned int aEndIndex)
   147 {
   148   A11Y_TRYBLOCK_BEGIN
   150   if (mAccessible->IsDefunct())
   151     return CO_E_OBJNOTCONNECTED;
   153   nsRefPtr<nsRange> range = new nsRange(mAccessible->GetContent());
   154   if (NS_FAILED(range->SetStart(mAccessible->GetContent(), aStartIndex)))
   155     return E_FAIL;
   157   if (NS_FAILED(range->SetEnd(mAccessible->GetContent(), aEndIndex)))
   158     return E_FAIL;
   160   nsresult rv =
   161     nsCoreUtils::ScrollSubstringTo(mAccessible->GetFrame(), range,
   162                                    nsIAccessibleScrollType::SCROLL_TYPE_ANYWHERE);
   163   return GetHRESULT(rv);
   165   A11Y_TRYBLOCK_END
   166 }
   168 STDMETHODIMP
   169 sdnTextAccessible::get_fontFamily(BSTR __RPC_FAR* aFontFamily)
   170 {
   171   A11Y_TRYBLOCK_BEGIN
   173   if (!aFontFamily)
   174     return E_INVALIDARG;
   175   *aFontFamily = nullptr;
   177   if (mAccessible->IsDefunct())
   178     return CO_E_OBJNOTCONNECTED;
   180   nsIFrame* frame = mAccessible->GetFrame();
   181   if (!frame)
   182     return E_FAIL;
   184   nsRefPtr<nsFontMetrics> fm;
   185   nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm));
   187   const nsString& name = fm->GetThebesFontGroup()->GetFontAt(0)->GetName();
   188   if (name.IsEmpty())
   189     return S_FALSE;
   191   *aFontFamily = ::SysAllocStringLen(name.get(), name.Length());
   192   return *aFontFamily ? S_OK : E_OUTOFMEMORY;
   194   A11Y_TRYBLOCK_END
   195 }
   197 nsIFrame*
   198 sdnTextAccessible::GetPointFromOffset(nsIFrame* aContainingFrame,
   199                                       int32_t aOffset,
   200                                       bool aPreferNext,
   201                                       nsPoint& aOutPoint)
   202 {
   203   nsIFrame* textFrame = nullptr;
   204   int32_t outOffset;
   205   aContainingFrame->GetChildFrameContainingOffset(aOffset, aPreferNext,
   206                                                   &outOffset, &textFrame);
   207   if (textFrame)
   208     textFrame->GetPointFromOffset(aOffset, &aOutPoint);
   210   return textFrame;
   211 }

mercurial