diff -r 000000000000 -r 6474c204b198 layout/generic/nsBRFrame.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/layout/generic/nsBRFrame.cpp Wed Dec 31 06:09:35 2014 +0100
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* rendering object for HTML
elements */
+
+#include "nsCOMPtr.h"
+#include "nsFrame.h"
+#include "nsPresContext.h"
+#include "nsLineLayout.h"
+#include "nsStyleConsts.h"
+#include "nsGkAtoms.h"
+#include "nsRenderingContext.h"
+#include "nsLayoutUtils.h"
+
+//FOR SELECTION
+#include "nsIContent.h"
+//END INCLUDES FOR SELECTION
+
+using namespace mozilla;
+
+class BRFrame : public nsFrame {
+public:
+ NS_DECL_FRAMEARENA_HELPERS
+
+ friend nsIFrame* NS_NewBRFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
+
+ virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint) MOZ_OVERRIDE;
+
+ virtual FrameSearchResult PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
+ virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
+ bool aRespectClusters = true) MOZ_OVERRIDE;
+ virtual FrameSearchResult PeekOffsetWord(bool aForward, bool aWordSelectEatSpace,
+ bool aIsKeyboardSelect, int32_t* aOffset,
+ PeekWordState* aState) MOZ_OVERRIDE;
+
+ virtual nsresult Reflow(nsPresContext* aPresContext,
+ nsHTMLReflowMetrics& aDesiredSize,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus) MOZ_OVERRIDE;
+ virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
+ InlineMinWidthData *aData) MOZ_OVERRIDE;
+ virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
+ InlinePrefWidthData *aData) MOZ_OVERRIDE;
+ virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+ virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+ virtual nsIAtom* GetType() const MOZ_OVERRIDE;
+ virtual nscoord GetBaseline() const MOZ_OVERRIDE;
+
+ virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
+ {
+ return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced |
+ nsIFrame::eLineParticipant));
+ }
+
+#ifdef ACCESSIBILITY
+ virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
+#endif
+
+protected:
+ BRFrame(nsStyleContext* aContext) : nsFrame(aContext) {}
+ virtual ~BRFrame();
+
+ nscoord mAscent;
+};
+
+nsIFrame*
+NS_NewBRFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
+{
+ return new (aPresShell) BRFrame(aContext);
+}
+
+NS_IMPL_FRAMEARENA_HELPERS(BRFrame)
+
+BRFrame::~BRFrame()
+{
+}
+
+nsresult
+BRFrame::Reflow(nsPresContext* aPresContext,
+ nsHTMLReflowMetrics& aMetrics,
+ const nsHTMLReflowState& aReflowState,
+ nsReflowStatus& aStatus)
+{
+ DO_GLOBAL_REFLOW_COUNT("BRFrame");
+ DISPLAY_REFLOW(aPresContext, this, aReflowState, aMetrics, aStatus);
+ aMetrics.Height() = 0; // BR frames with height 0 are ignored in quirks
+ // mode by nsLineLayout::VerticalAlignFrames .
+ // However, it's not always 0. See below.
+ aMetrics.Width() = 0;
+ aMetrics.SetTopAscent(0);
+
+ // Only when the BR is operating in a line-layout situation will it
+ // behave like a BR.
+ nsLineLayout* ll = aReflowState.mLineLayout;
+ if (ll) {
+ // Note that the compatibility mode check excludes AlmostStandards
+ // mode, since this is the inline box model. See bug 161691.
+ if ( ll->LineIsEmpty() ||
+ aPresContext->CompatibilityMode() == eCompatibility_FullStandards ) {
+ // The line is logically empty; any whitespace is trimmed away.
+ //
+ // If this frame is going to terminate the line we know
+ // that nothing else will go on the line. Therefore, in this
+ // case, we provide some height for the BR frame so that it
+ // creates some vertical whitespace. It's necessary to use the
+ // line-height rather than the font size because the
+ // quirks-mode fix that doesn't apply the block's min
+ // line-height makes this necessary to make BR cause a line
+ // of the full line-height
+
+ // We also do this in strict mode because BR should act like a
+ // normal inline frame. That line-height is used is important
+ // here for cases where the line-height is less than 1.
+ nsRefPtr fm;
+ nsLayoutUtils::GetFontMetricsForFrame(this, getter_AddRefs(fm),
+ nsLayoutUtils::FontSizeInflationFor(this));
+ aReflowState.rendContext->SetFont(fm); // FIXME: maybe not needed?
+ if (fm) {
+ nscoord logicalHeight = aReflowState.CalcLineHeight();
+ aMetrics.Height() = logicalHeight;
+ aMetrics.SetTopAscent(nsLayoutUtils::GetCenteredFontBaseline(fm, logicalHeight));
+ }
+ else {
+ aMetrics.SetTopAscent(aMetrics.Height() = 0);
+ }
+
+ // XXX temporary until I figure out a better solution; see the
+ // code in nsLineLayout::VerticalAlignFrames that zaps minY/maxY
+ // if the width is zero.
+ // XXX This also fixes bug 10036!
+ // Warning: nsTextControlFrame::CalculateSizeStandard depends on
+ // the following line, see bug 228752.
+ aMetrics.Width() = 1;
+ }
+
+ // Return our reflow status
+ uint32_t breakType = aReflowState.mStyleDisplay->mBreakType;
+ if (NS_STYLE_CLEAR_NONE == breakType) {
+ breakType = NS_STYLE_CLEAR_LINE;
+ }
+
+ aStatus = NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER |
+ NS_INLINE_MAKE_BREAK_TYPE(breakType);
+ ll->SetLineEndsInBR(true);
+ }
+ else {
+ aStatus = NS_FRAME_COMPLETE;
+ }
+
+ aMetrics.SetOverflowAreasToDesiredBounds();
+
+ mAscent = aMetrics.TopAscent();
+
+ NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
+ return NS_OK;
+}
+
+/* virtual */ void
+BRFrame::AddInlineMinWidth(nsRenderingContext *aRenderingContext,
+ nsIFrame::InlineMinWidthData *aData)
+{
+ aData->ForceBreak(aRenderingContext);
+}
+
+/* virtual */ void
+BRFrame::AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
+ nsIFrame::InlinePrefWidthData *aData)
+{
+ aData->ForceBreak(aRenderingContext);
+}
+
+/* virtual */ nscoord
+BRFrame::GetMinWidth(nsRenderingContext *aRenderingContext)
+{
+ nscoord result = 0;
+ DISPLAY_MIN_WIDTH(this, result);
+ return result;
+}
+
+/* virtual */ nscoord
+BRFrame::GetPrefWidth(nsRenderingContext *aRenderingContext)
+{
+ nscoord result = 0;
+ DISPLAY_PREF_WIDTH(this, result);
+ return result;
+}
+
+nsIAtom*
+BRFrame::GetType() const
+{
+ return nsGkAtoms::brFrame;
+}
+
+nscoord
+BRFrame::GetBaseline() const
+{
+ return mAscent;
+}
+
+nsIFrame::ContentOffsets BRFrame::CalcContentOffsetsFromFramePoint(nsPoint aPoint)
+{
+ ContentOffsets offsets;
+ offsets.content = mContent->GetParent();
+ if (offsets.content) {
+ offsets.offset = offsets.content->IndexOf(mContent);
+ offsets.secondaryOffset = offsets.offset;
+ offsets.associateWithNext = true;
+ }
+ return offsets;
+}
+
+nsIFrame::FrameSearchResult
+BRFrame::PeekOffsetNoAmount(bool aForward, int32_t* aOffset)
+{
+ NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
+ int32_t startOffset = *aOffset;
+ // If we hit the end of a BR going backwards, go to its beginning and stay there.
+ if (!aForward && startOffset != 0) {
+ *aOffset = 0;
+ return FOUND;
+ }
+ // Otherwise, stop if we hit the beginning, continue (forward) if we hit the end.
+ return (startOffset == 0) ? FOUND : CONTINUE;
+}
+
+nsIFrame::FrameSearchResult
+BRFrame::PeekOffsetCharacter(bool aForward, int32_t* aOffset,
+ bool aRespectClusters)
+{
+ NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
+ // Keep going. The actual line jumping will stop us.
+ return CONTINUE;
+}
+
+nsIFrame::FrameSearchResult
+BRFrame::PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
+ int32_t* aOffset, PeekWordState* aState)
+{
+ NS_ASSERTION (aOffset && *aOffset <= 1, "aOffset out of range");
+ // Keep going. The actual line jumping will stop us.
+ return CONTINUE;
+}
+
+#ifdef ACCESSIBILITY
+a11y::AccType
+BRFrame::AccessibleType()
+{
+ nsIContent *parent = mContent->GetParent();
+ if (parent && parent->IsRootOfNativeAnonymousSubtree() &&
+ parent->GetChildCount() == 1) {
+ // This
is the only node in a text control, therefore it is the hacky
+ // "bogus node" used when there is no text in the control
+ return a11y::eNoType;
+ }
+
+ return a11y::eHTMLBRType;
+}
+#endif
+