summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc205
1 files changed, 162 insertions, 43 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc b/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
index 3ac1c1fbcb5..b662f819135 100644
--- a/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
+++ b/chromium/third_party/blink/renderer/core/layout/ng/custom/css_layout_definition.cc
@@ -13,6 +13,8 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_fragment_result_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_function.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_callback.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_intrinsic_sizes_result_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_layout_callback.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_no_argument_constructor.h"
#include "third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h"
@@ -23,20 +25,41 @@
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_edges.h"
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/custom/custom_layout_scope.h"
-#include "third_party/blink/renderer/core/layout/ng/custom/fragment_result_options.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h"
#include "third_party/blink/renderer/platform/bindings/microtask.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding_macros.h"
#include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
+namespace {
+
+void GatherChildren(const NGBlockNode& node,
+ CustomLayoutScope* custom_layout_scope,
+ HeapVector<Member<CustomLayoutChild>>* children) {
+ // TODO(ikilpatrick): Determine if knowing the size of the array ahead of
+ // time improves performance in any noticeable way.
+ for (NGLayoutInputNode child = node.FirstChild(); child;
+ child = child.NextSibling()) {
+ if (child.IsOutOfFlowPositioned())
+ continue;
+
+ CustomLayoutChild* layout_child = child.GetCustomLayoutChild();
+ layout_child->SetCustomLayoutToken(custom_layout_scope->Token());
+ DCHECK(layout_child);
+ children->push_back(layout_child);
+ }
+}
+
+} // anonymous namespace
+
CSSLayoutDefinition::CSSLayoutDefinition(
ScriptState* script_state,
V8NoArgumentConstructor* constructor,
- V8Function* intrinsic_sizes,
+ V8IntrinsicSizesCallback* intrinsic_sizes,
V8LayoutCallback* layout,
const Vector<CSSPropertyID>& native_invalidation_properties,
const Vector<AtomicString>& custom_invalidation_properties,
@@ -44,7 +67,7 @@ CSSLayoutDefinition::CSSLayoutDefinition(
const Vector<AtomicString>& child_custom_invalidation_properties)
: script_state_(script_state),
constructor_(constructor),
- unused_intrinsic_sizes_(intrinsic_sizes),
+ intrinsic_sizes_(intrinsic_sizes),
layout_(layout),
native_invalidation_properties_(native_invalidation_properties),
custom_invalidation_properties_(custom_invalidation_properties),
@@ -66,8 +89,9 @@ bool CSSLayoutDefinition::Instance::Layout(
const NGBlockNode& node,
const LogicalSize& border_box_size,
const NGBoxStrut& border_scrollbar_padding,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max,
CustomLayoutScope* custom_layout_scope,
- FragmentResultOptions* fragment_result_options,
+ FragmentResultOptions*& fragment_result_options,
scoped_refptr<SerializedScriptValue>* fragment_result_data) {
ScriptState* script_state = definition_->GetScriptState();
v8::Isolate* isolate = script_state->GetIsolate();
@@ -77,19 +101,8 @@ bool CSSLayoutDefinition::Instance::Layout(
ScriptState::Scope scope(script_state);
- // TODO(ikilpatrick): Determine if knowing the size of the array ahead of
- // time improves performance in any noticeable way.
HeapVector<Member<CustomLayoutChild>> children;
- for (NGLayoutInputNode child = node.FirstChild(); child;
- child = child.NextSibling()) {
- if (child.IsOutOfFlowPositioned())
- continue;
-
- CustomLayoutChild* layout_child = child.GetCustomLayoutChild();
- layout_child->SetCustomLayoutToken(custom_layout_scope->Token());
- DCHECK(layout_child);
- children.push_back(layout_child);
- }
+ GatherChildren(node, custom_layout_scope, &children);
CustomLayoutEdges* edges =
MakeGarbageCollected<CustomLayoutEdges>(border_scrollbar_padding);
@@ -121,18 +134,20 @@ bool CSSLayoutDefinition::Instance::Layout(
v8::Local<v8::Value> v8_return_value = return_value.V8Value();
if (v8_return_value.IsEmpty() || !v8_return_value->IsPromise()) {
- execution_context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kInfo,
- "The layout function must be async or return a "
- "promise, falling back to block layout."));
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "The layout function must be async or return a "
+ "promise, falling back to block layout."));
return false;
}
// Run the work queue until exhaustion.
while (!custom_layout_scope->Queue()->IsEmpty()) {
- for (auto& task : *custom_layout_scope->Queue())
- task.Run(space, node.Style());
+ for (auto& task : *custom_layout_scope->Queue()) {
+ task.Run(space, node.Style(),
+ child_percentage_resolution_block_size_for_min_max);
+ }
custom_layout_scope->Queue()->clear();
{
v8::MicrotasksScope microtasks_scope(isolate, microtask_queue,
@@ -149,27 +164,28 @@ bool CSSLayoutDefinition::Instance::Layout(
v8::Local<v8::Promise>::Cast(v8_return_value);
if (v8_result_promise->State() != v8::Promise::kFulfilled) {
- execution_context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kInfo,
- "The layout function promise must resolve, "
- "falling back to block layout."));
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "The layout function promise must resolve, "
+ "falling back to block layout."));
return false;
}
v8::Local<v8::Value> inner_value = v8_result_promise->Result();
// Attempt to convert the result.
- V8FragmentResultOptions::ToImpl(isolate, inner_value, fragment_result_options,
- exception_state);
+ fragment_result_options =
+ NativeValueTraits<FragmentResultOptions>::NativeValue(
+ isolate, inner_value, exception_state);
if (exception_state.HadException()) {
V8ScriptRunner::ReportException(isolate, exception_state.GetException());
exception_state.ClearException();
- execution_context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kInfo,
- "Unable to parse the layout function "
- "result, falling back to block layout."));
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "Unable to parse the layout function "
+ "result, falling back to block layout."));
return false;
}
@@ -188,11 +204,114 @@ bool CSSLayoutDefinition::Instance::Layout(
if (exception_state.HadException()) {
V8ScriptRunner::ReportException(isolate, exception_state.GetException());
exception_state.ClearException();
- execution_context->AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
- mojom::ConsoleMessageLevel::kInfo,
- "Unable to serialize the data provided in the "
- "result, falling back to block layout."));
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "Unable to serialize the data provided in the "
+ "result, falling back to block layout."));
+ return false;
+ }
+
+ return true;
+}
+
+bool CSSLayoutDefinition::Instance::IntrinsicSizes(
+ const NGConstraintSpace& space,
+ const Document& document,
+ const NGBlockNode& node,
+ const LogicalSize& border_box_size,
+ const NGBoxStrut& border_scrollbar_padding,
+ const LayoutUnit child_percentage_resolution_block_size_for_min_max,
+ CustomLayoutScope* custom_layout_scope,
+ IntrinsicSizesResultOptions*& intrinsic_sizes_result_options) {
+ ScriptState* script_state = definition_->GetScriptState();
+ v8::Isolate* isolate = script_state->GetIsolate();
+
+ if (!script_state->ContextIsValid())
+ return false;
+
+ ScriptState::Scope scope(script_state);
+
+ HeapVector<Member<CustomLayoutChild>> children;
+ GatherChildren(node, custom_layout_scope, &children);
+
+ CustomLayoutEdges* edges =
+ MakeGarbageCollected<CustomLayoutEdges>(border_scrollbar_padding);
+
+ // TODO(ikilpatrick): Instead of creating a new style_map each time here,
+ // store on LayoutCustom, and update when the style changes.
+ StylePropertyMapReadOnly* style_map =
+ MakeGarbageCollected<PrepopulatedComputedStylePropertyMap>(
+ document, node.Style(), definition_->native_invalidation_properties_,
+ definition_->custom_invalidation_properties_);
+
+ ScriptValue return_value;
+ if (!definition_->intrinsic_sizes_
+ ->Invoke(instance_.NewLocal(isolate), children, edges, style_map)
+ .To(&return_value))
+ return false;
+
+ ExecutionContext* execution_context = ExecutionContext::From(script_state);
+ v8::MicrotaskQueue* microtask_queue = ToMicrotaskQueue(execution_context);
+ DCHECK(microtask_queue);
+
+ ExceptionState exception_state(isolate, ExceptionState::kExecutionContext,
+ "CSSLayoutAPI", "IntrinsicSizes");
+
+ v8::Local<v8::Value> v8_return_value = return_value.V8Value();
+ if (v8_return_value.IsEmpty() || !v8_return_value->IsPromise()) {
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "The intrinsicSizes function must be async or return a "
+ "promise, falling back to block layout."));
+ return false;
+ }
+
+ // Run the work queue until exhaustion.
+ while (!custom_layout_scope->Queue()->IsEmpty()) {
+ for (auto& task : *custom_layout_scope->Queue()) {
+ task.Run(space, node.Style(),
+ child_percentage_resolution_block_size_for_min_max);
+ }
+ custom_layout_scope->Queue()->clear();
+ {
+ v8::MicrotasksScope microtasks_scope(isolate, microtask_queue,
+ v8::MicrotasksScope::kRunMicrotasks);
+ }
+ }
+
+ if (exception_state.HadException()) {
+ ReportException(&exception_state);
+ return false;
+ }
+
+ v8::Local<v8::Promise> v8_result_promise =
+ v8::Local<v8::Promise>::Cast(v8_return_value);
+
+ if (v8_result_promise->State() != v8::Promise::kFulfilled) {
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "The intrinsicSizes function promise must resolve, "
+ "falling back to block layout."));
+ return false;
+ }
+ v8::Local<v8::Value> inner_value = v8_result_promise->Result();
+
+ // Attempt to convert the result.
+ intrinsic_sizes_result_options =
+ NativeValueTraits<IntrinsicSizesResultOptions>::NativeValue(
+ isolate, inner_value, exception_state);
+
+ if (exception_state.HadException()) {
+ V8ScriptRunner::ReportException(isolate, exception_state.GetException());
+ exception_state.ClearException();
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kInfo,
+ "Unable to parse the intrinsicSizes function "
+ "result, falling back to block layout."));
return false;
}
@@ -209,7 +328,7 @@ void CSSLayoutDefinition::Instance::ReportException(
// again (as the callbacks are invoked directly by the UA).
V8ScriptRunner::ReportException(isolate, exception_state->GetException());
exception_state->ClearException();
- execution_context->AddConsoleMessage(ConsoleMessage::Create(
+ execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kJavaScript,
mojom::ConsoleMessageLevel::kInfo,
"The layout function failed, falling back to block layout."));
@@ -234,14 +353,14 @@ CSSLayoutDefinition::Instance* CSSLayoutDefinition::CreateInstance() {
return MakeGarbageCollected<Instance>(this, instance.V8Value());
}
-void CSSLayoutDefinition::Instance::Trace(blink::Visitor* visitor) {
+void CSSLayoutDefinition::Instance::Trace(Visitor* visitor) {
visitor->Trace(definition_);
visitor->Trace(instance_);
}
void CSSLayoutDefinition::Trace(Visitor* visitor) {
visitor->Trace(constructor_);
- visitor->Trace(unused_intrinsic_sizes_);
+ visitor->Trace(intrinsic_sizes_);
visitor->Trace(layout_);
visitor->Trace(script_state_);
}