void
nsSVGEffects::UpdateEffects(nsIFrame *aFrame)
{
  NS_ASSERTION(aFrame->GetContent()->IsElement(),
               "aFrame's content should be an element");

  FrameProperties props = aFrame->Properties();
  props.Delete(FilterProperty());
  props.Delete(MaskProperty());
  props.Delete(ClipPathProperty());
  props.Delete(MarkerBeginProperty());
  props.Delete(MarkerMiddleProperty());
  props.Delete(MarkerEndProperty());
  props.Delete(FillProperty());
  props.Delete(StrokeProperty());
  props.Delete(BackgroundImageProperty());

  // Ensure that the filter is repainted correctly
  // We can't do that in DoUpdate as the referenced frame may not be valid
  GetEffectProperty(aFrame->GetStyleSVGReset()->mFilter,
                    aFrame, FilterProperty(), CreateFilterProperty);

  if (aFrame->IsFrameOfType(nsIFrame::eSVG)) {
    // Set marker properties here to avoid reference loops
    const nsStyleSVG *style = aFrame->GetStyleSVG();
    GetEffectProperty(style->mMarkerStart, aFrame, MarkerBeginProperty(),
                      CreateMarkerProperty);
    GetEffectProperty(style->mMarkerMid, aFrame, MarkerMiddleProperty(),
                      CreateMarkerProperty);
    GetEffectProperty(style->mMarkerEnd, aFrame, MarkerEndProperty(),
                      CreateMarkerProperty);
  }
}
static void
ParseFrameAttribute(nsIFrame* aFrame, nsIAtom* aAttribute,
                    bool aAllowMultiValues)
{
  nsAutoString attrValue;

  nsIContent* frameContent = aFrame->GetContent();
  frameContent->GetAttr(kNameSpaceID_None, aAttribute, attrValue);

  if (!attrValue.IsEmpty()) {
    nsTArray<int8_t>* valueList =
      ExtractStyleValues(attrValue, aAttribute, aAllowMultiValues);

    // If valueList is null, that indicates a problem with the attribute value.
    // Only set properties on a valid attribute value.
    if (valueList) {
      // The code reading the property assumes that this list is nonempty.
      NS_ASSERTION(valueList->Length() >= 1, "valueList should not be empty!");
      FrameProperties props = aFrame->Properties();
      props.Set(AttributeToProperty(aAttribute), valueList);
    } else {
      ReportParseError(aFrame, aAttribute->GetUTF16String(), attrValue.get());
    }
  }
}
static nsSVGRenderingObserver *
GetEffectPropertyForURI(nsIURI *aURI, nsIFrame *aFrame,
                        const FramePropertyDescriptor *aProperty,
                        nsSVGRenderingObserver * (* aCreate)(nsIURI *, nsIFrame *, bool))
{
  if (!aURI)
    return nsnull;

  FrameProperties props = aFrame->Properties();
  nsSVGEffects::URIObserverHashtable *hashtable =
    static_cast<nsSVGEffects::URIObserverHashtable*>(props.Get(aProperty));
  if (!hashtable) {
    hashtable = new nsSVGEffects::URIObserverHashtable();
    hashtable->Init();
    props.Set(aProperty, hashtable);
  }
  nsSVGRenderingObserver* prop =
    static_cast<nsSVGRenderingObserver*>(hashtable->GetWeak(aURI));
  if (!prop) {
    bool watchImage = aProperty == nsSVGEffects::BackgroundImageProperty();
    prop = aCreate(aURI, aFrame, watchImage);
    hashtable->Put(aURI, prop);
  }
  return prop;
}
// static
StickyScrollContainer*
StickyScrollContainer::GetStickyScrollContainerForScrollFrame(nsIFrame* aFrame)
{
  FrameProperties props = aFrame->Properties();
  return static_cast<StickyScrollContainer*>
    (props.Get(StickyScrollContainerProperty()));
}
static PRUnichar*
GetValueAt(nsIFrame*                      aTableOrRowFrame,
           const FramePropertyDescriptor* aProperty,
           nsIAtom*                       aAttribute,
           int32_t                        aRowOrColIndex)
{
  FrameProperties props = aTableOrRowFrame->Properties();
  nsValueList* valueList = static_cast<nsValueList*>(props.Get(aProperty));
  if (!valueList) {
    // The property isn't there yet, so set it
    nsAutoString values;
    aTableOrRowFrame->GetContent()->GetAttr(kNameSpaceID_None, aAttribute, values);
    if (!values.IsEmpty())
      valueList = new nsValueList(values);
    if (!valueList || !valueList->mArray.Length()) {
      delete valueList; // ok either way, delete is null safe
      return nullptr;
    }
    props.Set(aProperty, valueList);
  }
  int32_t count = valueList->mArray.Length();
  return (aRowOrColIndex < count)
         ? valueList->mArray[aRowOrColIndex]
         : valueList->mArray[count-1];
}
// static
void
StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary(nsIFrame* aFrame,
                                                                      nsIFrame* aOldParent)
{
  nsIScrollableFrame* oldScrollFrame =
    nsLayoutUtils::GetNearestScrollableFrame(aOldParent,
      nsLayoutUtils::SCROLLABLE_SAME_DOC |
      nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
  if (!oldScrollFrame) {
    // XXX maybe aFrame has sticky descendants that can be sticky now, but
    // we aren't going to handle that.
    return;
  }
  FrameProperties props = static_cast<nsIFrame*>(do_QueryFrame(oldScrollFrame))->
    Properties();
  StickyScrollContainer* oldSSC = static_cast<StickyScrollContainer*>
    (props.Get(StickyScrollContainerProperty()));
  if (!oldSSC) {
    // aOldParent had no sticky descendants, so aFrame doesn't have any sticky
    // descendants, and we're done here.
    return;
  }

  auto i = oldSSC->mFrames.Length();
  while (i-- > 0) {
    nsIFrame* f = oldSSC->mFrames[i];
    StickyScrollContainer* newSSC = GetStickyScrollContainerForFrame(f);
    if (newSSC != oldSSC) {
      oldSSC->RemoveFrame(f);
      if (newSSC) {
        newSSC->AddFrame(f);
      }
    }
  }
}
static LayerActivity*
GetLayerActivity(nsIFrame* aFrame)
{
  if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) {
    return nullptr;
  }
  FrameProperties properties = aFrame->Properties();
  return static_cast<LayerActivity*>(properties.Get(LayerActivityProperty()));
}
/* static */ void
ActiveLayerTracker::TransferActivityToContent(nsIFrame* aFrame, nsIContent* aContent)
{
  if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) {
    return;
  }
  FrameProperties properties = aFrame->Properties();
  LayerActivity* layerActivity = properties.Remove(LayerActivityProperty());
  aFrame->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
  if (!layerActivity) {
    return;
  }
  layerActivity->mFrame = nullptr;
  layerActivity->mContent = aContent;
  aContent->SetProperty(nsGkAtoms::LayerActivity, layerActivity,
                        nsINode::DeleteProperty<LayerActivity>, true);
}
void
nsFloatManager::StoreRegionFor(nsIFrame* aFloat,
                               nsRect&   aRegion)
{
  nsRect rect = aFloat->GetRect();
  FrameProperties props = aFloat->Properties();
  if (aRegion.IsEqualEdges(rect)) {
    props.Delete(FloatRegionProperty());
  }
  else {
    nsMargin* storedMargin = static_cast<nsMargin*>
      (props.Get(FloatRegionProperty()));
    if (!storedMargin) {
      storedMargin = new nsMargin();
      props.Set(FloatRegionProperty(), storedMargin);
    }
    *storedMargin = aRegion - rect;
  }
}
static LayerActivity*
GetLayerActivityForUpdate(nsIFrame* aFrame)
{
  FrameProperties properties = aFrame->Properties();
  LayerActivity* layerActivity =
    static_cast<LayerActivity*>(properties.Get(LayerActivityProperty()));
  if (layerActivity) {
    gLayerActivityTracker->MarkUsed(layerActivity);
  } else {
    if (!gLayerActivityTracker) {
      gLayerActivityTracker = new LayerActivityTracker();
    }
    layerActivity = new LayerActivity(aFrame);
    gLayerActivityTracker->AddObject(layerActivity);
    aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
    properties.Set(LayerActivityProperty(), layerActivity);
  }
  return layerActivity;
}
Esempio n. 11
0
static nsSVGFilterProperty*
GetOrCreateFilterProperty(nsIFrame *aFrame)
{
  const nsStyleSVGReset* style = aFrame->StyleSVGReset();
  if (!style->HasFilters())
    return nullptr;

  FrameProperties props = aFrame->Properties();
  nsSVGFilterProperty *prop =
    static_cast<nsSVGFilterProperty*>(props.Get(nsSVGEffects::FilterProperty()));
  if (prop)
    return prop;
  prop = new nsSVGFilterProperty(style->mFilters, aFrame);
  if (!prop)
    return nullptr;
  NS_ADDREF(prop);
  props.Set(nsSVGEffects::FilterProperty(), static_cast<nsISupports*>(prop));
  return prop;
}
Esempio n. 12
0
void
nsFloatManager::StoreRegionFor(WritingMode aWM, nsIFrame* aFloat,
                               const LogicalRect& aRegion,
                               const nsSize& aContainerSize)
{
  nsRect region = aRegion.GetPhysicalRect(aWM, aContainerSize);
  nsRect rect = aFloat->GetRect();
  FrameProperties props = aFloat->Properties();
  if (region.IsEqualEdges(rect)) {
    props.Delete(FloatRegionProperty());
  }
  else {
    nsMargin* storedMargin = props.Get(FloatRegionProperty());
    if (!storedMargin) {
      storedMargin = new nsMargin();
      props.Set(FloatRegionProperty(), storedMargin);
    }
    *storedMargin = region - rect;
  }
}
Esempio n. 13
0
static nsSVGRenderingObserver *
GetEffectProperty(nsIURI *aURI, nsIFrame *aFrame,
                  const FramePropertyDescriptor *aProperty,
                  nsSVGRenderingObserver * (* aCreate)(nsIURI *, nsIFrame *, bool))
{
  if (!aURI)
    return nsnull;

  FrameProperties props = aFrame->Properties();
  nsSVGRenderingObserver *prop =
    static_cast<nsSVGRenderingObserver*>(props.Get(aProperty));
  if (prop)
    return prop;
  prop = aCreate(aURI, aFrame, false);
  if (!prop)
    return nsnull;
  NS_ADDREF(prop);
  props.Set(aProperty, static_cast<nsISupports*>(prop));
  return prop;
}
/* This method looks for a property that applies to a cell, but it looks
 * recursively because some cell properties can come from the cell, a row,
 * a table, etc. This function searches through the heirarchy for a property
 * and returns its value. The function stops searching after checking a <mtable>
 * frame.
 */
static nsTArray<int8_t>*
FindCellProperty(const nsIFrame* aCellFrame,
                 const FramePropertyDescriptor* aFrameProperty)
{
  const nsIFrame* currentFrame = aCellFrame;
  nsTArray<int8_t>* propertyData = nullptr;

  while (currentFrame) {
    FrameProperties props = currentFrame->Properties();
    propertyData = static_cast<nsTArray<int8_t>*>(props.Get(aFrameProperty));
    bool frameIsTable = (currentFrame->GetType() == nsGkAtoms::tableFrame);

    if (propertyData || frameIsTable)
      currentFrame = nullptr; // A null frame pointer exits the loop
    else
      currentFrame = currentFrame->GetParent(); // Go to the parent frame
  }

  return propertyData;
}
// static
void
StickyScrollContainer::ComputeStickyOffsets(nsIFrame* aFrame)
{
  nsIScrollableFrame* scrollableFrame =
    nsLayoutUtils::GetNearestScrollableFrame(aFrame->GetParent(),
      nsLayoutUtils::SCROLLABLE_SAME_DOC |
      nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);

  if (!scrollableFrame) {
    // Bail.
    return;
  }

  nsSize scrollContainerSize = scrollableFrame->GetScrolledFrame()->
    GetContentRectRelativeToSelf().Size();

  nsMargin computedOffsets;
  const nsStylePosition* position = aFrame->StylePosition();

  computedOffsets.left   = ComputeStickySideOffset(eSideLeft, position->mOffset,
                                                   scrollContainerSize.width);
  computedOffsets.right  = ComputeStickySideOffset(eSideRight, position->mOffset,
                                                   scrollContainerSize.width);
  computedOffsets.top    = ComputeStickySideOffset(eSideTop, position->mOffset,
                                                   scrollContainerSize.height);
  computedOffsets.bottom = ComputeStickySideOffset(eSideBottom, position->mOffset,
                                                   scrollContainerSize.height);

  // Store the offset
  FrameProperties props = aFrame->Properties();
  nsMargin* offsets = static_cast<nsMargin*>
    (props.Get(nsIFrame::ComputedOffsetProperty()));
  if (offsets) {
    *offsets = computedOffsets;
  } else {
    props.Set(nsIFrame::ComputedOffsetProperty(),
              new nsMargin(computedOffsets));
  }
}
Esempio n. 16
0
nsresult
nsBox::BeginLayout(nsBoxLayoutState& aState)
{
#ifdef DEBUG_LAYOUT 

  nsBoxAddIndents();
  printf("Layout: ");
  DumpBox(stdout);
  printf("\n");
  gIndent++;
#endif

  // mark ourselves as dirty so no child under us
  // can post an incremental layout.
  // XXXldb Is this still needed?
  mState |= NS_FRAME_HAS_DIRTY_CHILDREN;

  if (GetStateBits() & NS_FRAME_IS_DIRTY)
  {
    // If the parent is dirty, all the children are dirty (nsHTMLReflowState
    // does this too).
    nsIFrame* box;
    for (box = GetChildBox(); box; box = box->GetNextBox())
      box->AddStateBits(NS_FRAME_IS_DIRTY);
  }

  // Another copy-over from nsHTMLReflowState.
  // Since we are in reflow, we don't need to store these properties anymore.
  FrameProperties props = Properties();
  props.Delete(UsedBorderProperty());
  props.Delete(UsedPaddingProperty());
  props.Delete(UsedMarginProperty());

#ifdef DEBUG_LAYOUT
  PropagateDebug(aState);
#endif

  return NS_OK;
}
Esempio n. 17
0
// static
StickyScrollContainer*
StickyScrollContainer::GetStickyScrollContainerForFrame(nsIFrame* aFrame)
{
  nsIScrollableFrame* scrollFrame =
    nsLayoutUtils::GetNearestScrollableFrame(aFrame->GetParent(),
      nsLayoutUtils::SCROLLABLE_SAME_DOC |
      nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
  if (!scrollFrame) {
    // We might not find any, for instance in the case of
    // <html style="position: fixed">
    return nullptr;
  }
  FrameProperties props = static_cast<nsIFrame*>(do_QueryFrame(scrollFrame))->
    Properties();
  StickyScrollContainer* s = static_cast<StickyScrollContainer*>
    (props.Get(StickyScrollContainerProperty()));
  if (!s) {
    s = new StickyScrollContainer(scrollFrame);
    props.Set(StickyScrollContainerProperty(), s);
  }
  return s;
}
Esempio n. 18
0
nscoord
nsTableRowFrame::GetUnpaginatedHeight(nsPresContext* aPresContext)
{
  FrameProperties props = GetFirstInFlow()->Properties();
  return NS_PTR_TO_INT32(props.Get(RowUnpaginatedHeightProperty()));
}