widget/xpwidgets/ContentHelper.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "ContentHelper.h"
     7 #include "nsQueryFrame.h"
     8 #include "nsIContent.h"
     9 #include "nsIScrollableFrame.h"
    10 #include "nsLayoutUtils.h"
    11 #include "nsStyleConsts.h"
    12 #include "nsView.h"
    14 namespace mozilla {
    15 namespace widget {
    17 uint32_t
    18 ContentHelper::GetTouchActionFromFrame(nsIFrame* aFrame)
    19 {
    20   if (!aFrame || !aFrame->GetContent() || !aFrame->GetContent()->GetPrimaryFrame()) {
    21     // If frame is invalid or null then return default value.
    22     return NS_STYLE_TOUCH_ACTION_AUTO;
    23   }
    25   if (!aFrame->IsFrameOfType(nsIFrame::eSVG) && !aFrame->IsFrameOfType(nsIFrame::eBlockFrame)) {
    26     // Since touch-action property can be applied to only svg and block-level
    27     // elements we ignore frames of other types.
    28     return NS_STYLE_TOUCH_ACTION_AUTO;
    29   }
    31   return (aFrame->GetContent()->GetPrimaryFrame()->StyleDisplay()->mTouchAction);
    32 }
    34 void
    35 ContentHelper::UpdateAllowedBehavior(uint32_t aTouchActionValue, bool aConsiderPanning, TouchBehaviorFlags& aOutBehavior)
    36 {
    37   if (aTouchActionValue != NS_STYLE_TOUCH_ACTION_AUTO) {
    38     // Double-tap-zooming need property value AUTO
    39     aOutBehavior &= ~AllowedTouchBehavior::DOUBLE_TAP_ZOOM;
    40     if (aTouchActionValue != NS_STYLE_TOUCH_ACTION_MANIPULATION) {
    41       // Pinch-zooming need value AUTO or MANIPULATION
    42       aOutBehavior &= ~AllowedTouchBehavior::PINCH_ZOOM;
    43     }
    44   }
    46   if (aConsiderPanning) {
    47     if (aTouchActionValue == NS_STYLE_TOUCH_ACTION_NONE) {
    48       aOutBehavior &= ~AllowedTouchBehavior::VERTICAL_PAN;
    49       aOutBehavior &= ~AllowedTouchBehavior::HORIZONTAL_PAN;
    50     }
    52     // Values pan-x and pan-y set at the same time to the same element do not affect panning constraints.
    53     // Therefore we need to check whether pan-x is set without pan-y and the same for pan-y.
    54     if ((aTouchActionValue & NS_STYLE_TOUCH_ACTION_PAN_X) && !(aTouchActionValue & NS_STYLE_TOUCH_ACTION_PAN_Y)) {
    55       aOutBehavior &= ~AllowedTouchBehavior::VERTICAL_PAN;
    56     } else if ((aTouchActionValue & NS_STYLE_TOUCH_ACTION_PAN_Y) && !(aTouchActionValue & NS_STYLE_TOUCH_ACTION_PAN_X)) {
    57       aOutBehavior &= ~AllowedTouchBehavior::HORIZONTAL_PAN;
    58     }
    59   }
    60 }
    62 ContentHelper::TouchBehaviorFlags
    63 ContentHelper::GetAllowedTouchBehavior(nsIWidget* aWidget, const nsIntPoint& aPoint)
    64 {
    65   nsView *view = nsView::GetViewFor(aWidget);
    66   nsIFrame *viewFrame = view->GetFrame();
    68   nsPoint relativePoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aPoint, viewFrame);
    70   nsIFrame *target = nsLayoutUtils::GetFrameForPoint(viewFrame, relativePoint, nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
    71   nsIScrollableFrame *nearestScrollableParent = nsLayoutUtils::GetNearestScrollableFrame(target, 0);
    72   nsIFrame* nearestScrollableFrame = do_QueryFrame(nearestScrollableParent);
    74   // We're walking up the DOM tree until we meet the element with touch behavior and accumulating
    75   // touch-action restrictions of all elements in this chain.
    76   // The exact quote from the spec, that clarifies more:
    77   // To determine the effect of a touch, find the nearest ancestor (starting from the element itself)
    78   // that has a default touch behavior. Then examine the touch-action property of each element between
    79   // the hit tested element and the element with the default touch behavior (including both the hit
    80   // tested element and the element with the default touch behavior). If the touch-action property of
    81   // any of those elements disallows the default touch behavior, do nothing. Otherwise allow the element
    82   // to start considering the touch for the purposes of executing a default touch behavior.
    84   // Currently we support only two touch behaviors: panning and zooming.
    85   // For panning we walk up until we meet the first scrollable element (the element that supports panning)
    86   // or root element.
    87   // For zooming we walk up until the root element since Firefox currently supports only zooming of the
    88   // root frame but not the subframes.
    90   bool considerPanning = true;
    91   TouchBehaviorFlags behavior = AllowedTouchBehavior::VERTICAL_PAN | AllowedTouchBehavior::HORIZONTAL_PAN |
    92                                 AllowedTouchBehavior::PINCH_ZOOM | AllowedTouchBehavior::DOUBLE_TAP_ZOOM;
    94   for (nsIFrame *frame = target; frame && frame->GetContent() && behavior; frame = frame->GetParent()) {
    95     UpdateAllowedBehavior(GetTouchActionFromFrame(frame), considerPanning, behavior);
    97     if (frame == nearestScrollableFrame) {
    98       // We met the scrollable element, after it we shouldn't consider touch-action
    99       // values for the purpose of panning but only for zooming.
   100       considerPanning = false;
   101     }
   102   }
   104   return behavior;
   105 }
   107 }
   108 }

mercurial