Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : /**
8 : * A fake content node class so that the image frame for
9 : * content: url(foo);
10 : * in CSS can have an nsIImageLoadingContent but use an
11 : * imgIRequest that's already been loaded from the style system.
12 : */
13 :
14 : #include "nsContentCreatorFunctions.h"
15 : #include "nsXMLElement.h"
16 : #include "nsImageLoadingContent.h"
17 : #include "imgIRequest.h"
18 : #include "mozilla/BasicEvents.h"
19 : #include "mozilla/EventDispatcher.h"
20 : #include "mozilla/EventStates.h"
21 :
22 : using namespace mozilla;
23 :
24 : class nsGenConImageContent final : public nsXMLElement,
25 : public nsImageLoadingContent
26 : {
27 : public:
28 0 : explicit nsGenConImageContent(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
29 0 : : nsXMLElement(aNodeInfo)
30 : {
31 : // nsImageLoadingContent starts out broken, so we start out
32 : // suppressed to match it.
33 0 : AddStatesSilently(NS_EVENT_STATE_SUPPRESSED);
34 0 : }
35 :
36 0 : nsresult Init(imgRequestProxy* aImageRequest)
37 : {
38 : // No need to notify, since we have no frame.
39 0 : return UseAsPrimaryRequest(aImageRequest, false, eImageLoadType_Normal);
40 : }
41 :
42 : // nsIContent overrides
43 : virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
44 : nsIContent* aBindingParent,
45 : bool aCompileEventHandlers) override;
46 : virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
47 : virtual EventStates IntrinsicState() const override;
48 :
49 0 : virtual nsresult GetEventTargetParent(EventChainPreVisitor& aVisitor) override
50 : {
51 0 : MOZ_ASSERT(IsInNativeAnonymousSubtree());
52 0 : if (aVisitor.mEvent->mMessage == eLoad ||
53 0 : aVisitor.mEvent->mMessage == eLoadError) {
54 : // Don't propagate the events to the parent.
55 0 : return NS_OK;
56 : }
57 0 : return nsXMLElement::GetEventTargetParent(aVisitor);
58 : }
59 :
60 : protected:
61 0 : nsIContent* AsContent() override { return this; }
62 :
63 : private:
64 : virtual ~nsGenConImageContent();
65 :
66 : public:
67 : NS_DECL_ISUPPORTS_INHERITED
68 : };
69 :
70 0 : NS_IMPL_ISUPPORTS_INHERITED(nsGenConImageContent,
71 : nsXMLElement,
72 : nsIImageLoadingContent,
73 : imgINotificationObserver,
74 : imgIOnloadBlocker)
75 :
76 : nsresult
77 0 : NS_NewGenConImageContent(nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
78 : imgRequestProxy* aImageRequest)
79 : {
80 0 : NS_PRECONDITION(aImageRequest, "Must have request!");
81 0 : nsGenConImageContent *it = new nsGenConImageContent(aNodeInfo);
82 0 : NS_ADDREF(*aResult = it);
83 0 : nsresult rv = it->Init(aImageRequest);
84 0 : if (NS_FAILED(rv))
85 0 : NS_RELEASE(*aResult);
86 0 : return rv;
87 : }
88 :
89 0 : nsGenConImageContent::~nsGenConImageContent()
90 : {
91 0 : DestroyImageLoadingContent();
92 0 : }
93 :
94 : nsresult
95 0 : nsGenConImageContent::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
96 : nsIContent* aBindingParent,
97 : bool aCompileEventHandlers)
98 : {
99 : nsresult rv;
100 0 : rv = nsXMLElement::BindToTree(aDocument, aParent, aBindingParent,
101 0 : aCompileEventHandlers);
102 0 : NS_ENSURE_SUCCESS(rv, rv);
103 :
104 0 : nsImageLoadingContent::BindToTree(aDocument, aParent, aBindingParent,
105 0 : aCompileEventHandlers);
106 0 : return NS_OK;
107 : }
108 :
109 : void
110 0 : nsGenConImageContent::UnbindFromTree(bool aDeep, bool aNullParent)
111 : {
112 0 : nsImageLoadingContent::UnbindFromTree(aDeep, aNullParent);
113 0 : nsXMLElement::UnbindFromTree(aDeep, aNullParent);
114 0 : }
115 :
116 : EventStates
117 0 : nsGenConImageContent::IntrinsicState() const
118 : {
119 0 : EventStates state = nsXMLElement::IntrinsicState();
120 :
121 0 : EventStates imageState = nsImageLoadingContent::ImageState();
122 0 : if (imageState.HasAtLeastOneOfStates(NS_EVENT_STATE_BROKEN | NS_EVENT_STATE_USERDISABLED)) {
123 : // We should never be in an error state; if the image fails to load, we
124 : // just go to the suppressed state.
125 0 : imageState |= NS_EVENT_STATE_SUPPRESSED;
126 0 : imageState &= ~NS_EVENT_STATE_BROKEN;
127 : }
128 0 : imageState &= ~NS_EVENT_STATE_LOADING;
129 0 : return state | imageState;
130 : }
|