Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
4c41b140
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
4c41b140
编写于
3月 23, 2020
作者:
M
Mouad Debbar
提交者:
GitHub
3月 23, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[web] Introduce js interop to enable experimental flags on web (#17099)
上级
21f5d7f3
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
168 addition
and
25 deletion
+168
-25
ci/licenses_golden/licenses_flutter
ci/licenses_golden/licenses_flutter
+1
-0
lib/web_ui/lib/src/engine.dart
lib/web_ui/lib/src/engine.dart
+3
-0
lib/web_ui/lib/src/engine/text/measurement.dart
lib/web_ui/lib/src/engine/text/measurement.dart
+1
-8
lib/web_ui/lib/src/engine/web_experiments.dart
lib/web_ui/lib/src/engine/web_experiments.dart
+53
-0
lib/web_ui/test/canvas_test.dart
lib/web_ui/test/canvas_test.dart
+4
-0
lib/web_ui/test/engine/web_experiments_test.dart
lib/web_ui/test/engine/web_experiments_test.dart
+80
-0
lib/web_ui/test/golden_tests/engine/scuba.dart
lib/web_ui/test/golden_tests/engine/scuba.dart
+5
-3
lib/web_ui/test/golden_tests/engine/text_overflow_golden_test.dart
...i/test/golden_tests/engine/text_overflow_golden_test.dart
+3
-3
lib/web_ui/test/paragraph_builder_test.dart
lib/web_ui/test/paragraph_builder_test.dart
+5
-0
lib/web_ui/test/paragraph_test.dart
lib/web_ui/test/paragraph_test.dart
+13
-11
未找到文件。
ci/licenses_golden/licenses_flutter
浏览文件 @
4c41b140
...
...
@@ -495,6 +495,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/text_editing/text_editing.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/util.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/validators.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/vector_math.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/web_experiments.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/window.dart
FILE: ../../../flutter/lib/web_ui/lib/src/ui/annotations.dart
FILE: ../../../flutter/lib/web_ui/lib/src/ui/canvas.dart
...
...
lib/web_ui/lib/src/engine.dart
浏览文件 @
4c41b140
...
...
@@ -117,6 +117,7 @@ part 'engine/text_editing/text_editing.dart';
part
'engine/util.dart'
;
part
'engine/validators.dart'
;
part
'engine/vector_math.dart'
;
part
'engine/web_experiments.dart'
;
part
'engine/window.dart'
;
bool
_engineInitialized
=
false
;
...
...
@@ -161,6 +162,8 @@ void webOnlyInitializeEngine() {
// initialize framework bindings.
domRenderer
;
WebExperiments
.
ensureInitialized
();
bool
waitingForAnimation
=
false
;
ui
.
webOnlyScheduleFrameCallback
=
()
{
// We're asked to schedule a frame and call `frameHandler` when the frame
...
...
lib/web_ui/lib/src/engine/text/measurement.dart
浏览文件 @
4c41b140
...
...
@@ -187,13 +187,6 @@ abstract class TextMeasurementService {
static
TextMeasurementService
get
canvasInstance
=>
CanvasTextMeasurementService
.
instance
;
/// Whether the new experimental implementation of canvas-based text
/// measurement is enabled or not.
///
/// This is only used for testing at the moment. Once the implementation is
/// complete and production-ready, we'll get rid of this flag.
static
bool
enableExperimentalCanvasImplementation
=
const
bool
.
fromEnvironment
(
'FLUTTER_WEB_USE_EXPERIMENTAL_CANVAS_TEXT'
,
defaultValue:
false
);
/// Gets the appropriate [TextMeasurementService] instance for the given
/// [paragraph].
static
TextMeasurementService
forParagraph
(
ui
.
Paragraph
paragraph
)
{
...
...
@@ -206,7 +199,7 @@ abstract class TextMeasurementService {
// Skip using canvas measurements until the iframe becomes visible.
// see: https://github.com/flutter/flutter/issues/36341
if
(!
window
.
physicalSize
.
isEmpty
&&
enableExperimentalCanvasImplementation
&&
WebExperiments
.
instance
.
useCanvasText
&&
_canUseCanvasMeasurement
(
paragraph
))
{
return
canvasInstance
;
}
...
...
lib/web_ui/lib/src/engine/web_experiments.dart
0 → 100644
浏览文件 @
4c41b140
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.6
part of
engine
;
/// A bag of all experiment flags in the web engine.
///
/// This class also handles platform messages that can be sent to enable/disable
/// certain experiments at runtime without the need to access engine internals.
class
WebExperiments
{
WebExperiments
.
_
()
{
js
.
context
[
'_flutter_internal_update_experiment'
]
=
updateExperiment
;
registerHotRestartListener
(()
{
js
.
context
[
'_flutter_internal_update_experiment'
]
=
null
;
});
}
static
WebExperiments
ensureInitialized
()
{
if
(
WebExperiments
.
instance
==
null
)
{
WebExperiments
.
instance
=
WebExperiments
.
_
();
}
return
WebExperiments
.
instance
;
}
static
WebExperiments
instance
;
/// Experiment flag for using canvas-based text measurement.
bool
get
useCanvasText
=>
_useCanvasText
??
false
;
set
useCanvasText
(
bool
enabled
)
{
_useCanvasText
=
enabled
;
}
bool
_useCanvasText
=
const
bool
.
fromEnvironment
(
'FLUTTER_WEB_USE_EXPERIMENTAL_CANVAS_TEXT'
,
defaultValue:
null
,
);
/// Reset all experimental flags to their default values.
void
reset
()
{
_useCanvasText
=
null
;
}
/// Used to enable/disable experimental flags in the web engine.
void
updateExperiment
(
String
name
,
bool
enabled
)
{
switch
(
name
)
{
case
'useCanvasText'
:
_useCanvasText
=
enabled
;
break
;
}
}
}
lib/web_ui/test/canvas_test.dart
浏览文件 @
4c41b140
...
...
@@ -11,6 +11,10 @@ import 'package:test/test.dart';
import
'mock_engine_canvas.dart'
;
void
main
(
)
{
setUpAll
(()
{
WebExperiments
.
ensureInitialized
();
});
group
(
'EngineCanvas'
,
()
{
MockEngineCanvas
mockCanvas
;
ui
.
Paragraph
paragraph
;
...
...
lib/web_ui/test/engine/web_experiments_test.dart
0 → 100644
浏览文件 @
4c41b140
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.6
import
'dart:html'
as
html
;
import
'dart:js_util'
as
js_util
;
import
'package:test/test.dart'
;
import
'package:ui/src/engine.dart'
;
void
main
(
)
{
setUp
(()
{
WebExperiments
.
ensureInitialized
();
});
tearDown
(()
{
WebExperiments
.
instance
.
reset
();
});
test
(
'default web experiment values'
,
()
{
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
});
test
(
'can turn on/off web experiments'
,
()
{
WebExperiments
.
instance
.
updateExperiment
(
'useCanvasText'
,
true
);
expect
(
WebExperiments
.
instance
.
useCanvasText
,
true
);
WebExperiments
.
instance
.
updateExperiment
(
'useCanvasText'
,
false
);
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
WebExperiments
.
instance
.
updateExperiment
(
'useCanvasText'
,
null
);
// Goes back to default value.
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
});
test
(
'ignores unknown experiments'
,
()
{
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
WebExperiments
.
instance
.
updateExperiment
(
'foobarbazqux'
,
true
);
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
WebExperiments
.
instance
.
updateExperiment
(
'foobarbazqux'
,
false
);
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
});
test
(
'can reset web experiments'
,
()
{
WebExperiments
.
instance
.
updateExperiment
(
'useCanvasText'
,
true
);
WebExperiments
.
instance
.
reset
();
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
WebExperiments
.
instance
.
updateExperiment
(
'useCanvasText'
,
true
);
WebExperiments
.
instance
.
updateExperiment
(
'foobarbazqux'
,
true
);
WebExperiments
.
instance
.
reset
();
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
});
test
(
'js interop also works'
,
()
{
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
expect
(()
=>
jsUpdateExperiment
(
'useCanvasText'
,
true
),
returnsNormally
);
expect
(
WebExperiments
.
instance
.
useCanvasText
,
true
);
expect
(()
=>
jsUpdateExperiment
(
'useCanvasText'
,
null
),
returnsNormally
);
expect
(
WebExperiments
.
instance
.
useCanvasText
,
false
);
});
test
(
'js interop throws on wrong type'
,
()
{
expect
(()
=>
jsUpdateExperiment
(
123
,
true
),
throwsA
(
anything
));
expect
(()
=>
jsUpdateExperiment
(
'foo'
,
123
),
throwsA
(
anything
));
expect
(()
=>
jsUpdateExperiment
(
'foo'
,
'bar'
),
throwsA
(
anything
));
expect
(()
=>
jsUpdateExperiment
(
false
,
'foo'
),
throwsA
(
anything
));
});
}
void
jsUpdateExperiment
(
dynamic
name
,
dynamic
enabled
)
{
js_util
.
callMethod
(
html
.
window
,
'_flutter_internal_update_experiment'
,
<
dynamic
>[
name
,
enabled
],
);
}
lib/web_ui/test/golden_tests/engine/scuba.dart
浏览文件 @
4c41b140
...
...
@@ -71,7 +71,7 @@ class EngineScubaTester {
sceneElement
.
append
(
canvas
.
rootElement
);
html
.
document
.
body
.
append
(
sceneElement
);
String
screenshotName
=
'
${fileName}
_
${canvas.runtimeType}
'
;
if
(
TextMeasurementService
.
enableExperimentalCanvasImplementation
)
{
if
(
WebExperiments
.
instance
.
useCanvasText
)
{
screenshotName
+=
'+canvas_measurement'
;
}
await
diffScreenshot
(
...
...
@@ -96,18 +96,20 @@ void testEachCanvas(String description, CanvasTest body,
test
(
'
$description
(bitmap)'
,
()
{
try
{
TextMeasurementService
.
initialize
(
rulerCacheCapacity:
2
);
WebExperiments
.
instance
.
useCanvasText
=
false
;
return
body
(
BitmapCanvas
(
bounds
));
}
finally
{
WebExperiments
.
instance
.
useCanvasText
=
null
;
TextMeasurementService
.
clearCache
();
}
});
test
(
'
$description
(bitmap + canvas measurement)'
,
()
async
{
try
{
TextMeasurementService
.
initialize
(
rulerCacheCapacity:
2
);
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
true
;
WebExperiments
.
instance
.
useCanvasText
=
true
;
await
body
(
BitmapCanvas
(
bounds
));
}
finally
{
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
false
;
WebExperiments
.
instance
.
useCanvasText
=
null
;
TextMeasurementService
.
clearCache
();
}
});
...
...
lib/web_ui/test/golden_tests/engine/text_overflow_golden_test.dart
浏览文件 @
4c41b140
...
...
@@ -5,7 +5,7 @@
// @dart = 2.6
import
'dart:async'
;
import
'package:ui/ui.dart'
;
import
'package:ui/ui.dart'
hide
window
;
import
'package:ui/src/engine.dart'
;
import
'scuba.dart'
;
...
...
@@ -89,7 +89,7 @@ void main() async {
offset
=
offset
.
translate
(
0
,
p
.
height
+
10
);
// Only the first line is rendered with an ellipsis.
if
(!
TextMeasurementService
.
enableExperimentalCanvasImplementation
)
{
if
(!
WebExperiments
.
instance
.
useCanvasText
)
{
// This is now correct with the canvas-based measurement, so we shouldn't
// print the "(wrong)" warning.
p
=
warning
(
'(wrong)'
);
...
...
@@ -106,7 +106,7 @@ void main() async {
// Only the first two lines are rendered and the ellipsis appears on the 2nd
// line.
if
(!
TextMeasurementService
.
enableExperimentalCanvasImplementation
)
{
if
(!
WebExperiments
.
instance
.
useCanvasText
)
{
// This is now correct with the canvas-based measurement, so we shouldn't
// print the "(wrong)" warning.
p
=
warning
(
'(wrong)'
);
...
...
lib/web_ui/test/paragraph_builder_test.dart
浏览文件 @
4c41b140
...
...
@@ -3,11 +3,16 @@
// found in the LICENSE file.
// @dart = 2.6
import
'package:ui/src/engine.dart'
;
import
'package:ui/ui.dart'
;
import
'package:test/test.dart'
;
void
main
(
)
{
setUpAll
(()
{
WebExperiments
.
ensureInitialized
();
});
test
(
'Should be able to build and layout a paragraph'
,
()
{
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
());
builder
.
addText
(
'Hello'
);
...
...
lib/web_ui/test/paragraph_test.dart
浏览文件 @
4c41b140
...
...
@@ -4,7 +4,7 @@
// @dart = 2.6
import
'package:ui/src/engine.dart'
;
import
'package:ui/ui.dart'
;
import
'package:ui/ui.dart'
hide
window
;
import
'package:test/test.dart'
;
...
...
@@ -12,18 +12,20 @@ void testEachMeasurement(String description, VoidCallback body, {bool skip}) {
test
(
'
$description
(dom measurement)'
,
()
async
{
try
{
TextMeasurementService
.
initialize
(
rulerCacheCapacity:
2
);
WebExperiments
.
instance
.
useCanvasText
=
false
;
return
body
();
}
finally
{
WebExperiments
.
instance
.
useCanvasText
=
null
;
TextMeasurementService
.
clearCache
();
}
},
skip:
skip
);
test
(
'
$description
(canvas measurement)'
,
()
async
{
try
{
TextMeasurementService
.
initialize
(
rulerCacheCapacity:
2
);
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
true
;
WebExperiments
.
instance
.
useCanvasText
=
true
;
return
body
();
}
finally
{
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
false
;
WebExperiments
.
instance
.
useCanvasText
=
null
;
TextMeasurementService
.
clearCache
();
}
},
skip:
skip
);
...
...
@@ -184,7 +186,7 @@ void main() async {
test
(
'getPositionForOffset multi-line'
,
()
{
// [Paragraph.getPositionForOffset] for multi-line text doesn't work well
// with dom-based measurement.
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
true
;
WebExperiments
.
instance
.
useCanvasText
=
true
;
TextMeasurementService
.
initialize
(
rulerCacheCapacity:
2
);
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
(
...
...
@@ -280,11 +282,11 @@ void main() async {
);
TextMeasurementService
.
clearCache
();
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
false
;
WebExperiments
.
instance
.
useCanvasText
=
null
;
});
test
(
'getPositionForOffset multi-line centered'
,
()
{
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
true
;
WebExperiments
.
instance
.
useCanvasText
=
true
;
TextMeasurementService
.
initialize
(
rulerCacheCapacity:
2
);
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
(
...
...
@@ -387,7 +389,7 @@ void main() async {
);
TextMeasurementService
.
clearCache
();
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
false
;
WebExperiments
.
instance
.
useCanvasText
=
null
;
});
testEachMeasurement
(
'getBoxesForRange returns a box'
,
()
{
...
...
@@ -782,7 +784,7 @@ void main() async {
test
(
'longestLine'
,
()
{
// [Paragraph.longestLine] is only supported by canvas-based measurement.
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
true
;
WebExperiments
.
instance
.
useCanvasText
=
true
;
TextMeasurementService
.
initialize
(
rulerCacheCapacity:
2
);
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
(
...
...
@@ -797,7 +799,7 @@ void main() async {
expect
(
paragraph
.
longestLine
,
50.0
);
TextMeasurementService
.
clearCache
();
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
false
;
WebExperiments
.
instance
.
useCanvasText
=
null
;
});
testEachMeasurement
(
'getLineBoundary (single-line)'
,
()
{
...
...
@@ -824,7 +826,7 @@ void main() async {
test
(
'getLineBoundary (multi-line)'
,
()
{
// [Paragraph.getLineBoundary] for multi-line paragraphs is only supported
// by canvas-based measurement.
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
true
;
WebExperiments
.
instance
.
useCanvasText
=
true
;
TextMeasurementService
.
initialize
(
rulerCacheCapacity:
2
);
final
ParagraphBuilder
builder
=
ParagraphBuilder
(
ParagraphStyle
(
...
...
@@ -867,7 +869,7 @@ void main() async {
}
TextMeasurementService
.
clearCache
();
TextMeasurementService
.
enableExperimentalCanvasImplementation
=
false
;
WebExperiments
.
instance
.
useCanvasText
=
null
;
});
testEachMeasurement
(
'width should be a whole integer'
,
()
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录