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