void CustomElement::enqueueDisconnectedCallback(Element* element) { DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom); CustomElementDefinition* definition = definitionForElement(*element); if (definition->hasDisconnectedCallback()) definition->enqueueDisconnectedCallback(element); }
// https://html.spec.whatwg.org/multipage/scripting.html#dom-customelementsregistry-get ScriptValue CustomElementRegistry::get(const AtomicString& name) { CustomElementDefinition* definition = definitionForName(name); if (!definition) { // Binding layer converts |ScriptValue()| to script specific value, // e.g. |undefined| for v8. return ScriptValue(); } return definition->getConstructorForScript(); }
void CustomElement::enqueueAttributeChangedCallback(Element* element, const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue) { DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom); CustomElementDefinition* definition = definitionForElement(*element); if (definition->hasAttributeChangedCallback(name)) definition->enqueueAttributeChangedCallback(element, name, oldValue, newValue); }
CustomElementDefinition* CustomElementRegistry::definitionFor( const CustomElementDescriptor& desc) const { CustomElementDefinition* definition = definitionForName(desc.name()); if (!definition) return nullptr; // The definition for a customized built-in element, such as // <button is="my-button"> should not be provided for an // autonomous element, such as <my-button>, even though the // name "my-button" matches. return definition->descriptor() == desc ? definition : nullptr; }
void nsStyledElement::InlineStyleDeclarationWillChange(MutationClosureData& aData) { MOZ_ASSERT(OwnerDoc()->UpdateNestingLevel() > 0, "Should be inside document update!"); bool modification = false; if (MayHaveStyle()) { bool needsOldValue = !StaticPrefs::dom_mutation_events_cssom_disabled() && nsContentUtils::HasMutationListeners(this, NS_EVENT_BITS_MUTATION_ATTRMODIFIED, this); if (!needsOldValue) { CustomElementDefinition* definition = GetCustomElementDefinition(); if (definition && definition->IsInObservedAttributeList(nsGkAtoms::style)) { needsOldValue = true; } } if (needsOldValue) { nsAutoString oldValueStr; modification = GetAttr(kNameSpaceID_None, nsGkAtoms::style, oldValueStr); if (modification) { aData.mOldValue.emplace(); aData.mOldValue->SetTo(oldValueStr); } } else { modification = HasAttr(kNameSpaceID_None, nsGkAtoms::style); } } aData.mModType = modification ? static_cast<uint8_t>(MutationEvent_Binding::MODIFICATION) : static_cast<uint8_t>(MutationEvent_Binding::ADDITION); nsNodeUtils::AttributeWillChange(this, kNameSpaceID_None, nsGkAtoms::style, aData.mModType, nullptr); //XXXsmaug In order to make attribute handling more consistent, consider to // call BeforeSetAttr and pass kCallAfterSetAttr to // SetAttrAndNotify in SetInlineStyleDeclaration. // Handling of mozAutoDocUpdate may require changes in that case. }
void CustomElementRegistrationContext::registerElement(Document* document, CustomElementConstructorBuilder* constructorBuilder, const AtomicString& type, CustomElement::NameSet validNames, ExceptionState& exceptionState) { CustomElementDefinition* definition = m_registry.registerElement(document, constructorBuilder, type, validNames, exceptionState); if (!definition) return; // Upgrade elements that were waiting for this definition. const CustomElementUpgradeCandidateMap::ElementSet& upgradeCandidates = m_candidates.takeUpgradeCandidatesFor(definition->descriptor()); for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgradeCandidates.begin(); it != upgradeCandidates.end(); ++it) CustomElement::define(*it, definition); }
void CustomElementRegistrationContext::registerElement(Document* document, CustomElementConstructorBuilder* constructorBuilder, const AtomicString& type, CustomElement::NameSet validNames, ExceptionState& exceptionState) { CustomElementDefinition* definition = m_registry.registerElement(document, constructorBuilder, type, validNames, exceptionState); if (!definition) return; // Upgrade elements that were waiting for this definition. OwnPtrWillBeRawPtr<CustomElementUpgradeCandidateMap::ElementSet> upgradeCandidates = m_candidates->takeUpgradeCandidatesFor(definition->descriptor()); if (!upgradeCandidates) return; for (const auto& candidate : *upgradeCandidates) CustomElement::define(candidate, definition); }
// http://w3c.github.io/webcomponents/spec/custom/#dfn-element-definition void CustomElementRegistry::define(const AtomicString& name, CustomElementDefinitionBuilder& builder, const ElementDefinitionOptions& options, ExceptionState& exceptionState) { if (!builder.checkConstructorIntrinsics()) return; if (throwIfInvalidName(name, exceptionState)) return; if (nameIsDefined(name) || v0NameIsDefined(name)) { exceptionState.throwDOMException( NotSupportedError, "this name has already been used with this registry"); return; } if (!builder.checkConstructorNotRegistered()) return; // Step 7. customized built-in elements definition // element interface extends option checks if (RuntimeEnabledFeatures::customElementsBuiltinEnabled() && options.hasExtends()) { // If element interface is valid custom element name, throw exception if (throwIfValidName(AtomicString(options.extends()), exceptionState)) return; // If element interface is undefined element, throw exception // Set localname to extends } // TODO(dominicc): Add a test where the prototype getter destroys // the context. // 8. If this CustomElementRegistry's element definition is // running flag is set, then throw a "NotSupportedError" // DOMException and abort these steps. if (m_elementDefinitionIsRunning) { exceptionState.throwDOMException( NotSupportedError, "an element definition is already being processed"); return; } { // 9. Set this CustomElementRegistry's element definition is // running flag. ElementDefinitionIsRunning defining(m_elementDefinitionIsRunning); // 10.1-2 if (!builder.checkPrototype()) return; // 10.3-6 if (!builder.rememberOriginalProperties()) return; // "Then, perform the following substep, regardless of whether // the above steps threw an exception or not: Unset this // CustomElementRegistry's element definition is running // flag." // (ElementDefinitionIsRunning destructor does this.) } CustomElementDescriptor descriptor(name, name); CustomElementDefinition* definition = builder.build(descriptor); CHECK(!exceptionState.hadException()); CHECK(definition->descriptor() == descriptor); DefinitionMap::AddResult result = m_definitions.add(descriptor.name(), definition); CHECK(result.isNewEntry); HeapVector<Member<Element>> candidates; collectCandidates(descriptor, &candidates); for (Element* candidate : candidates) definition->enqueueUpgradeReaction(candidate); // 16: when-defined promise processing const auto& entry = m_whenDefinedPromiseMap.find(name); if (entry == m_whenDefinedPromiseMap.end()) return; entry->value->resolve(); m_whenDefinedPromiseMap.remove(entry); }