Changeset 197611 in webkit


Ignore:
Timestamp:
Mar 4, 2016 11:50:54 PM (8 years ago)
Author:
rniwa@webkit.org
Message:

Add basic support for attributeChanged lifecycle callback
https://bugs.webkit.org/show_bug.cgi?id=155011

Reviewed by Antti Koivisto.

Source/WebCore:

Add basic support for attributeChangedCallback in setAttribute, removeAttribute, setAttributeNS,
remoteAttributeNS, setAttributeNode, and removeAttributeNS. There are many other DOM APIs that
could modify attributes but we would annotate those APIs in a separate patch to limit the scope
of this change.

In order to invoke the lifecycle callback right before returning to the author script, allocate
an instance of CustomElementLifecycleProcessingStack in each of these functions' binding code.
The stack object's destructor invokes all callbacks enqueued by the DOM API if there are any.

Spec: https://w3c.github.io/webcomponents/spec/custom/#dfn-attribute-changed-callback

Tests: fast/custom-elements/attribute-changed-callback.html

fast/custom-elements/lifecycle-callback-timing.html

  • CMakeLists.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • bindings/js/JSCustomElementInterface.cpp:

(WebCore::JSCustomElementInterface::attributeChanged): Added. Invokes attributeChangedCallback.

  • bindings/js/JSCustomElementInterface.h:
  • bindings/js/JSMainThreadExecState.h:

(JSMainThreadNullState): Allocate an instance of CustomElementLifecycleProcessingStack in GObject
and Objective-C binding code for consistency with JavaScript. We can't do this in JavaScript
because there is no RAII object all functions, getters, and setters allocate (for a good reason).

  • bindings/scripts/CodeGeneratorJS.pm:

(GenerateImplementation): Generate an instance of CustomElementLifecycleProcessingStack when
NeedsLifecycleProcessingStack is specified as an extended IDL attribute.

  • bindings/scripts/IDLAttributes.txt: Added NeedsLifecycleProcessingStack.
  • bindings/scripts/test/JS/JSTestObj.cpp:

(WebCore::jsTestObjPrototypeFunctionMethodWithNeedsLifecycleProcessingStack):

  • bindings/scripts/test/TestObj.idl: Added a test for NeedsLifecycleProcessingStack.
  • dom/DOMAllInOne.cpp:
  • dom/Element.cpp:

(WebCore::Element::attributeChanged): Enqueue attributeChanged callback if the context object
is a custom element and there is a CustomElementLifecycleProcessingStack allocated in the stack.

  • dom/Element.idl:
  • dom/LifecycleCallbackQueue.cpp: Added.

(WebCore::LifecycleQueueItem): Added.
(WebCore::LifecycleQueueItem::LifecycleQueueItem): Added.
(WebCore::LifecycleQueueItem::invoke): Added.
(WebCore::LifecycleCallbackQueue::LifecycleCallbackQueue): Added.
(WebCore::LifecycleCallbackQueue::~LifecycleCallbackQueue): Added.
(WebCore::LifecycleCallbackQueue::enqueueAttributeChangedCallback): Added.
(WebCore::LifecycleCallbackQueue::invokeAll): Added.
(WebCore::CustomElementLifecycleProcessingStack::ensureCurrentQueue): Added. As noted in FIXME,
the early exit in the code is necessary only because we haven't added NeedsLifecycleProcessingStack
in all places. It should go away in a follow up patch.
(WebCore::CustomElementLifecycleProcessingStack::processQueue): Added.

  • dom/LifecycleCallbackQueue.h: Added.

(WebCore::CustomElementLifecycleProcessingStack): This is a light weight RAII object the binding
code will allocate in order to queue up lifecycle callbacks. We don't use Ref or std::unique_ptr
in m_queue to avoid generating the code to destruct LifecycleCallbackQueue everywhere.
(WebCore::CustomElementLifecycleProcessingStack::CustomElementLifecycleProcessingStack): Added.
(WebCore::CustomElementLifecycleProcessingStack::~CustomElementLifecycleProcessingStack): Added.
(WebCore::CustomElementLifecycleProcessingStack::hasCurrentProcessingStack): Added.

LayoutTests:

Added a test for attributeChangedCallback and a test for the timing of lifecycle callbacks in general.

  • fast/custom-elements/attribute-changed-callback-expected.txt: Added.
  • fast/custom-elements/attribute-changed-callback.html: Added.
  • fast/custom-elements/lifecycle-callback-timing-expected.txt: Added.
  • fast/custom-elements/lifecycle-callback-timing.html: Added.
Location:
trunk
Files:
6 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r197610 r197611  
     12016-03-04  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Add basic support for attributeChanged lifecycle callback
     4        https://bugs.webkit.org/show_bug.cgi?id=155011
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Added a test for attributeChangedCallback and a test for the timing of lifecycle callbacks in general.
     9
     10        * fast/custom-elements/attribute-changed-callback-expected.txt: Added.
     11        * fast/custom-elements/attribute-changed-callback.html: Added.
     12        * fast/custom-elements/lifecycle-callback-timing-expected.txt: Added.
     13        * fast/custom-elements/lifecycle-callback-timing.html: Added.
     14
    1152016-03-04  Tim Horton  <timothy_horton@apple.com>
    216
  • trunk/Source/WebCore/CMakeLists.txt

    r197592 r197611  
    14541454    dom/InlineStyleSheetOwner.cpp
    14551455    dom/KeyboardEvent.cpp
     1456    dom/LifecycleCallbackQueue.cpp
    14561457    dom/LiveNodeList.cpp
    14571458    dom/MessageChannel.cpp
  • trunk/Source/WebCore/ChangeLog

    r197609 r197611  
     12016-03-04  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Add basic support for attributeChanged lifecycle callback
     4        https://bugs.webkit.org/show_bug.cgi?id=155011
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Add basic support for attributeChangedCallback in setAttribute, removeAttribute, setAttributeNS,
     9        remoteAttributeNS, setAttributeNode, and removeAttributeNS. There are many other DOM APIs that
     10        could modify attributes but we would annotate those APIs in a separate patch to limit the scope
     11        of this change.
     12
     13        In order to invoke the lifecycle callback right before returning to the author script, allocate
     14        an instance of CustomElementLifecycleProcessingStack in each of these functions' binding code.
     15        The stack object's destructor invokes all callbacks enqueued by the DOM API if there are any.
     16
     17        Spec: https://w3c.github.io/webcomponents/spec/custom/#dfn-attribute-changed-callback
     18
     19        Tests: fast/custom-elements/attribute-changed-callback.html
     20               fast/custom-elements/lifecycle-callback-timing.html
     21
     22        * CMakeLists.txt:
     23        * WebCore.xcodeproj/project.pbxproj:
     24        * bindings/js/JSCustomElementInterface.cpp:
     25        (WebCore::JSCustomElementInterface::attributeChanged): Added. Invokes attributeChangedCallback.
     26        * bindings/js/JSCustomElementInterface.h:
     27        * bindings/js/JSMainThreadExecState.h:
     28        (JSMainThreadNullState): Allocate an instance of CustomElementLifecycleProcessingStack in GObject
     29        and Objective-C binding code for consistency with JavaScript. We can't do this in JavaScript
     30        because there is no RAII object all functions, getters, and setters allocate (for a good reason).
     31
     32        * bindings/scripts/CodeGeneratorJS.pm:
     33        (GenerateImplementation): Generate an instance of CustomElementLifecycleProcessingStack when
     34        NeedsLifecycleProcessingStack is specified as an extended IDL attribute.
     35        * bindings/scripts/IDLAttributes.txt: Added NeedsLifecycleProcessingStack.
     36        * bindings/scripts/test/JS/JSTestObj.cpp:
     37        (WebCore::jsTestObjPrototypeFunctionMethodWithNeedsLifecycleProcessingStack):
     38        * bindings/scripts/test/TestObj.idl: Added a test for NeedsLifecycleProcessingStack.
     39
     40        * dom/DOMAllInOne.cpp:
     41        * dom/Element.cpp:
     42        (WebCore::Element::attributeChanged): Enqueue attributeChanged callback if the context object
     43        is a custom element and there is a CustomElementLifecycleProcessingStack allocated in the stack.
     44        * dom/Element.idl:
     45
     46        * dom/LifecycleCallbackQueue.cpp: Added.
     47        (WebCore::LifecycleQueueItem): Added.
     48        (WebCore::LifecycleQueueItem::LifecycleQueueItem): Added.
     49        (WebCore::LifecycleQueueItem::invoke): Added.
     50        (WebCore::LifecycleCallbackQueue::LifecycleCallbackQueue): Added.
     51        (WebCore::LifecycleCallbackQueue::~LifecycleCallbackQueue): Added.
     52        (WebCore::LifecycleCallbackQueue::enqueueAttributeChangedCallback): Added.
     53        (WebCore::LifecycleCallbackQueue::invokeAll): Added.
     54        (WebCore::CustomElementLifecycleProcessingStack::ensureCurrentQueue): Added. As noted in FIXME,
     55        the early exit in the code is necessary only because we haven't added NeedsLifecycleProcessingStack
     56        in all places. It should go away in a follow up patch.
     57        (WebCore::CustomElementLifecycleProcessingStack::processQueue): Added.
     58        * dom/LifecycleCallbackQueue.h: Added.
     59        (WebCore::CustomElementLifecycleProcessingStack): This is a light weight RAII object the binding
     60        code will allocate in order to queue up lifecycle callbacks. We don't use Ref or std::unique_ptr
     61        in m_queue to avoid generating the code to destruct LifecycleCallbackQueue everywhere.
     62        (WebCore::CustomElementLifecycleProcessingStack::CustomElementLifecycleProcessingStack): Added.
     63        (WebCore::CustomElementLifecycleProcessingStack::~CustomElementLifecycleProcessingStack): Added.
     64        (WebCore::CustomElementLifecycleProcessingStack::hasCurrentProcessingStack): Added.
     65
    1662016-03-04  Carlos Garcia Campos  <cgarcia@igalia.com>
    267
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r197596 r197611  
    40194019                9B532EA41BA928570038A827 /* SlotAssignment.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B532EA21BA928570038A827 /* SlotAssignment.h */; };
    40204020                9B55EEE91B3E8898005342BC /* EditorCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9B55EEE81B3E8898005342BC /* EditorCocoa.mm */; };
     4021                9B56C9AA1C89329A00C456DF /* LifecycleCallbackQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B56C9A91C89329A00C456DF /* LifecycleCallbackQueue.cpp */; };
    40214022                9B69D3B41B98FFE900E3512B /* HTMLSlotElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9B69D3B21B98FFE900E3512B /* HTMLSlotElement.cpp */; };
    40224023                9B69D3B51B98FFE900E3512B /* HTMLSlotElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B69D3B31B98FFE900E3512B /* HTMLSlotElement.h */; };
     
    1169711698                9B55EEE81B3E8898005342BC /* EditorCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EditorCocoa.mm; sourceTree = "<group>"; };
    1169811699                9B55EEEA1B3F3FEF005342BC /* EditorCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EditorCocoa.h; sourceTree = "<group>"; };
     11700                9B56C9A81C89312800C456DF /* LifecycleCallbackQueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LifecycleCallbackQueue.h; sourceTree = "<group>"; };
     11701                9B56C9A91C89329A00C456DF /* LifecycleCallbackQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LifecycleCallbackQueue.cpp; sourceTree = "<group>"; };
    1169911702                9B69D3B11B98FF0A00E3512B /* HTMLSlotElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLSlotElement.idl; sourceTree = "<group>"; };
    1170011703                9B69D3B21B98FFE900E3512B /* HTMLSlotElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLSlotElement.cpp; sourceTree = "<group>"; };
     
    2432424327                                85031B2E0A44EFC700F992E0 /* KeyboardEvent.h */,
    2432524328                                14CF7C2009F7110600EB3665 /* KeyboardEvent.idl */,
     24329                                9B56C9A91C89329A00C456DF /* LifecycleCallbackQueue.cpp */,
     24330                                9B56C9A81C89312800C456DF /* LifecycleCallbackQueue.h */,
    2432624331                                BC7FA61E0D1F0CBD00DB22A9 /* LiveNodeList.cpp */,
    2432724332                                BC7FA61F0D1F0CBD00DB22A9 /* LiveNodeList.h */,
     
    2987029875                                977B3872122883E900B81FF8 /* HTMLPreloadScanner.cpp in Sources */,
    2987129876                                A43BF5981149290A00C643CA /* HTMLProgressElement.cpp in Sources */,
     29877                                9B56C9AA1C89329A00C456DF /* LifecycleCallbackQueue.cpp in Sources */,
    2987229878                                A8CFF7A50A156978000A4234 /* HTMLQuoteElement.cpp in Sources */,
    2987329879                                A8D223FD16B52E4E00157288 /* HTMLResourcePreloader.cpp in Sources */,
  • trunk/Source/WebCore/bindings/js/JSCustomElementInterface.cpp

    r197463 r197611  
    102102}
    103103
     104void JSCustomElementInterface::attributeChanged(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
     105{
     106    if (!canInvokeCallback())
     107        return;
     108
     109    Ref<JSCustomElementInterface> protect(*this);
     110
     111    JSLockHolder lock(m_isolatedWorld->vm());
     112
     113    ScriptExecutionContext* context = scriptExecutionContext();
     114    if (!context)
     115        return;
     116
     117    ASSERT(context->isDocument());
     118    JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(context, *m_isolatedWorld);
     119    ExecState* state = globalObject->globalExec();
     120
     121    JSObject* jsElement = asObject(toJS(state, globalObject, &element));
     122
     123    PropertyName attributeChanged(Identifier::fromString(state, "attributeChangedCallback"));
     124    JSValue callback = jsElement->get(state, attributeChanged);
     125    CallData callData;
     126    CallType callType = getCallData(callback, callData);
     127    if (callType == CallTypeNone)
     128        return;
     129
     130    const AtomicString& namespaceURI = attributeName.namespaceURI();
     131    MarkedArgumentBuffer args;
     132    args.append(jsStringWithCache(state, attributeName.localName()));
     133    args.append(oldValue == nullAtom ? jsNull() : jsStringWithCache(state, oldValue));
     134    args.append(newValue == nullAtom ? jsNull() : jsStringWithCache(state, newValue));
     135    args.append(namespaceURI == nullAtom ? jsNull() : jsStringWithCache(state, attributeName.namespaceURI()));
     136
     137    InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(context, callType, callData);
     138
     139    NakedPtr<Exception> exception;
     140    JSMainThreadExecState::call(state, callback, callType, callData, jsElement, args, exception);
     141
     142    InspectorInstrumentation::didCallFunction(cookie, context);
     143
     144    if (exception)
     145        reportException(state, exception);
     146}
     147
    104148} // namespace WebCore
    105149
  • trunk/Source/WebCore/bindings/js/JSCustomElementInterface.h

    r197463 r197611  
    5151class JSDOMGlobalObject;
    5252class MathMLElement;
     53class QualifiedName;
    5354class SVGElement;
    5455
     
    6263    enum class ShouldClearException { Clear, DoNotClear };
    6364    RefPtr<Element> constructElement(const AtomicString&, ShouldClearException);
     65
     66    void attributeChanged(Element&, const QualifiedName&, const AtomicString& oldValue, const AtomicString& newValue);
    6467
    6568    ScriptExecutionContext* scriptExecutionContext() const { return ContextDestructionObserver::scriptExecutionContext(); }
  • trunk/Source/WebCore/bindings/js/JSMainThreadExecState.h

    r195538 r197611  
    2828
    2929#include "JSDOMBinding.h"
     30#include "LifecycleCallbackQueue.h"
    3031#include <runtime/Completion.h>
    3132#include <runtime/Microtask.h>
     
    147148private:
    148149    JSC::ExecState* m_previousState;
     150#if ENABLE(CUSTOM_ELEMENTS)
     151    CustomElementLifecycleProcessingStack m_lifecycleProcessingStack;
     152#endif
    149153};
    150154
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r197353 r197611  
    29142914            $implIncludes{"<runtime/Error.h>"} = 1;
    29152915
     2916            if ($function->signature->extendedAttributes->{"InvokesCustomElementLifecycleCallbacks"}) {
     2917                push(@implContent, "#if ENABLE(CUSTOM_ELEMENTS)\n");
     2918                push(@implContent, "    CustomElementLifecycleProcessingStack customElementLifecycleProcessingStack;\n");
     2919                push(@implContent, "#endif\n");
     2920                $implIncludes{"LifecycleCallbackQueue.h"} = 1;
     2921            }
     2922
    29162923            if ($function->isStatic) {
    29172924                if ($isCustom) {
  • trunk/Source/WebCore/bindings/scripts/IDLAttributes.txt

    r197353 r197611  
    9292MasqueradesAsUndefined
    9393NamedConstructor=*
     94InvokesCustomElementLifecycleCallbacks
    9495NewImpurePropertyFiresWatchpoints
    9596NewObject
  • trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp

    r197353 r197611  
    4646#include "JSTestSubObj.h"
    4747#include "JSbool.h"
     48#include "LifecycleCallbackQueue.h"
    4849#include "SVGDocument.h"
    4950#include "SVGPoint.h"
     
    186187JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionTestPromiseFunctionWithException(JSC::ExecState*);
    187188JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionTestPromiseFunctionWithOptionalIntArgument(JSC::ExecState*);
     189JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithNeedsLifecycleProcessingStack(JSC::ExecState*);
    188190JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionSymbolIterator(JSC::ExecState*);
    189191JSC::EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionEntries(JSC::ExecState*);
     
    714716    { "testPromiseFunctionWithException", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionTestPromiseFunctionWithException), (intptr_t) (0) } },
    715717    { "testPromiseFunctionWithOptionalIntArgument", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionTestPromiseFunctionWithOptionalIntArgument), (intptr_t) (0) } },
     718    { "methodWithNeedsLifecycleProcessingStack", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionMethodWithNeedsLifecycleProcessingStack), (intptr_t) (0) } },
    716719    { "entries", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionEntries), (intptr_t) (0) } },
    717720    { "keys", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestObjPrototypeFunctionKeys), (intptr_t) (0) } },
     
    50225025}
    50235026
     5027EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionMethodWithNeedsLifecycleProcessingStack(ExecState* state)
     5028{
     5029#if ENABLE(CUSTOM_ELEMENTS)
     5030    CustomElementLifecycleProcessingStack customElementLifecycleProcessingStack;
     5031#endif
     5032    JSValue thisValue = state->thisValue();
     5033    auto castedThis = jsDynamicCast<JSTestObj*>(thisValue);
     5034    if (UNLIKELY(!castedThis))
     5035        return throwThisTypeError(*state, "TestObj", "methodWithNeedsLifecycleProcessingStack");
     5036    ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     5037    auto& impl = castedThis->wrapped();
     5038    impl.methodWithNeedsLifecycleProcessingStack();
     5039    return JSValue::encode(jsUndefined());
     5040}
     5041
    50245042using TestObjIterator = JSKeyValueIterator<JSTestObj>;
    50255043using TestObjIteratorPrototype = JSKeyValueIteratorPrototype<JSTestObj>;
  • trunk/Source/WebCore/bindings/scripts/test/TestObj.idl

    r197353 r197611  
    333333    [PutForwards=name] readonly attribute TestNode putForwardsAttribute;
    334334    [PutForwards=name] readonly attribute TestNode? putForwardsNullableAttribute;
     335
     336#if defined(TESTING_JS)
     337    [NeedsLifecycleProcessingStack] void methodWithNeedsLifecycleProcessingStack();
     338#endif
    335339};
    336340
  • trunk/Source/WebCore/dom/DOMAllInOne.cpp

    r193286 r197611  
    9494#include "InlineStyleSheetOwner.cpp"
    9595#include "KeyboardEvent.cpp"
     96#include "LifecycleCallbackQueue.cpp"
    9697#include "LiveNodeList.cpp"
    9798#include "MessageChannel.cpp"
  • trunk/Source/WebCore/dom/Element.cpp

    r197478 r197611  
    3838#include "ComposedTreeAncestorIterator.h"
    3939#include "ContainerNodeAlgorithms.h"
     40#include "CustomElementDefinitions.h"
    4041#include "DOMTokenList.h"
    4142#include "Dictionary.h"
     
    6263#include "JSLazyEventListener.h"
    6364#include "KeyboardEvent.h"
     65#include "LifecycleCallbackQueue.h"
    6466#include "MainFrame.h"
    6567#include "MutationObserverInterestGroup.h"
     
    12631265    document().incDOMTreeVersion();
    12641266
     1267#if ENABLE(CUSTOM_ELEMENTS)
     1268    if (UNLIKELY(isCustomElement())) {
     1269        auto* definitions = document().customElementDefinitions();
     1270        auto* interface = definitions->findInterface(tagQName());
     1271        RELEASE_ASSERT(interface);
     1272        LifecycleCallbackQueue::enqueueAttributeChangedCallback(*this, *interface, name, oldValue, newValue);
     1273    }
     1274#endif
     1275
    12651276    if (valueIsSameAsBefore)
    12661277        return;
  • trunk/Source/WebCore/dom/Element.idl

    r197353 r197611  
    2929
    3030    DOMString? getAttribute([Default=Undefined] optional DOMString name);
    31     [ObjCLegacyUnnamedParameters, RaisesException] void setAttribute([Default=Undefined] optional DOMString name,
    32                                      [Default=Undefined] optional DOMString value);
    33     void removeAttribute([Default=Undefined] optional DOMString name);
     31
     32    [ObjCLegacyUnnamedParameters, RaisesException, InvokesCustomElementLifecycleCallbacks]
     33    void setAttribute([Default=Undefined] optional DOMString name, [Default=Undefined] optional DOMString value);
     34
     35    [InvokesCustomElementLifecycleCallbacks] void removeAttribute([Default=Undefined] optional DOMString name);
    3436    Attr getAttributeNode([Default=Undefined] optional DOMString name);
    35     [RaisesException] Attr setAttributeNode([Default=Undefined] optional Attr newAttr);
    36     [RaisesException] Attr removeAttributeNode([Default=Undefined] optional Attr oldAttr);
     37    [RaisesException, InvokesCustomElementLifecycleCallbacks] Attr setAttributeNode([Default=Undefined] optional Attr newAttr);
     38    [RaisesException, InvokesCustomElementLifecycleCallbacks] Attr removeAttributeNode([Default=Undefined] optional Attr oldAttr);
    3739
    3840#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
     
    5153
    5254    [ObjCLegacyUnnamedParameters] DOMString? getAttributeNS([Default=Undefined] optional DOMString? namespaceURI, [Default=Undefined] optional DOMString localName);
    53     [ObjCLegacyUnnamedParameters, RaisesException] void setAttributeNS([Default=Undefined] optional DOMString? namespaceURI,
    54         [Default=Undefined] optional DOMString qualifiedName,
    55         [Default=Undefined] optional DOMString value);
    56     [ObjCLegacyUnnamedParameters] void removeAttributeNS(DOMString? namespaceURI, DOMString localName);
     55
     56    [ObjCLegacyUnnamedParameters, RaisesException, InvokesCustomElementLifecycleCallbacks]
     57    void setAttributeNS([Default=Undefined] optional DOMString? namespaceURI,
     58        [Default=Undefined] optional DOMString qualifiedName, [Default=Undefined] optional DOMString value);
     59
     60    [ObjCLegacyUnnamedParameters, InvokesCustomElementLifecycleCallbacks] void removeAttributeNS(DOMString? namespaceURI, DOMString localName);
    5761
    5862#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
     
    6266#endif
    6367    [ObjCLegacyUnnamedParameters] Attr getAttributeNodeNS([Default=Undefined] optional DOMString? namespaceURI, [Default=Undefined] optional DOMString localName);
    64     [RaisesException] Attr setAttributeNodeNS([Default=Undefined] optional Attr newAttr);
     68    [RaisesException, InvokesCustomElementLifecycleCallbacks] Attr setAttributeNodeNS([Default=Undefined] optional Attr newAttr);
    6569    boolean hasAttribute(DOMString name);
    6670    [ObjCLegacyUnnamedParameters] boolean hasAttributeNS([Default=Undefined] optional DOMString? namespaceURI, [Default=Undefined] optional DOMString localName);
Note: See TracChangeset for help on using the changeset viewer.