зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1733238) for causing hybrid build bustages. CLOSED TREE
Backed out changeset 7753b03a092a (bug 1733238) Backed out changeset 352c6a7ae5cd (bug 1733238) Backed out changeset 9c132ebfabb2 (bug 1733238)
This commit is contained in:
Родитель
e31b5644cc
Коммит
a373e25460
|
@ -365,6 +365,25 @@ void nsAccessibilityService::FireAccessibleEvent(uint32_t aEvent,
|
|||
nsEventShell::FireEvent(aEvent, aTarget);
|
||||
}
|
||||
|
||||
void nsAccessibilityService::NotifyOfImageSizeAvailable(
|
||||
mozilla::PresShell* aPresShell, nsIContent* aContent) {
|
||||
// If the size of an image is initially unknown, it will have the invisible
|
||||
// state (and a 0 width and height), causing it to be ignored by some screen
|
||||
// readers. Fire a state change event to update any client caches.
|
||||
DocAccessible* document = GetDocAccessible(aPresShell);
|
||||
if (document) {
|
||||
LocalAccessible* accessible = document->GetAccessible(aContent);
|
||||
// The accessible may not be an ImageAccessible if this was previously a
|
||||
// broken image with an alt attribute. In that case, do nothing; the
|
||||
// accessible will be recreated if this becomes a valid image.
|
||||
if (accessible && accessible->IsImage()) {
|
||||
RefPtr<AccEvent> event =
|
||||
new AccStateChangeEvent(accessible, states::INVISIBLE, false);
|
||||
document->FireDelayedEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsAccessibilityService::NotifyOfPossibleBoundsChange(
|
||||
mozilla::PresShell* aPresShell, nsIContent* aContent) {
|
||||
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
|
||||
|
|
|
@ -221,6 +221,15 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
|
|||
|
||||
void FireAccessibleEvent(uint32_t aEvent, LocalAccessible* aTarget);
|
||||
|
||||
/**
|
||||
* Notify accessibility that the size has become available for an image.
|
||||
* This occurs when the size of an image is initially not known, but we've
|
||||
* now loaded enough data to know the size.
|
||||
* Called by layout.
|
||||
*/
|
||||
void NotifyOfImageSizeAvailable(mozilla::PresShell* aPresShell,
|
||||
nsIContent* aContent);
|
||||
|
||||
void NotifyOfPossibleBoundsChange(mozilla::PresShell* aPresShell,
|
||||
nsIContent* aContent);
|
||||
|
||||
|
|
|
@ -23,27 +23,13 @@
|
|||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(ImageAccessible, LinkableAccessible,
|
||||
imgINotificationObserver)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ImageAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ImageAccessible::ImageAccessible(nsIContent* aContent, DocAccessible* aDoc)
|
||||
: LinkableAccessible(aContent, aDoc),
|
||||
mImageRequestStatus(imgIRequest::STATUS_NONE) {
|
||||
: LinkableAccessible(aContent, aDoc) {
|
||||
mType = eImageType;
|
||||
nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mContent));
|
||||
if (content) {
|
||||
content->AddNativeObserver(this);
|
||||
nsCOMPtr<imgIRequest> imageRequest;
|
||||
content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
getter_AddRefs(imageRequest));
|
||||
if (imageRequest) {
|
||||
imageRequest->GetImageStatus(&mImageRequestStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImageAccessible::~ImageAccessible() {}
|
||||
|
@ -51,34 +37,43 @@ ImageAccessible::~ImageAccessible() {}
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// LocalAccessible public
|
||||
|
||||
void ImageAccessible::Shutdown() {
|
||||
nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mContent));
|
||||
if (content) {
|
||||
content->RemoveNativeObserver(this);
|
||||
}
|
||||
|
||||
LinkableAccessible::Shutdown();
|
||||
}
|
||||
|
||||
uint64_t ImageAccessible::NativeState() const {
|
||||
// The state is a bitfield, get our inherited state, then logically OR it with
|
||||
// states::ANIMATED if this is an animated image.
|
||||
|
||||
uint64_t state = LinkableAccessible::NativeState();
|
||||
|
||||
if (mImageRequestStatus & imgIRequest::STATUS_IS_ANIMATED) {
|
||||
state |= states::ANIMATED;
|
||||
nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mContent));
|
||||
nsCOMPtr<imgIRequest> imageRequest;
|
||||
|
||||
if (content) {
|
||||
content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
getter_AddRefs(imageRequest));
|
||||
}
|
||||
|
||||
if (!(mImageRequestStatus & imgIRequest::STATUS_SIZE_AVAILABLE)) {
|
||||
if (imageRequest) {
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
imageRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
if (imgContainer) {
|
||||
bool animated = false;
|
||||
imgContainer->GetAnimated(&animated);
|
||||
if (animated) {
|
||||
state |= states::ANIMATED;
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame* frame = GetFrame();
|
||||
MOZ_ASSERT(!frame || frame->AccessibleType() == eImageType ||
|
||||
frame->AccessibleType() == a11y::eHTMLImageMapType);
|
||||
if (frame && !(frame->GetStateBits() & IMAGE_SIZECONSTRAINED)) {
|
||||
// The size of this image hasn't been constrained and we haven't loaded
|
||||
// enough of the image to know its size yet. This means it currently
|
||||
// has 0 width and height.
|
||||
state |= states::INVISIBLE;
|
||||
uint32_t status = imgIRequest::STATUS_NONE;
|
||||
imageRequest->GetImageStatus(&status);
|
||||
if (!(status & imgIRequest::STATUS_SIZE_AVAILABLE)) {
|
||||
// The size of this image hasn't been constrained and we haven't loaded
|
||||
// enough of the image to know its size yet. This means it currently
|
||||
// has 0 width and height.
|
||||
state |= states::INVISIBLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,42 +200,3 @@ already_AddRefed<nsIURI> ImageAccessible::GetLongDescURI() const {
|
|||
bool ImageAccessible::IsLongDescIndex(uint8_t aIndex) const {
|
||||
return aIndex == LinkableAccessible::ActionCount();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// imgINotificationObserver
|
||||
|
||||
void ImageAccessible::Notify(imgIRequest* aRequest, int32_t aType,
|
||||
const nsIntRect* aData) {
|
||||
if (aType != imgINotificationObserver::FRAME_COMPLETE &&
|
||||
aType != imgINotificationObserver::LOAD_COMPLETE &&
|
||||
aType != imgINotificationObserver::DECODE_COMPLETE) {
|
||||
// We should update our state if the whole image was decoded,
|
||||
// or the first frame in the case of a gif.
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsDefunct() || !mParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t status = imgIRequest::STATUS_NONE;
|
||||
aRequest->GetImageStatus(&status);
|
||||
|
||||
if ((status ^ mImageRequestStatus) & imgIRequest::STATUS_SIZE_AVAILABLE) {
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (frame && !(frame->GetStateBits() & IMAGE_SIZECONSTRAINED)) {
|
||||
RefPtr<AccEvent> event = new AccStateChangeEvent(
|
||||
this, states::INVISIBLE,
|
||||
!(status & imgIRequest::STATUS_SIZE_AVAILABLE));
|
||||
mDoc->FireDelayedEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
if ((status ^ mImageRequestStatus) & imgIRequest::STATUS_IS_ANIMATED) {
|
||||
RefPtr<AccEvent> event = new AccStateChangeEvent(
|
||||
this, states::ANIMATED, (status & imgIRequest::STATUS_IS_ANIMATED));
|
||||
mDoc->FireDelayedEvent(event);
|
||||
}
|
||||
|
||||
mImageRequestStatus = status;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#define mozilla_a11y_ImageAccessible_h__
|
||||
|
||||
#include "BaseAccessibles.h"
|
||||
#include "imgINotificationObserver.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
@ -17,16 +16,11 @@ namespace a11y {
|
|||
* - gets name, role
|
||||
* - support basic state
|
||||
*/
|
||||
class ImageAccessible : public LinkableAccessible,
|
||||
public imgINotificationObserver {
|
||||
class ImageAccessible : public LinkableAccessible {
|
||||
public:
|
||||
ImageAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_IMGINOTIFICATIONOBSERVER
|
||||
|
||||
// LocalAccessible
|
||||
virtual void Shutdown() override;
|
||||
virtual a11y::role NativeRole() const override;
|
||||
virtual uint64_t NativeState() const override;
|
||||
virtual already_AddRefed<AccAttributes> NativeAttributes() override;
|
||||
|
@ -72,8 +66,6 @@ class ImageAccessible : public LinkableAccessible,
|
|||
* @returns true if index is valid for longdesc action.
|
||||
*/
|
||||
inline bool IsLongDescIndex(uint8_t aIndex) const;
|
||||
|
||||
uint32_t mImageRequestStatus;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
support-files =
|
||||
../../../dom/media/test/bug461281.ogg
|
||||
../../../dom/security/test/csp/dummy.pdf
|
||||
../../../image/test/mochitest/animated-gif-finalframe.gif
|
||||
../../../image/test/mochitest/animated-gif.gif
|
||||
dumbfile.zip
|
||||
formimage.png
|
||||
letters.gif
|
||||
|
|
|
@ -2,11 +2,8 @@
|
|||
support-files =
|
||||
focus.html
|
||||
scroll.html
|
||||
slow_image.sjs
|
||||
!/accessible/tests/mochitest/*.js
|
||||
!/accessible/tests/mochitest/letters.gif
|
||||
!/image/test/mochitest/animated-gif-finalframe.gif
|
||||
!/image/test/mochitest/animated-gif.gif
|
||||
|
||||
[test_announcement.html]
|
||||
[test_aria_alert.html]
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
// small red image
|
||||
const IMG_BYTES = atob(
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12" +
|
||||
"P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
|
||||
);
|
||||
|
||||
// stolen from file_blocked_script.sjs
|
||||
function setGlobalState(data, key) {
|
||||
x = { data: data, QueryInterface: function(iid) { return this } };
|
||||
x.wrappedJSObject = x;
|
||||
setObjectState(key, x);
|
||||
}
|
||||
|
||||
function getGlobalState(key) {
|
||||
var data;
|
||||
getObjectState(key, function(x) {
|
||||
data = x && x.wrappedJSObject.data;
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
function handleRequest(request, response) {
|
||||
if (request.queryString == "complete") {
|
||||
// Unblock the previous request.
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "application/json", false);
|
||||
response.write("true"); // the payload doesn't matter.
|
||||
|
||||
let blockedResponse = getGlobalState("a11y-image");
|
||||
if (blockedResponse) {
|
||||
blockedResponse.setStatusLine(request.httpVersion, 200, "OK");
|
||||
blockedResponse.setHeader("Cache-Control", "no-cache", false);
|
||||
blockedResponse.setHeader("Content-Type", "image/png", false);
|
||||
blockedResponse.write(IMG_BYTES);
|
||||
blockedResponse.finish();
|
||||
|
||||
setGlobalState(undefined, "a11y-image");
|
||||
}
|
||||
} else {
|
||||
// Getting the image
|
||||
response.processAsync();
|
||||
// Store the response in the global state
|
||||
setGlobalState(response, "a11y-image");
|
||||
}
|
||||
}
|
|
@ -229,47 +229,6 @@
|
|||
"article is READONLY and not EDITABLE");
|
||||
}
|
||||
|
||||
async function testAnimatedImage() {
|
||||
testStates("animated-image",
|
||||
STATE_ANIMATED, 0,
|
||||
0, 0,
|
||||
"image should be animated 1");
|
||||
let p = waitForEvent(...stateChange(STATE_ANIMATED, false, false, "animated-image"));
|
||||
getNode("animated-image").src = "../animated-gif-finalframe.gif";
|
||||
await p;
|
||||
testStates("animated-image",
|
||||
0, 0,
|
||||
STATE_ANIMATED, 0,
|
||||
"image should not be animated 2");
|
||||
p = waitForEvent(...stateChange(STATE_ANIMATED, false, true, "animated-image"));
|
||||
getNode("animated-image").src = "../animated-gif.gif";
|
||||
await p;
|
||||
testStates("animated-image",
|
||||
STATE_ANIMATED, 0,
|
||||
0, 0,
|
||||
"image should be animated 3");
|
||||
}
|
||||
|
||||
async function testImageLoad() {
|
||||
let img = document.createElement("img");
|
||||
img.id = "image";
|
||||
img.src = "http://example.com/a11y/accessible/tests/mochitest/events/slow_image.sjs";
|
||||
let p = waitForEvent(EVENT_SHOW, "image");
|
||||
getNode("eventdump").before(img);
|
||||
await p;
|
||||
testStates("image",
|
||||
STATE_INVISIBLE, 0,
|
||||
0, 0,
|
||||
"image should be invisible");
|
||||
p = waitForEvent(...stateChange(STATE_INVISIBLE, false, false, "image"));
|
||||
await fetch("http://example.com/a11y/accessible/tests/mochitest/events/slow_image.sjs?complete");
|
||||
await p;
|
||||
testStates("image",
|
||||
0, 0,
|
||||
STATE_INVISIBLE, 0,
|
||||
"image should be invisible");
|
||||
}
|
||||
|
||||
async function doTests() {
|
||||
// Test opening details objects
|
||||
await openNode("detailsOpen", "summaryOpen", true);
|
||||
|
@ -327,10 +286,6 @@
|
|||
|
||||
await testDefaultSubmitChange();
|
||||
|
||||
await testAnimatedImage();
|
||||
|
||||
await testImageLoad();
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
@ -430,13 +385,6 @@
|
|||
|
||||
<div id="article" role="article">hello</div>
|
||||
|
||||
<form id="form">
|
||||
<button id="default-button">hello</button>
|
||||
<button>world</button>
|
||||
</form>
|
||||
|
||||
<img id="animated-image" src="../animated-gif.gif">
|
||||
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<button id="popupButton">action</button>
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
// State constants
|
||||
|
||||
// const STATE_BUSY is defined in common.js
|
||||
const STATE_ANIMATED = nsIAccessibleStates.STATE_ANIMATED;
|
||||
const STATE_CHECKED = nsIAccessibleStates.STATE_CHECKED;
|
||||
const STATE_CHECKABLE = nsIAccessibleStates.STATE_CHECKABLE;
|
||||
const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
|
||||
|
|
|
@ -949,6 +949,13 @@ void nsImageFrame::UpdateImage(imgIRequest* aRequest, imgIContainer* aImage) {
|
|||
// Now we need to reflow if we have an unconstrained size and have
|
||||
// already gotten the initial reflow.
|
||||
if (!(mState & IMAGE_SIZECONSTRAINED)) {
|
||||
#ifdef ACCESSIBILITY
|
||||
if (mKind != Kind::ListStyleImage) {
|
||||
if (nsAccessibilityService* accService = GetAccService()) {
|
||||
accService->NotifyOfImageSizeAvailable(PresShell(), mContent);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
PresShell()->FrameNeedsReflow(this, IntrinsicDirty::StyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
} else if (PresShell()->IsActive()) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче