blob: c9099e8d08938aaf6c662a4faf562eab660102bf [file] [log] [blame]
// 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.
#include "sky/engine/config.h"
#include "sky/engine/core/dom/custom/custom_element.h"
#include "base/bind.h"
#include "dart/runtime/include/dart_api.h"
#include "sky/engine/core/dom/Document.h"
#include "sky/engine/core/dom/Element.h"
#include "sky/engine/core/dom/Microtask.h"
#include "sky/engine/core/dom/custom/custom_element_callback_scope.h"
#include "sky/engine/core/dom/custom/custom_element_registry.h"
#include "sky/engine/tonic/dart_converter.h"
#include "sky/engine/tonic/dart_invoke.h"
#include "sky/engine/tonic/dart_state.h"
#include "sky/engine/wtf/text/AtomicString.h"
namespace blink {
namespace {
void ScheduleCallback(const base::Closure& callback) {
if (auto* scope = CustomElementCallbackScope::Current()) {
scope->Enqueue(callback);
} else {
Microtask::enqueueMicrotask(callback);
}
}
void CallAttributeDidChangedCallback(RefPtr<Element> element,
AtomicString name,
AtomicString oldValue,
AtomicString newValue) {
auto* dart_state = element->document().elementRegistry().dart_state().get();
if (!dart_state)
return;
DartState::Scope scope(dart_state);
Dart_Handle wrapper = ToDart(element);
Dart_Handle callback = Dart_NewStringFromCString("attributeChangedCallback");
Dart_Handle args[] = {
StringToDart(dart_state, name),
StringToDart(dart_state, oldValue),
StringToDart(dart_state, newValue),
};
DartInvokeAppField(wrapper, callback, arraysize(args), args);
}
void CallDidAttachedCallback(RefPtr<Element> element, RefPtr<Document> document) {
auto* dart_state = document->elementRegistry().dart_state().get();
if (!dart_state)
return;
DartState::Scope scope(dart_state);
Dart_Handle wrapper = ToDart(element);
Dart_Handle callback = Dart_NewStringFromCString("attachedCallback");
LogIfError(Dart_Invoke(wrapper, callback, 0, nullptr));
}
void CallDidDetachedCallback(RefPtr<Element> element, RefPtr<Document> document) {
auto* dart_state = document->elementRegistry().dart_state().get();
if (!dart_state)
return;
DartState::Scope scope(dart_state);
Dart_Handle wrapper = ToDart(element);
Dart_Handle callback = Dart_NewStringFromCString("detachedCallback");
LogIfError(Dart_Invoke(wrapper, callback, 0, nullptr));
}
} // namespace
void CustomElement::AttributeDidChange(Element* element,
const AtomicString& name,
const AtomicString& oldValue,
const AtomicString& newValue) {
ScheduleCallback(base::Bind(CallAttributeDidChangedCallback,
element, name, oldValue, newValue));
}
void CustomElement::DidAttach(Element* element, Document& document) {
ScheduleCallback(base::Bind(CallDidAttachedCallback, element, &document));
}
void CustomElement::DidDetach(Element* element, Document& document) {
ScheduleCallback(base::Bind(CallDidDetachedCallback, element, &document));
}
} // namespace blink