|
|
|
|
| 10 |
#include "nsCOMPtr.h" |
10 |
#include "nsCOMPtr.h" |
| 11 |
#include "nsIServiceManager.h" |
11 |
#include "nsIServiceManager.h" |
| 12 |
#include "nsGkAtoms.h" |
12 |
#include "nsGkAtoms.h" |
| 13 |
|
13 |
|
| 14 |
#include "nsVideoFrame.h" |
14 |
#include "nsVideoFrame.h" |
| 15 |
#include "nsHTMLVideoElement.h" |
15 |
#include "nsHTMLVideoElement.h" |
| 16 |
#include "nsIDOMHTMLVideoElement.h" |
16 |
#include "nsIDOMHTMLVideoElement.h" |
| 17 |
#include "nsIDOMHTMLImageElement.h" |
17 |
#include "nsIDOMHTMLImageElement.h" |
|
|
18 |
#include "nsIDOMHTMLElement.h" |
| 18 |
#include "nsDisplayList.h" |
19 |
#include "nsDisplayList.h" |
| 19 |
#include "gfxContext.h" |
20 |
#include "gfxContext.h" |
| 20 |
#include "gfxImageSurface.h" |
21 |
#include "gfxImageSurface.h" |
| 21 |
#include "nsPresContext.h" |
22 |
#include "nsPresContext.h" |
| 22 |
#include "nsTransform2D.h" |
23 |
#include "nsTransform2D.h" |
| 23 |
#include "nsContentCreatorFunctions.h" |
24 |
#include "nsContentCreatorFunctions.h" |
| 24 |
#include "nsBoxLayoutState.h" |
25 |
#include "nsBoxLayoutState.h" |
| 25 |
#include "nsBoxFrame.h" |
26 |
#include "nsBoxFrame.h" |
|
Lines 58-83
NS_QUERYFRAME_HEAD(nsVideoFrame)
|
Link Here
|
|---|
|
| 58 |
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator) |
59 |
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator) |
| 59 |
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) |
60 |
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame) |
| 60 |
|
61 |
|
| 61 |
nsresult |
62 |
nsresult |
| 62 |
nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) |
63 |
nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements) |
| 63 |
{ |
64 |
{ |
| 64 |
nsNodeInfoManager *nodeInfoManager = GetContent()->GetCurrentDoc()->NodeInfoManager(); |
65 |
nsNodeInfoManager *nodeInfoManager = GetContent()->GetCurrentDoc()->NodeInfoManager(); |
| 65 |
nsCOMPtr<nsINodeInfo> nodeInfo; |
66 |
nsCOMPtr<nsINodeInfo> nodeInfo; |
|
|
67 |
Element *element; |
| 68 |
|
| 66 |
if (HasVideoElement()) { |
69 |
if (HasVideoElement()) { |
| 67 |
// Create an anonymous image element as a child to hold the poster |
70 |
// Create an anonymous image element as a child to hold the poster |
| 68 |
// image. We may not have a poster image now, but one could be added |
71 |
// image. We may not have a poster image now, but one could be added |
| 69 |
// before we load, or on a subsequent load. |
72 |
// before we load, or on a subsequent load. |
| 70 |
nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::img, |
73 |
nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::img, |
| 71 |
nullptr, |
74 |
nullptr, |
| 72 |
kNameSpaceID_XHTML, |
75 |
kNameSpaceID_XHTML, |
| 73 |
nsIDOMNode::ELEMENT_NODE); |
76 |
nsIDOMNode::ELEMENT_NODE); |
| 74 |
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); |
77 |
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); |
| 75 |
Element* element = NS_NewHTMLImageElement(nodeInfo.forget()); |
78 |
element = NS_NewHTMLImageElement(nodeInfo.forget()); |
| 76 |
mPosterImage = element; |
79 |
mPosterImage = element; |
| 77 |
NS_ENSURE_TRUE(mPosterImage, NS_ERROR_OUT_OF_MEMORY); |
80 |
NS_ENSURE_TRUE(mPosterImage, NS_ERROR_OUT_OF_MEMORY); |
| 78 |
|
81 |
|
| 79 |
// Push a null JSContext on the stack so that code that runs |
82 |
// Push a null JSContext on the stack so that code that runs |
| 80 |
// within the below code doesn't think it's being called by |
83 |
// within the below code doesn't think it's being called by |
| 81 |
// JS. See bug 604262. |
84 |
// JS. See bug 604262. |
| 82 |
nsCxPusher pusher; |
85 |
nsCxPusher pusher; |
| 83 |
pusher.PushNull(); |
86 |
pusher.PushNull(); |
|
Lines 107-136
nsVideoFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
|
Link Here
|
|---|
|
| 107 |
kNameSpaceID_XUL, |
110 |
kNameSpaceID_XUL, |
| 108 |
nsIDOMNode::ELEMENT_NODE); |
111 |
nsIDOMNode::ELEMENT_NODE); |
| 109 |
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); |
112 |
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); |
| 110 |
|
113 |
|
| 111 |
NS_TrustedNewXULElement(getter_AddRefs(mVideoControls), nodeInfo.forget()); |
114 |
NS_TrustedNewXULElement(getter_AddRefs(mVideoControls), nodeInfo.forget()); |
| 112 |
if (!aElements.AppendElement(mVideoControls)) |
115 |
if (!aElements.AppendElement(mVideoControls)) |
| 113 |
return NS_ERROR_OUT_OF_MEMORY; |
116 |
return NS_ERROR_OUT_OF_MEMORY; |
| 114 |
|
117 |
|
|
|
118 |
// Set up the caption overlay div for showing any TextTrack data |
| 119 |
nodeInfo = nodeInfoManager->GetNodeInfo(nsGkAtoms::div, |
| 120 |
nullptr, |
| 121 |
kNameSpaceID_XHTML, |
| 122 |
nsIDOMNode::ELEMENT_NODE); |
| 123 |
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY); |
| 124 |
element = NS_NewHTMLDivElement(nodeInfo.forget()); |
| 125 |
mCaptionDiv = element; |
| 126 |
NS_ENSURE_TRUE(mCaptionDiv, NS_ERROR_OUT_OF_MEMORY); |
| 127 |
// hang a class name on the div for default styling |
| 128 |
nsresult rv = mCaptionDiv->SetAttr(kNameSpaceID_None, |
| 129 |
nsGkAtoms::_class, |
| 130 |
NS_LITERAL_STRING("captionDiv"), |
| 131 |
true); |
| 132 |
NS_ENSURE_SUCCESS(rv, rv); |
| 133 |
|
| 134 |
if (!aElements.AppendElement(mCaptionDiv)) |
| 135 |
return NS_ERROR_OUT_OF_MEMORY; |
| 136 |
|
| 137 |
// add a test string so we can test the div |
| 138 |
nsCOMPtr<nsIDOMHTMLElement> div = do_QueryInterface(mCaptionDiv); |
| 139 |
rv = div->SetInnerHTML(NS_LITERAL_STRING("<p>Lorem ipsum dolor</p>")); |
| 140 |
NS_ENSURE_SUCCESS(rv, rv); |
| 141 |
|
| 115 |
return NS_OK; |
142 |
return NS_OK; |
| 116 |
} |
143 |
} |
| 117 |
|
144 |
|
| 118 |
void |
145 |
void |
| 119 |
nsVideoFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, |
146 |
nsVideoFrame::AppendAnonymousContentTo(nsBaseContentList& aElements, |
| 120 |
uint32_t aFliter) |
147 |
uint32_t aFliter) |
| 121 |
{ |
148 |
{ |
| 122 |
aElements.MaybeAppendElement(mPosterImage); |
149 |
aElements.MaybeAppendElement(mPosterImage); |
| 123 |
aElements.MaybeAppendElement(mVideoControls); |
150 |
aElements.MaybeAppendElement(mVideoControls); |
|
|
151 |
aElements.MaybeAppendElement(mCaptionDiv); |
| 124 |
} |
152 |
} |
| 125 |
|
153 |
|
| 126 |
void |
154 |
void |
| 127 |
nsVideoFrame::DestroyFrom(nsIFrame* aDestructRoot) |
155 |
nsVideoFrame::DestroyFrom(nsIFrame* aDestructRoot) |
| 128 |
{ |
156 |
{ |
|
|
157 |
nsContentUtils::DestroyAnonymousContent(&mCaptionDiv); |
| 129 |
nsContentUtils::DestroyAnonymousContent(&mVideoControls); |
158 |
nsContentUtils::DestroyAnonymousContent(&mVideoControls); |
| 130 |
nsContentUtils::DestroyAnonymousContent(&mPosterImage); |
159 |
nsContentUtils::DestroyAnonymousContent(&mPosterImage); |
| 131 |
nsContainerFrame::DestroyFrom(aDestructRoot); |
160 |
nsContainerFrame::DestroyFrom(aDestructRoot); |
| 132 |
} |
161 |
} |
| 133 |
|
162 |
|
| 134 |
bool |
163 |
bool |
| 135 |
nsVideoFrame::IsLeaf() const |
164 |
nsVideoFrame::IsLeaf() const |
| 136 |
{ |
165 |
{ |
|
Lines 241-257
nsVideoFrame::Reflow(nsPresContext* aPresContext,
|
Link Here
|
|---|
|
| 241 |
aMetrics.width += mBorderPadding.left + mBorderPadding.right; |
270 |
aMetrics.width += mBorderPadding.left + mBorderPadding.right; |
| 242 |
aMetrics.height += mBorderPadding.top + mBorderPadding.bottom; |
271 |
aMetrics.height += mBorderPadding.top + mBorderPadding.bottom; |
| 243 |
|
272 |
|
| 244 |
// Reflow the child frames. We may have up to two, an image frame |
273 |
// Reflow the child frames. We may have up to two, an image frame |
| 245 |
// which is the poster, and a box frame, which is the video controls. |
274 |
// which is the poster, and a box frame, which is the video controls. |
| 246 |
for (nsIFrame *child = mFrames.FirstChild(); |
275 |
for (nsIFrame *child = mFrames.FirstChild(); |
| 247 |
child; |
276 |
child; |
| 248 |
child = child->GetNextSibling()) { |
277 |
child = child->GetNextSibling()) { |
| 249 |
if (child->GetType() == nsGkAtoms::imageFrame) { |
278 |
if (child->GetContent() == mPosterImage) { |
| 250 |
// Reflow the poster frame. |
279 |
// Reflow the poster frame. |
| 251 |
nsImageFrame* imageFrame = static_cast<nsImageFrame*>(child); |
280 |
nsImageFrame* imageFrame = static_cast<nsImageFrame*>(child); |
| 252 |
nsHTMLReflowMetrics kidDesiredSize; |
281 |
nsHTMLReflowMetrics kidDesiredSize; |
| 253 |
nsSize availableSize = nsSize(aReflowState.availableWidth, |
282 |
nsSize availableSize = nsSize(aReflowState.availableWidth, |
| 254 |
aReflowState.availableHeight); |
283 |
aReflowState.availableHeight); |
| 255 |
nsHTMLReflowState kidReflowState(aPresContext, |
284 |
nsHTMLReflowState kidReflowState(aPresContext, |
| 256 |
aReflowState, |
285 |
aReflowState, |
| 257 |
imageFrame, |
286 |
imageFrame, |
|
Lines 281-305
nsVideoFrame::Reflow(nsPresContext* aPresContext,
|
Link Here
|
|---|
|
| 281 |
kidReflowState.SetComputedHeight(scaledPosterSize.height); |
310 |
kidReflowState.SetComputedHeight(scaledPosterSize.height); |
| 282 |
posterTopLeft.x = ((computedArea.width - scaledPosterSize.width) / 2) + mBorderPadding.left; |
311 |
posterTopLeft.x = ((computedArea.width - scaledPosterSize.width) / 2) + mBorderPadding.left; |
| 283 |
posterTopLeft.y = ((computedArea.height - scaledPosterSize.height) / 2) + mBorderPadding.top; |
312 |
posterTopLeft.y = ((computedArea.height - scaledPosterSize.height) / 2) + mBorderPadding.top; |
| 284 |
|
313 |
|
| 285 |
ReflowChild(imageFrame, aPresContext, kidDesiredSize, kidReflowState, |
314 |
ReflowChild(imageFrame, aPresContext, kidDesiredSize, kidReflowState, |
| 286 |
posterTopLeft.x, posterTopLeft.y, 0, aStatus); |
315 |
posterTopLeft.x, posterTopLeft.y, 0, aStatus); |
| 287 |
FinishReflowChild(imageFrame, aPresContext, &kidReflowState, kidDesiredSize, |
316 |
FinishReflowChild(imageFrame, aPresContext, &kidReflowState, kidDesiredSize, |
| 288 |
posterTopLeft.x, posterTopLeft.y, 0); |
317 |
posterTopLeft.x, posterTopLeft.y, 0); |
| 289 |
} else if (child->GetType() == nsGkAtoms::boxFrame) { |
318 |
} else if (child->GetContent() == mVideoControls) { |
| 290 |
// Reflow the video controls frame. |
319 |
// Reflow the video controls frame. |
| 291 |
nsBoxLayoutState boxState(PresContext(), aReflowState.rendContext); |
320 |
nsBoxLayoutState boxState(PresContext(), aReflowState.rendContext); |
| 292 |
nsBoxFrame::LayoutChildAt(boxState, |
321 |
nsBoxFrame::LayoutChildAt(boxState, |
| 293 |
child, |
322 |
child, |
| 294 |
nsRect(mBorderPadding.left, |
323 |
nsRect(mBorderPadding.left, |
| 295 |
mBorderPadding.top, |
324 |
mBorderPadding.top, |
| 296 |
aReflowState.ComputedWidth(), |
325 |
aReflowState.ComputedWidth(), |
| 297 |
aReflowState.ComputedHeight())); |
326 |
aReflowState.ComputedHeight())); |
|
|
327 |
} else if (child->GetContent() == mCaptionDiv) { |
| 328 |
// Reflow to caption div |
| 329 |
nsHTMLReflowMetrics kidDesiredSize; |
| 330 |
nsSize availableSize = nsSize(aReflowState.availableWidth, |
| 331 |
aReflowState.availableHeight); |
| 332 |
nsHTMLReflowState kidReflowState(aPresContext, |
| 333 |
aReflowState, |
| 334 |
child, |
| 335 |
availableSize, |
| 336 |
aMetrics.width, |
| 337 |
aMetrics.height); |
| 338 |
kidReflowState.SetComputedWidth(aReflowState.ComputedWidth()); |
| 339 |
kidReflowState.SetComputedHeight(aReflowState.ComputedHeight()); |
| 340 |
ReflowChild(child, aPresContext, kidDesiredSize, kidReflowState, |
| 341 |
mBorderPadding.left, mBorderPadding.top, 0, aStatus); |
| 342 |
FinishReflowChild(child, aPresContext, |
| 343 |
&kidReflowState, kidDesiredSize, |
| 344 |
mBorderPadding.left, mBorderPadding.top, 0); |
| 298 |
} |
345 |
} |
| 299 |
} |
346 |
} |
| 300 |
aMetrics.SetOverflowAreasToDesiredBounds(); |
347 |
aMetrics.SetOverflowAreasToDesiredBounds(); |
| 301 |
|
348 |
|
| 302 |
FinishAndStoreOverflow(&aMetrics); |
349 |
FinishAndStoreOverflow(&aMetrics); |
| 303 |
|
350 |
|
| 304 |
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, |
351 |
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, |
| 305 |
("exit nsVideoFrame::Reflow: size=%d,%d", |
352 |
("exit nsVideoFrame::Reflow: size=%d,%d", |
|
Lines 381-407
nsVideoFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
Link Here
|
|---|
|
| 381 |
nsDisplayList replacedContent; |
428 |
nsDisplayList replacedContent; |
| 382 |
|
429 |
|
| 383 |
if (HasVideoElement() && !ShouldDisplayPoster()) { |
430 |
if (HasVideoElement() && !ShouldDisplayPoster()) { |
| 384 |
rv = replacedContent.AppendNewToTop( |
431 |
rv = replacedContent.AppendNewToTop( |
| 385 |
new (aBuilder) nsDisplayVideo(aBuilder, this)); |
432 |
new (aBuilder) nsDisplayVideo(aBuilder, this)); |
| 386 |
NS_ENSURE_SUCCESS(rv, rv); |
433 |
NS_ENSURE_SUCCESS(rv, rv); |
| 387 |
} |
434 |
} |
| 388 |
|
435 |
|
| 389 |
// Add child frames to display list. We expect up to two children, an image |
436 |
// Add child frames to display list. We expect various children, |
| 390 |
// frame for the poster, and the box frame for the video controls. |
437 |
// but only want to draw mPosterImage conditionally. Others we |
|
|
438 |
// always add to the display list. |
| 391 |
for (nsIFrame *child = mFrames.FirstChild(); |
439 |
for (nsIFrame *child = mFrames.FirstChild(); |
| 392 |
child; |
440 |
child; |
| 393 |
child = child->GetNextSibling()) { |
441 |
child = child->GetNextSibling()) { |
| 394 |
if (child->GetType() == nsGkAtoms::imageFrame && ShouldDisplayPoster()) { |
442 |
if (child->GetContent() != mPosterImage || ShouldDisplayPoster()) { |
| 395 |
rv = child->BuildDisplayListForStackingContext(aBuilder, |
|
|
| 396 |
aDirtyRect - child->GetOffsetTo(this), |
| 397 |
&replacedContent); |
| 398 |
NS_ENSURE_SUCCESS(rv,rv); |
| 399 |
} else if (child->GetType() == nsGkAtoms::boxFrame) { |
| 400 |
rv = child->BuildDisplayListForStackingContext(aBuilder, |
443 |
rv = child->BuildDisplayListForStackingContext(aBuilder, |
| 401 |
aDirtyRect - child->GetOffsetTo(this), |
444 |
aDirtyRect - child->GetOffsetTo(this), |
| 402 |
&replacedContent); |
445 |
&replacedContent); |
| 403 |
NS_ENSURE_SUCCESS(rv,rv); |
446 |
NS_ENSURE_SUCCESS(rv,rv); |
| 404 |
} |
447 |
} |
| 405 |
} |
448 |
} |
| 406 |
|
449 |
|
| 407 |
WrapReplacedContentForBorderRadius(aBuilder, &replacedContent, aLists); |
450 |
WrapReplacedContentForBorderRadius(aBuilder, &replacedContent, aLists); |