Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
6a88ec6d
Commit
6a88ec6d
authored
Sep 21, 2015
by
Ian Hickson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1248 from abarth/fn3
Prototype of fn3
parents
130a5cb6
b4ff5ca6
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
610 additions
and
1 deletion
+610
-1
fn3.dart
packages/flutter/lib/src/fn3.dart
+8
-0
basic.dart
packages/flutter/lib/src/fn3/basic.dart
+57
-0
framework.dart
packages/flutter/lib/src/fn3/framework.dart
+340
-0
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+1
-1
render_object_widget_test.dart
packages/unit/test/fn3/render_object_widget_test.dart
+160
-0
widget_tester.dart
packages/unit/test/fn3/widget_tester.dart
+44
-0
No files found.
packages/flutter/lib/src/fn3.dart
0 → 100644
View file @
6a88ec6d
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library
fn3
;
export
'fn3/basic.dart'
;
export
'fn3/framework.dart'
;
packages/flutter/lib/src/fn3/basic.dart
0 → 100644
View file @
6a88ec6d
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:sky/rendering.dart'
;
import
'package:sky/src/fn3/framework.dart'
;
export
'package:sky/rendering.dart'
show
BackgroundImage
,
BlockDirection
,
Border
,
BorderSide
,
BoxConstraints
,
BoxDecoration
,
BoxDecorationPosition
,
BoxShadow
,
Color
,
EdgeDims
,
EventDisposition
,
FlexAlignItems
,
FlexDirection
,
FlexJustifyContent
,
Offset
,
Paint
,
Path
,
Point
,
Rect
,
ScrollDirection
,
Shape
,
ShrinkWrap
,
Size
,
ValueChanged
;
class
DecoratedBox
extends
OneChildRenderObjectWidget
{
DecoratedBox
({
Key
key
,
this
.
decoration
,
this
.
position
:
BoxDecorationPosition
.
background
,
Widget
child
})
:
super
(
key:
key
,
child:
child
)
{
assert
(
decoration
!=
null
);
assert
(
position
!=
null
);
}
final
BoxDecoration
decoration
;
final
BoxDecorationPosition
position
;
RenderObject
createRenderObject
()
=>
new
RenderDecoratedBox
(
decoration:
decoration
,
position:
position
);
void
updateRenderObject
(
RenderDecoratedBox
renderObject
)
{
renderObject
.
decoration
=
decoration
;
renderObject
.
position
=
position
;
}
}
packages/flutter/lib/src/fn3/framework.dart
0 → 100644
View file @
6a88ec6d
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:sky/rendering.dart'
;
abstract
class
Key
{
}
abstract
class
Widget
{
Widget
(
this
.
key
);
final
Key
key
;
Element
createElement
();
}
typedef
Widget
WidgetBuilder
(
);
abstract
class
RenderObjectWidget
extends
Widget
{
RenderObjectWidget
({
Key
key
})
:
super
(
key
);
Element
createElement
()
=>
new
RenderObjectElement
(
this
);
RenderObject
createRenderObject
();
void
updateRenderObject
(
RenderObject
renderObject
);
}
abstract
class
OneChildRenderObjectWidget
extends
RenderObjectWidget
{
OneChildRenderObjectWidget
({
Key
key
,
Widget
this
.
child
})
:
super
(
key:
key
);
final
Widget
child
;
Element
createElement
()
=>
new
OneChildRenderObjectElement
(
this
);
}
abstract
class
MultiChildRenderObjectWidget
extends
RenderObjectWidget
{
MultiChildRenderObjectWidget
({
Key
key
,
List
<
Widget
>
this
.
children
})
:
super
(
key:
key
);
final
List
<
Widget
>
children
;
Element
createElement
()
=>
new
MultiChildRenderObjectElement
(
this
);
}
abstract
class
Component
extends
Widget
{
Component
({
Key
key
})
:
super
(
key
);
Element
createElement
()
=>
new
ComponentElement
(
this
);
Widget
build
();
}
abstract
class
ComponentState
<
T
extends
ComponentConfiguration
>
{
ComponentStateElement
_holder
;
void
setState
(
void
fn
())
{
fn
();
_holder
.
scheduleBuild
();
}
T
get
config
=>
_config
;
T
_config
;
/// Override this setter to update additional state when the config changes.
void
set
config
(
T
config
)
{
_config
=
config
;
}
/// Called when this object is removed from the tree
void
didUnmount
()
{
}
Widget
build
();
}
abstract
class
ComponentConfiguration
extends
Widget
{
ComponentConfiguration
({
Key
key
})
:
super
(
key
);
ComponentStateElement
createElement
()
=>
new
ComponentStateElement
(
this
);
ComponentState
createState
();
}
bool
_canUpdate
(
Widget
oldWidget
,
Widget
newWidget
)
{
return
oldWidget
.
runtimeType
==
newWidget
.
runtimeType
&&
oldWidget
.
key
==
newWidget
.
key
;
}
void
_debugReportException
(
String
context
,
dynamic
exception
,
StackTrace
stack
)
{
print
(
'------------------------------------------------------------------------'
);
'Exception caught while
$context
'
.
split
(
'
\n
'
).
forEach
(
print
);
print
(
'
$exception
'
);
print
(
'Stack trace:'
);
'
$stack
'
.
split
(
'
\n
'
).
forEach
(
print
);
print
(
'------------------------------------------------------------------------'
);
}
enum
_ElementLifecycle
{
initial
,
mounted
,
defunct
,
}
typedef
void
ElementVisitor
(
Element
element
);
abstract
class
Element
<
T
extends
Widget
>
{
Element
(
T
widget
)
:
_widget
=
widget
{
assert
(
_widget
!=
null
);
}
Element
_parent
;
T
_widget
;
_ElementLifecycle
_lifecycleState
=
_ElementLifecycle
.
initial
;
void
visitChildren
(
ElementVisitor
visitor
)
{
}
void
visitDescendants
(
ElementVisitor
visitor
)
{
void
walk
(
Element
element
)
{
visitor
(
element
);
element
.
visitChildren
(
walk
);
}
visitChildren
(
walk
);
}
void
mount
(
dynamic
slot
)
{
assert
(
_lifecycleState
==
_ElementLifecycle
.
initial
);
assert
(
_widget
!=
null
);
_lifecycleState
=
_ElementLifecycle
.
mounted
;
assert
(
_parent
==
null
||
_parent
.
_lifecycleState
==
_ElementLifecycle
.
mounted
);
}
void
update
(
T
updated
,
dynamic
slot
)
{
assert
(
_lifecycleState
==
_ElementLifecycle
.
mounted
);
assert
(
_widget
!=
null
);
assert
(
updated
!=
null
);
assert
(
_canUpdate
(
_widget
,
updated
));
_widget
=
updated
;
}
void
unmount
()
{
assert
(
_lifecycleState
==
_ElementLifecycle
.
mounted
);
assert
(
_widget
!=
null
);
_lifecycleState
=
_ElementLifecycle
.
defunct
;
}
void
_detachChild
(
Element
child
)
{
if
(
child
==
null
)
return
;
child
.
_parent
=
null
;
bool
haveDetachedRenderObject
=
false
;
void
detach
(
Element
descendant
)
{
if
(!
haveDetachedRenderObject
&&
descendant
is
RenderObjectElement
)
{
descendant
.
detachRenderObject
();
haveDetachedRenderObject
=
true
;
}
descendant
.
unmount
();
}
detach
(
child
);
child
.
visitDescendants
(
detach
);
}
Element
_updateChild
(
Element
child
,
Widget
updated
,
dynamic
slot
)
{
if
(
updated
==
null
)
{
_detachChild
(
child
);
return
null
;
}
if
(
child
!=
null
)
{
if
(
_canUpdate
(
child
.
_widget
,
updated
))
{
child
.
update
(
updated
,
slot
);
return
child
;
}
_detachChild
(
child
);
assert
(
child
.
_parent
==
null
);
}
Element
newChild
=
updated
.
createElement
();
newChild
.
_parent
=
this
;
newChild
.
mount
(
slot
);
return
newChild
;
}
}
abstract
class
BuildableElement
<
T
extends
Widget
>
extends
Element
<
T
>
{
BuildableElement
(
T
widget
)
:
super
(
widget
);
WidgetBuilder
_builder
;
Element
_child
;
void
_rebuild
(
dynamic
slot
)
{
Widget
built
;
try
{
built
=
_builder
();
assert
(
built
!=
null
);
}
catch
(
e
,
stack
)
{
_debugReportException
(
'building
$this
'
,
e
,
stack
);
}
_child
=
_updateChild
(
_child
,
built
,
slot
);
}
void
visitChildren
(
ElementVisitor
visitor
)
{
if
(
_child
!=
null
)
visitor
(
_child
);
}
void
mount
(
dynamic
slot
)
{
super
.
mount
(
slot
);
assert
(
_child
==
null
);
_rebuild
(
slot
);
assert
(
_child
!=
null
);
}
}
class
ComponentElement
extends
BuildableElement
<
Component
>
{
ComponentElement
(
Component
component
)
:
super
(
component
)
{
_builder
=
component
.
build
;
}
void
update
(
Component
updated
,
dynamic
slot
)
{
super
.
update
(
updated
,
slot
);
assert
(
_widget
==
updated
);
_builder
=
_widget
.
build
;
_rebuild
(
slot
);
}
}
class
ComponentStateElement
extends
BuildableElement
<
ComponentConfiguration
>
{
ComponentStateElement
(
ComponentConfiguration
configuration
)
:
_state
=
configuration
.
createState
(),
super
(
configuration
)
{
_builder
=
_state
.
build
;
_state
.
_holder
=
this
;
_state
.
config
=
configuration
;
}
ComponentState
_state
;
void
update
(
ComponentConfiguration
updated
,
dynamic
slot
)
{
super
.
update
(
updated
,
slot
);
assert
(
_widget
==
updated
);
_state
.
config
=
_widget
;
_rebuild
(
slot
);
}
void
unmount
()
{
super
.
unmount
();
_state
.
didUnmount
();
_state
=
null
;
}
void
scheduleBuild
()
{
// TODO(abarth): Implement rebuilding.
}
}
RenderObjectElement
_findAncestorRenderObjectElement
(
Element
ancestor
)
{
while
(
ancestor
!=
null
&&
ancestor
is
!
RenderObjectElement
)
ancestor
=
ancestor
.
_parent
;
return
ancestor
;
}
class
RenderObjectElement
<
T
extends
RenderObjectWidget
>
extends
Element
<
T
>
{
RenderObjectElement
(
T
widget
)
:
renderObject
=
widget
.
createRenderObject
(),
super
(
widget
);
final
RenderObject
renderObject
;
RenderObjectElement
_ancestorRenderObjectElement
;
void
mount
(
dynamic
slot
)
{
super
.
mount
(
slot
);
assert
(
_ancestorRenderObjectElement
==
null
);
_ancestorRenderObjectElement
=
_findAncestorRenderObjectElement
(
_parent
);
if
(
_ancestorRenderObjectElement
!=
null
)
_ancestorRenderObjectElement
.
insertChildRenderObject
(
renderObject
,
slot
);
}
void
update
(
T
updated
,
dynamic
slot
)
{
super
.
update
(
updated
,
slot
);
assert
(
_widget
==
updated
);
_widget
.
updateRenderObject
(
renderObject
);
}
void
detachRenderObject
()
{
if
(
_ancestorRenderObjectElement
!=
null
)
{
_ancestorRenderObjectElement
.
removeChildRenderObject
(
renderObject
);
_ancestorRenderObjectElement
=
null
;
}
}
void
insertChildRenderObject
(
RenderObject
child
,
dynamic
slot
)
{
assert
(
false
);
}
void
removeChildRenderObject
(
RenderObject
child
)
{
assert
(
false
);
}
}
class
OneChildRenderObjectElement
<
T
extends
OneChildRenderObjectWidget
>
extends
RenderObjectElement
<
T
>
{
OneChildRenderObjectElement
(
T
widget
)
:
super
(
widget
);
Element
_child
;
void
visitChildren
(
ElementVisitor
visitor
)
{
if
(
_child
!=
null
)
visitor
(
_child
);
}
void
mount
(
dynamic
slot
)
{
super
.
mount
(
slot
);
_child
=
_updateChild
(
_child
,
_widget
.
child
,
null
);
}
void
update
(
T
updated
,
dynamic
slot
)
{
super
.
update
(
updated
,
slot
);
assert
(
_widget
==
updated
);
_child
=
_updateChild
(
_child
,
_widget
.
child
,
null
);
}
void
insertChildRenderObject
(
RenderObject
child
,
dynamic
slot
)
{
final
renderObject
=
this
.
renderObject
;
// TODO(ianh): Remove this once the analyzer is cleverer
assert
(
renderObject
is
RenderObjectWithChildMixin
);
assert
(
slot
==
null
);
renderObject
.
child
=
child
;
assert
(
renderObject
==
this
.
renderObject
);
// TODO(ianh): Remove this once the analyzer is cleverer
}
void
removeChildRenderObject
(
RenderObject
child
)
{
final
renderObject
=
this
.
renderObject
;
// TODO(ianh): Remove this once the analyzer is cleverer
assert
(
renderObject
is
RenderObjectWithChildMixin
);
assert
(
renderObject
.
child
==
child
);
renderObject
.
child
=
null
;
assert
(
renderObject
==
this
.
renderObject
);
// TODO(ianh): Remove this once the analyzer is cleverer
}
}
class
MultiChildRenderObjectElement
<
T
extends
MultiChildRenderObjectWidget
>
extends
RenderObjectElement
<
T
>
{
MultiChildRenderObjectElement
(
T
widget
)
:
super
(
widget
);
}
packages/flutter/lib/src/widgets/framework.dart
View file @
6a88ec6d
...
...
@@ -22,7 +22,7 @@ export 'package:sky/src/rendering/object.dart' show Point, Offset, Size, Rect, C
final
bool
_shouldLogRenderDuration
=
false
;
// see also 'enableProfilingLoop' argument to runApp()
typedef
Widget
Builder
(
);
typedef
void
WidgetTreeWalker
(
Widget
);
typedef
void
WidgetTreeWalker
(
Widget
widget
);
abstract
class
Key
{
const
Key
.
constructor
();
// so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor
...
...
packages/unit/test/fn3/render_object_widget_test.dart
0 → 100644
View file @
6a88ec6d
import
'package:sky/rendering.dart'
;
import
'package:sky/src/fn3.dart'
;
import
'package:test/test.dart'
;
import
'widget_tester.dart'
;
final
BoxDecoration
kBoxDecorationA
=
new
BoxDecoration
();
final
BoxDecoration
kBoxDecorationB
=
new
BoxDecoration
();
final
BoxDecoration
kBoxDecorationC
=
new
BoxDecoration
();
void
main
(
)
{
test
(
'RenderObjectWidget smoke test'
,
()
{
WidgetTester
tester
=
new
WidgetTester
();
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationA
));
OneChildRenderObjectElement
element
=
tester
.
findElement
((
element
)
=>
element
is
OneChildRenderObjectElement
);
expect
(
element
,
isNotNull
);
expect
(
element
.
renderObject
is
RenderDecoratedBox
,
isTrue
);
RenderDecoratedBox
renderObject
=
element
.
renderObject
;
expect
(
renderObject
.
decoration
,
equals
(
kBoxDecorationA
));
expect
(
renderObject
.
position
,
equals
(
BoxDecorationPosition
.
background
));
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationB
));
element
=
tester
.
findElement
((
element
)
=>
element
is
OneChildRenderObjectElement
);
expect
(
element
,
isNotNull
);
expect
(
element
.
renderObject
is
RenderDecoratedBox
,
isTrue
);
renderObject
=
element
.
renderObject
;
expect
(
renderObject
.
decoration
,
equals
(
kBoxDecorationB
));
expect
(
renderObject
.
position
,
equals
(
BoxDecorationPosition
.
background
));
});
test
(
'RenderObjectWidget can add and remove children'
,
()
{
WidgetTester
tester
=
new
WidgetTester
();
void
checkFullTree
()
{
OneChildRenderObjectElement
element
=
tester
.
findElement
((
element
)
=>
element
is
OneChildRenderObjectElement
);
expect
(
element
,
isNotNull
);
expect
(
element
.
renderObject
is
RenderDecoratedBox
,
isTrue
);
RenderDecoratedBox
renderObject
=
element
.
renderObject
;
expect
(
renderObject
.
decoration
,
equals
(
kBoxDecorationA
));
expect
(
renderObject
.
position
,
equals
(
BoxDecorationPosition
.
background
));
expect
(
renderObject
.
child
,
isNotNull
);
expect
(
renderObject
.
child
is
RenderDecoratedBox
,
isTrue
);
RenderDecoratedBox
child
=
renderObject
.
child
;
expect
(
child
.
decoration
,
equals
(
kBoxDecorationB
));
expect
(
child
.
position
,
equals
(
BoxDecorationPosition
.
background
));
expect
(
child
.
child
,
isNull
);
}
void
childBareTree
()
{
OneChildRenderObjectElement
element
=
tester
.
findElement
((
element
)
=>
element
is
OneChildRenderObjectElement
);
expect
(
element
,
isNotNull
);
expect
(
element
.
renderObject
is
RenderDecoratedBox
,
isTrue
);
RenderDecoratedBox
renderObject
=
element
.
renderObject
;
expect
(
renderObject
.
decoration
,
equals
(
kBoxDecorationA
));
expect
(
renderObject
.
position
,
equals
(
BoxDecorationPosition
.
background
));
expect
(
renderObject
.
child
,
isNull
);
}
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationA
,
child:
new
DecoratedBox
(
decoration:
kBoxDecorationB
)
));
checkFullTree
();
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationA
,
child:
new
TestComponent
(
child:
new
DecoratedBox
(
decoration:
kBoxDecorationB
)
)
));
checkFullTree
();
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationA
,
child:
new
DecoratedBox
(
decoration:
kBoxDecorationB
)
));
checkFullTree
();
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationA
));
childBareTree
();
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationA
,
child:
new
TestComponent
(
child:
new
TestComponent
(
child:
new
DecoratedBox
(
decoration:
kBoxDecorationB
)
)
)
));
checkFullTree
();
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationA
));
childBareTree
();
});
test
(
'Detached render tree is intact'
,
()
{
WidgetTester
tester
=
new
WidgetTester
();
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationA
,
child:
new
DecoratedBox
(
decoration:
kBoxDecorationB
,
child:
new
DecoratedBox
(
decoration:
kBoxDecorationC
)
)
));
OneChildRenderObjectElement
element
=
tester
.
findElement
((
element
)
=>
element
is
OneChildRenderObjectElement
);
expect
(
element
.
renderObject
is
RenderDecoratedBox
,
isTrue
);
RenderDecoratedBox
parent
=
element
.
renderObject
;
expect
(
parent
.
child
is
RenderDecoratedBox
,
isTrue
);
RenderDecoratedBox
child
=
parent
.
child
;
expect
(
child
.
decoration
,
equals
(
kBoxDecorationB
));
expect
(
child
.
child
is
RenderDecoratedBox
,
isTrue
);
RenderDecoratedBox
grandChild
=
child
.
child
;
expect
(
grandChild
.
decoration
,
equals
(
kBoxDecorationC
));
expect
(
grandChild
.
child
,
isNull
);
tester
.
pumpFrame
(
new
DecoratedBox
(
decoration:
kBoxDecorationA
));
element
=
tester
.
findElement
((
element
)
=>
element
is
OneChildRenderObjectElement
);
expect
(
element
.
renderObject
is
RenderDecoratedBox
,
isTrue
);
expect
(
element
.
renderObject
,
equals
(
parent
));
expect
(
parent
.
child
,
isNull
);
expect
(
child
.
parent
,
isNull
);
expect
(
child
.
decoration
,
equals
(
kBoxDecorationB
));
expect
(
child
.
child
,
equals
(
grandChild
));
expect
(
grandChild
.
parent
,
equals
(
child
));
expect
(
grandChild
.
decoration
,
equals
(
kBoxDecorationC
));
expect
(
grandChild
.
child
,
isNull
);
});
}
packages/unit/test/fn3/widget_tester.dart
0 → 100644
View file @
6a88ec6d
import
'package:sky/src/fn3/framework.dart'
;
class
TestComponent
extends
Component
{
TestComponent
({
this
.
child
});
final
Widget
child
;
Widget
build
()
=>
child
;
}
class
WidgetTester
{
ComponentElement
_rootElement
;
void
walkElements
(
ElementVisitor
visitor
)
{
void
walk
(
Element
element
)
{
visitor
(
element
);
element
.
visitChildren
(
walk
);
}
_rootElement
.
visitChildren
(
walk
);
}
Element
findElement
(
bool
predicate
(
Element
widget
))
{
try
{
walkElements
((
Element
widget
)
{
if
(
predicate
(
widget
))
throw
widget
;
});
}
catch
(
e
)
{
if
(
e
is
Element
)
return
e
;
rethrow
;
}
return
null
;
}
void
pumpFrame
(
Widget
widget
)
{
if
(
_rootElement
==
null
)
{
_rootElement
=
new
ComponentElement
(
new
TestComponent
(
child:
widget
));
_rootElement
.
mount
(
null
);
}
else
{
_rootElement
.
update
(
new
TestComponent
(
child:
widget
),
null
);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment