Range* DOMSelection::getRangeAt(int index, ExceptionState& exceptionState) { if (!isAvailable()) return nullptr; if (index < 0 || index >= rangeCount()) { exceptionState.throwDOMException( IndexSizeError, String::number(index) + " is not a valid index."); return nullptr; } // If you're hitting this, you've added broken multi-range selection support DCHECK_EQ(rangeCount(), 1); Position anchor = anchorPosition(visibleSelection()); if (!anchor.anchorNode()->isInShadowTree()) return frame()->selection().firstRange(); Node* node = shadowAdjustedNode(anchor); if (!node) // crbug.com/595100 return nullptr; if (!visibleSelection().isBaseFirst()) return Range::create(*anchor.document(), focusNode(), focusOffset(), node, anchorOffset()); return Range::create(*anchor.document(), node, anchorOffset(), focusNode(), focusOffset()); }
void RotationViewportAnchor::setAnchor() { RootFrameViewport* rootFrameViewport = m_rootFrameView->getRootFrameViewport(); DCHECK(rootFrameViewport); m_oldPageScaleFactor = m_visualViewport->scale(); m_oldMinimumPageScaleFactor = m_pageScaleConstraintsSet.finalConstraints().minimumScale; // Save the absolute location in case we won't find the anchor node, we'll // fall back to that. m_visualViewportInDocument = FloatPoint(rootFrameViewport->visibleContentRect().location()); m_anchorNode.clear(); m_anchorNodeBounds = LayoutRect(); m_anchorInNodeCoords = FloatSize(); m_normalizedVisualViewportOffset = FloatSize(); IntRect innerViewRect = rootFrameViewport->visibleContentRect(); // Preserve origins at the absolute screen origin. if (innerViewRect.location() == IntPoint::zero() || innerViewRect.isEmpty()) return; IntRect outerViewRect = layoutViewport().visibleContentRect(IncludeScrollbars); // Normalize by the size of the outer rect DCHECK(!outerViewRect.isEmpty()); m_normalizedVisualViewportOffset = m_visualViewport->getScrollOffset(); m_normalizedVisualViewportOffset.scale(1.0 / outerViewRect.width(), 1.0 / outerViewRect.height()); // Note, we specifically use the unscaled visual viewport size here as the // conversion into content-space below will apply the scale. FloatPoint anchorOffset(m_visualViewport->size()); anchorOffset.scale(m_anchorInInnerViewCoords.width(), m_anchorInInnerViewCoords.height()); // Note, we specifically convert to the rootFrameView contents here, rather // than the layout viewport. That's because hit testing works from the // FrameView's content coordinates even if it's not the layout viewport. const FloatPoint anchorPointInContents = m_rootFrameView->frameToContents( m_visualViewport->viewportToRootFrame(anchorOffset)); Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPointInContents), innerViewRect, m_rootFrameView->frame().eventHandler()); if (!node) return; m_anchorNode = node; m_anchorNodeBounds = node->boundingBox(); m_anchorInNodeCoords = anchorPointInContents - FloatPoint(m_anchorNodeBounds.location()); m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height()); }
void RotationViewportAnchor::setAnchor() { // FIXME: Scroll offsets are now fractional (DoublePoint and FloatPoint for the FrameView and VisualViewport // respectively. This path should be rewritten without pixel snapping. IntRect outerViewRect = m_rootFrameView->layoutViewportScrollableArea()->visibleContentRect(IncludeScrollbars); IntRect innerViewRect = enclosedIntRect(m_rootFrameView->getScrollableArea()->visibleContentRectDouble()); m_oldPageScaleFactor = m_visualViewport->scale(); m_oldMinimumPageScaleFactor = m_pageScaleConstraintsSet.finalConstraints().minimumScale; // Save the absolute location in case we won't find the anchor node, we'll fall back to that. m_visualViewportInDocument = FloatPoint(m_rootFrameView->getScrollableArea()->visibleContentRectDouble().location()); m_anchorNode.clear(); m_anchorNodeBounds = LayoutRect(); m_anchorInNodeCoords = FloatSize(); m_normalizedVisualViewportOffset = FloatSize(); if (innerViewRect.isEmpty()) return; // Preserve origins at the absolute screen origin if (innerViewRect.location() == IntPoint::zero()) return; // Inner rectangle should be within the outer one. DCHECK(outerViewRect.contains(innerViewRect)); // Outer rectangle is used as a scale, we need positive width and height. DCHECK(!outerViewRect.isEmpty()); m_normalizedVisualViewportOffset = FloatSize(innerViewRect.location() - outerViewRect.location()); // Normalize by the size of the outer rect m_normalizedVisualViewportOffset.scale(1.0 / outerViewRect.width(), 1.0 / outerViewRect.height()); FloatSize anchorOffset(innerViewRect.size()); anchorOffset.scale(m_anchorInInnerViewCoords.width(), m_anchorInInnerViewCoords.height()); const FloatPoint anchorPoint = FloatPoint(innerViewRect.location()) + anchorOffset; Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPoint), innerViewRect, m_rootFrameView->frame().eventHandler()); if (!node) return; m_anchorNode = node; m_anchorNodeBounds = node->boundingBox(); m_anchorInNodeCoords = anchorPoint - FloatPoint(m_anchorNodeBounds.location()); m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height()); }
PassRefPtrWillBeRawPtr<Range> DOMSelection::getRangeAt(int index, ExceptionState& exceptionState) { if (!m_frame) return nullptr; if (index < 0 || index >= rangeCount()) { exceptionState.throwDOMException(IndexSizeError, String::number(index) + " is not a valid index."); return nullptr; } // If you're hitting this, you've added broken multi-range selection support ASSERT(rangeCount() == 1); Position anchor = anchorPosition(visibleSelection()); if (!anchor.anchorNode()->isInShadowTree()) return m_frame->selection().firstRange(); if (!visibleSelection().isBaseFirst()) return Range::create(*anchor.document(), focusNode(), focusOffset(), shadowAdjustedNode(anchor), anchorOffset()); return Range::create(*anchor.document(), shadowAdjustedNode(anchor), anchorOffset(), focusNode(), focusOffset()); }
void RotationViewportAnchor::setAnchor() { RootFrameViewport* rootFrameViewport = m_rootFrameView->getRootFrameViewport(); DCHECK(rootFrameViewport); IntRect outerViewRect = layoutViewport().visibleContentRect(IncludeScrollbars); IntRect innerViewRect = rootFrameViewport->visibleContentRect(); m_oldPageScaleFactor = m_visualViewport->scale(); m_oldMinimumPageScaleFactor = m_pageScaleConstraintsSet.finalConstraints().minimumScale; // Save the absolute location in case we won't find the anchor node, we'll // fall back to that. m_visualViewportInDocument = FloatPoint(rootFrameViewport->visibleContentRect().location()); m_anchorNode.clear(); m_anchorNodeBounds = LayoutRect(); m_anchorInNodeCoords = FloatSize(); m_normalizedVisualViewportOffset = FloatSize(); if (innerViewRect.isEmpty()) return; // Preserve origins at the absolute screen origin if (innerViewRect.location() == IntPoint::zero()) return; // Inner rectangle should be within the outer one. DCHECK(outerViewRect.contains(innerViewRect)); // Outer rectangle is used as a scale, we need positive width and height. DCHECK(!outerViewRect.isEmpty()); m_normalizedVisualViewportOffset = FloatSize(innerViewRect.location() - outerViewRect.location()); // Normalize by the size of the outer rect m_normalizedVisualViewportOffset.scale(1.0 / outerViewRect.width(), 1.0 / outerViewRect.height()); FloatPoint anchorOffset(innerViewRect.size()); anchorOffset.scale(m_anchorInInnerViewCoords.width(), m_anchorInInnerViewCoords.height()); const FloatPoint anchorPointInContents = m_rootFrameView->rootFrameToContents( m_visualViewport->viewportToRootFrame(anchorOffset)); Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPointInContents), innerViewRect, m_rootFrameView->frame().eventHandler()); if (!node) return; m_anchorNode = node; m_anchorNodeBounds = node->boundingBox(); m_anchorInNodeCoords = anchorPointInContents - FloatPoint(m_anchorNodeBounds.location()); m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anchorNodeBounds.height()); }