|
|
|
|
|
|
public readonly Widget child; |
|
|
|
} |
|
|
|
|
|
|
|
public abstract class ParentDataWidget<T> : ProxyWidget where T : RenderObjectWidget { |
|
|
|
public abstract class ParentDataWidget : ProxyWidget { |
|
|
|
return new ParentDataElement<T>(this); |
|
|
|
return new ParentDataElement(this); |
|
|
|
D.assert(typeof(T) != typeof(RenderObjectWidget)); |
|
|
|
return ancestor is T; |
|
|
|
return ancestor is RenderObjectWidget; |
|
|
|
} |
|
|
|
|
|
|
|
public virtual string debugDescribeInvalidAncestorChain( |
|
|
|
|
|
|
D.assert(typeof(T) != typeof(RenderObjectWidget)); |
|
|
|
|
|
|
|
"{2} has no {1} ancestor at all.\n", this.GetType(), typeof(T), description); |
|
|
|
"{2} has no {1} ancestor at all.\n", this.GetType(), typeof(RenderObjectWidget), description); |
|
|
|
this.GetType(), typeof(T), description); |
|
|
|
this.GetType(), typeof(RenderObjectWidget), description); |
|
|
|
|
|
|
|
foreach (Widget ancestor in badAncestors) { |
|
|
|
if (ancestor.GetType() == this.GetType()) { |
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
result += "These widgets cannot come between a " + this.GetType() + " and its " + typeof(T) + ".\n"; |
|
|
|
result += "These widgets cannot come between a " + this.GetType() + " and its " + typeof(RenderObjectWidget) + ".\n"; |
|
|
|
} |
|
|
|
|
|
|
|
result += "The ownership chain for the parent of the offending " |
|
|
|
|
|
|
public abstract void notifyClients(ProxyWidget oldWidget); |
|
|
|
} |
|
|
|
|
|
|
|
public class ParentDataElement<T> : ProxyElement where T : RenderObjectWidget { |
|
|
|
public ParentDataElement(ParentDataWidget<T> widget) : base(widget) { |
|
|
|
public class ParentDataElement : ProxyElement { |
|
|
|
public ParentDataElement(ParentDataWidget widget) : base(widget) { |
|
|
|
public new ParentDataWidget<T> widget { |
|
|
|
get { return (ParentDataWidget<T>) base.widget; } |
|
|
|
public new ParentDataWidget widget { |
|
|
|
get { return (ParentDataWidget) base.widget; } |
|
|
|
} |
|
|
|
|
|
|
|
public override void mount(Element parent, object newSlot) { |
|
|
|
|
|
|
while (ancestor != null) { |
|
|
|
if (ancestor is ParentDataElement<RenderObjectWidget>) { |
|
|
|
if (ancestor is ParentDataElement) { |
|
|
|
badAncestors.Add(ancestor.widget); |
|
|
|
} else if (ancestor is RenderObjectElement) { |
|
|
|
if (this.widget.debugIsValidAncestor(((RenderObjectElement) ancestor).widget)) { |
|
|
|
|
|
|
base.mount(parent, newSlot); |
|
|
|
} |
|
|
|
|
|
|
|
void _applyParentData(ParentDataWidget<T> widget) { |
|
|
|
void _applyParentData(ParentDataWidget widget) { |
|
|
|
D.assert(!(child is ParentDataElement<RenderObjectWidget>)); |
|
|
|
D.assert(!(child is ParentDataElement)); |
|
|
|
child.visitChildren(applyParentDataToChild); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
public void applyWidgetOutOfTurn(ParentDataWidget<T> newWidget) { |
|
|
|
public void applyWidgetOutOfTurn(ParentDataWidget newWidget) { |
|
|
|
D.assert(newWidget != null); |
|
|
|
D.assert(newWidget.debugCanApplyOutOfTurn()); |
|
|
|
D.assert(newWidget.child == this.widget.child); |
|
|
|
|
|
|
return ancestor as RenderObjectElement; |
|
|
|
} |
|
|
|
|
|
|
|
ParentDataElement<RenderObjectWidget> _findAncestorParentDataElement() { |
|
|
|
ParentDataElement _findAncestorParentDataElement() { |
|
|
|
var element = ancestor as ParentDataElement<RenderObjectWidget>; |
|
|
|
var element = ancestor as ParentDataElement; |
|
|
|
if (element != null) { |
|
|
|
return element; |
|
|
|
} |
|
|
|
|
|
|
this.widget.didUnmountRenderObject(this.renderObject); |
|
|
|
} |
|
|
|
|
|
|
|
internal void _updateParentData<T>(ParentDataWidget<T> parentData) where T : RenderObjectWidget { |
|
|
|
internal void _updateParentData(ParentDataWidget parentData) { |
|
|
|
parentData.applyParentData(this.renderObject); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
this._ancestorRenderObjectElement.insertChildRenderObject(this.renderObject, newSlot); |
|
|
|
} |
|
|
|
|
|
|
|
ParentDataElement<RenderObjectWidget> parentDataElement = this._findAncestorParentDataElement(); |
|
|
|
ParentDataElement parentDataElement = this._findAncestorParentDataElement(); |
|
|
|
if (parentDataElement != null) { |
|
|
|
this._updateParentData(parentDataElement.widget); |
|
|
|
} |
|
|
|