mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
This commit is contained in:
commit
3018aec902
@ -18,7 +18,7 @@ interface nsIAccessiblePivot;
|
||||
* nsIAccessible for a given DOM node. More documentation at:
|
||||
* http://www.mozilla.org/projects/ui/accessibility
|
||||
*/
|
||||
[scriptable, uuid(310ce77d-c92b-4761-82e8-77e1a728e8d4)]
|
||||
[scriptable, uuid(aed712cb-708b-4caa-981d-767be0fba984)]
|
||||
interface nsIAccessibleRetrieval : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -84,6 +84,16 @@ interface nsIAccessibleRetrieval : nsISupports
|
||||
* @return a new pivot
|
||||
*/
|
||||
nsIAccessiblePivot createAccessiblePivot(in nsIAccessible aRoot);
|
||||
|
||||
/**
|
||||
* Enable logging for the given modules, all other modules aren't logged.
|
||||
*
|
||||
* @param aModules [in] list of modules, format is comma separated list
|
||||
* like 'docload,doccreate'.
|
||||
* @note Works on debug build only.
|
||||
* @see Logging.cpp for list of possible values.
|
||||
*/
|
||||
void setLogging(in ACString aModules);
|
||||
};
|
||||
|
||||
|
||||
|
@ -4,11 +4,17 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef _nsTextAccessibleWrap_H_
|
||||
#define _nsTextAccessibleWrap_H_
|
||||
#ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
#define mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
|
||||
#include "nsTextAccessible.h"
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
typedef class nsTextAccessible nsTextAccessibleWrap;
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class TextLeafAccessible TextLeafAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
487
accessible/src/base/Logging.cpp
Normal file
487
accessible/src/base/Logging.cpp
Normal file
@ -0,0 +1,487 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=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/. */
|
||||
|
||||
#include "Logging.h"
|
||||
|
||||
#include "AccEvent.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
|
||||
#include "nsDocShellLoadTypes.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsTraceRefcntImpl.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "prenv.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Logging helpers
|
||||
|
||||
static PRUint32 sModules = 0;
|
||||
|
||||
struct ModuleRep {
|
||||
const char* mStr;
|
||||
logging::EModules mModule;
|
||||
};
|
||||
|
||||
static void
|
||||
EnableLogging(const char* aModulesStr)
|
||||
{
|
||||
sModules = 0;
|
||||
if (!aModulesStr)
|
||||
return;
|
||||
|
||||
static ModuleRep modules[] = {
|
||||
{ "docload", logging::eDocLoad },
|
||||
{ "doccreate", logging::eDocCreate },
|
||||
{ "docdestroy", logging::eDocDestroy },
|
||||
{ "doclifecycle", logging::eDocLifeCycle }
|
||||
};
|
||||
|
||||
const char* token = aModulesStr;
|
||||
while (*token != '\0') {
|
||||
size_t tokenLen = strcspn(token, ",");
|
||||
for (unsigned int idx = 0; idx < ArrayLength(modules); idx++) {
|
||||
if (strncmp(token, modules[idx].mStr, tokenLen) == 0) {
|
||||
sModules |= modules[idx].mModule;
|
||||
printf("\n\nmodule enabled: %s\n", modules[idx].mStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
token += tokenLen;
|
||||
|
||||
if (*token == ',')
|
||||
token++; // skip ',' char
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LogDocURI(nsIDocument* aDocumentNode)
|
||||
{
|
||||
nsIURI* uri = aDocumentNode->GetDocumentURI();
|
||||
nsCAutoString spec;
|
||||
uri->GetSpec(spec);
|
||||
printf("uri: %s", spec.get());
|
||||
}
|
||||
|
||||
static void
|
||||
LogDocShellState(nsIDocument* aDocumentNode)
|
||||
{
|
||||
printf("docshell busy: ");
|
||||
|
||||
nsCAutoString docShellBusy;
|
||||
nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
|
||||
if (container) {
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
|
||||
PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
|
||||
docShell->GetBusyFlags(&busyFlags);
|
||||
if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE)
|
||||
printf("'none'");
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY)
|
||||
printf("'busy'");
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD)
|
||||
printf(", 'before page load'");
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING)
|
||||
printf(", 'page loading'");
|
||||
} else {
|
||||
printf("[failed]");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LogDocType(nsIDocument* aDocumentNode)
|
||||
{
|
||||
if (aDocumentNode->IsActive()) {
|
||||
bool isContent = nsCoreUtils::IsContentDocument(aDocumentNode);
|
||||
printf("%s document", (isContent ? "content" : "chrome"));
|
||||
} else {
|
||||
printf("document type: [failed]");\
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LogDocShellTree(nsIDocument* aDocumentNode)
|
||||
{
|
||||
if (aDocumentNode->IsActive()) {
|
||||
nsCOMPtr<nsISupports> container = aDocumentNode->GetContainer();
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
|
||||
treeItem->GetParent(getter_AddRefs(parentTreeItem));
|
||||
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
|
||||
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
|
||||
printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;",
|
||||
static_cast<void*>(parentTreeItem), static_cast<void*>(rootTreeItem),
|
||||
(nsCoreUtils::IsTabDocument(aDocumentNode) ? "yes" : "no"));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LogDocState(nsIDocument* aDocumentNode)
|
||||
{
|
||||
const char* docState = nsnull;
|
||||
nsIDocument::ReadyState docStateFlag = aDocumentNode->GetReadyStateEnum();
|
||||
switch (docStateFlag) {
|
||||
case nsIDocument::READYSTATE_UNINITIALIZED:
|
||||
docState = "uninitialized";
|
||||
break;
|
||||
case nsIDocument::READYSTATE_LOADING:
|
||||
docState = "loading";
|
||||
break;
|
||||
case nsIDocument::READYSTATE_INTERACTIVE:
|
||||
docState = "interactive";
|
||||
break;
|
||||
case nsIDocument::READYSTATE_COMPLETE:
|
||||
docState = "complete";
|
||||
break;
|
||||
}
|
||||
|
||||
printf("doc state: %s", docState);
|
||||
printf(", %sinitial", aDocumentNode->IsInitialDocument() ? "" : "not ");
|
||||
printf(", %sshowing", aDocumentNode->IsShowing() ? "" : "not ");
|
||||
printf(", %svisible", aDocumentNode->IsVisible() ? "" : "not ");
|
||||
printf(", %sactive", aDocumentNode->IsActive() ? "" : "not ");
|
||||
}
|
||||
|
||||
static void
|
||||
LogPresShell(nsIDocument* aDocumentNode)
|
||||
{
|
||||
nsIPresShell* ps = aDocumentNode->GetShell();
|
||||
printf("presshell: %p", static_cast<void*>(ps));
|
||||
nsIScrollableFrame *sf = ps ?
|
||||
ps->GetRootScrollFrameAsScrollableExternal() : nsnull;
|
||||
printf(", root scroll frame: %p", static_cast<void*>(sf));
|
||||
}
|
||||
|
||||
static void
|
||||
LogDocLoadGroup(nsIDocument* aDocumentNode)
|
||||
{
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = aDocumentNode->GetDocumentLoadGroup();
|
||||
printf("load group: %p", static_cast<void*>(loadGroup));
|
||||
}
|
||||
|
||||
static void
|
||||
LogDocParent(nsIDocument* aDocumentNode)
|
||||
{
|
||||
nsIDocument* parentDoc = aDocumentNode->GetParentDocument();
|
||||
printf("parent id: %p", static_cast<void*>(parentDoc));
|
||||
if (parentDoc) {
|
||||
printf("\n parent ");
|
||||
LogDocURI(parentDoc);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LogDocInfo(nsIDocument* aDocumentNode, nsDocAccessible* aDocument)
|
||||
{
|
||||
printf(" {\n");
|
||||
|
||||
printf(" DOM id: %p, acc id: %p\n ",
|
||||
static_cast<void*>(aDocumentNode), static_cast<void*>(aDocument));
|
||||
|
||||
// log document info
|
||||
if (aDocumentNode) {
|
||||
LogDocURI(aDocumentNode);
|
||||
printf("\n ");
|
||||
LogDocShellState(aDocumentNode);
|
||||
printf("; ");
|
||||
LogDocType(aDocumentNode);
|
||||
printf("\n ");
|
||||
LogDocShellTree(aDocumentNode);
|
||||
printf("\n ");
|
||||
LogDocState(aDocumentNode);
|
||||
printf("\n ");
|
||||
LogPresShell(aDocumentNode);
|
||||
printf("\n ");
|
||||
LogDocLoadGroup(aDocumentNode);
|
||||
printf(", ");
|
||||
LogDocParent(aDocumentNode);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf(" }\n");
|
||||
}
|
||||
|
||||
static void
|
||||
LogShellLoadType(nsIDocShell* aDocShell)
|
||||
{
|
||||
printf("load type: ");
|
||||
|
||||
PRUint32 loadType = 0;
|
||||
aDocShell->GetLoadType(&loadType);
|
||||
switch (loadType) {
|
||||
case LOAD_NORMAL:
|
||||
printf("normal; ");
|
||||
break;
|
||||
case LOAD_NORMAL_REPLACE:
|
||||
printf("normal replace; ");
|
||||
break;
|
||||
case LOAD_NORMAL_EXTERNAL:
|
||||
printf("normal external; ");
|
||||
break;
|
||||
case LOAD_HISTORY:
|
||||
printf("history; ");
|
||||
break;
|
||||
case LOAD_NORMAL_BYPASS_CACHE:
|
||||
printf("normal bypass cache; ");
|
||||
break;
|
||||
case LOAD_NORMAL_BYPASS_PROXY:
|
||||
printf("normal bypass proxy; ");
|
||||
break;
|
||||
case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE:
|
||||
printf("normal bypass proxy and cache; ");
|
||||
break;
|
||||
case LOAD_RELOAD_NORMAL:
|
||||
printf("reload normal; ");
|
||||
break;
|
||||
case LOAD_RELOAD_BYPASS_CACHE:
|
||||
printf("reload bypass cache; ");
|
||||
break;
|
||||
case LOAD_RELOAD_BYPASS_PROXY:
|
||||
printf("reload bypass proxy; ");
|
||||
break;
|
||||
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
|
||||
printf("reload bypass proxy and cache; ");
|
||||
break;
|
||||
case LOAD_LINK:
|
||||
printf("link; ");
|
||||
break;
|
||||
case LOAD_REFRESH:
|
||||
printf("refresh; ");
|
||||
break;
|
||||
case LOAD_RELOAD_CHARSET_CHANGE:
|
||||
printf("reload charset change; ");
|
||||
break;
|
||||
case LOAD_BYPASS_HISTORY:
|
||||
printf("bypass history; ");
|
||||
break;
|
||||
case LOAD_STOP_CONTENT:
|
||||
printf("stop content; ");
|
||||
break;
|
||||
case LOAD_STOP_CONTENT_AND_REPLACE:
|
||||
printf("stop content and replace; ");
|
||||
break;
|
||||
case LOAD_PUSHSTATE:
|
||||
printf("load pushstate; ");
|
||||
break;
|
||||
case LOAD_ERROR_PAGE:
|
||||
printf("error page;");
|
||||
break;
|
||||
default:
|
||||
printf("unknown");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LogRequest(nsIRequest* aRequest)
|
||||
{
|
||||
if (aRequest) {
|
||||
nsCAutoString name;
|
||||
aRequest->GetName(name);
|
||||
printf(" request spec: %s\n", name.get());
|
||||
PRUint32 loadFlags = 0;
|
||||
aRequest->GetLoadFlags(&loadFlags);
|
||||
printf(" request load flags: %x; ", loadFlags);
|
||||
if (loadFlags & nsIChannel::LOAD_DOCUMENT_URI)
|
||||
printf("document uri; ");
|
||||
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI)
|
||||
printf("retargeted document uri; ");
|
||||
if (loadFlags & nsIChannel::LOAD_REPLACE)
|
||||
printf("replace; ");
|
||||
if (loadFlags & nsIChannel::LOAD_INITIAL_DOCUMENT_URI)
|
||||
printf("initial document uri; ");
|
||||
if (loadFlags & nsIChannel::LOAD_TARGETED)
|
||||
printf("targeted; ");
|
||||
if (loadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS)
|
||||
printf("call content sniffers; ");
|
||||
if (loadFlags & nsIChannel::LOAD_CLASSIFY_URI)
|
||||
printf("classify uri; ");
|
||||
} else {
|
||||
printf(" no request");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
GetDocLoadEventType(AccEvent* aEvent, nsACString& aEventType)
|
||||
{
|
||||
PRUint32 type = aEvent->GetEventType();
|
||||
if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED) {
|
||||
aEventType.AssignLiteral("load stopped");
|
||||
} else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE) {
|
||||
aEventType.AssignLiteral("load complete");
|
||||
} else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD) {
|
||||
aEventType.AssignLiteral("reload");
|
||||
} else if (type == nsIAccessibleEvent::EVENT_STATE_CHANGE) {
|
||||
AccStateChangeEvent* event = downcast_accEvent(aEvent);
|
||||
if (event->GetState() == states::BUSY) {
|
||||
aEventType.AssignLiteral("busy ");
|
||||
if (event->IsStateEnabled())
|
||||
aEventType.AppendLiteral("true");
|
||||
else
|
||||
aEventType.AppendLiteral("false");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// namespace logging:: document life cycle logging methods
|
||||
|
||||
void
|
||||
logging::DocLoad(const char* aMsg, nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, PRUint32 aStateFlags)
|
||||
{
|
||||
printf("\nA11Y DOCLOAD: %s\n", aMsg);
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> DOMWindow;
|
||||
aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow));
|
||||
if (!DOMWindow)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> DOMDocument;
|
||||
DOMWindow->GetDocument(getter_AddRefs(DOMDocument));
|
||||
if (!DOMDocument)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDocument> documentNode(do_QueryInterface(DOMDocument));
|
||||
nsDocAccessible* document =
|
||||
GetAccService()->GetDocAccessibleFromCache(documentNode);
|
||||
|
||||
LogDocInfo(documentNode, document);
|
||||
|
||||
printf(" {\n");
|
||||
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
|
||||
printf(" ");
|
||||
LogShellLoadType(docShell);
|
||||
printf("\n");
|
||||
LogRequest(aRequest);
|
||||
printf("\n");
|
||||
printf(" state flags: %x", aStateFlags);
|
||||
bool isDocLoading;
|
||||
aWebProgress->GetIsLoadingDocument(&isDocLoading);
|
||||
printf(", document is %sloading\n", (isDocLoading ? "" : "not "));
|
||||
printf(" }\n");
|
||||
}
|
||||
|
||||
void
|
||||
logging::DocLoad(const char* aMsg, nsIDocument* aDocumentNode)
|
||||
{
|
||||
printf("\nA11Y DOCLOAD: %s\n", aMsg);
|
||||
|
||||
nsDocAccessible* document =
|
||||
GetAccService()->GetDocAccessibleFromCache(aDocumentNode);
|
||||
LogDocInfo(aDocumentNode, document);
|
||||
}
|
||||
|
||||
void
|
||||
logging::DocLoadEventFired(AccEvent* aEvent)
|
||||
{
|
||||
nsCAutoString strEventType;
|
||||
GetDocLoadEventType(aEvent, strEventType);
|
||||
if (!strEventType.IsEmpty())
|
||||
printf(" fire: %s\n", strEventType.get());
|
||||
}
|
||||
|
||||
void
|
||||
logging::DocLoadEventHandled(AccEvent* aEvent)
|
||||
{
|
||||
nsCAutoString strEventType;
|
||||
GetDocLoadEventType(aEvent, strEventType);
|
||||
if (!strEventType.IsEmpty()) {
|
||||
printf("\nA11Y DOCEVENT: handled '%s' event ", strEventType.get());
|
||||
|
||||
nsINode* node = aEvent->GetNode();
|
||||
if (node->IsNodeOfType(nsINode::eDOCUMENT)) {
|
||||
nsIDocument* documentNode = static_cast<nsIDocument*>(node);
|
||||
nsDocAccessible* document = aEvent->GetDocAccessible();
|
||||
LogDocInfo(documentNode, document);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
logging::DocCreate(const char* aMsg, nsIDocument* aDocumentNode,
|
||||
nsDocAccessible* aDocument)
|
||||
{
|
||||
nsDocAccessible* document = aDocument ?
|
||||
aDocument : GetAccService()->GetDocAccessibleFromCache(aDocumentNode);
|
||||
|
||||
printf("\nA11Y DOCCREATE: %s\n", aMsg);
|
||||
LogDocInfo(aDocumentNode, document);
|
||||
}
|
||||
|
||||
void
|
||||
logging::DocDestroy(const char* aMsg, nsIDocument* aDocumentNode,
|
||||
nsDocAccessible* aDocument)
|
||||
{
|
||||
nsDocAccessible* document = aDocument ?
|
||||
aDocument : GetAccService()->GetDocAccessibleFromCache(aDocumentNode);
|
||||
|
||||
printf("\nA11Y DOCDESTROY: %s\n", aMsg);
|
||||
LogDocInfo(aDocumentNode, document);
|
||||
}
|
||||
|
||||
void
|
||||
logging::Address(const char* aDescr, nsAccessible* aAcc)
|
||||
{
|
||||
nsINode* node = aAcc->GetNode();
|
||||
nsIDocument* docNode = aAcc->GetDocumentNode();
|
||||
nsDocAccessible* doc = GetAccService()->GetDocAccessibleFromCache(docNode);
|
||||
printf(" %s accessible: %p, node: %p\n", aDescr,
|
||||
static_cast<void*>(aAcc), static_cast<void*>(node));
|
||||
printf(" docacc for %s accessible: %p, node: %p\n", aDescr,
|
||||
static_cast<void*>(doc), static_cast<void*>(docNode));
|
||||
printf(" ");
|
||||
LogDocURI(docNode);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
logging::Msg(const char* aMsg)
|
||||
{
|
||||
printf("\n%s\n", aMsg);
|
||||
}
|
||||
|
||||
void
|
||||
logging::Text(const char* aText)
|
||||
{
|
||||
printf(" %s\n", aText);
|
||||
}
|
||||
|
||||
void
|
||||
logging::Stack()
|
||||
{
|
||||
printf(" stack: \n");
|
||||
nsTraceRefcntImpl::WalkTheStack(stdout);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// namespace logging:: initialization
|
||||
|
||||
bool
|
||||
logging::IsEnabled(PRUint32 aModules)
|
||||
{
|
||||
return sModules & aModules;
|
||||
}
|
||||
|
||||
void
|
||||
logging::Enable(const nsAFlatCString& aModules)
|
||||
{
|
||||
EnableLogging(aModules.get());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
logging::CheckEnv()
|
||||
{
|
||||
EnableLogging(PR_GetEnv("A11YLOG"));
|
||||
}
|
101
accessible/src/base/Logging.h
Normal file
101
accessible/src/base/Logging.h
Normal file
@ -0,0 +1,101 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=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/. */
|
||||
|
||||
#ifndef mozilla_a11y_logs_h__
|
||||
#define mozilla_a11y_logs_h__
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsAString.h"
|
||||
|
||||
class AccEvent;
|
||||
class nsAccessible;
|
||||
class nsDocAccessible;
|
||||
class nsIDocument;
|
||||
class nsIRequest;
|
||||
class nsIWebProgress;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
namespace logging {
|
||||
|
||||
enum EModules {
|
||||
eDocLoad = 1 << 0,
|
||||
eDocCreate = 1 << 1,
|
||||
eDocDestroy = 1 << 2,
|
||||
eDocLifeCycle = eDocLoad | eDocCreate | eDocDestroy
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true if the given module is logged.
|
||||
*/
|
||||
bool IsEnabled(PRUint32 aModule);
|
||||
|
||||
/**
|
||||
* Log the document loading progress.
|
||||
*/
|
||||
void DocLoad(const char* aMsg, nsIWebProgress* aWebProgress,
|
||||
nsIRequest* aRequest, PRUint32 aStateFlags);
|
||||
void DocLoad(const char* aMsg, nsIDocument* aDocumentNode);
|
||||
|
||||
/**
|
||||
* Log that document load event was fired.
|
||||
*/
|
||||
void DocLoadEventFired(AccEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Log that document laod event was handled.
|
||||
*/
|
||||
void DocLoadEventHandled(AccEvent* aEvent);
|
||||
|
||||
/**
|
||||
* Log the document was created.
|
||||
*/
|
||||
void DocCreate(const char* aMsg, nsIDocument* aDocumentNode,
|
||||
nsDocAccessible* aDocument = nsnull);
|
||||
|
||||
/**
|
||||
* Log the document was destroyed.
|
||||
*/
|
||||
void DocDestroy(const char* aMsg, nsIDocument* aDocumentNode,
|
||||
nsDocAccessible* aDocument = nsnull);
|
||||
|
||||
/**
|
||||
* Log the message, a piece of text on own line, no offset.
|
||||
*/
|
||||
void Msg(const char* aMsg);
|
||||
|
||||
/**
|
||||
* Log the text, two spaces offset is used.
|
||||
*/
|
||||
void Text(const char* aText);
|
||||
|
||||
/**
|
||||
* Log the accesisble object address, two spaces offset is used.
|
||||
*/
|
||||
void Address(const char* aDescr, nsAccessible* aAcc);
|
||||
|
||||
/**
|
||||
* Log the call stack, two spaces offset is used.
|
||||
*/
|
||||
void Stack();
|
||||
|
||||
/**
|
||||
* Enable logging of the specified modules, all other modules aren't logged.
|
||||
*/
|
||||
void Enable(const nsAFlatCString& aModules);
|
||||
|
||||
/**
|
||||
* Enable logging of modules specified by A11YLOG environment variable,
|
||||
* all other modules aren't logged.
|
||||
*/
|
||||
void CheckEnv();
|
||||
|
||||
} // namespace logs
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -36,7 +36,6 @@ CPPSRCS = \
|
||||
nsBaseWidgetAccessible.cpp \
|
||||
nsEventShell.cpp \
|
||||
nsCaretAccessible.cpp \
|
||||
nsTextAccessible.cpp \
|
||||
nsTextEquivUtils.cpp \
|
||||
RoleAsserts.cpp \
|
||||
StyleInfo.cpp \
|
||||
@ -44,6 +43,12 @@ CPPSRCS = \
|
||||
TextUpdater.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_DEBUG
|
||||
CPPSRCS += \
|
||||
Logging.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
EXPORTS = \
|
||||
a11yGeneric.h \
|
||||
nsAccDocManager.h \
|
||||
|
@ -11,9 +11,9 @@
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsEventShell.h"
|
||||
#include "nsTextAccessible.h"
|
||||
#include "FocusManager.h"
|
||||
#include "Role.h"
|
||||
#include "TextLeafAccessible.h"
|
||||
#include "TextUpdater.h"
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
@ -7,10 +7,12 @@
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsTextAccessible.h"
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
void
|
||||
TextUpdater::Run(nsDocAccessible* aDocument, nsTextAccessible* aTextLeaf,
|
||||
TextUpdater::Run(nsDocAccessible* aDocument, TextLeafAccessible* aTextLeaf,
|
||||
const nsAString& aNewText)
|
||||
{
|
||||
NS_ASSERTION(aTextLeaf, "No text leaf accessible?");
|
||||
|
@ -19,11 +19,13 @@ public:
|
||||
/**
|
||||
* Start text of the text leaf update.
|
||||
*/
|
||||
static void Run(nsDocAccessible* aDocument, nsTextAccessible* aTextLeaf,
|
||||
static void Run(nsDocAccessible* aDocument,
|
||||
mozilla::a11y::TextLeafAccessible* aTextLeaf,
|
||||
const nsAString& aNewText);
|
||||
|
||||
private:
|
||||
TextUpdater(nsDocAccessible* aDocument, nsTextAccessible* aTextLeaf) :
|
||||
TextUpdater(nsDocAccessible* aDocument,
|
||||
mozilla::a11y::TextLeafAccessible* aTextLeaf) :
|
||||
mDocument(aDocument), mTextLeaf(aTextLeaf), mHyperText(nsnull),
|
||||
mTextOffset(-1) { }
|
||||
|
||||
@ -82,7 +84,7 @@ private:
|
||||
|
||||
private:
|
||||
nsDocAccessible* mDocument;
|
||||
nsTextAccessible* mTextLeaf;
|
||||
mozilla::a11y::TextLeafAccessible* mTextLeaf;
|
||||
nsHyperTextAccessible* mHyperText;
|
||||
PRInt32 mTextOffset;
|
||||
};
|
||||
|
@ -12,6 +12,10 @@
|
||||
#include "RootAccessibleWrap.h"
|
||||
#include "States.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsDocShellLoadTypes.h"
|
||||
#include "nsIChannel.h"
|
||||
@ -140,7 +144,10 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
|
||||
|
||||
// Document was loaded.
|
||||
if (aStateFlags & STATE_STOP) {
|
||||
NS_LOG_ACCDOCLOAD("document loaded", aWebProgress, aRequest, aStateFlags)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocLoad))
|
||||
logging::DocLoad("document loaded", aWebProgress, aRequest, aStateFlags);
|
||||
#endif
|
||||
|
||||
// Figure out an event type to notify the document has been loaded.
|
||||
PRUint32 eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED;
|
||||
@ -166,8 +173,10 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
|
||||
}
|
||||
|
||||
// Document loading was started.
|
||||
NS_LOG_ACCDOCLOAD("start document loading", aWebProgress, aRequest,
|
||||
aStateFlags)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocLoad))
|
||||
logging::DocLoad("start document loading", aWebProgress, aRequest, aStateFlags);
|
||||
#endif
|
||||
|
||||
nsDocAccessible* docAcc = mDocAccessibleCache.GetWeak(document);
|
||||
if (!docAcc)
|
||||
@ -253,7 +262,10 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
|
||||
// accessible and all its sub document accessible are shutdown as result of
|
||||
// processing.
|
||||
|
||||
NS_LOG_ACCDOCDESTROY("received 'pagehide' event", document)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocDestroy))
|
||||
logging::DocDestroy("received 'pagehide' event", document);
|
||||
#endif
|
||||
|
||||
// Ignore 'pagehide' on temporary documents since we ignore them entirely in
|
||||
// accessibility.
|
||||
@ -276,7 +288,11 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
|
||||
// webprogress notifications nor 'pageshow' event.
|
||||
if (type.EqualsLiteral("DOMContentLoaded") &&
|
||||
nsCoreUtils::IsErrorPage(document)) {
|
||||
NS_LOG_ACCDOCLOAD2("handled 'DOMContentLoaded' event", document)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocLoad))
|
||||
logging::DocLoad("handled 'DOMContentLoaded' event", document);
|
||||
#endif
|
||||
|
||||
HandleDOMDocumentLoad(document,
|
||||
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
|
||||
}
|
||||
@ -313,12 +329,18 @@ nsAccDocManager::AddListeners(nsIDocument *aDocument,
|
||||
elm->AddEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
|
||||
NS_EVENT_FLAG_CAPTURE);
|
||||
|
||||
NS_LOG_ACCDOCCREATE_TEXT(" added 'pagehide' listener")
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocCreate))
|
||||
logging::Text("added 'pagehide' listener");
|
||||
#endif
|
||||
|
||||
if (aAddDOMContentLoadedListener) {
|
||||
elm->AddEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
|
||||
NS_EVENT_FLAG_CAPTURE);
|
||||
NS_LOG_ACCDOCCREATE_TEXT(" added 'DOMContentLoaded' listener")
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocCreate))
|
||||
logging::Text("added 'DOMContentLoaded' listener");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -392,8 +414,12 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
|
||||
parentDocAcc->BindChildDocument(docAcc);
|
||||
}
|
||||
|
||||
NS_LOG_ACCDOCCREATE("document creation finished", aDocument)
|
||||
NS_LOG_ACCDOCCREATE_STACK
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocCreate)) {
|
||||
logging::DocCreate("document creation finished", aDocument);
|
||||
logging::Stack();
|
||||
}
|
||||
#endif
|
||||
|
||||
AddListeners(aDocument, isRootDoc);
|
||||
return docAcc;
|
||||
|
@ -16,8 +16,6 @@
|
||||
class nsAccessible;
|
||||
class nsDocAccessible;
|
||||
|
||||
//#define DEBUG_ACCDOCMGR
|
||||
|
||||
/**
|
||||
* Manage the document accessible life cycle.
|
||||
*/
|
||||
@ -146,423 +144,4 @@ private:
|
||||
nsDocAccessibleHashtable mDocAccessibleCache;
|
||||
};
|
||||
|
||||
/**
|
||||
* nsAccDocManager debugging macros.
|
||||
*/
|
||||
#ifdef DEBUG_ACCDOCMGR
|
||||
|
||||
#include "nsTraceRefcntImpl.h"
|
||||
|
||||
// Enable these to log accessible document loading, creation or destruction.
|
||||
#define DEBUG_ACCDOCMGR_DOCLOAD
|
||||
#define DEBUG_ACCDOCMGR_DOCCREATE
|
||||
#define DEBUG_ACCDOCMGR_DOCDESTROY
|
||||
|
||||
// Common macros, do not use directly.
|
||||
#define NS_LOG_ACCDOC_ADDRESS(aDocument, aDocAcc) \
|
||||
printf("DOM id: %p, acc id: %p", aDocument, aDocAcc);
|
||||
|
||||
#define NS_LOG_ACCDOC_URI(aDocument) \
|
||||
nsIURI *uri = aDocument->GetDocumentURI(); \
|
||||
nsCAutoString spec; \
|
||||
uri->GetSpec(spec); \
|
||||
printf("uri: %s", spec);
|
||||
|
||||
#define NS_LOG_ACCDOC_TYPE(aDocument) \
|
||||
if (aDocument->IsActive()) { \
|
||||
bool isContent = nsCoreUtils::IsContentDocument(aDocument); \
|
||||
printf("%s document", (isContent ? "content" : "chrome")); \
|
||||
} else { \
|
||||
printf("document type: [failed]"); \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCSHELLTREE(aDocument) \
|
||||
if (aDocument->IsActive()) { \
|
||||
nsCOMPtr<nsISupports> container = aDocument->GetContainer(); \
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container)); \
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem; \
|
||||
treeItem->GetParent(getter_AddRefs(parentTreeItem)); \
|
||||
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem; \
|
||||
treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); \
|
||||
printf("docshell hierarchy, parent: %p, root: %p, is tab document: %s;", \
|
||||
parentTreeItem, rootTreeItem, \
|
||||
(nsCoreUtils::IsTabDocument(aDocument) ? "yes" : "no")); \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOC_SHELLSTATE(aDocument) \
|
||||
nsCAutoString docShellBusy; \
|
||||
nsCOMPtr<nsISupports> container = aDocument->GetContainer(); \
|
||||
if (container) { \
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container); \
|
||||
PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE; \
|
||||
docShell->GetBusyFlags(&busyFlags); \
|
||||
if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) \
|
||||
docShellBusy.AppendLiteral("'none'"); \
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY) \
|
||||
docShellBusy.AppendLiteral("'busy'"); \
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD) \
|
||||
docShellBusy.AppendLiteral(", 'before page load'"); \
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING) \
|
||||
docShellBusy.AppendLiteral(", 'page loading'"); \
|
||||
} \
|
||||
else { \
|
||||
docShellBusy.AppendLiteral("[failed]"); \
|
||||
} \
|
||||
printf("docshell busy: %s", docShellBusy.get());
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCSTATES(aDocument) \
|
||||
const char *docState = 0; \
|
||||
nsIDocument::ReadyState docStateFlag = aDocument->GetReadyStateEnum(); \
|
||||
switch (docStateFlag) { \
|
||||
case nsIDocument::READYSTATE_UNINITIALIZED: \
|
||||
docState = "uninitialized"; \
|
||||
break; \
|
||||
case nsIDocument::READYSTATE_LOADING: \
|
||||
docState = "loading"; \
|
||||
break; \
|
||||
case nsIDocument::READYSTATE_INTERACTIVE: \
|
||||
docState = "interactive"; \
|
||||
break; \
|
||||
case nsIDocument::READYSTATE_COMPLETE: \
|
||||
docState = "complete"; \
|
||||
break; \
|
||||
} \
|
||||
printf("doc state: %s", docState); \
|
||||
printf(", %sinitial", aDocument->IsInitialDocument() ? "" : "not "); \
|
||||
printf(", %sshowing", aDocument->IsShowing() ? "" : "not "); \
|
||||
printf(", %svisible", aDocument->IsVisible() ? "" : "not "); \
|
||||
printf(", %sactive", aDocument->IsActive() ? "" : "not ");
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCPRESSHELL(aDocument) \
|
||||
nsIPresShell *ps = aDocument->GetShell(); \
|
||||
printf("presshell: %p", ps); \
|
||||
nsIScrollableFrame *sf = ps ? \
|
||||
ps->GetRootScrollFrameAsScrollableExternal() : nsnull; \
|
||||
printf(", root scroll frame: %p", sf);
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCLOADGROUP(aDocument) \
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = aDocument->GetDocumentLoadGroup(); \
|
||||
printf("load group: %p", loadGroup);
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCPARENT(aDocument) \
|
||||
nsIDocument *parentDoc = aDocument->GetParentDocument(); \
|
||||
printf("parent id: %p", parentDoc); \
|
||||
if (parentDoc) { \
|
||||
printf("\n parent "); \
|
||||
NS_LOG_ACCDOC_URI(parentDoc) \
|
||||
printf("\n"); \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOC_SHELLLOADTYPE(aDocShell) \
|
||||
{ \
|
||||
printf("load type: "); \
|
||||
PRUint32 loadType; \
|
||||
docShell->GetLoadType(&loadType); \
|
||||
switch (loadType) { \
|
||||
case LOAD_NORMAL: \
|
||||
printf("normal; "); \
|
||||
break; \
|
||||
case LOAD_NORMAL_REPLACE: \
|
||||
printf("normal replace; "); \
|
||||
break; \
|
||||
case LOAD_NORMAL_EXTERNAL: \
|
||||
printf("normal external; "); \
|
||||
break; \
|
||||
case LOAD_HISTORY: \
|
||||
printf("history; "); \
|
||||
break; \
|
||||
case LOAD_NORMAL_BYPASS_CACHE: \
|
||||
printf("normal bypass cache; "); \
|
||||
break; \
|
||||
case LOAD_NORMAL_BYPASS_PROXY: \
|
||||
printf("normal bypass proxy; "); \
|
||||
break; \
|
||||
case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE: \
|
||||
printf("normal bypass proxy and cache; "); \
|
||||
break; \
|
||||
case LOAD_RELOAD_NORMAL: \
|
||||
printf("reload normal; "); \
|
||||
break; \
|
||||
case LOAD_RELOAD_BYPASS_CACHE: \
|
||||
printf("reload bypass cache; "); \
|
||||
break; \
|
||||
case LOAD_RELOAD_BYPASS_PROXY: \
|
||||
printf("reload bypass proxy; "); \
|
||||
break; \
|
||||
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE: \
|
||||
printf("reload bypass proxy and cache; "); \
|
||||
break; \
|
||||
case LOAD_LINK: \
|
||||
printf("link; "); \
|
||||
break; \
|
||||
case LOAD_REFRESH: \
|
||||
printf("refresh; "); \
|
||||
break; \
|
||||
case LOAD_RELOAD_CHARSET_CHANGE: \
|
||||
printf("reload charset change; "); \
|
||||
break; \
|
||||
case LOAD_BYPASS_HISTORY: \
|
||||
printf("bypass history; "); \
|
||||
break; \
|
||||
case LOAD_STOP_CONTENT: \
|
||||
printf("stop content; "); \
|
||||
break; \
|
||||
case LOAD_STOP_CONTENT_AND_REPLACE: \
|
||||
printf("stop content and replace; "); \
|
||||
break; \
|
||||
case LOAD_PUSHSTATE: \
|
||||
printf("load pushstate; "); \
|
||||
break; \
|
||||
case LOAD_ERROR_PAGE: \
|
||||
printf("error page;"); \
|
||||
break; \
|
||||
default: \
|
||||
printf("unknown"); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCINFO_BEGIN \
|
||||
printf(" {\n");
|
||||
#define NS_LOG_ACCDOC_DOCINFO_BODY(aDocument, aDocAcc) \
|
||||
{ \
|
||||
printf(" "); \
|
||||
NS_LOG_ACCDOC_ADDRESS(aDocument, aDocAcc) \
|
||||
printf("\n "); \
|
||||
if (aDocument) { \
|
||||
NS_LOG_ACCDOC_URI(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_SHELLSTATE(aDocument) \
|
||||
printf("; "); \
|
||||
NS_LOG_ACCDOC_TYPE(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCSHELLTREE(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCSTATES(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCPRESSHELL(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCLOADGROUP(aDocument) \
|
||||
printf(", "); \
|
||||
NS_LOG_ACCDOC_DOCPARENT(aDocument) \
|
||||
printf("\n"); \
|
||||
} \
|
||||
}
|
||||
#define NS_LOG_ACCDOC_DOCINFO_END \
|
||||
printf(" }\n");
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc) \
|
||||
NS_LOG_ACCDOC_DOCINFO_BEGIN \
|
||||
NS_LOG_ACCDOC_DOCINFO_BODY(aDocument, aDocAcc) \
|
||||
NS_LOG_ACCDOC_DOCINFO_END
|
||||
|
||||
#define NS_GET_ACCDOC_EVENTTYPE(aEvent) \
|
||||
nsCAutoString strEventType; \
|
||||
PRUint32 type = aEvent->GetEventType(); \
|
||||
if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED) { \
|
||||
strEventType.AssignLiteral("load stopped"); \
|
||||
} else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE) { \
|
||||
strEventType.AssignLiteral("load complete"); \
|
||||
} else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD) { \
|
||||
strEventType.AssignLiteral("reload"); \
|
||||
} else if (type == nsIAccessibleEvent::EVENT_STATE_CHANGE) { \
|
||||
AccStateChangeEvent* event = downcast_accEvent(aEvent); \
|
||||
if (event->GetState() == states::BUSY) { \
|
||||
strEventType.AssignLiteral("busy "); \
|
||||
if (event->IsStateEnabled()) \
|
||||
strEventType.AppendLiteral("true"); \
|
||||
else \
|
||||
strEventType.AppendLiteral("false"); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc) \
|
||||
{ \
|
||||
nsINode* node = aAcc->GetNode(); \
|
||||
nsIDocument* doc = aAcc->GetDocumentNode(); \
|
||||
nsDocAccessible *docacc = GetAccService()->GetDocAccessibleFromCache(doc); \
|
||||
printf(" " aName " accessible: %p, node: %p\n", aAcc, node); \
|
||||
printf(" docacc for " aName " accessible: %p, node: %p\n", docacc, doc); \
|
||||
printf(" "); \
|
||||
NS_LOG_ACCDOC_URI(doc) \
|
||||
printf("\n"); \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOC_MSG(aMsg) \
|
||||
printf("\n" aMsg "\n"); \
|
||||
|
||||
#define NS_LOG_ACCDOC_TEXT(aMsg) \
|
||||
printf(" " aMsg "\n");
|
||||
|
||||
#define NS_LOG_ACCDOC_STACK \
|
||||
printf(" stack: \n"); \
|
||||
nsTraceRefcntImpl::WalkTheStack(stdout);
|
||||
|
||||
// Accessible document loading macros.
|
||||
#ifdef DEBUG_ACCDOCMGR_DOCLOAD
|
||||
|
||||
#define NS_LOG_ACCDOCLOAD_REQUEST(aRequest) \
|
||||
if (aRequest) { \
|
||||
nsCAutoString name; \
|
||||
aRequest->GetName(name); \
|
||||
printf(" request spec: %s\n", name.get()); \
|
||||
PRUint32 loadFlags = 0; \
|
||||
aRequest->GetLoadFlags(&loadFlags); \
|
||||
printf(" request load flags: %x; ", loadFlags); \
|
||||
if (loadFlags & nsIChannel::LOAD_DOCUMENT_URI) \
|
||||
printf("document uri; "); \
|
||||
if (loadFlags & nsIChannel::LOAD_RETARGETED_DOCUMENT_URI) \
|
||||
printf("retargeted document uri; "); \
|
||||
if (loadFlags & nsIChannel::LOAD_REPLACE) \
|
||||
printf("replace; "); \
|
||||
if (loadFlags & nsIChannel::LOAD_INITIAL_DOCUMENT_URI) \
|
||||
printf("initial document uri; "); \
|
||||
if (loadFlags & nsIChannel::LOAD_TARGETED) \
|
||||
printf("targeted; "); \
|
||||
if (loadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS) \
|
||||
printf("call content sniffers; "); \
|
||||
if (loadFlags & nsIChannel::LOAD_CLASSIFY_URI) \
|
||||
printf("classify uri; "); \
|
||||
} else { \
|
||||
printf(" no request"); \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOCLOAD(aMsg, aWebProgress, aRequest, aStateFlags) \
|
||||
{ \
|
||||
NS_LOG_ACCDOC_MSG("A11Y DOCLOAD: " aMsg); \
|
||||
\
|
||||
nsCOMPtr<nsIDOMWindow> DOMWindow; \
|
||||
aWebProgress->GetDOMWindow(getter_AddRefs(DOMWindow)); \
|
||||
if (DOMWindow) { \
|
||||
nsCOMPtr<nsIDOMDocument> DOMDocument; \
|
||||
DOMWindow->GetDocument(getter_AddRefs(DOMDocument)); \
|
||||
if (DOMDocument) { \
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(DOMDocument)); \
|
||||
nsDocAccessible *docAcc = \
|
||||
GetAccService()->GetDocAccessibleFromCache(document); \
|
||||
NS_LOG_ACCDOC_DOCINFO(document, docAcc) \
|
||||
\
|
||||
printf(" {\n"); \
|
||||
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow)); \
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav)); \
|
||||
printf(" "); \
|
||||
NS_LOG_ACCDOC_SHELLLOADTYPE(docShell) \
|
||||
printf("\n"); \
|
||||
NS_LOG_ACCDOCLOAD_REQUEST(aRequest) \
|
||||
printf("\n"); \
|
||||
printf(" state flags: %x", aStateFlags); \
|
||||
bool isDocLoading; \
|
||||
aWebProgress->GetIsLoadingDocument(&isDocLoading); \
|
||||
printf(", document is %sloading\n", (isDocLoading ? "" : "not ")); \
|
||||
printf(" }\n"); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOCLOAD2(aMsg, aDocument) \
|
||||
{ \
|
||||
NS_LOG_ACCDOC_MSG("A11Y DOCLOAD: " aMsg); \
|
||||
nsDocAccessible *docAcc = \
|
||||
GetAccService()->GetDocAccessibleFromCache(aDocument); \
|
||||
NS_LOG_ACCDOC_DOCINFO(aDocument, docAcc) \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOCLOAD_FIREEVENT(aEvent) \
|
||||
{ \
|
||||
NS_GET_ACCDOC_EVENTTYPE(aEvent) \
|
||||
if (!strEventType.IsEmpty()) \
|
||||
printf(" fire: %s\n", strEventType.get()); \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOCLOAD_HANDLEEVENT(aEvent) \
|
||||
{ \
|
||||
NS_GET_ACCDOC_EVENTTYPE(aEvent) \
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(aEvent->GetNode())); \
|
||||
if (doc && !strEventType.IsEmpty()) { \
|
||||
printf("\nA11Y DOCEVENT: handled '%s' event ", strEventType.get()); \
|
||||
nsDocAccessible *docAcc = aEvent->GetDocAccessible(); \
|
||||
NS_LOG_ACCDOC_DOCINFO(doc, docAcc) \
|
||||
printf("\n"); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOCLOAD_TEXT(aMsg) \
|
||||
NS_LOG_ACCDOC_TEXT(aMsg)
|
||||
|
||||
#endif // DEBUG_ACCDOCMGR_DOCLOAD
|
||||
|
||||
// Accessible document creation macros.
|
||||
#ifdef DEBUG_ACCDOCMGR_DOCCREATE
|
||||
#define NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, aDocAcc) \
|
||||
NS_LOG_ACCDOC_MSG("A11Y DOCCREATE: " aMsg); \
|
||||
NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
|
||||
|
||||
#define NS_LOG_ACCDOCCREATE(aMsg, aDocument) \
|
||||
{ \
|
||||
nsDocAccessible *docAcc = \
|
||||
GetAccService()->GetDocAccessibleFromCache(aDocument); \
|
||||
NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, docAcc) \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOCCREATE_ACCADDRESS(aName, aAcc) \
|
||||
NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc)
|
||||
|
||||
#define NS_LOG_ACCDOCCREATE_TEXT(aMsg) \
|
||||
NS_LOG_ACCDOC_TEXT(aMsg)
|
||||
|
||||
#define NS_LOG_ACCDOCCREATE_STACK \
|
||||
NS_LOG_ACCDOC_STACK
|
||||
|
||||
#endif // DEBUG_ACCDOCMGR_DOCCREATE
|
||||
|
||||
// Accessible document destruction macros.
|
||||
#ifdef DEBUG_ACCDOCMGR_DOCDESTROY
|
||||
#define NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, aDocAcc) \
|
||||
NS_LOG_ACCDOC_MSG("A11Y DOCDESTROY: " aMsg); \
|
||||
NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
|
||||
|
||||
#define NS_LOG_ACCDOCDESTROY(aMsg, aDocument) \
|
||||
{ \
|
||||
nsDocAccessible* docAcc = \
|
||||
GetAccService()->GetDocAccessibleFromCache(aDocument); \
|
||||
NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, docAcc) \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOCDESTROY_ACCADDRESS(aName, aAcc) \
|
||||
NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc)
|
||||
|
||||
#define NS_LOG_ACCDOCDESTROY_MSG(aMsg) \
|
||||
NS_LOG_ACCDOC_MSG(aMsg)
|
||||
|
||||
#define NS_LOG_ACCDOCDESTROY_TEXT(aMsg) \
|
||||
NS_LOG_ACCDOC_TEXT(aMsg)
|
||||
|
||||
#endif // DEBUG_ACCDOCMGR_DOCDESTROY
|
||||
|
||||
#endif // DEBUG_ACCDOCMGR
|
||||
|
||||
#ifndef DEBUG_ACCDOCMGR_DOCLOAD
|
||||
#define NS_LOG_ACCDOCLOAD(aMsg, aWebProgress, aRequest, aStateFlags)
|
||||
#define NS_LOG_ACCDOCLOAD2(aMsg, aDocument)
|
||||
#define NS_LOG_ACCDOCLOAD_EVENT(aMsg, aEvent)
|
||||
#define NS_LOG_ACCDOCLOAD_FIREEVENT(aEvent)
|
||||
#define NS_LOG_ACCDOCLOAD_HANDLEEVENT(aEvent)
|
||||
#define NS_LOG_ACCDOCLOAD_TEXT(aMsg)
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_ACCDOCMGR_DOCCREATE
|
||||
#define NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, aDocAcc)
|
||||
#define NS_LOG_ACCDOCCREATE(aMsg, aDocument)
|
||||
#define NS_LOG_ACCDOCCREATE_ACCADDRESS(aName, aAcc)
|
||||
#define NS_LOG_ACCDOCCREATE_TEXT(aMsg)
|
||||
#define NS_LOG_ACCDOCCREATE_STACK
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_ACCDOCMGR_DOCDESTROY
|
||||
#define NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, aDocAcc)
|
||||
#define NS_LOG_ACCDOCDESTROY(aMsg, aDocument)
|
||||
#define NS_LOG_ACCDOCDESTROY_MSG(aMsg)
|
||||
#define NS_LOG_ACCDOCDESTROY_ACCADDRESS(aName, aAcc)
|
||||
#define NS_LOG_ACCDOCDESTROY_TEXT(aMsg)
|
||||
#endif
|
||||
|
||||
#endif // nsAccDocManager_h_
|
||||
|
@ -12,9 +12,9 @@
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsHyperTextAccessible.h"
|
||||
#include "nsIAccessibleTypes.h"
|
||||
#include "nsTextAccessible.h"
|
||||
#include "Role.h"
|
||||
#include "States.h"
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
#include "nsIDOMXULContainerElement.h"
|
||||
#include "nsIDOMXULSelectCntrlEl.h"
|
||||
@ -447,7 +447,7 @@ nsAccUtils::TextLength(nsAccessible *aAccessible)
|
||||
if (!IsText(aAccessible))
|
||||
return 1;
|
||||
|
||||
nsTextAccessible* textLeaf = aAccessible->AsTextLeaf();
|
||||
TextLeafAccessible* textLeaf = aAccessible->AsTextLeaf();
|
||||
if (textLeaf)
|
||||
return textLeaf->Text().Length();
|
||||
|
||||
|
@ -35,6 +35,11 @@
|
||||
#ifdef XP_WIN
|
||||
#include "nsHTMLWin32ObjectAccessible.h"
|
||||
#endif
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsEventStates.h"
|
||||
@ -405,11 +410,11 @@ nsAccessibilityService::CreateHTMLTableRowAccessible(nsIContent* aContent,
|
||||
}
|
||||
|
||||
already_AddRefed<nsAccessible>
|
||||
nsAccessibilityService::CreateHTMLTextAccessible(nsIContent* aContent,
|
||||
nsAccessibilityService::CreateTextLeafAccessible(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell)
|
||||
{
|
||||
nsAccessible* accessible =
|
||||
new nsHTMLTextAccessible(aContent, GetDocAccessible(aPresShell));
|
||||
new TextLeafAccessible(aContent, GetDocAccessible(aPresShell));
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
@ -611,7 +616,10 @@ nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
NS_LOG_ACCDOCDESTROY("presshell destroyed", doc)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocDestroy))
|
||||
logging::DocDestroy("presshell destroyed", doc);
|
||||
#endif
|
||||
|
||||
nsDocAccessible* docAccessible = GetDocAccessibleFromCache(doc);
|
||||
if (docAccessible)
|
||||
@ -884,6 +892,15 @@ nsAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::SetLogging(const nsACString& aModules)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
logging::Enable(PromiseFlatCString(aModules));
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessibilityService public
|
||||
|
||||
@ -1242,6 +1259,10 @@ nsAccessibilityService::Init()
|
||||
static const PRUnichar kInitIndicator[] = { '1', 0 };
|
||||
observerService->NotifyObservers(nsnull, "a11y-init-or-shutdown", kInitIndicator);
|
||||
|
||||
#ifdef DEBUG
|
||||
logging::CheckEnv();
|
||||
#endif
|
||||
|
||||
// Initialize accessibility.
|
||||
nsAccessNodeWrap::InitAccessibility();
|
||||
|
||||
|
@ -101,7 +101,7 @@ public:
|
||||
already_AddRefed<nsAccessible>
|
||||
CreateHTMLTableRowAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
|
||||
already_AddRefed<nsAccessible>
|
||||
CreateHTMLTextAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
|
||||
CreateTextLeafAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
|
||||
already_AddRefed<nsAccessible>
|
||||
CreateHTMLTextFieldAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
|
||||
already_AddRefed<nsAccessible>
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "States.h"
|
||||
#include "StyleInfo.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIDOMCSSValue.h"
|
||||
#include "nsIDOMCSSPrimitiveValue.h"
|
||||
#include "nsIDOMElement.h"
|
||||
@ -787,7 +788,7 @@ nsAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
nsPoint offset(presContext->DevPixelsToAppUnits(aX) - screenRect.x,
|
||||
presContext->DevPixelsToAppUnits(aY) - screenRect.y);
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
|
||||
nsIPresShell* presShell = presContext->PresShell();
|
||||
nsIFrame *foundFrame = presShell->GetFrameForPoint(frame, offset);
|
||||
|
||||
nsIContent* content = nsnull;
|
||||
@ -1679,13 +1680,8 @@ nsAccessible::Value(nsString& aValue)
|
||||
return;
|
||||
|
||||
// Check if it's a simple xlink.
|
||||
if (nsCoreUtils::IsXLink(mContent)) {
|
||||
nsIPresShell* presShell = mDoc->PresShell();
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
|
||||
presShell->GetLinkLocation(DOMNode, aValue);
|
||||
}
|
||||
}
|
||||
if (nsCoreUtils::IsXLink(mContent))
|
||||
nsContentUtils::GetLinkLocation(mContent->AsElement(), aValue);
|
||||
}
|
||||
|
||||
// nsIAccessibleValue
|
||||
|
@ -37,6 +37,7 @@ namespace a11y {
|
||||
|
||||
class HTMLLIAccessible;
|
||||
class TableAccessible;
|
||||
class TextLeafAccessible;
|
||||
|
||||
/**
|
||||
* Name type flags.
|
||||
@ -54,7 +55,7 @@ enum ENameValueFlag {
|
||||
|
||||
}
|
||||
}
|
||||
class nsTextAccessible;
|
||||
|
||||
class nsXULTreeAccessible;
|
||||
|
||||
struct nsRect;
|
||||
@ -482,7 +483,7 @@ public:
|
||||
virtual mozilla::a11y::TableAccessible* AsTable() { return nsnull; }
|
||||
|
||||
inline bool IsTextLeaf() const { return mFlags & eTextLeafAccessible; }
|
||||
nsTextAccessible* AsTextLeaf();
|
||||
mozilla::a11y::TextLeafAccessible* AsTextLeaf();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// ActionAccessible
|
||||
|
@ -171,7 +171,7 @@ nsCoreUtils::GetAccessKeyFor(nsIContent *aContent)
|
||||
if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::accesskey))
|
||||
return 0;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = aContent->OwnerDoc()->GetShell();
|
||||
nsIPresShell* presShell = aContent->OwnerDoc()->GetShell();
|
||||
if (!presShell)
|
||||
return 0;
|
||||
|
||||
|
@ -43,6 +43,11 @@
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsIXULDocument.h"
|
||||
#endif
|
||||
@ -581,7 +586,10 @@ nsDocAccessible::GetAccessible(nsINode* aNode) const
|
||||
bool
|
||||
nsDocAccessible::Init()
|
||||
{
|
||||
NS_LOG_ACCDOCCREATE_FOR("document initialize", mDocument, this)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocCreate))
|
||||
logging::DocCreate("document initialize", mDocument, this);
|
||||
#endif
|
||||
|
||||
// Initialize notification controller.
|
||||
mNotificationController = new NotificationController(this, mPresShell);
|
||||
@ -604,7 +612,10 @@ nsDocAccessible::Shutdown()
|
||||
if (!mPresShell) // already shutdown
|
||||
return;
|
||||
|
||||
NS_LOG_ACCDOCDESTROY_FOR("document shutdown", mDocument, this)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocDestroy))
|
||||
logging::DocDestroy("document shutdown", mDocument, this);
|
||||
#endif
|
||||
|
||||
if (mNotificationController) {
|
||||
mNotificationController->Shutdown();
|
||||
@ -818,7 +829,10 @@ void nsDocAccessible::AddScrollListener()
|
||||
nsIScrollableFrame* sf = mPresShell->GetRootScrollFrameAsScrollableExternal();
|
||||
if (sf) {
|
||||
sf->AddScrollPositionListener(this);
|
||||
NS_LOG_ACCDOCCREATE_TEXT("add scroll listener")
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocCreate))
|
||||
logging::Text("add scroll listener");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1264,14 +1278,14 @@ nsDocAccessible::ParentChainChanged(nsIContent *aContent)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible
|
||||
|
||||
#ifdef DEBUG_ACCDOCMGR
|
||||
#ifdef DEBUG
|
||||
nsresult
|
||||
nsDocAccessible::HandleAccEvent(AccEvent* aAccEvent)
|
||||
nsDocAccessible::HandleAccEvent(AccEvent* aEvent)
|
||||
{
|
||||
NS_LOG_ACCDOCLOAD_HANDLEEVENT(aAccEvent)
|
||||
|
||||
return nsHyperTextAccessible::HandleAccEvent(aAccEvent);
|
||||
if (logging::IsEnabled(logging::eDocLoad))
|
||||
logging::DocLoadEventHandled(aEvent);
|
||||
|
||||
return nsHyperTextAccessible::HandleAccEvent(aEvent);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1711,7 +1725,11 @@ nsresult
|
||||
nsDocAccessible::FireDelayedAccessibleEvent(AccEvent* aEvent)
|
||||
{
|
||||
NS_ENSURE_ARG(aEvent);
|
||||
NS_LOG_ACCDOCLOAD_FIREEVENT(aEvent)
|
||||
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocLoad))
|
||||
logging::DocLoadEventFired(aEvent);
|
||||
#endif
|
||||
|
||||
if (mNotificationController)
|
||||
mNotificationController->QueueEvent(aEvent);
|
||||
|
@ -86,8 +86,8 @@ public:
|
||||
|
||||
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
|
||||
|
||||
#ifdef DEBUG_ACCDOCMGR
|
||||
virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
|
||||
#ifdef DEBUG
|
||||
virtual nsresult HandleAccEvent(AccEvent* aEvent);
|
||||
#endif
|
||||
|
||||
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
|
||||
|
@ -1,40 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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/. */
|
||||
|
||||
#include "nsTextAccessible.h"
|
||||
|
||||
#include "Role.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsTextAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsTextAccessible::
|
||||
nsTextAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
nsLinkableAccessible(aContent, aDoc)
|
||||
{
|
||||
mFlags |= eTextLeafAccessible;
|
||||
}
|
||||
|
||||
role
|
||||
nsTextAccessible::NativeRole()
|
||||
{
|
||||
return roles::TEXT_LEAF;
|
||||
}
|
||||
|
||||
void
|
||||
nsTextAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
aText.Append(Substring(mText, aStartOffset, aLength));
|
||||
}
|
||||
|
||||
void
|
||||
nsTextAccessible::CacheChildren()
|
||||
{
|
||||
// No children for text accessible.
|
||||
}
|
@ -20,6 +20,7 @@ CPPSRCS = \
|
||||
FormControlAccessible.cpp \
|
||||
OuterDocAccessible.cpp \
|
||||
RootAccessible.cpp \
|
||||
TextLeafAccessible.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
@ -10,6 +10,10 @@
|
||||
#include "Role.h"
|
||||
#include "States.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "Logging.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
@ -119,13 +123,21 @@ OuterDocAccessible::Shutdown()
|
||||
// change however the presshell of underlying document isn't destroyed and
|
||||
// the document doesn't get pagehide events. Shutdown underlying document if
|
||||
// any to avoid hanging document accessible.
|
||||
NS_LOG_ACCDOCDESTROY_MSG("A11y outerdoc shutdown")
|
||||
NS_LOG_ACCDOCDESTROY_ACCADDRESS("outerdoc", this)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocDestroy)) {
|
||||
logging::Msg("A11y outerdoc shutdown");
|
||||
logging::Address("outerdoc", this);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsAccessible* childAcc = mChildren.SafeElementAt(0, nsnull);
|
||||
if (childAcc) {
|
||||
NS_LOG_ACCDOCDESTROY("outerdoc's child document shutdown",
|
||||
childAcc->GetDocumentNode())
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocDestroy)) {
|
||||
logging::DocDestroy("outerdoc's child document shutdown",
|
||||
childAcc->GetDocumentNode());
|
||||
}
|
||||
#endif
|
||||
childAcc->Shutdown();
|
||||
}
|
||||
|
||||
@ -164,9 +176,13 @@ OuterDocAccessible::AppendChild(nsAccessible* aAccessible)
|
||||
if (!nsAccessibleWrap::AppendChild(aAccessible))
|
||||
return false;
|
||||
|
||||
NS_LOG_ACCDOCCREATE("append document to outerdoc",
|
||||
aAccessible->GetDocumentNode())
|
||||
NS_LOG_ACCDOCCREATE_ACCADDRESS("outerdoc", this)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocCreate)) {
|
||||
logging::DocCreate("append document to outerdoc",
|
||||
aAccessible->GetDocumentNode());
|
||||
logging::Address("outerdoc", this);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -180,9 +196,13 @@ OuterDocAccessible::RemoveChild(nsAccessible* aAccessible)
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_LOG_ACCDOCDESTROY_FOR("remove document from outerdoc",
|
||||
child->GetDocumentNode(), child)
|
||||
NS_LOG_ACCDOCDESTROY_ACCADDRESS("outerdoc", this)
|
||||
#ifdef DEBUG
|
||||
if (logging::IsEnabled(logging::eDocDestroy)) {
|
||||
logging::DocDestroy("remove document from outerdoc", child->GetDocumentNode(),
|
||||
child->AsDoc());
|
||||
logging::Address("outerdoc", this);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool wasRemoved = nsAccessibleWrap::RemoveChild(child);
|
||||
|
||||
|
70
accessible/src/generic/TextLeafAccessible.cpp
Normal file
70
accessible/src/generic/TextLeafAccessible.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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/. */
|
||||
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "Role.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TextLeafAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TextLeafAccessible::
|
||||
TextLeafAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
nsLinkableAccessible(aContent, aDoc)
|
||||
{
|
||||
mFlags |= eTextLeafAccessible;
|
||||
}
|
||||
|
||||
TextLeafAccessible::~TextLeafAccessible()
|
||||
{
|
||||
}
|
||||
|
||||
role
|
||||
TextLeafAccessible::NativeRole()
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (frame && frame->IsGeneratedContentFrame())
|
||||
return roles::STATICTEXT;
|
||||
|
||||
return roles::TEXT_LEAF;
|
||||
}
|
||||
|
||||
void
|
||||
TextLeafAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
aText.Append(Substring(mText, aStartOffset, aLength));
|
||||
}
|
||||
|
||||
ENameValueFlag
|
||||
TextLeafAccessible::Name(nsString& aName)
|
||||
{
|
||||
// Text node, ARIA can't be used.
|
||||
aName = mText;
|
||||
return eNameOK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
TextLeafAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
if (NativeRole() == roles::STATICTEXT) {
|
||||
nsAutoString oldValueUnused;
|
||||
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("auto-generated"),
|
||||
NS_LITERAL_STRING("true"), oldValueUnused);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
TextLeafAccessible::CacheChildren()
|
||||
{
|
||||
// No children for text accessible.
|
||||
}
|
@ -3,25 +3,31 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef _nsTextAccessible_H_
|
||||
#define _nsTextAccessible_H_
|
||||
#ifndef mozilla_a11y_TextLeafAccessible_h__
|
||||
#define mozilla_a11y_TextLeafAccessible_h__
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
/**
|
||||
* Generic class used for text nodes.
|
||||
*/
|
||||
class nsTextAccessible : public nsLinkableAccessible
|
||||
class TextLeafAccessible : public nsLinkableAccessible
|
||||
{
|
||||
public:
|
||||
nsTextAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
TextLeafAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
virtual ~TextLeafAccessible();
|
||||
|
||||
// nsAccessible
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
virtual void AppendTextTo(nsAString& aText, PRUint32 aStartOffset = 0,
|
||||
PRUint32 aLength = PR_UINT32_MAX);
|
||||
virtual ENameValueFlag Name(nsString& aName);
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
|
||||
|
||||
// nsTextAccessible
|
||||
// TextLeafAccessible
|
||||
void SetText(const nsAString& aText) { mText = aText; }
|
||||
const nsString& Text() const { return mText; }
|
||||
|
||||
@ -33,15 +39,17 @@ protected:
|
||||
nsString mText;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible downcast method
|
||||
|
||||
inline nsTextAccessible*
|
||||
inline mozilla::a11y::TextLeafAccessible*
|
||||
nsAccessible::AsTextLeaf()
|
||||
{
|
||||
return mFlags & eTextLeafAccessible ?
|
||||
static_cast<nsTextAccessible*>(this) : nsnull;
|
||||
static_cast<mozilla::a11y::TextLeafAccessible*>(this) : nsnull;
|
||||
}
|
||||
|
||||
#endif
|
@ -6,10 +6,11 @@
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "Role.h"
|
||||
#include "States.h"
|
||||
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsEventStates.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
@ -77,12 +78,8 @@ nsHTMLLinkAccessible::Value(nsString& aValue)
|
||||
aValue.Truncate();
|
||||
|
||||
nsHyperTextAccessible::Value(aValue);
|
||||
if (!aValue.IsEmpty())
|
||||
return;
|
||||
|
||||
nsIPresShell* presShell(mDoc->PresShell());
|
||||
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
|
||||
presShell->GetLinkLocation(DOMNode, aValue);
|
||||
if (aValue.IsEmpty())
|
||||
nsContentUtils::GetLinkLocation(mContent->AsElement(), aValue);
|
||||
}
|
||||
|
||||
PRUint8
|
||||
|
@ -150,7 +150,7 @@ nsHTMLSelectListAccessible::CacheOptSiblings(nsIContent *aParentContent)
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> tag = childContent->Tag();
|
||||
nsIAtom* tag = childContent->Tag();
|
||||
if (tag == nsGkAtoms::option ||
|
||||
tag == nsGkAtoms::optgroup) {
|
||||
|
||||
|
@ -15,67 +15,6 @@
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLTextAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTMLTextAccessible::
|
||||
nsHTMLTextAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
nsTextAccessibleWrap(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTextAccessible, nsTextAccessible)
|
||||
|
||||
ENameValueFlag
|
||||
nsHTMLTextAccessible::Name(nsString& aName)
|
||||
{
|
||||
// Text node, ARIA can't be used.
|
||||
aName = mText;
|
||||
return eNameOK;
|
||||
}
|
||||
|
||||
role
|
||||
nsHTMLTextAccessible::NativeRole()
|
||||
{
|
||||
nsIFrame *frame = GetFrame();
|
||||
// Don't return on null frame -- we still return a role
|
||||
// after accessible is shutdown/DEFUNCT
|
||||
if (frame && frame->IsGeneratedContentFrame())
|
||||
return roles::STATICTEXT;
|
||||
|
||||
return nsTextAccessible::NativeRole();
|
||||
}
|
||||
|
||||
PRUint64
|
||||
nsHTMLTextAccessible::NativeState()
|
||||
{
|
||||
PRUint64 state = nsTextAccessible::NativeState();
|
||||
|
||||
nsDocAccessible* docAccessible = Document();
|
||||
if (docAccessible) {
|
||||
PRUint64 docState = docAccessible->State();
|
||||
if (0 == (docState & states::EDITABLE)) {
|
||||
state |= states::READONLY; // Links not focusable in editor
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLTextAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
if (NativeRole() == roles::STATICTEXT) {
|
||||
nsAutoString oldValueUnused;
|
||||
aAttributes->SetStringProperty(NS_LITERAL_CSTRING("auto-generated"),
|
||||
NS_LITERAL_STRING("true"), oldValueUnused);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLHRAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -6,28 +6,9 @@
|
||||
#ifndef _nsHTMLTextAccessible_H_
|
||||
#define _nsHTMLTextAccessible_H_
|
||||
|
||||
#include "nsTextAccessibleWrap.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
|
||||
/**
|
||||
* Used for text nodes within HTML document.
|
||||
*/
|
||||
class nsHTMLTextAccessible : public nsTextAccessibleWrap
|
||||
{
|
||||
public:
|
||||
nsHTMLTextAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsAccessible
|
||||
virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
virtual PRUint64 NativeState();
|
||||
};
|
||||
|
||||
/**
|
||||
* Used for HTML hr element.
|
||||
*/
|
||||
|
@ -423,11 +423,14 @@ nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndOffset,
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 startOffset = ConvertMagicOffset(aStartOffset);
|
||||
PRInt32 startChildIdx = GetChildIndexAtOffset(startOffset);
|
||||
if (startChildIdx == -1)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
PRInt32 endOffset = ConvertMagicOffset(aEndOffset);
|
||||
|
||||
PRInt32 startChildIdx = GetChildIndexAtOffset(startOffset);
|
||||
if (startChildIdx == -1) {
|
||||
// 0 offsets are considered valid for empty text.
|
||||
return (startOffset == 0 && endOffset == 0) ? NS_OK : NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
PRInt32 endChildIdx = GetChildIndexAtOffset(endOffset);
|
||||
if (endChildIdx == -1)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
@ -3,11 +3,17 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef _nsTextAccessibleWrap_H_
|
||||
#define _nsTextAccessibleWrap_H_
|
||||
#ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
#define mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
|
||||
#include "nsTextAccessible.h"
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
typedef class nsTextAccessible nsTextAccessibleWrap;
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class TextLeafAccessible TextLeafAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -20,7 +20,6 @@ CPPSRCS = \
|
||||
ARIAGridAccessibleWrap.cpp \
|
||||
nsAccessNodeWrap.cpp \
|
||||
nsAccessibleWrap.cpp \
|
||||
nsTextAccessibleWrap.cpp \
|
||||
nsDocAccessibleWrap.cpp \
|
||||
nsHTMLWin32ObjectAccessible.cpp \
|
||||
nsXULMenuAccessibleWrap.cpp \
|
||||
@ -43,6 +42,7 @@ CPPSRCS = \
|
||||
CAccessibleValue.cpp \
|
||||
Compatibility.cpp \
|
||||
RootAccessibleWrap.cpp \
|
||||
TextLeafAccessibleWrap.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
|
@ -3,7 +3,7 @@
|
||||
* 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/. */
|
||||
|
||||
#include "nsTextAccessibleWrap.h"
|
||||
#include "TextLeafAccessibleWrap.h"
|
||||
#include "ISimpleDOMText_i.c"
|
||||
|
||||
#include "nsCoreUtils.h"
|
||||
@ -19,26 +19,29 @@
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsTextAccessibleWrap Accessible
|
||||
// TextLeafAccessibleWrap
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsTextAccessibleWrap::
|
||||
nsTextAccessibleWrap(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
nsTextAccessible(aContent, aDoc)
|
||||
TextLeafAccessibleWrap::
|
||||
TextLeafAccessibleWrap(nsIContent* aContent, nsDocAccessible* aDoc) :
|
||||
TextLeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) nsTextAccessibleWrap::AddRef()
|
||||
STDMETHODIMP_(ULONG)
|
||||
TextLeafAccessibleWrap::AddRef()
|
||||
{
|
||||
return nsAccessNode::AddRef();
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) nsTextAccessibleWrap::Release()
|
||||
STDMETHODIMP_(ULONG)
|
||||
TextLeafAccessibleWrap::Release()
|
||||
{
|
||||
return nsAccessNode::Release();
|
||||
}
|
||||
|
||||
STDMETHODIMP nsTextAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
|
||||
STDMETHODIMP
|
||||
TextLeafAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
|
||||
{
|
||||
*ppv = nsnull;
|
||||
|
||||
@ -55,7 +58,8 @@ STDMETHODIMP nsTextAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsTextAccessibleWrap::get_domText(
|
||||
STDMETHODIMP
|
||||
TextLeafAccessibleWrap::get_domText(
|
||||
/* [retval][out] */ BSTR __RPC_FAR *aDomText)
|
||||
{
|
||||
__try {
|
||||
@ -80,7 +84,8 @@ __try {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsTextAccessibleWrap::get_clippedSubstringBounds(
|
||||
STDMETHODIMP
|
||||
TextLeafAccessibleWrap::get_clippedSubstringBounds(
|
||||
/* [in] */ unsigned int aStartIndex,
|
||||
/* [in] */ unsigned int aEndIndex,
|
||||
/* [out] */ int __RPC_FAR *aX,
|
||||
@ -117,7 +122,8 @@ __try {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsTextAccessibleWrap::get_unclippedSubstringBounds(
|
||||
STDMETHODIMP
|
||||
TextLeafAccessibleWrap::get_unclippedSubstringBounds(
|
||||
/* [in] */ unsigned int aStartIndex,
|
||||
/* [in] */ unsigned int aEndIndex,
|
||||
/* [out] */ int __RPC_FAR *aX,
|
||||
@ -140,8 +146,8 @@ __try {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP nsTextAccessibleWrap::scrollToSubstring(
|
||||
STDMETHODIMP
|
||||
TextLeafAccessibleWrap::scrollToSubstring(
|
||||
/* [in] */ unsigned int aStartIndex,
|
||||
/* [in] */ unsigned int aEndIndex)
|
||||
{
|
||||
@ -160,10 +166,11 @@ __try {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
nsIFrame* nsTextAccessibleWrap::GetPointFromOffset(nsIFrame *aContainingFrame,
|
||||
PRInt32 aOffset,
|
||||
bool aPreferNext,
|
||||
nsPoint& aOutPoint)
|
||||
nsIFrame*
|
||||
TextLeafAccessibleWrap::GetPointFromOffset(nsIFrame* aContainingFrame,
|
||||
PRInt32 aOffset,
|
||||
bool aPreferNext,
|
||||
nsPoint& aOutPoint)
|
||||
{
|
||||
nsIFrame *textFrame = nsnull;
|
||||
PRInt32 outOffset;
|
||||
@ -179,9 +186,13 @@ nsIFrame* nsTextAccessibleWrap::GetPointFromOffset(nsIFrame *aContainingFrame,
|
||||
/*
|
||||
* Given an offset, the x, y, width, and height values are filled appropriately.
|
||||
*/
|
||||
nsresult nsTextAccessibleWrap::GetCharacterExtents(PRInt32 aStartOffset, PRInt32 aEndOffset,
|
||||
PRInt32* aX, PRInt32* aY,
|
||||
PRInt32* aWidth, PRInt32* aHeight)
|
||||
nsresult
|
||||
TextLeafAccessibleWrap::GetCharacterExtents(PRInt32 aStartOffset,
|
||||
PRInt32 aEndOffset,
|
||||
PRInt32* aX,
|
||||
PRInt32* aY,
|
||||
PRInt32* aWidth,
|
||||
PRInt32* aHeight)
|
||||
{
|
||||
*aX = *aY = *aWidth = *aHeight = 0;
|
||||
|
||||
@ -221,7 +232,8 @@ nsresult nsTextAccessibleWrap::GetCharacterExtents(PRInt32 aStartOffset, PRInt32
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsTextAccessibleWrap::get_fontFamily(
|
||||
STDMETHODIMP
|
||||
TextLeafAccessibleWrap::get_fontFamily(
|
||||
/* [retval][out] */ BSTR __RPC_FAR *aFontFamily)
|
||||
{
|
||||
__try {
|
@ -3,22 +3,25 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef _nsTextAccessibleWrap_H_
|
||||
#define _nsTextAccessibleWrap_H_
|
||||
#ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
#define mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
|
||||
#include "nsTextAccessible.h"
|
||||
#include "TextLeafAccessible.h"
|
||||
#include "ISimpleDOMText.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
class nsIFrame;
|
||||
class nsRenderingContext;
|
||||
|
||||
class nsTextAccessibleWrap : public nsTextAccessible,
|
||||
public ISimpleDOMText
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class TextLeafAccessibleWrap : public TextLeafAccessible,
|
||||
public ISimpleDOMText
|
||||
{
|
||||
public:
|
||||
nsTextAccessibleWrap(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
virtual ~nsTextAccessibleWrap() {}
|
||||
TextLeafAccessibleWrap(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
virtual ~TextLeafAccessibleWrap() {}
|
||||
|
||||
// IUnknown methods - see iunknown.h for documentation
|
||||
STDMETHODIMP_(ULONG) AddRef();
|
||||
@ -61,5 +64,8 @@ public:
|
||||
PRInt32 aOffset, bool aPreferNext, nsPoint& aOutPoint);
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
@ -1686,7 +1686,7 @@ nsAccessibleWrap::GetHWNDFor(nsAccessible *aAccessible)
|
||||
bool isVisible = false;
|
||||
widget->IsVisible(isVisible);
|
||||
if (isVisible) {
|
||||
nsCOMPtr<nsIPresShell> shell(document->PresShell());
|
||||
nsIPresShell* shell = document->PresShell();
|
||||
nsIViewManager* vm = shell->GetViewManager();
|
||||
if (vm) {
|
||||
nsCOMPtr<nsIWidget> rootWidget;
|
||||
|
@ -3,11 +3,17 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef _nsTextAccessibleWrap_H_
|
||||
#define _nsTextAccessibleWrap_H_
|
||||
#ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
#define mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
|
||||
#include "nsTextAccessible.h"
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
typedef class nsTextAccessible nsTextAccessibleWrap;
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class TextLeafAccessible TextLeafAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -187,7 +187,7 @@ nsXULTreeAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
return nsnull;
|
||||
|
||||
nsPresContext *presContext = frame->PresContext();
|
||||
nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
|
||||
nsIPresShell* presShell = presContext->PresShell();
|
||||
|
||||
nsIFrame *rootFrame = presShell->GetRootFrame();
|
||||
NS_ENSURE_TRUE(rootFrame, nsnull);
|
||||
|
@ -630,7 +630,7 @@ nsXULTreeGridRowAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
return nsnull;
|
||||
|
||||
nsPresContext *presContext = frame->PresContext();
|
||||
nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
|
||||
nsIPresShell* presShell = presContext->PresShell();
|
||||
|
||||
nsIFrame *rootFrame = presShell->GetRootFrame();
|
||||
NS_ENSURE_TRUE(rootFrame, nsnull);
|
||||
|
@ -21,6 +21,14 @@
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// null getText
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var emptyTextAcc = getAccessible("nulltext", [nsIAccessibleText]);
|
||||
is(emptyTextAcc.getText(0, -1), "", "getText() END_OF_TEXT with null string");
|
||||
is(emptyTextAcc.getText(0, 0), "", "getText() Len==0 with null string");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// hypertext
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -85,11 +93,19 @@
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=638326">
|
||||
Bug 638326
|
||||
</a>
|
||||
<a target="_blank"
|
||||
title="getText(0, -1) fails with empty text"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=749810">
|
||||
Bug 749810
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="nulltext"></div>
|
||||
|
||||
<div id="hypertext">hello <a>friend</a> see <img></div>
|
||||
<div id="hypertext2">hello <a>friend</a> see <input></div>
|
||||
<ol id="list"><li id="listitem">foo</li></ol>
|
||||
|
@ -961,7 +961,6 @@ pref("services.sync.prefs.sync.browser.tabs.closeButtons", true);
|
||||
pref("services.sync.prefs.sync.browser.tabs.loadInBackground", true);
|
||||
pref("services.sync.prefs.sync.browser.tabs.warnOnClose", true);
|
||||
pref("services.sync.prefs.sync.browser.tabs.warnOnOpen", true);
|
||||
pref("services.sync.prefs.sync.browser.tabs.onTop", true);
|
||||
pref("services.sync.prefs.sync.browser.urlbar.autocomplete.enabled", true);
|
||||
pref("services.sync.prefs.sync.browser.urlbar.default.behavior", true);
|
||||
pref("services.sync.prefs.sync.browser.urlbar.maxRichResults", true);
|
||||
|
@ -116,18 +116,12 @@ function appUpdater()
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isPending) {
|
||||
if (this.isPending || this.isApplied) {
|
||||
this.setupUpdateButton("update.restart." +
|
||||
(this.isMajor ? "upgradeButton" : "updateButton"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isApplied) {
|
||||
this.setupUpdateButton("update.restart." +
|
||||
(this.isMajor ? "upgradeButton" : "restartButton"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isDownloading) {
|
||||
this.startDownload();
|
||||
return;
|
||||
@ -539,7 +533,7 @@ appUpdater.prototype =
|
||||
if (status == "applied" || status == "applied-service") {
|
||||
self.selectPanel("updateButtonBox");
|
||||
self.setupUpdateButton("update.restart." +
|
||||
(self.isMajor ? "upgradeButton" : "restartButton"));
|
||||
(self.isMajor ? "upgradeButton" : "updateButton"));
|
||||
timer.cancel();
|
||||
timer = null;
|
||||
} else if (status == "failed") {
|
||||
|
@ -375,7 +375,7 @@
|
||||
#endif
|
||||
oncommand="openPreferences();">
|
||||
<menupopup id="appmenu_customizeMenu"
|
||||
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleTabsOnTop').previousSibling);">
|
||||
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleToolbarsSeparator'));">
|
||||
<menuitem id="appmenu_preferences"
|
||||
#ifdef XP_UNIX
|
||||
label="&preferencesCmdUnix.label;"
|
||||
@ -384,7 +384,7 @@
|
||||
#endif
|
||||
oncommand="openPreferences();"/>
|
||||
<menuseparator/>
|
||||
<menuseparator/>
|
||||
<menuseparator id="appmenu_toggleToolbarsSeparator"/>
|
||||
<menuitem id="appmenu_toggleTabsOnTop"
|
||||
label="&viewTabsOnTop.label;"
|
||||
type="checkbox"
|
||||
|
@ -184,7 +184,6 @@
|
||||
type="checkbox"
|
||||
label="&viewTabsOnTop.label;"
|
||||
accesskey="&viewTabsOnTop.accesskey;"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_customizeToolbars"
|
||||
label="&viewCustomizeToolbar.label;"
|
||||
accesskey="&viewCustomizeToolbar.accesskey;"
|
||||
|
@ -4299,6 +4299,12 @@ var FullScreen = {
|
||||
// Add a listener to clean up state after the warning is hidden.
|
||||
this.warningBox.addEventListener("transitionend", this);
|
||||
this.warningBox.removeAttribute("hidden");
|
||||
} else {
|
||||
if (this.warningFadeOutTimeout) {
|
||||
clearTimeout(this.warningFadeOutTimeout);
|
||||
this.warningFadeOutTimeout = null;
|
||||
}
|
||||
this.warningBox.removeAttribute("fade-warning-out");
|
||||
}
|
||||
|
||||
// If fullscreen mode has not yet been approved for the fullscreen
|
||||
@ -4308,9 +4314,10 @@ var FullScreen = {
|
||||
// showing a local file or a local data URI, and we require explicit
|
||||
// approval every time.
|
||||
let authUI = document.getElementById("full-screen-approval-pane");
|
||||
if (isApproved)
|
||||
if (isApproved) {
|
||||
authUI.setAttribute("hidden", "true");
|
||||
else {
|
||||
this.warningBox.removeAttribute("obscure-browser");
|
||||
} else {
|
||||
// Partially obscure the <browser> element underneath the approval UI.
|
||||
this.warningBox.setAttribute("obscure-browser", "true");
|
||||
authUI.removeAttribute("hidden");
|
||||
@ -5430,6 +5437,12 @@ function setToolbarVisibility(toolbar, isVisible) {
|
||||
var TabsOnTop = {
|
||||
init: function TabsOnTop_init() {
|
||||
Services.prefs.addObserver(this._prefName, this, false);
|
||||
|
||||
// Only show the toggle UI if the user disabled tabs on top.
|
||||
if (Services.prefs.getBoolPref(this._prefName)) {
|
||||
for (let item of document.querySelectorAll("menuitem[command=cmd_ToggleTabsOnTop]"))
|
||||
item.parentNode.removeChild(item);
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function TabsOnTop_uninit() {
|
||||
|
@ -204,7 +204,6 @@
|
||||
type="checkbox"
|
||||
label="&viewTabsOnTop.label;"
|
||||
accesskey="&viewTabsOnTop.accesskey;"/>
|
||||
<menuseparator/>
|
||||
<menuitem command="cmd_CustomizeToolbars"
|
||||
label="&viewCustomizeToolbar.label;"
|
||||
accesskey="&viewCustomizeToolbar.accesskey;"/>
|
||||
|
@ -156,8 +156,6 @@ update.openUpdateUI.applyButton.label=Apply Update…
|
||||
update.openUpdateUI.applyButton.accesskey=A
|
||||
update.restart.updateButton.label=Restart to Update
|
||||
update.restart.updateButton.accesskey=R
|
||||
update.restart.restartButton.label=Update & Restart
|
||||
update.restart.restartButton.accesskey=R
|
||||
update.openUpdateUI.upgradeButton.label=Upgrade Now…
|
||||
update.openUpdateUI.upgradeButton.accesskey=U
|
||||
update.restart.upgradeButton.label=Upgrade Now
|
||||
|
@ -309,7 +309,7 @@ WinNativeApp.prototype = {
|
||||
writer.setString("Webapp", "Profile", this.installDir.leafName);
|
||||
writer.setString("Webapp", "Executable", this.appNameAsFilename);
|
||||
writer.setString("WebappRT", "InstallDir", this.processFolder.path);
|
||||
writer.writeFile();
|
||||
writer.writeFile(null, Ci.nsIINIParserWriter.WRITE_UTF16);
|
||||
|
||||
// ${UninstallDir}/shortcuts_log.ini
|
||||
let shortcutLogsINI = this.uninstallDir.clone().QueryInterface(Ci.nsILocalFile);
|
||||
@ -319,7 +319,7 @@ WinNativeApp.prototype = {
|
||||
writer.setString("STARTMENU", "Shortcut0", this.appNameAsFilename + ".lnk");
|
||||
writer.setString("DESKTOP", "Shortcut0", this.appNameAsFilename + ".lnk");
|
||||
writer.setString("TASKBAR", "Migrated", "true");
|
||||
writer.writeFile();
|
||||
writer.writeFile(null, Ci.nsIINIParserWriter.WRITE_UTF16);
|
||||
|
||||
writer = null;
|
||||
factory = null;
|
||||
|
@ -138,7 +138,7 @@ class DeviceManagerADB(DeviceManager):
|
||||
return_code = m.group(1)
|
||||
outputfile.seek(-2, 2)
|
||||
outputfile.truncate() # truncate off the return code
|
||||
return return_code
|
||||
return int(return_code)
|
||||
|
||||
return None
|
||||
|
||||
|
@ -272,7 +272,7 @@ class DeviceManagerSUT(DeviceManager):
|
||||
if lastline:
|
||||
m = re.search('return code \[([0-9]+)\]', lastline)
|
||||
if m:
|
||||
return m.group(1)
|
||||
return int(m.group(1))
|
||||
|
||||
# woops, we couldn't find an end of line/return value
|
||||
return None
|
||||
|
@ -340,13 +340,16 @@ MAKE_JARS_FLAGS += --both-manifests
|
||||
endif
|
||||
|
||||
TAR_CREATE_FLAGS = -cvhf
|
||||
TAR_CREATE_FLAGS_QUIET = -chf
|
||||
|
||||
ifeq ($(OS_ARCH),BSD_OS)
|
||||
TAR_CREATE_FLAGS = -cvLf
|
||||
TAR_CREATE_FLAGS_QUIET = -cLf
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),OS2)
|
||||
TAR_CREATE_FLAGS = -cvf
|
||||
TAR_CREATE_FLAGS_QUIET = -cf
|
||||
endif
|
||||
|
||||
#
|
||||
|
@ -1388,6 +1388,12 @@ public:
|
||||
bool aClick, bool aIsUserTriggered,
|
||||
bool aIsTrusted);
|
||||
|
||||
/**
|
||||
* Get the link location.
|
||||
*/
|
||||
static void GetLinkLocation(mozilla::dom::Element* aElement,
|
||||
nsString& aLocationString);
|
||||
|
||||
/**
|
||||
* Return top-level widget in the parent chain.
|
||||
*/
|
||||
@ -2002,6 +2008,24 @@ public:
|
||||
static void SplitMimeType(const nsAString& aValue, nsString& aType,
|
||||
nsString& aParams);
|
||||
|
||||
/**
|
||||
* Takes a window and a string to check prefs against. Assumes that
|
||||
* the window is an app window, and that the pref is a comma
|
||||
* seperated list of app urls that have permission to use whatever
|
||||
* the preference refers to (for example, does the current window
|
||||
* have access to mozTelephony). Chrome is always given permissions
|
||||
* for the requested preference. Sets aAllowed based on preference.
|
||||
*
|
||||
* @param aWindow Current window asking for preference permission
|
||||
* @param aPrefURL Preference name
|
||||
* @param aAllowed [out] outparam on whether or not window is allowed
|
||||
* to access pref
|
||||
*
|
||||
* @return NS_OK on successful preference lookup, error code otherwise
|
||||
*/
|
||||
static nsresult IsOnPrefWhitelist(nsPIDOMWindow* aWindow,
|
||||
const char* aPrefURL, bool *aAllowed);
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
@ -11,8 +11,9 @@
|
||||
*/
|
||||
|
||||
// Module stuff
|
||||
var EXPORTED_SYMBOLS = ["CSPRep", "CSPSourceList", "CSPSource",
|
||||
"CSPHost", "CSPWarning", "CSPError", "CSPdebug"];
|
||||
var EXPORTED_SYMBOLS = ["CSPRep", "CSPSourceList", "CSPSource", "CSPHost",
|
||||
"CSPWarning", "CSPError", "CSPdebug",
|
||||
"CSPViolationReportListener"];
|
||||
|
||||
|
||||
// these are not exported
|
||||
@ -1442,3 +1443,41 @@ CSPHost.prototype = {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Class that listens to violation report transmission and logs errors.
|
||||
*/
|
||||
function CSPViolationReportListener(reportURI) {
|
||||
this._reportURI = reportURI;
|
||||
}
|
||||
|
||||
CSPViolationReportListener.prototype = {
|
||||
_reportURI: null,
|
||||
|
||||
QueryInterface: function(iid) {
|
||||
if(iid.equals(Ci.nsIStreamListener) ||
|
||||
iid.equals(Ci.nsIRequestObserver) ||
|
||||
iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
onStopRequest:
|
||||
function(request, context, status) {
|
||||
if (!Components.isSuccessCode(status)) {
|
||||
CSPdebug("error " + status.toString(16) +
|
||||
" while sending violation report to " +
|
||||
this._reportURI);
|
||||
}
|
||||
},
|
||||
|
||||
onStartRequest:
|
||||
function(request, context) { },
|
||||
|
||||
onDataAvailable:
|
||||
function(request, context, inputStream, offset, count) { },
|
||||
|
||||
};
|
||||
|
||||
|
@ -116,6 +116,7 @@ protected:
|
||||
return !!uri;
|
||||
}
|
||||
|
||||
nsIURI* GetCachedURI() const { return mCachedURI; }
|
||||
bool HasCachedURI() const { return !!mCachedURI; }
|
||||
|
||||
private:
|
||||
|
@ -253,7 +253,8 @@ ContentSecurityPolicy.prototype = {
|
||||
if (aLineNum)
|
||||
report["csp-report"]["line-number"] = aLineNum;
|
||||
|
||||
CSPdebug("Constructed violation report:\n" + JSON.stringify(report));
|
||||
var reportString = JSON.stringify(report);
|
||||
CSPdebug("Constructed violation report:\n" + reportString);
|
||||
|
||||
CSPWarning("Directive \"" + violatedDirective + "\" violated"
|
||||
+ (blockedUri['asciiSpec'] ? " by " + blockedUri.asciiSpec : ""),
|
||||
@ -269,30 +270,56 @@ ContentSecurityPolicy.prototype = {
|
||||
if (uris[i] === "")
|
||||
continue;
|
||||
|
||||
var failure = function(aEvt) {
|
||||
if (req.readyState == 4 && req.status != 200) {
|
||||
CSPError("Failed to send report to " + uris[i]);
|
||||
}
|
||||
};
|
||||
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
|
||||
try {
|
||||
req.open("POST", uris[i], true);
|
||||
req.setRequestHeader('Content-Type', 'application/json');
|
||||
req.upload.addEventListener("error", failure, false);
|
||||
req.upload.addEventListener("abort", failure, false);
|
||||
var chan = Services.io.newChannel(uris[i], null, null);
|
||||
if(!chan) {
|
||||
CSPdebug("Error creating channel for " + uris[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// we need to set an nsIChannelEventSink on the XHR object
|
||||
var content = Cc["@mozilla.org/io/string-input-stream;1"]
|
||||
.createInstance(Ci.nsIStringInputStream);
|
||||
content.data = reportString + "\n\n";
|
||||
|
||||
// make sure this is an anonymous request (no cookies) so in case the
|
||||
// policy URI is injected, it can't be abused for CSRF.
|
||||
chan.loadFlags |= Ci.nsIChannel.LOAD_ANONYMOUS;
|
||||
|
||||
// we need to set an nsIChannelEventSink on the channel object
|
||||
// so we can tell it to not follow redirects when posting the reports
|
||||
req.channel.notificationCallbacks = new CSPReportRedirectSink();
|
||||
chan.notificationCallbacks = new CSPReportRedirectSink();
|
||||
|
||||
req.send(JSON.stringify(report));
|
||||
chan.QueryInterface(Ci.nsIUploadChannel)
|
||||
.setUploadStream(content, "application/json", content.available());
|
||||
|
||||
try {
|
||||
// if this is an HTTP channel, set the request method to post
|
||||
chan.QueryInterface(Ci.nsIHttpChannel);
|
||||
chan.requestMethod = "POST";
|
||||
} catch(e) {} // throws only if chan is not an nsIHttpChannel.
|
||||
|
||||
// check with the content policy service to see if we're allowed to
|
||||
// send this request.
|
||||
try {
|
||||
var contentPolicy = Cc["@mozilla.org/layout/content-policy;1"]
|
||||
.getService(Ci.nsIContentPolicy);
|
||||
if (contentPolicy.shouldLoad(Ci.nsIContentPolicy.TYPE_OTHER,
|
||||
chan.URI, null, null, null, null)
|
||||
!= Ci.nsIContentPolicy.ACCEPT) {
|
||||
continue; // skip unauthorized URIs
|
||||
}
|
||||
} catch(e) {
|
||||
continue; // refuse to load if we can't do a security check.
|
||||
}
|
||||
|
||||
//send data (and set up error notifications)
|
||||
chan.asyncOpen(new CSPViolationReportListener(uris[i]), null);
|
||||
CSPdebug("Sent violation report to " + uris[i]);
|
||||
} catch(e) {
|
||||
// it's possible that the URI was invalid, just log a
|
||||
// warning and skip over that.
|
||||
CSPWarning("Tried to send report to invalid URI: \"" + uris[i] + "\"");
|
||||
CSPWarning("error was: \"" + e + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,6 @@
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
@ -4490,6 +4489,19 @@ nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsContentUtils::GetLinkLocation(Element* aElement, nsString& aLocationString)
|
||||
{
|
||||
nsCOMPtr<nsIURI> hrefURI = aElement->GetHrefURI();
|
||||
if (hrefURI) {
|
||||
nsCAutoString specUTF8;
|
||||
nsresult rv = hrefURI->GetSpec(specUTF8);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
CopyUTF8toUTF16(specUTF8, aLocationString);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsIWidget*
|
||||
nsContentUtils::GetTopLevelWidget(nsIWidget* aWidget)
|
||||
@ -6666,3 +6678,77 @@ nsContentUtils::JSArrayToAtomArray(JSContext* aCx, const JS::Value& aJSArray,
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsContentUtils::IsOnPrefWhitelist(nsPIDOMWindow* aWindow,
|
||||
const char* aPrefURL, bool* aAllowed)
|
||||
{
|
||||
// Make sure we're dealing with an inner window.
|
||||
nsPIDOMWindow* innerWindow = aWindow->IsInnerWindow() ?
|
||||
aWindow :
|
||||
aWindow->GetCurrentInnerWindow();
|
||||
NS_ENSURE_TRUE(innerWindow, NS_ERROR_FAILURE);
|
||||
|
||||
// Make sure we're being called from a window that we have permission to
|
||||
// access.
|
||||
if (!nsContentUtils::CanCallerAccess(innerWindow)) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
// Need the document in order to make security decisions.
|
||||
nsCOMPtr<nsIDocument> document =
|
||||
do_QueryInterface(innerWindow->GetExtantDocument());
|
||||
NS_ENSURE_TRUE(document, NS_NOINTERFACE);
|
||||
|
||||
// Do security checks. We assume that chrome is always allowed.
|
||||
if (nsContentUtils::IsSystemPrincipal(document->NodePrincipal())) {
|
||||
*aAllowed = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We also allow a comma seperated list of pages specified by
|
||||
// preferences.
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
nsresult rv =
|
||||
document->NodePrincipal()->GetURI(getter_AddRefs(originalURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> documentURI;
|
||||
rv = originalURI->Clone(getter_AddRefs(documentURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Strip the query string (if there is one) before comparing.
|
||||
nsCOMPtr<nsIURL> documentURL = do_QueryInterface(documentURI);
|
||||
if (documentURL) {
|
||||
rv = documentURL->SetQuery(EmptyCString());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
bool allowed = false;
|
||||
|
||||
// The pref may not exist but in that case we deny access just as we do if
|
||||
// the url doesn't match.
|
||||
nsCString whitelist;
|
||||
if (NS_SUCCEEDED(Preferences::GetCString(aPrefURL,
|
||||
&whitelist))) {
|
||||
nsCOMPtr<nsIIOService> ios = do_GetIOService();
|
||||
NS_ENSURE_TRUE(ios, NS_ERROR_FAILURE);
|
||||
|
||||
nsCCharSeparatedTokenizer tokenizer(whitelist, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), tokenizer.nextToken(),
|
||||
nsnull, nsnull, ios))) {
|
||||
rv = documentURI->EqualsExceptRef(uri, &allowed);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (allowed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*aAllowed = allowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -68,7 +68,6 @@
|
||||
#include "nsIJSON.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsIFileChannel.h"
|
||||
#include "nsIMultiPartChannel.h"
|
||||
#include "nsIRefreshURI.h"
|
||||
|
@ -65,7 +65,6 @@
|
||||
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsXBLBinding.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIBoxObject.h"
|
||||
#include "nsClientRect.h"
|
||||
|
153
content/base/test/unit/test_cspreports.js
Normal file
153
content/base/test/unit/test_cspreports.js
Normal file
@ -0,0 +1,153 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Content Security Policy Data Structures testing code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Sid Stamm <sid@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import('resource://gre/modules/CSPUtils.jsm');
|
||||
Components.utils.import('resource://gre/modules/NetUtil.jsm');
|
||||
|
||||
// load the HTTP server
|
||||
do_load_httpd_js();
|
||||
|
||||
const REPORT_SERVER_PORT = 9000;
|
||||
const REPORT_SERVER_URI = "http://localhost";
|
||||
const REPORT_SERVER_PATH = "/report";
|
||||
|
||||
var httpServer = null;
|
||||
var testsToFinish = 0;
|
||||
|
||||
/**
|
||||
* Construct a callback that listens to a report submission and either passes
|
||||
* or fails a test based on what it gets.
|
||||
*/
|
||||
function makeReportHandler(testpath, message, expectedJSON) {
|
||||
return function(request, response) {
|
||||
// we only like "POST" submissions for reports!
|
||||
if (request.method !== "POST") {
|
||||
do_throw("violation report should be a POST request");
|
||||
return;
|
||||
}
|
||||
|
||||
// obtain violation report
|
||||
var reportObj = JSON.parse(
|
||||
NetUtil.readInputStreamToString(
|
||||
request.bodyInputStream,
|
||||
request.bodyInputStream.available()));
|
||||
|
||||
dump("GOT REPORT:\n" + JSON.stringify(reportObj) + "\n");
|
||||
dump("TESTPATH: " + testpath + "\n");
|
||||
dump("EXPECTED: \n" + JSON.stringify(expectedJSON) + "\n\n");
|
||||
|
||||
for (var i in expectedJSON)
|
||||
do_check_eq(expectedJSON[i], reportObj['csp-report'][i]);
|
||||
|
||||
// self-destroy
|
||||
testsToFinish--;
|
||||
httpServer.registerPathHandler(testpath, null);
|
||||
if (testsToFinish < 1)
|
||||
httpServer.stop(do_test_finished);
|
||||
else
|
||||
do_test_finished();
|
||||
};
|
||||
}
|
||||
|
||||
function makeTest(id, expectedJSON, callback) {
|
||||
testsToFinish++;
|
||||
do_test_pending();
|
||||
|
||||
// set up a new CSP instance for each test.
|
||||
var csp = Cc["@mozilla.org/contentsecuritypolicy;1"]
|
||||
.createInstance(Ci.nsIContentSecurityPolicy);
|
||||
var policy = "allow 'none'; " +
|
||||
"report-uri " + REPORT_SERVER_URI +
|
||||
":" + REPORT_SERVER_PORT +
|
||||
"/test" + id;
|
||||
var selfuri = NetUtil.newURI(REPORT_SERVER_URI +
|
||||
":" + REPORT_SERVER_PORT +
|
||||
"/foo/self");
|
||||
var selfchan = NetUtil.newChannel(selfuri);
|
||||
|
||||
dump("Created test " + id + " : " + policy + "\n\n");
|
||||
|
||||
// make the reports seem authentic by "binding" them to a channel.
|
||||
csp.scanRequestData(selfchan);
|
||||
|
||||
// Load up the policy
|
||||
csp.refinePolicy(policy, selfuri);
|
||||
|
||||
// prime the report server
|
||||
var handler = makeReportHandler("/test" + id, "Test " + id, expectedJSON);
|
||||
httpServer.registerPathHandler("/test" + id, handler);
|
||||
|
||||
//trigger the violation
|
||||
callback(csp);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
var selfuri = NetUtil.newURI(REPORT_SERVER_URI +
|
||||
":" + REPORT_SERVER_PORT +
|
||||
"/foo/self");
|
||||
|
||||
httpServer = new nsHttpServer();
|
||||
httpServer.start(REPORT_SERVER_PORT);
|
||||
|
||||
// test that inline script violations cause a report.
|
||||
makeTest(0, {"blocked-uri": "self"},
|
||||
function(csp) {
|
||||
if(!csp.allowsInlineScript) {
|
||||
// force the logging, since the getter doesn't.
|
||||
csp.logViolationDetails(Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_INLINE_SCRIPT,
|
||||
selfuri.asciiSpec,
|
||||
"script sample",
|
||||
0);
|
||||
}
|
||||
});
|
||||
|
||||
makeTest(1, {"blocked-uri": "self"},
|
||||
function(csp) {
|
||||
if(!csp.allowsEval) {
|
||||
// force the logging, since the getter doesn't.
|
||||
csp.logViolationDetails(Ci.nsIContentSecurityPolicy.VIOLATION_TYPE_INLINE_SCRIPT,
|
||||
selfuri.asciiSpec,
|
||||
"script sample",
|
||||
1);
|
||||
}
|
||||
});
|
||||
|
||||
makeTest(2, {"blocked-uri": "http://blocked.test/foo.js"},
|
||||
function(csp) {
|
||||
csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT,
|
||||
NetUtil.newURI("http://blocked.test/foo.js"),
|
||||
null, null, null, null);
|
||||
});
|
||||
}
|
@ -6,6 +6,7 @@ tail =
|
||||
[test_bug558431.js]
|
||||
[test_bug737966.js]
|
||||
[test_csputils.js]
|
||||
[test_cspreports.js]
|
||||
[test_error_codes.js]
|
||||
[test_thirdpartyutil.js]
|
||||
[test_xhr_standalone.js]
|
||||
|
@ -80,7 +80,6 @@ WebGLContext::WebGLContext()
|
||||
mGeneration = 0;
|
||||
mInvalidated = false;
|
||||
mResetLayer = true;
|
||||
mVerbose = false;
|
||||
mOptionsFrozen = false;
|
||||
|
||||
mActiveTexture = 0;
|
||||
@ -153,6 +152,8 @@ WebGLContext::WebGLContext()
|
||||
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mContextStatus = ContextStable;
|
||||
mContextLostErrorSet = false;
|
||||
|
||||
mAlreadyReportedMessages = 0;
|
||||
}
|
||||
|
||||
WebGLContext::~WebGLContext()
|
||||
@ -203,8 +204,6 @@ WebGLContext::DestroyResourcesAndContext()
|
||||
mShaders.Last()->DeleteOnce();
|
||||
while (mPrograms.Length())
|
||||
mPrograms.Last()->DeleteOnce();
|
||||
while (mUniformLocations.Length())
|
||||
mUniformLocations.Last()->DeleteOnce();
|
||||
|
||||
if (mBlackTexturesAreInitialized) {
|
||||
gl->fDeleteTextures(1, &mBlackTexture2D);
|
||||
@ -298,7 +297,7 @@ WebGLContext::SetContextOptions(nsIPropertyBag *aOptions)
|
||||
newOpts.depth |= newOpts.stencil;
|
||||
|
||||
#if 0
|
||||
LogMessage("aaHint: %d stencil: %d depth: %d alpha: %d premult: %d preserve: %d\n",
|
||||
GenerateWarning("aaHint: %d stencil: %d depth: %d alpha: %d premult: %d preserve: %d\n",
|
||||
newOpts.antialias ? 1 : 0,
|
||||
newOpts.stencil ? 1 : 0,
|
||||
newOpts.depth ? 1 : 0,
|
||||
@ -373,16 +372,12 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
Preferences::GetBool("webgl.force-enabled", false);
|
||||
bool disabled =
|
||||
Preferences::GetBool("webgl.disabled", false);
|
||||
bool verbose =
|
||||
Preferences::GetBool("webgl.verbose", false);
|
||||
|
||||
ScopedGfxFeatureReporter reporter("WebGL", forceEnabled);
|
||||
|
||||
if (disabled)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mVerbose = verbose;
|
||||
|
||||
// We're going to create an entirely new context. If our
|
||||
// generation is not 0 right now (that is, if this isn't the first
|
||||
// context we're creating), we may have to dispatch a context lost
|
||||
@ -496,7 +491,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
if (renderer == gl::GLContext::RendererAdreno200 ||
|
||||
renderer == gl::GLContext::RendererAdreno205)
|
||||
{
|
||||
LogMessage("WebGL blocked on this Adreno driver!");
|
||||
GenerateWarning("WebGL blocked on this Adreno driver!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -506,10 +501,10 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
if (forceOSMesa) {
|
||||
gl = gl::GLContextProviderOSMesa::CreateOffscreen(gfxIntSize(width, height), format);
|
||||
if (!gl || !InitAndValidateGL()) {
|
||||
LogMessage("OSMesa forced, but creating context failed -- aborting!");
|
||||
GenerateWarning("OSMesa forced, but creating context failed -- aborting!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
LogMessage("Using software rendering via OSMesa (THIS WILL BE SLOW)");
|
||||
GenerateWarning("Using software rendering via OSMesa (THIS WILL BE SLOW)");
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
@ -517,7 +512,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
if (!gl && (preferEGL || useANGLE) && !preferOpenGL) {
|
||||
gl = gl::GLContextProviderEGL::CreateOffscreen(gfxIntSize(width, height), format);
|
||||
if (!gl || !InitAndValidateGL()) {
|
||||
LogMessage("Error during ANGLE OpenGL ES initialization");
|
||||
GenerateWarning("Error during ANGLE OpenGL ES initialization");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -527,7 +522,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
if (!gl && useOpenGL) {
|
||||
gl = gl::GLContextProvider::CreateOffscreen(gfxIntSize(width, height), format);
|
||||
if (gl && !InitAndValidateGL()) {
|
||||
LogMessage("Error during OpenGL initialization");
|
||||
GenerateWarning("Error during OpenGL initialization");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
@ -537,16 +532,16 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
gl = gl::GLContextProviderOSMesa::CreateOffscreen(gfxIntSize(width, height), format);
|
||||
if (gl) {
|
||||
if (!InitAndValidateGL()) {
|
||||
LogMessage("Error during OSMesa initialization");
|
||||
GenerateWarning("Error during OSMesa initialization");
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
LogMessage("Using software rendering via OSMesa (THIS WILL BE SLOW)");
|
||||
GenerateWarning("Using software rendering via OSMesa (THIS WILL BE SLOW)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!gl) {
|
||||
LogMessage("Can't get a usable WebGL context");
|
||||
GenerateWarning("Can't get a usable WebGL context");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -386,7 +386,7 @@ protected:
|
||||
T *mRawPtr;
|
||||
};
|
||||
|
||||
typedef PRUint64 WebGLMonotonicHandle;
|
||||
typedef uint64_t WebGLMonotonicHandle;
|
||||
|
||||
/* WebGLFastArray offers a fast array for the use case where all what one needs is to append
|
||||
* and remove elements. Removal is fast because the array is always kept sorted with respect
|
||||
@ -601,7 +601,7 @@ public:
|
||||
void ErrorInvalidOperation(const char *fmt = 0, ...);
|
||||
void ErrorInvalidValue(const char *fmt = 0, ...);
|
||||
void ErrorInvalidFramebufferOperation(const char *fmt = 0, ...);
|
||||
void ErrorInvalidEnumInfo(const char *info, PRUint32 enumvalue) {
|
||||
void ErrorInvalidEnumInfo(const char *info, WebGLenum enumvalue) {
|
||||
return ErrorInvalidEnum("%s: invalid enum value 0x%x", info, enumvalue);
|
||||
}
|
||||
void ErrorOutOfMemory(const char *fmt = 0, ...);
|
||||
@ -623,14 +623,14 @@ public:
|
||||
|
||||
// a number that increments every time we have an event that causes
|
||||
// all context resources to be lost.
|
||||
PRUint32 Generation() { return mGeneration.value(); }
|
||||
uint32_t Generation() { return mGeneration.value(); }
|
||||
|
||||
const WebGLRectangleObject *FramebufferRectangleObject() const;
|
||||
|
||||
// this is similar to GLContext::ClearSafely, but is more comprehensive
|
||||
// (takes care of scissor, stencil write mask, dithering, viewport...)
|
||||
// WebGL has more complex needs than GLContext as content controls GL state.
|
||||
void ForceClearFramebufferWithDefaultValues(PRUint32 mask, const nsIntRect& viewportRect);
|
||||
void ForceClearFramebufferWithDefaultValues(uint32_t mask, const nsIntRect& viewportRect);
|
||||
|
||||
// if the preserveDrawingBuffer context option is false, we need to clear the back buffer
|
||||
// after it's been presented to the compositor. This function does that if needed.
|
||||
@ -1094,8 +1094,8 @@ protected:
|
||||
|
||||
static CheckedUint32 GetImageSize(WebGLsizei height,
|
||||
WebGLsizei width,
|
||||
PRUint32 pixelSize,
|
||||
PRUint32 alignment);
|
||||
uint32_t pixelSize,
|
||||
uint32_t alignment);
|
||||
|
||||
// Returns x rounded to the next highest multiple of y.
|
||||
static CheckedUint32 RoundedToNextMultipleOf(CheckedUint32 x, CheckedUint32 y) {
|
||||
@ -1112,7 +1112,6 @@ protected:
|
||||
|
||||
bool mInvalidated;
|
||||
bool mResetLayer;
|
||||
bool mVerbose;
|
||||
bool mOptionsFrozen;
|
||||
bool mMinCapability;
|
||||
bool mDisableExtensions;
|
||||
@ -1128,15 +1127,15 @@ protected:
|
||||
bool mShaderValidation;
|
||||
|
||||
// some GL constants
|
||||
PRInt32 mGLMaxVertexAttribs;
|
||||
PRInt32 mGLMaxTextureUnits;
|
||||
PRInt32 mGLMaxTextureSize;
|
||||
PRInt32 mGLMaxCubeMapTextureSize;
|
||||
PRInt32 mGLMaxTextureImageUnits;
|
||||
PRInt32 mGLMaxVertexTextureImageUnits;
|
||||
PRInt32 mGLMaxVaryingVectors;
|
||||
PRInt32 mGLMaxFragmentUniformVectors;
|
||||
PRInt32 mGLMaxVertexUniformVectors;
|
||||
int32_t mGLMaxVertexAttribs;
|
||||
int32_t mGLMaxTextureUnits;
|
||||
int32_t mGLMaxTextureSize;
|
||||
int32_t mGLMaxCubeMapTextureSize;
|
||||
int32_t mGLMaxTextureImageUnits;
|
||||
int32_t mGLMaxVertexTextureImageUnits;
|
||||
int32_t mGLMaxVaryingVectors;
|
||||
int32_t mGLMaxFragmentUniformVectors;
|
||||
int32_t mGLMaxVertexUniformVectors;
|
||||
|
||||
// Represents current status, or state, of the context. That is, is it lost
|
||||
// or stable and what part of the context lost process are we currently at.
|
||||
@ -1176,7 +1175,7 @@ protected:
|
||||
nsTArray<WebGLenum> mCompressedTextureFormats;
|
||||
|
||||
bool InitAndValidateGL();
|
||||
bool ValidateBuffers(PRInt32* maxAllowedCount, const char *info);
|
||||
bool ValidateBuffers(int32_t *maxAllowedCount, const char *info);
|
||||
bool ValidateCapabilityEnum(WebGLenum cap, const char *info);
|
||||
bool ValidateBlendEquationEnum(WebGLenum cap, const char *info);
|
||||
bool ValidateBlendFuncDstEnum(WebGLenum mode, const char *info);
|
||||
@ -1188,7 +1187,7 @@ protected:
|
||||
bool ValidateFaceEnum(WebGLenum face, const char *info);
|
||||
bool ValidateBufferUsageEnum(WebGLenum target, const char *info);
|
||||
bool ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
|
||||
PRUint32 *texelSize, const char *info);
|
||||
uint32_t *texelSize, const char *info);
|
||||
bool ValidateDrawModeEnum(WebGLenum mode, const char *info);
|
||||
bool ValidateAttribIndex(WebGLuint index, const char *info);
|
||||
bool ValidateStencilParamsForDrawCall();
|
||||
@ -1201,7 +1200,7 @@ protected:
|
||||
bool ValidateCompressedTextureSize(WebGLint level, WebGLenum format, WebGLsizei width, WebGLsizei height, uint32_t byteLength, const char* info);
|
||||
bool ValidateLevelWidthHeightForTarget(WebGLenum target, WebGLint level, WebGLsizei width, WebGLsizei height, const char* info);
|
||||
|
||||
static PRUint32 GetBitsPerTexel(WebGLenum format, WebGLenum type);
|
||||
static uint32_t GetBitsPerTexel(WebGLenum format, WebGLenum type);
|
||||
|
||||
void Invalidate();
|
||||
void DestroyResourcesAndContext();
|
||||
@ -1212,21 +1211,21 @@ protected:
|
||||
void TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum internalformat,
|
||||
WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero, WebGLint border,
|
||||
WebGLenum format, WebGLenum type,
|
||||
void *data, PRUint32 byteLength,
|
||||
void *data, uint32_t byteLength,
|
||||
int jsArrayType,
|
||||
WebGLTexelFormat srcFormat, bool srcPremultiplied);
|
||||
void TexSubImage2D_base(WebGLenum target, WebGLint level,
|
||||
WebGLint xoffset, WebGLint yoffset,
|
||||
WebGLsizei width, WebGLsizei height, WebGLsizei srcStrideOrZero,
|
||||
WebGLenum format, WebGLenum type,
|
||||
void *pixels, PRUint32 byteLength,
|
||||
void *pixels, uint32_t byteLength,
|
||||
int jsArrayType,
|
||||
WebGLTexelFormat srcFormat, bool srcPremultiplied);
|
||||
void TexParameter_base(WebGLenum target, WebGLenum pname,
|
||||
WebGLint *intParamPtr, WebGLfloat *floatParamPtr);
|
||||
|
||||
void ConvertImage(size_t width, size_t height, size_t srcStride, size_t dstStride,
|
||||
const PRUint8*src, PRUint8 *dst,
|
||||
const uint8_t* src, uint8_t *dst,
|
||||
WebGLTexelFormat srcFormat, bool srcPremultiplied,
|
||||
WebGLTexelFormat dstFormat, bool dstPremultiplied,
|
||||
size_t dstTexelSize);
|
||||
@ -1267,7 +1266,7 @@ private:
|
||||
bool ValidateObjectAssumeNonNull(const char* info, ObjectType *aObject);
|
||||
|
||||
protected:
|
||||
PRInt32 MaxTextureSizeForTarget(WebGLenum target) const {
|
||||
int32_t MaxTextureSizeForTarget(WebGLenum target) const {
|
||||
return target == LOCAL_GL_TEXTURE_2D ? mGLMaxTextureSize : mGLMaxCubeMapTextureSize;
|
||||
}
|
||||
|
||||
@ -1307,7 +1306,7 @@ protected:
|
||||
|
||||
WebGLRefPtr<WebGLProgram> mCurrentProgram;
|
||||
|
||||
PRUint32 mMaxFramebufferColorAttachments;
|
||||
uint32_t mMaxFramebufferColorAttachments;
|
||||
|
||||
WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer;
|
||||
WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer;
|
||||
@ -1318,10 +1317,9 @@ protected:
|
||||
WebGLFastArray<WebGLShader*> mShaders;
|
||||
WebGLFastArray<WebGLRenderbuffer*> mRenderbuffers;
|
||||
WebGLFastArray<WebGLFramebuffer*> mFramebuffers;
|
||||
WebGLFastArray<WebGLUniformLocation*> mUniformLocations;
|
||||
|
||||
// PixelStore parameters
|
||||
PRUint32 mPixelStorePackAlignment, mPixelStoreUnpackAlignment, mPixelStoreColorspaceConversion;
|
||||
uint32_t mPixelStorePackAlignment, mPixelStoreUnpackAlignment, mPixelStoreColorspaceConversion;
|
||||
bool mPixelStoreFlipY, mPixelStorePremultiplyAlpha;
|
||||
|
||||
FakeBlackStatus mFakeBlackStatus;
|
||||
@ -1355,6 +1353,8 @@ protected:
|
||||
ContextStatus mContextStatus;
|
||||
bool mContextLostErrorSet;
|
||||
|
||||
int mAlreadyReportedMessages;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime
|
||||
// Debouncing note: we don't want to switch GPUs too frequently, so try to not create and destroy
|
||||
@ -1368,10 +1368,8 @@ protected:
|
||||
|
||||
public:
|
||||
// console logging helpers
|
||||
static void LogMessage(const char *fmt, ...);
|
||||
static void LogMessage(const char *fmt, va_list ap);
|
||||
void LogMessageIfVerbose(const char *fmt, ...);
|
||||
void LogMessageIfVerbose(const char *fmt, va_list ap);
|
||||
void GenerateWarning(const char *fmt, ...);
|
||||
void GenerateWarning(const char *fmt, va_list ap);
|
||||
|
||||
friend class WebGLTexture;
|
||||
friend class WebGLFramebuffer;
|
||||
@ -1402,7 +1400,7 @@ public:
|
||||
|
||||
protected:
|
||||
WebGLContext *mContext;
|
||||
PRUint32 mContextGeneration;
|
||||
uint32_t mContextGeneration;
|
||||
};
|
||||
|
||||
struct WebGLVertexAttribData {
|
||||
@ -1533,9 +1531,9 @@ public:
|
||||
|
||||
// this method too is only for element array buffers. It returns the maximum value in the part of
|
||||
// the buffer starting at given offset, consisting of given count of elements. The type T is the type
|
||||
// to interprete the array elements as, must be GLushort or GLubyte.
|
||||
// to interpret the array elements as, must be GLushort or GLubyte.
|
||||
template<typename T>
|
||||
PRInt32 FindMaxElementInSubArray(GLuint count, GLuint byteOffset)
|
||||
T FindMaxElementInSubArray(GLuint count, GLuint byteOffset)
|
||||
{
|
||||
const T* start = reinterpret_cast<T*>(reinterpret_cast<size_t>(mData) + byteOffset);
|
||||
const T* stop = start + count;
|
||||
@ -1551,7 +1549,7 @@ public:
|
||||
mHasCachedMaxUshortElement = false;
|
||||
}
|
||||
|
||||
PRInt32 FindMaxUbyteElement() {
|
||||
int32_t FindMaxUbyteElement() {
|
||||
if (mHasCachedMaxUbyteElement) {
|
||||
return mCachedMaxUbyteElement;
|
||||
} else {
|
||||
@ -1561,7 +1559,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
PRInt32 FindMaxUshortElement() {
|
||||
int32_t FindMaxUshortElement() {
|
||||
if (mHasCachedMaxUshortElement) {
|
||||
return mCachedMaxUshortElement;
|
||||
} else {
|
||||
@ -1582,9 +1580,9 @@ protected:
|
||||
GLenum mTarget;
|
||||
WebGLMonotonicHandle mMonotonicHandle;
|
||||
|
||||
PRUint8 mCachedMaxUbyteElement;
|
||||
uint8_t mCachedMaxUbyteElement;
|
||||
bool mHasCachedMaxUbyteElement;
|
||||
PRUint16 mCachedMaxUshortElement;
|
||||
uint16_t mCachedMaxUshortElement;
|
||||
bool mHasCachedMaxUshortElement;
|
||||
|
||||
void* mData; // in the case of an Element Array Buffer, we keep a copy.
|
||||
@ -1684,11 +1682,11 @@ public:
|
||||
return is_pot_assuming_nonnegative(mWidth) &&
|
||||
is_pot_assuming_nonnegative(mHeight); // negative sizes should never happen (caught in texImage2D...)
|
||||
}
|
||||
PRInt64 MemoryUsage() const {
|
||||
int64_t MemoryUsage() const {
|
||||
if (!mIsDefined)
|
||||
return 0;
|
||||
PRInt64 texelSizeInBits = WebGLContext::GetBitsPerTexel(mFormat, mType);
|
||||
return PRInt64(mWidth) * PRInt64(mHeight) * texelSizeInBits / 8;
|
||||
int64_t texelSizeInBits = WebGLContext::GetBitsPerTexel(mFormat, mType);
|
||||
return int64_t(mWidth) * int64_t(mHeight) * texelSizeInBits / 8;
|
||||
}
|
||||
WebGLenum Format() const { return mFormat; }
|
||||
WebGLenum Type() const { return mType; }
|
||||
@ -1723,10 +1721,10 @@ public:
|
||||
return target == LOCAL_GL_TEXTURE_2D ? 0 : target - LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
}
|
||||
|
||||
PRInt64 MemoryUsage() const {
|
||||
int64_t MemoryUsage() const {
|
||||
if (IsDeleted())
|
||||
return 0;
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for(size_t face = 0; face < mFacesCount; face++) {
|
||||
if (mHaveGeneratedMipmap) {
|
||||
// Each mipmap level is 1/4 the size of the previous level
|
||||
@ -1981,12 +1979,12 @@ public:
|
||||
if (DoesMinFilterRequireMipmap())
|
||||
{
|
||||
if (!IsMipmapTexture2DComplete()) {
|
||||
mContext->LogMessageIfVerbose
|
||||
mContext->GenerateWarning
|
||||
("%s is a 2D texture, with a minification filter requiring a mipmap, "
|
||||
"and is not mipmap complete (as defined in section 3.7.10).", msg_rendering_as_black);
|
||||
mFakeBlackStatus = DoNeedFakeBlack;
|
||||
} else if (!ImageInfoAt(0).IsPowerOfTwo()) {
|
||||
mContext->LogMessageIfVerbose
|
||||
mContext->GenerateWarning
|
||||
("%s is a 2D texture, with a minification filter requiring a mipmap, "
|
||||
"and either its width or height is not a power of two.", msg_rendering_as_black);
|
||||
mFakeBlackStatus = DoNeedFakeBlack;
|
||||
@ -1995,12 +1993,12 @@ public:
|
||||
else // no mipmap required
|
||||
{
|
||||
if (!ImageInfoAt(0).IsPositive()) {
|
||||
mContext->LogMessageIfVerbose
|
||||
mContext->GenerateWarning
|
||||
("%s is a 2D texture and its width or height is equal to zero.",
|
||||
msg_rendering_as_black);
|
||||
mFakeBlackStatus = DoNeedFakeBlack;
|
||||
} else if (!AreBothWrapModesClampToEdge() && !ImageInfoAt(0).IsPowerOfTwo()) {
|
||||
mContext->LogMessageIfVerbose
|
||||
mContext->GenerateWarning
|
||||
("%s is a 2D texture, with a minification filter not requiring a mipmap, "
|
||||
"with its width or height not a power of two, and with a wrap mode "
|
||||
"different from CLAMP_TO_EDGE.", msg_rendering_as_black);
|
||||
@ -2017,12 +2015,12 @@ public:
|
||||
if (DoesMinFilterRequireMipmap())
|
||||
{
|
||||
if (!IsMipmapCubeComplete()) {
|
||||
mContext->LogMessageIfVerbose("%s is a cube map texture, with a minification filter requiring a mipmap, "
|
||||
mContext->GenerateWarning("%s is a cube map texture, with a minification filter requiring a mipmap, "
|
||||
"and is not mipmap cube complete (as defined in section 3.7.10).",
|
||||
msg_rendering_as_black);
|
||||
mFakeBlackStatus = DoNeedFakeBlack;
|
||||
} else if (!areAllLevel0ImagesPOT) {
|
||||
mContext->LogMessageIfVerbose("%s is a cube map texture, with a minification filter requiring a mipmap, "
|
||||
mContext->GenerateWarning("%s is a cube map texture, with a minification filter requiring a mipmap, "
|
||||
"and either the width or the height of some level 0 image is not a power of two.",
|
||||
msg_rendering_as_black);
|
||||
mFakeBlackStatus = DoNeedFakeBlack;
|
||||
@ -2031,12 +2029,12 @@ public:
|
||||
else // no mipmap required
|
||||
{
|
||||
if (!IsCubeComplete()) {
|
||||
mContext->LogMessageIfVerbose("%s is a cube map texture, with a minification filter not requiring a mipmap, "
|
||||
mContext->GenerateWarning("%s is a cube map texture, with a minification filter not requiring a mipmap, "
|
||||
"and is not cube complete (as defined in section 3.7.10).",
|
||||
msg_rendering_as_black);
|
||||
mFakeBlackStatus = DoNeedFakeBlack;
|
||||
} else if (!AreBothWrapModesClampToEdge() && !areAllLevel0ImagesPOT) {
|
||||
mContext->LogMessageIfVerbose("%s is a cube map texture, with a minification filter not requiring a mipmap, "
|
||||
mContext->GenerateWarning("%s is a cube map texture, with a minification filter not requiring a mipmap, "
|
||||
"with some level 0 image having width or height not a power of two, and with a wrap mode "
|
||||
"different from CLAMP_TO_EDGE.", msg_rendering_as_black);
|
||||
mFakeBlackStatus = DoNeedFakeBlack;
|
||||
@ -2060,11 +2058,11 @@ struct WebGLMappedIdentifier {
|
||||
};
|
||||
|
||||
struct WebGLUniformInfo {
|
||||
PRUint32 arraySize;
|
||||
uint32_t arraySize;
|
||||
bool isArray;
|
||||
ShDataType type;
|
||||
|
||||
WebGLUniformInfo(PRUint32 s = 0, bool a = false, ShDataType t = SH_NONE)
|
||||
WebGLUniformInfo(uint32_t s = 0, bool a = false, ShDataType t = SH_NONE)
|
||||
: arraySize(s), isArray(a), type(t) {}
|
||||
|
||||
int ElementSize() const {
|
||||
@ -2247,7 +2245,7 @@ public:
|
||||
WebGLuint GLName() { return mGLName; }
|
||||
const nsTArray<WebGLRefPtr<WebGLShader> >& AttachedShaders() const { return mAttachedShaders; }
|
||||
bool LinkStatus() { return mLinkStatus; }
|
||||
PRUint32 Generation() const { return mGeneration.value(); }
|
||||
uint32_t Generation() const { return mGeneration.value(); }
|
||||
void SetLinkStatus(bool val) { mLinkStatus = val; }
|
||||
|
||||
bool ContainsShader(WebGLShader *shader) {
|
||||
@ -2278,7 +2276,7 @@ public:
|
||||
}
|
||||
|
||||
bool HasAttachedShaderOfType(GLenum shaderType) {
|
||||
for (PRUint32 i = 0; i < mAttachedShaders.Length(); ++i) {
|
||||
for (uint32_t i = 0; i < mAttachedShaders.Length(); ++i) {
|
||||
if (mAttachedShaders[i] && mAttachedShaders[i]->ShaderType() == shaderType) {
|
||||
return true;
|
||||
}
|
||||
@ -2504,8 +2502,8 @@ public:
|
||||
WebGLenum InternalFormatForGL() const { return mInternalFormatForGL; }
|
||||
void SetInternalFormatForGL(WebGLenum aInternalFormatForGL) { mInternalFormatForGL = aInternalFormatForGL; }
|
||||
|
||||
PRInt64 MemoryUsage() const {
|
||||
PRInt64 pixels = PRInt64(Width()) * PRInt64(Height());
|
||||
int64_t MemoryUsage() const {
|
||||
int64_t pixels = int64_t(Width()) * int64_t(Height());
|
||||
switch (mInternalFormatForGL) {
|
||||
case LOCAL_GL_STENCIL_INDEX8:
|
||||
return pixels;
|
||||
@ -2908,7 +2906,7 @@ public:
|
||||
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
|
||||
return false;
|
||||
|
||||
PRUint32 mask = 0;
|
||||
uint32_t mask = 0;
|
||||
|
||||
if (mColorAttachment.HasUninitializedRenderbuffer())
|
||||
mask |= LOCAL_GL_COLOR_BUFFER_BIT;
|
||||
@ -2958,7 +2956,6 @@ public:
|
||||
class WebGLUniformLocation MOZ_FINAL
|
||||
: public nsIWebGLUniformLocation
|
||||
, public WebGLContextBoundObject
|
||||
, public WebGLRefCountedObject<WebGLUniformLocation>
|
||||
{
|
||||
public:
|
||||
WebGLUniformLocation(WebGLContext *context, WebGLProgram *program, GLint location, const WebGLUniformInfo& info)
|
||||
@ -2969,23 +2966,20 @@ public:
|
||||
, mInfo(info)
|
||||
{
|
||||
mElementSize = info.ElementSize();
|
||||
mMonotonicHandle = mContext->mUniformLocations.AppendElement(this);
|
||||
}
|
||||
|
||||
~WebGLUniformLocation() {
|
||||
DeleteOnce();
|
||||
}
|
||||
|
||||
void Delete() {
|
||||
mProgram = nsnull;
|
||||
mContext->mUniformLocations.RemoveElement(mMonotonicHandle);
|
||||
}
|
||||
// needed for certain helper functions like ValidateObject.
|
||||
// WebGLUniformLocation's can't be 'Deleted' in the WebGL sense.
|
||||
bool IsDeleted() const { return false; }
|
||||
|
||||
const WebGLUniformInfo &Info() const { return mInfo; }
|
||||
|
||||
WebGLProgram *Program() const { return mProgram; }
|
||||
GLint Location() const { return mLocation; }
|
||||
PRUint32 ProgramGeneration() const { return mProgramGeneration; }
|
||||
uint32_t ProgramGeneration() const { return mProgramGeneration; }
|
||||
int ElementSize() const { return mElementSize; }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -2995,11 +2989,10 @@ protected:
|
||||
// we just want to avoid having a dangling pointer.
|
||||
nsRefPtr<WebGLProgram> mProgram;
|
||||
|
||||
PRUint32 mProgramGeneration;
|
||||
uint32_t mProgramGeneration;
|
||||
GLint mLocation;
|
||||
WebGLUniformInfo mInfo;
|
||||
int mElementSize;
|
||||
WebGLMonotonicHandle mMonotonicHandle;
|
||||
friend class WebGLProgram;
|
||||
};
|
||||
|
||||
@ -3168,70 +3161,70 @@ class WebGLMemoryMultiReporterWrapper
|
||||
}
|
||||
}
|
||||
|
||||
static PRInt64 GetTextureMemoryUsed() {
|
||||
static int64_t GetTextureMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i)
|
||||
for (size_t j = 0; j < contexts[i]->mTextures.Length(); ++j)
|
||||
result += contexts[i]->mTextures[j]->MemoryUsage();
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetTextureCount() {
|
||||
static int64_t GetTextureCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i)
|
||||
result += contexts[i]->mTextures.Length();
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetBufferMemoryUsed() {
|
||||
static int64_t GetBufferMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i)
|
||||
for (size_t j = 0; j < contexts[i]->mBuffers.Length(); ++j)
|
||||
result += contexts[i]->mBuffers[j]->ByteLength();
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetBufferCacheMemoryUsed();
|
||||
static int64_t GetBufferCacheMemoryUsed();
|
||||
|
||||
static PRInt64 GetBufferCount() {
|
||||
static int64_t GetBufferCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i)
|
||||
result += contexts[i]->mBuffers.Length();
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetRenderbufferMemoryUsed() {
|
||||
static int64_t GetRenderbufferMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i)
|
||||
for (size_t j = 0; j < contexts[i]->mRenderbuffers.Length(); ++j)
|
||||
result += contexts[i]->mRenderbuffers[j]->MemoryUsage();
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetRenderbufferCount() {
|
||||
static int64_t GetRenderbufferCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i)
|
||||
result += contexts[i]->mRenderbuffers.Length();
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetShaderSize();
|
||||
static int64_t GetShaderSize();
|
||||
|
||||
static PRInt64 GetShaderCount() {
|
||||
static int64_t GetShaderCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i)
|
||||
result += contexts[i]->mShaders.Length();
|
||||
return result;
|
||||
}
|
||||
|
||||
static PRInt64 GetContextCount() {
|
||||
static int64_t GetContextCount() {
|
||||
return Contexts().Length();
|
||||
}
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -141,10 +141,10 @@ WebGLMemoryMultiReporterWrapper::~WebGLMemoryMultiReporterWrapper()
|
||||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOfFun, "webgl-buffer")
|
||||
|
||||
PRInt64
|
||||
int64_t
|
||||
WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for (size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (size_t j = 0; j < contexts[i]->mBuffers.Length(); ++j)
|
||||
if (contexts[i]->mBuffers[j]->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||
@ -155,10 +155,10 @@ WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
|
||||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOfFun, "webgl-shader")
|
||||
|
||||
PRInt64
|
||||
int64_t
|
||||
WebGLMemoryMultiReporterWrapper::GetShaderSize() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
PRInt64 result = 0;
|
||||
int64_t result = 0;
|
||||
for (size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (size_t j = 0; j < contexts[i]->mShaders.Length(); ++j)
|
||||
result += contexts[i]->mShaders[j]->SizeOfIncludingThis(WebGLShaderMallocSizeOfFun);
|
||||
|
@ -32,20 +32,25 @@
|
||||
using namespace mozilla;
|
||||
|
||||
void
|
||||
WebGLContext::LogMessage(const char *fmt, ...)
|
||||
WebGLContext::GenerateWarning(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
LogMessage(fmt, ap);
|
||||
GenerateWarning(fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::LogMessage(const char *fmt, va_list ap)
|
||||
WebGLContext::GenerateWarning(const char *fmt, va_list ap)
|
||||
{
|
||||
if (!fmt) return;
|
||||
const int MaxReportedMessages = 32;
|
||||
|
||||
if (mAlreadyReportedMessages >= MaxReportedMessages)
|
||||
return;
|
||||
|
||||
mAlreadyReportedMessages++;
|
||||
|
||||
char buf[1024];
|
||||
PR_vsnprintf(buf, 1024, fmt, ap);
|
||||
@ -54,40 +59,21 @@ WebGLContext::LogMessage(const char *fmt, va_list ap)
|
||||
|
||||
nsCOMPtr<nsIJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||
JSContext* ccx = nsnull;
|
||||
if (stack && NS_SUCCEEDED(stack->Peek(&ccx)) && ccx)
|
||||
if (stack && NS_SUCCEEDED(stack->Peek(&ccx)) && ccx) {
|
||||
JS_ReportWarning(ccx, "WebGL: %s", buf);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::LogMessageIfVerbose(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
LogMessageIfVerbose(fmt, ap);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
WebGLContext::LogMessageIfVerbose(const char *fmt, va_list ap)
|
||||
{
|
||||
static bool firstTime = true;
|
||||
|
||||
if (mVerbose)
|
||||
LogMessage(fmt, ap);
|
||||
else if (firstTime)
|
||||
LogMessage("There are WebGL warnings or messages in this page, but they are hidden. To see them, "
|
||||
"go to about:config, set the webgl.verbose preference, and reload this page.");
|
||||
|
||||
firstTime = false;
|
||||
if (mAlreadyReportedMessages == MaxReportedMessages) {
|
||||
JS_ReportWarning(ccx,
|
||||
"WebGL: no further warnings will be reported for this WebGL context "
|
||||
"(already reported %d warnings)", mAlreadyReportedMessages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckedUint32
|
||||
WebGLContext::GetImageSize(WebGLsizei height,
|
||||
WebGLsizei width,
|
||||
PRUint32 pixelSize,
|
||||
PRUint32 packOrUnpackAlignment)
|
||||
uint32_t pixelSize,
|
||||
uint32_t packOrUnpackAlignment)
|
||||
{
|
||||
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * pixelSize;
|
||||
|
||||
@ -122,7 +108,7 @@ WebGLContext::SynthesizeGLError(WebGLenum err, const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
LogMessageIfVerbose(fmt, va);
|
||||
GenerateWarning(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return SynthesizeGLError(err);
|
||||
@ -133,7 +119,7 @@ WebGLContext::ErrorInvalidEnum(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
LogMessageIfVerbose(fmt, va);
|
||||
GenerateWarning(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return SynthesizeGLError(LOCAL_GL_INVALID_ENUM);
|
||||
@ -144,7 +130,7 @@ WebGLContext::ErrorInvalidOperation(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
LogMessageIfVerbose(fmt, va);
|
||||
GenerateWarning(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return SynthesizeGLError(LOCAL_GL_INVALID_OPERATION);
|
||||
@ -155,7 +141,7 @@ WebGLContext::ErrorInvalidValue(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
LogMessageIfVerbose(fmt, va);
|
||||
GenerateWarning(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return SynthesizeGLError(LOCAL_GL_INVALID_VALUE);
|
||||
@ -166,7 +152,7 @@ WebGLContext::ErrorInvalidFramebufferOperation(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
LogMessageIfVerbose(fmt, va);
|
||||
GenerateWarning(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return SynthesizeGLError(LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
|
||||
@ -177,7 +163,7 @@ WebGLContext::ErrorOutOfMemory(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
LogMessageIfVerbose(fmt, va);
|
||||
GenerateWarning(fmt, va);
|
||||
va_end(va);
|
||||
|
||||
return SynthesizeGLError(LOCAL_GL_OUT_OF_MEMORY);
|
||||
|
@ -69,7 +69,7 @@ WebGLProgram::UpdateInfo()
|
||||
*/
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateBuffers(PRInt32 *maxAllowedCount, const char *info)
|
||||
WebGLContext::ValidateBuffers(int32_t *maxAllowedCount, const char *info)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
GLint currentProgram = 0;
|
||||
@ -83,8 +83,8 @@ WebGLContext::ValidateBuffers(PRInt32 *maxAllowedCount, const char *info)
|
||||
|
||||
*maxAllowedCount = -1;
|
||||
|
||||
PRUint32 attribs = mAttribBuffers.Length();
|
||||
for (PRUint32 i = 0; i < attribs; ++i) {
|
||||
uint32_t attribs = mAttribBuffers.Length();
|
||||
for (uint32_t i = 0; i < attribs; ++i) {
|
||||
const WebGLVertexAttribData& vd = mAttribBuffers[i];
|
||||
|
||||
// If the attrib array isn't enabled, there's nothing to check;
|
||||
@ -310,7 +310,7 @@ bool WebGLContext::ValidateDrawModeEnum(WebGLenum mode, const char *info)
|
||||
|
||||
bool WebGLContext::ValidateGLSLVariableName(const nsAString& name, const char *info)
|
||||
{
|
||||
const PRUint32 maxSize = 256;
|
||||
const uint32_t maxSize = 256;
|
||||
if (name.Length() > maxSize) {
|
||||
ErrorInvalidValue("%s: identifier is %d characters long, exceeds the maximum allowed length of %d characters",
|
||||
info, name.Length(), maxSize);
|
||||
@ -326,7 +326,7 @@ bool WebGLContext::ValidateGLSLVariableName(const nsAString& name, const char *i
|
||||
|
||||
bool WebGLContext::ValidateGLSLString(const nsAString& string, const char *info)
|
||||
{
|
||||
for (PRUint32 i = 0; i < string.Length(); ++i) {
|
||||
for (uint32_t i = 0; i < string.Length(); ++i) {
|
||||
if (!ValidateGLSLCharacter(string.CharAt(i))) {
|
||||
ErrorInvalidValue("%s: string contains the illegal character '%d'", info, string.CharAt(i));
|
||||
return false;
|
||||
@ -427,24 +427,24 @@ bool WebGLContext::ValidateLevelWidthHeightForTarget(WebGLenum target, WebGLint
|
||||
}
|
||||
|
||||
if (!(maxTextureSize >> level)) {
|
||||
ErrorInvalidValue("%s: 2^level exceeds maximum texture size");
|
||||
ErrorInvalidValue("%s: 2^level exceeds maximum texture size", info);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width < 0 || height < 0) {
|
||||
ErrorInvalidValue("%s: width and height must be >= 0");
|
||||
ErrorInvalidValue("%s: width and height must be >= 0", info);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width > maxTextureSize || height > maxTextureSize) {
|
||||
ErrorInvalidValue("%s: width or height exceeds maximum texture size");
|
||||
ErrorInvalidValue("%s: width or height exceeds maximum texture size", info);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PRUint32 WebGLContext::GetBitsPerTexel(WebGLenum format, WebGLenum type)
|
||||
uint32_t WebGLContext::GetBitsPerTexel(WebGLenum format, WebGLenum type)
|
||||
{
|
||||
if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
|
||||
int multiplier = type == LOCAL_GL_FLOAT ? 32 : 8;
|
||||
@ -479,7 +479,7 @@ PRUint32 WebGLContext::GetBitsPerTexel(WebGLenum format, WebGLenum type)
|
||||
}
|
||||
|
||||
bool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType,
|
||||
PRUint32 *texelSize, const char *info)
|
||||
uint32_t *texelSize, const char *info)
|
||||
{
|
||||
if (type == LOCAL_GL_UNSIGNED_BYTE ||
|
||||
(IsExtensionEnabled(WebGL_OES_texture_float) && type == LOCAL_GL_FLOAT))
|
||||
@ -593,7 +593,7 @@ WebGLContext::InitAndValidateGL()
|
||||
|
||||
GLenum error = gl->fGetError();
|
||||
if (error != LOCAL_GL_NO_ERROR) {
|
||||
LogMessage("GL error 0x%x occurred during OpenGL context initialization, before WebGL initialization!", error);
|
||||
GenerateWarning("GL error 0x%x occurred during OpenGL context initialization, before WebGL initialization!", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -628,7 +628,7 @@ WebGLContext::InitAndValidateGL()
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
|
||||
}
|
||||
if (mGLMaxVertexAttribs < 8) {
|
||||
LogMessage("GL_MAX_VERTEX_ATTRIBS: %d is < 8!", mGLMaxVertexAttribs);
|
||||
GenerateWarning("GL_MAX_VERTEX_ATTRIBS: %d is < 8!", mGLMaxVertexAttribs);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -643,7 +643,7 @@ WebGLContext::InitAndValidateGL()
|
||||
gl->fGetIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGLMaxTextureUnits);
|
||||
}
|
||||
if (mGLMaxTextureUnits < 8) {
|
||||
LogMessage("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d is < 8!", mGLMaxTextureUnits);
|
||||
GenerateWarning("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d is < 8!", mGLMaxTextureUnits);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -684,7 +684,7 @@ WebGLContext::InitAndValidateGL()
|
||||
// before we start, we check that no error already occurred, to prevent hiding it in our subsequent error handling
|
||||
error = gl->GetAndClearError();
|
||||
if (error != LOCAL_GL_NO_ERROR) {
|
||||
LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
GenerateWarning("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -704,7 +704,7 @@ WebGLContext::InitAndValidateGL()
|
||||
mGLMaxVaryingVectors = 16; // = 64/4, 64 is the min value for maxVertexOutputComponents in OpenGL 3.2 spec
|
||||
break;
|
||||
default:
|
||||
LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
GenerateWarning("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -746,7 +746,7 @@ WebGLContext::InitAndValidateGL()
|
||||
// initialize shader translator
|
||||
if (mShaderValidation) {
|
||||
if (!ShInitialize()) {
|
||||
LogMessage("GLSL translator initialization failed!");
|
||||
GenerateWarning("GLSL translator initialization failed!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -756,7 +756,7 @@ WebGLContext::InitAndValidateGL()
|
||||
// it is also to reset the error flags so that a subsequent WebGL getError call will give the correct result.
|
||||
error = gl->GetAndClearError();
|
||||
if (error != LOCAL_GL_NO_ERROR) {
|
||||
LogMessage("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
GenerateWarning("GL error 0x%x occurred during WebGL context initialization!", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2516,6 +2516,7 @@ nsCanvasRenderingContext2DAzure::EnsureWritablePath()
|
||||
mPath->TransformedCopyToBuilder(mPathToDS, fillRule);
|
||||
mPath = nsnull;
|
||||
mPathBuilder = nsnull;
|
||||
mPathTransformWillUpdate = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
This is a local copy of the WebGL conformance suite, version 1.0.1, SVN revision 17159 (on the 1.0.1 branch, not on trunk)
|
||||
This is a local copy of the WebGL conformance suite, version 1.0.1, SVN revision 17794 (on the 1.0.1 branch, not on trunk)
|
||||
|
||||
The canonical location for this 1.0.1 test suite is:
|
||||
|
||||
|
@ -6,10 +6,10 @@ This is the initial release of the WebGL conformance test suite.
|
||||
NOTE TO USERS: Unless you are a WebGL implementor, there is no need to submit
|
||||
a conformance result using this process. Should you discover bugs in your
|
||||
browser's WebGL implementation, either via this test suite or otherwise,
|
||||
please report them to your browser vendor's bug tracking system.
|
||||
please report them through your browser vendor's bug tracking system.
|
||||
|
||||
FOR WEBGL IMPLEMENTORS: Please follow the isntructions below to create
|
||||
a formal conformance submission.'
|
||||
FOR WEBGL IMPLEMENTORS: Please follow the instructions below to create
|
||||
a formal conformance submission.
|
||||
|
||||
1) Open webgl-conformance-tests.html in your target browser
|
||||
|
||||
@ -20,9 +20,14 @@ a formal conformance submission.'
|
||||
4) Verify that the User Agent and WebGL renderer strings identify your browser and target correctly.
|
||||
|
||||
5) Copy the contents of the text summary (starting with "WebGL Conformance Test Results") and send via email to
|
||||
--- NEED ADDRESS HERE --- @khronos.org
|
||||
webgl_conformance_submissions@khronos.org
|
||||
|
||||
Please see CONFORMANCE_RULES.txt in this directory for guidelines
|
||||
about what constitutes a conformant WebGL implementation.
|
||||
|
||||
|
||||
- Version 1.0.0
|
||||
- February 24, 2011
|
||||
|
||||
- Version 1.0.1
|
||||
- February 23, 2012
|
||||
|
@ -128,8 +128,9 @@ debug("Enable an extra attribute with insufficient data buffer");
|
||||
gl.vertexAttribPointer(extraLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)');
|
||||
debug("Pass large negative index to vertexAttribPointer");
|
||||
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), -2000000000 * sizeInBytes(gl.FLOAT));
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
glErrorShouldBe(gl, gl.INVALID_VALUE);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)');
|
||||
|
||||
successfullyParsed = true;
|
||||
|
@ -374,7 +374,6 @@ VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
|
||||
|
||||
/* Shader Source */
|
||||
COMPILE_STATUS : 0x8B81,
|
||||
SHADER_COMPILER : 0x8DFA,
|
||||
|
||||
/* Shader Precision-Specified Types */
|
||||
LOW_FLOAT : 0x8DF0,
|
||||
|
@ -36,7 +36,7 @@ GLSLGenerator.runReferenceImageTest({
|
||||
args: "$(type) value",
|
||||
testFunc: "$(func)($(type))",
|
||||
gridRes: 8,
|
||||
tolerance: 2,
|
||||
tolerance: 3,
|
||||
extra: piConstants,
|
||||
tests: [
|
||||
{
|
||||
|
@ -31,6 +31,7 @@ GLSLGenerator.runFeatureTest({
|
||||
" return t * t * (3.0 - 2.0 * t);",
|
||||
"}"].join("\n"),
|
||||
gridRes: 8,
|
||||
tolerance: 1,
|
||||
tests: [
|
||||
["$(output) = vec4(",
|
||||
" $(func)(0.3, 0.7, $(input).x),",
|
||||
|
@ -292,7 +292,7 @@ VERTEX_ATTRIB_ARRAY_BUFFER_BINDING : 0x889F,
|
||||
//IMPLEMENTATION_COLOR_READ_TYPE : 0x8B9A,
|
||||
//IMPLEMENTATION_COLOR_READ_FORMAT : 0x8B9B,
|
||||
COMPILE_STATUS : 0x8B81,
|
||||
SHADER_COMPILER : 0x8DFA,
|
||||
//SHADER_COMPILER : 0x8DFA,
|
||||
LOW_FLOAT : 0x8DF0,
|
||||
MEDIUM_FLOAT : 0x8DF1,
|
||||
HIGH_FLOAT : 0x8DF2,
|
||||
|
@ -71,7 +71,7 @@ Tests.testVertexAttribPointerVBO = function(gl, prog, v,n,t) {
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertsArr, gl.STATIC_DRAW);
|
||||
gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 0);
|
||||
assertFail("negative offset",
|
||||
function(){gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, -1);});
|
||||
function(){gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, -4);});
|
||||
assertOk("out of range offset (OK because we can change the buffer later)",
|
||||
function(){gl.vertexAttribPointer(v, 3, gl.FLOAT, false, 0, 1200);});
|
||||
assertFail("Offset that is incompatible with type",
|
||||
|
@ -17,6 +17,8 @@ var gl = null;
|
||||
var textureLoc = null;
|
||||
var successfullyParsed = false;
|
||||
var imgCanvas;
|
||||
var red = [255, 0, 0];
|
||||
var green = [0, 255, 0];
|
||||
|
||||
function init()
|
||||
{
|
||||
@ -85,8 +87,6 @@ function runOneIteration(image, useTexSubImage2D, flipY, topColor, bottomColor)
|
||||
}
|
||||
|
||||
function runTestOnImage(image) {
|
||||
var red = [255, 0, 0];
|
||||
var green = [0, 255, 0];
|
||||
runOneIteration(image, false, true, red, green);
|
||||
runOneIteration(image, false, false, green, red);
|
||||
runOneIteration(image, true, true, red, green);
|
||||
@ -101,7 +101,16 @@ function runTest(image)
|
||||
imgCanvas.width = 1;
|
||||
imgCanvas.height = 2;
|
||||
var imgCtx = imgCanvas.getContext("2d");
|
||||
imgCtx.drawImage(image, 0, 0);
|
||||
var imgData = imgCtx.createImageData(1, 2);
|
||||
imgData.data[0] = red[0];
|
||||
imgData.data[1] = red[1];
|
||||
imgData.data[2] = red[2];
|
||||
imgData.data[3] = 255;
|
||||
imgData.data[4] = green[0];
|
||||
imgData.data[5] = green[1];
|
||||
imgData.data[6] = green[2];
|
||||
imgData.data[7] = 255;
|
||||
imgCtx.putImageData(imgData, 0, 0);
|
||||
|
||||
// apparently Image is different than <img>.
|
||||
var newImage = new Image();
|
||||
|
@ -385,12 +385,32 @@ function start() {
|
||||
tx += "Tests TIMED OUT: " + totalTimeouts + "\n";
|
||||
tx += "\n";
|
||||
tx += "-------------------\n\n";
|
||||
tx += "Individual Test Results (pass / total / timeout):\n\n";
|
||||
if (totalSuccessful < totalTests) {
|
||||
tx += "Failures:\n\n";
|
||||
for (var url in this.pagesByURL) {
|
||||
var page = this.pagesByURL[url];
|
||||
var pageTotalFail = page.totalTests - page.totalSuccessful;
|
||||
if (!(page.totalTests == 0 && page.totalTimeouts == 0) &&
|
||||
pageTotalFail > 0)
|
||||
{
|
||||
tx += url + ": " + pageTotalFail + " tests failed";
|
||||
if (page.totalTimeouts)
|
||||
tx += " (" + page.totalTimeouts + " timed out)";
|
||||
tx += "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tx += "All tests PASSED\n\n";
|
||||
}
|
||||
tx += "\n";
|
||||
tx += "-------------------\n\n";
|
||||
tx += "Complete Test Results (total / pass / fail / timeout):\n\n";
|
||||
for (var url in this.pagesByURL) {
|
||||
var page = this.pagesByURL[url];
|
||||
var pageTotalFail = page.totalTests - page.totalSuccessful;
|
||||
if (!(page.totalTests == 0 && page.totalTimeouts == 0)) {
|
||||
tx += url + ": " + page.totalSuccessful + " / " +
|
||||
page.totalTests + " / " + page.totalTimeouts + "\n";
|
||||
tx += url + ": " + page.totalTests + " / " +
|
||||
page.totalSuccessful + " / " + pageTotalFail + " / " + page.totalTimeouts + "\n";
|
||||
}
|
||||
}
|
||||
tx += "\n";
|
||||
|
@ -302,7 +302,9 @@ static nsresult GenerateFlatTextContent(nsRange* aRange,
|
||||
nsAutoString tmpStr;
|
||||
for (; !iter->IsDone(); iter->Next()) {
|
||||
nsINode* node = iter->GetCurrentNode();
|
||||
if (!node || !node->IsNodeOfType(nsINode::eCONTENT))
|
||||
if (!node)
|
||||
break;
|
||||
if (!node->IsNodeOfType(nsINode::eCONTENT))
|
||||
continue;
|
||||
nsIContent* content = static_cast<nsIContent*>(node);
|
||||
|
||||
@ -384,7 +386,9 @@ nsContentEventHandler::SetRangeFromFlatTextOffset(
|
||||
nsCOMPtr<nsIContent> content;
|
||||
for (; !iter->IsDone(); iter->Next()) {
|
||||
nsINode* node = iter->GetCurrentNode();
|
||||
if (!node || !node->IsNodeOfType(nsINode::eCONTENT))
|
||||
if (!node)
|
||||
break;
|
||||
if (!node->IsNodeOfType(nsINode::eCONTENT))
|
||||
continue;
|
||||
nsIContent* content = static_cast<nsIContent*>(node);
|
||||
|
||||
@ -616,7 +620,9 @@ nsContentEventHandler::OnQueryTextRect(nsQueryContentEvent* aEvent)
|
||||
do {
|
||||
iter->Next();
|
||||
node = iter->GetCurrentNode();
|
||||
if (!node || !node->IsNodeOfType(nsINode::eCONTENT))
|
||||
if (!node)
|
||||
break;
|
||||
if (!node->IsNodeOfType(nsINode::eCONTENT))
|
||||
continue;
|
||||
frame = static_cast<nsIContent*>(node)->GetPrimaryFrame();
|
||||
} while (!frame && !iter->IsDone());
|
||||
@ -921,7 +927,9 @@ nsContentEventHandler::GetFlatTextOffsetOfRange(nsIContent* aRootContent,
|
||||
*aNativeOffset = 0;
|
||||
for (; !iter->IsDone(); iter->Next()) {
|
||||
nsINode* node = iter->GetCurrentNode();
|
||||
if (!node || !node->IsNodeOfType(nsINode::eCONTENT))
|
||||
if (!node)
|
||||
break;
|
||||
if (!node->IsNodeOfType(nsINode::eCONTENT))
|
||||
continue;
|
||||
nsIContent* content = static_cast<nsIContent*>(node);
|
||||
|
||||
|
@ -413,6 +413,12 @@ nsHTMLAnchorElement::GetLinkState() const
|
||||
already_AddRefed<nsIURI>
|
||||
nsHTMLAnchorElement::GetHrefURI() const
|
||||
{
|
||||
nsIURI* uri = Link::GetCachedURI();
|
||||
if (uri) {
|
||||
NS_ADDREF(uri);
|
||||
return uri;
|
||||
}
|
||||
|
||||
return GetHrefURIForAnchors();
|
||||
}
|
||||
|
||||
|
@ -1794,35 +1794,45 @@ MediaStream::RemoveListener(MediaStreamListener* aListener)
|
||||
}
|
||||
|
||||
void
|
||||
SourceMediaStream::AddTrack(TrackID aID, TrackRate aRate, TrackTicks aStart,
|
||||
MediaSegment* aSegment)
|
||||
SourceMediaStream::DestroyImpl()
|
||||
{
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
TrackData* data = mUpdateTracks.AppendElement();
|
||||
data->mID = aID;
|
||||
data->mRate = aRate;
|
||||
data->mStart = aStart;
|
||||
data->mCommands = TRACK_CREATE;
|
||||
data->mData = aSegment;
|
||||
data->mHaveEnough = false;
|
||||
mDestroyed = true;
|
||||
}
|
||||
MediaStream::DestroyImpl();
|
||||
}
|
||||
|
||||
void
|
||||
SourceMediaStream::AddTrack(TrackID aID, TrackRate aRate, TrackTicks aStart,
|
||||
MediaSegment* aSegment)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
TrackData* data = mUpdateTracks.AppendElement();
|
||||
data->mID = aID;
|
||||
data->mRate = aRate;
|
||||
data->mStart = aStart;
|
||||
data->mCommands = TRACK_CREATE;
|
||||
data->mData = aSegment;
|
||||
data->mHaveEnough = false;
|
||||
if (!mDestroyed) {
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
|
||||
void
|
||||
SourceMediaStream::AppendToTrack(TrackID aID, MediaSegment* aSegment)
|
||||
{
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
TrackData *track = FindDataForTrack(aID);
|
||||
if (track) {
|
||||
track->mData->AppendFrom(aSegment);
|
||||
} else {
|
||||
NS_ERROR("Append to non-existant track!");
|
||||
}
|
||||
MutexAutoLock lock(mMutex);
|
||||
TrackData *track = FindDataForTrack(aID);
|
||||
if (track) {
|
||||
track->mData->AppendFrom(aSegment);
|
||||
} else {
|
||||
NS_ERROR("Append to non-existent track!");
|
||||
}
|
||||
if (!mDestroyed) {
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1858,36 +1868,36 @@ SourceMediaStream::DispatchWhenNotEnoughBuffered(TrackID aID,
|
||||
void
|
||||
SourceMediaStream::EndTrack(TrackID aID)
|
||||
{
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
TrackData *track = FindDataForTrack(aID);
|
||||
if (track) {
|
||||
track->mCommands |= TRACK_END;
|
||||
} else {
|
||||
NS_ERROR("End of non-existant track");
|
||||
}
|
||||
MutexAutoLock lock(mMutex);
|
||||
TrackData *track = FindDataForTrack(aID);
|
||||
if (track) {
|
||||
track->mCommands |= TRACK_END;
|
||||
} else {
|
||||
NS_ERROR("End of non-existant track");
|
||||
}
|
||||
if (!mDestroyed) {
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
|
||||
void
|
||||
SourceMediaStream::AdvanceKnownTracksTime(StreamTime aKnownTime)
|
||||
{
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mUpdateKnownTracksTime = aKnownTime;
|
||||
MutexAutoLock lock(mMutex);
|
||||
mUpdateKnownTracksTime = aKnownTime;
|
||||
if (!mDestroyed) {
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
|
||||
void
|
||||
SourceMediaStream::Finish()
|
||||
{
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
mUpdateFinished = true;
|
||||
MutexAutoLock lock(mMutex);
|
||||
mUpdateFinished = true;
|
||||
if (!mDestroyed) {
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
GraphImpl()->EnsureNextIteration();
|
||||
}
|
||||
|
||||
static const PRUint32 kThreadLimit = 4;
|
||||
|
@ -371,11 +371,14 @@ class SourceMediaStream : public MediaStream {
|
||||
public:
|
||||
SourceMediaStream(nsDOMMediaStream* aWrapper) :
|
||||
MediaStream(aWrapper), mMutex("mozilla::media::SourceMediaStream"),
|
||||
mUpdateKnownTracksTime(0), mUpdateFinished(false)
|
||||
mUpdateKnownTracksTime(0), mUpdateFinished(false), mDestroyed(false)
|
||||
{}
|
||||
|
||||
virtual SourceMediaStream* AsSourceStream() { return this; }
|
||||
|
||||
// Media graph thread only
|
||||
virtual void DestroyImpl();
|
||||
|
||||
// Call these on any thread.
|
||||
/**
|
||||
* Add a new track to the stream starting at the given base time (which
|
||||
@ -467,11 +470,14 @@ protected:
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// This must be acquired *before* MediaStreamGraphImpl's lock, if they are
|
||||
// held together.
|
||||
Mutex mMutex;
|
||||
// protected by mMutex
|
||||
StreamTime mUpdateKnownTracksTime;
|
||||
nsTArray<TrackData> mUpdateTracks;
|
||||
bool mUpdateFinished;
|
||||
bool mDestroyed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "nsWebMBufferedParser.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "nsTimeRanges.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#define VPX_DONT_DEFINE_STDINT_TYPES
|
||||
#include "vpx/vp8dx.h"
|
||||
@ -108,17 +107,10 @@ nsWebMReader::nsWebMReader(nsBuiltinDecoder* aDecoder)
|
||||
mAudioTrack(0),
|
||||
mAudioStartUsec(-1),
|
||||
mAudioFrames(0),
|
||||
mForceStereoMode(0),
|
||||
mHasVideo(false),
|
||||
mHasAudio(false),
|
||||
mStereoModeForced(false)
|
||||
mHasAudio(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsWebMReader);
|
||||
|
||||
mStereoModeForced =
|
||||
NS_SUCCEEDED(Preferences::GetInt(
|
||||
"media.webm.force_stereo_mode",
|
||||
&mForceStereoMode));
|
||||
}
|
||||
|
||||
nsWebMReader::~nsWebMReader()
|
||||
@ -284,26 +276,6 @@ nsresult nsWebMReader::ReadMetadata(nsVideoInfo* aInfo)
|
||||
mInfo.mStereoMode = STEREO_MODE_RIGHT_LEFT;
|
||||
break;
|
||||
}
|
||||
|
||||
// Switch only when stereo mode is explicitly set.
|
||||
if (mStereoModeForced) {
|
||||
switch (mForceStereoMode) {
|
||||
case 1:
|
||||
mInfo.mStereoMode = STEREO_MODE_LEFT_RIGHT;
|
||||
break;
|
||||
case 2:
|
||||
mInfo.mStereoMode = STEREO_MODE_RIGHT_LEFT;
|
||||
break;
|
||||
case 3:
|
||||
mInfo.mStereoMode = STEREO_MODE_TOP_BOTTOM;
|
||||
break;
|
||||
case 4:
|
||||
mInfo.mStereoMode = STEREO_MODE_BOTTOM_TOP;
|
||||
break;
|
||||
default:
|
||||
mInfo.mStereoMode = STEREO_MODE_MONO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!mHasAudio && type == NESTEGG_TRACK_AUDIO) {
|
||||
nestegg_audio_params params;
|
||||
|
@ -207,17 +207,9 @@ private:
|
||||
// Picture region, as relative to the initial frame size.
|
||||
nsIntRect mPicture;
|
||||
|
||||
// Value of the "media.webm.force_stereo_mode" pref, which we need off the
|
||||
// main thread.
|
||||
PRInt32 mForceStereoMode;
|
||||
|
||||
// Booleans to indicate if we have audio and/or video data
|
||||
bool mHasVideo;
|
||||
bool mHasAudio;
|
||||
|
||||
// Boolean which is set to true when the "media.webm.force_stereo_mode"
|
||||
// pref is explicitly set.
|
||||
bool mStereoModeForced;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -186,7 +186,7 @@ DOMSVGStringList::InternalList()
|
||||
{
|
||||
if (mIsConditionalProcessingAttribute) {
|
||||
nsCOMPtr<DOMSVGTests> tests = do_QueryInterface(mElement);
|
||||
return *tests->GetStringListAttribute(mAttrEnum);
|
||||
return *tests->GetOrCreateStringListAttribute(mAttrEnum);
|
||||
}
|
||||
return mElement->GetStringListInfo().mStringLists[mAttrEnum];
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "nsDOMError.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "mozilla/css/StyleRule.h"
|
||||
#include "nsRuleWalker.h"
|
||||
|
@ -1102,7 +1102,8 @@ nsSVGSVGElement::GetViewBoxWithSynthesis(
|
||||
SVGPreserveAspectRatio
|
||||
nsSVGSVGElement::GetPreserveAspectRatioWithOverride() const
|
||||
{
|
||||
if (GetCurrentDoc()->IsBeingUsedAsImage()) {
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc && doc->IsBeingUsedAsImage()) {
|
||||
const SVGPreserveAspectRatio *pAROverridePtr = GetPreserveAspectRatioProperty();
|
||||
if (pAROverridePtr) {
|
||||
return *pAROverridePtr;
|
||||
|
@ -10,7 +10,7 @@ VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
PARALLEL_DIRS = public src builtin
|
||||
PARALLEL_DIRS = src builtin
|
||||
|
||||
TEST_DIRS += test
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
#
|
||||
# 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/.
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = content
|
||||
|
||||
EXPORTS = \
|
||||
nsIXBLService.h \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -1,65 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
/*
|
||||
|
||||
Private interface to the XBL service
|
||||
|
||||
*/
|
||||
|
||||
#ifndef nsIXBLService_h__
|
||||
#define nsIXBLService_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIDOMEventTarget;
|
||||
class nsIDOMNodeList;
|
||||
class nsXBLBinding;
|
||||
class nsXBLDocumentInfo;
|
||||
class nsIURI;
|
||||
class nsIAtom;
|
||||
class nsIPrincipal;
|
||||
|
||||
#define NS_IXBLSERVICE_IID \
|
||||
{ 0x8a25483c, 0x1ac6, 0x4796, { 0xa6, 0x12, 0x5a, 0xe0, 0x5c, 0x83, 0x65, 0x0b } }
|
||||
|
||||
class nsIXBLService : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXBLSERVICE_IID)
|
||||
|
||||
// This function loads a particular XBL file and installs all of the bindings
|
||||
// onto the element. aOriginPrincipal must not be null here.
|
||||
NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal, bool aAugmentFlag,
|
||||
nsXBLBinding** aBinding, bool* aResolveStyle) = 0;
|
||||
|
||||
// Indicates whether or not a binding is fully loaded.
|
||||
NS_IMETHOD BindingReady(nsIContent* aBoundElement, nsIURI* aURI, bool* aIsReady) = 0;
|
||||
|
||||
// Retrieves our base class (e.g., tells us what type of frame and content node to build)
|
||||
NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult) = 0;
|
||||
|
||||
// This method checks the hashtable and then calls FetchBindingDocument on a
|
||||
// miss. aOriginPrincipal or aBoundDocument may be null to bypass security
|
||||
// checks.
|
||||
NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement,
|
||||
nsIDocument* aBoundDocument,
|
||||
nsIURI* aBindingURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
bool aForceSyncLoad,
|
||||
nsXBLDocumentInfo** aResult) = 0;
|
||||
|
||||
// Hooks up the global key event handlers to the document root.
|
||||
NS_IMETHOD AttachGlobalKeyHandler(nsIDOMEventTarget* aTarget) = 0;
|
||||
NS_IMETHOD DetachGlobalKeyHandler(nsIDOMEventTarget* aTarget) = 0;
|
||||
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIXBLService, NS_IXBLSERVICE_IID)
|
||||
|
||||
#endif // nsIXBLService_h__
|
@ -5,7 +5,7 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsXBLService.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
@ -845,11 +845,9 @@ nsBindingManager::AddLayeredBinding(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal)
|
||||
{
|
||||
// First we need to load our binding.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIXBLService> xblService =
|
||||
do_GetService("@mozilla.org/xbl;1", &rv);
|
||||
nsXBLService* xblService = nsXBLService::GetInstance();
|
||||
if (!xblService)
|
||||
return rv;
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Load the bindings.
|
||||
nsRefPtr<nsXBLBinding> binding;
|
||||
@ -920,11 +918,9 @@ nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc,
|
||||
NS_PRECONDITION(aURL, "Must have a URI to load!");
|
||||
|
||||
// First we need to load our binding.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIXBLService> xblService =
|
||||
do_GetService("@mozilla.org/xbl;1", &rv);
|
||||
nsXBLService* xblService = nsXBLService::GetInstance();
|
||||
if (!xblService)
|
||||
return rv;
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Load the binding doc.
|
||||
nsRefPtr<nsXBLDocumentInfo> info;
|
||||
|
@ -23,7 +23,6 @@ class nsIAtom;
|
||||
class nsIDocument;
|
||||
class nsIScriptContext;
|
||||
class nsSupportsHashtable;
|
||||
class nsIXBLService;
|
||||
class nsFixedSizeAllocator;
|
||||
class nsXBLProtoImplField;
|
||||
class nsXBLBinding;
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "nsIStyleRuleProcessor.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsXBLResourceLoader.h"
|
||||
#include "nsXBLPrototypeResources.h"
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsXBLService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsXBLResourceLoader.h"
|
||||
#include "nsXBLPrototypeResources.h"
|
||||
@ -202,7 +202,10 @@ nsXBLResourceLoader::AddResourceListener(nsIContent* aBoundElement)
|
||||
void
|
||||
nsXBLResourceLoader::NotifyBoundElements()
|
||||
{
|
||||
nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
|
||||
nsXBLService* xblService = nsXBLService::GetInstance();
|
||||
if (!xblService)
|
||||
return;
|
||||
|
||||
nsIURI* bindingURI = mBinding->BindingURI();
|
||||
|
||||
PRUint32 eltCount = mBoundElements.Count();
|
||||
|
@ -58,6 +58,8 @@ using namespace mozilla;
|
||||
|
||||
#define NS_MAX_XBL_BINDING_RECURSION 20
|
||||
|
||||
nsXBLService* nsXBLService::gInstance = nsnull;
|
||||
|
||||
static bool
|
||||
IsAncestorBinding(nsIDocument* aDocument,
|
||||
nsIURI* aChildBindingURI,
|
||||
@ -127,8 +129,7 @@ public:
|
||||
|
||||
// Get the binding.
|
||||
bool ready = false;
|
||||
gXBLService->BindingReady(mBoundElement, mBindingURI, &ready);
|
||||
|
||||
nsXBLService::GetInstance()->BindingReady(mBoundElement, mBindingURI, &ready);
|
||||
if (!ready)
|
||||
return;
|
||||
|
||||
@ -156,26 +157,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static nsIXBLService* gXBLService;
|
||||
static int gRefCnt;
|
||||
|
||||
protected:
|
||||
nsXBLBindingRequest(nsIURI* aURI, nsIContent* aBoundElement)
|
||||
: mBindingURI(aURI),
|
||||
mBoundElement(aBoundElement)
|
||||
{
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
CallGetService("@mozilla.org/xbl;1", &gXBLService);
|
||||
}
|
||||
}
|
||||
|
||||
~nsXBLBindingRequest()
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
NS_IF_RELEASE(gXBLService);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@ -193,9 +179,6 @@ static const PRInt32 kNumBuckets = sizeof(kBucketSizes)/sizeof(size_t);
|
||||
static const PRInt32 kNumElements = 64;
|
||||
static const PRInt32 kInitialSize = sizeof(nsXBLBindingRequest) * kNumElements;
|
||||
|
||||
nsIXBLService* nsXBLBindingRequest::gXBLService = nsnull;
|
||||
int nsXBLBindingRequest::gRefCnt = 0;
|
||||
|
||||
// nsXBLStreamListener, a helper class used for
|
||||
// asynchronous parsing of URLs
|
||||
/* Header file */
|
||||
@ -207,8 +190,7 @@ public:
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
nsXBLStreamListener(nsXBLService* aXBLService,
|
||||
nsIDocument* aBoundDocument,
|
||||
nsXBLStreamListener(nsIDocument* aBoundDocument,
|
||||
nsIXMLContentSink* aSink,
|
||||
nsIDocument* aBindingDocument);
|
||||
~nsXBLStreamListener();
|
||||
@ -217,8 +199,6 @@ public:
|
||||
bool HasRequest(nsIURI* aURI, nsIContent* aBoundElement);
|
||||
|
||||
private:
|
||||
nsXBLService* mXBLService; // [WEAK]
|
||||
|
||||
nsCOMPtr<nsIStreamListener> mInner;
|
||||
nsAutoTArray<nsXBLBindingRequest*, 8> mBindingRequests;
|
||||
|
||||
@ -233,14 +213,12 @@ NS_IMPL_ISUPPORTS3(nsXBLStreamListener,
|
||||
nsIRequestObserver,
|
||||
nsIDOMEventListener)
|
||||
|
||||
nsXBLStreamListener::nsXBLStreamListener(nsXBLService* aXBLService,
|
||||
nsIDocument* aBoundDocument,
|
||||
nsXBLStreamListener::nsXBLStreamListener(nsIDocument* aBoundDocument,
|
||||
nsIXMLContentSink* aSink,
|
||||
nsIDocument* aBindingDocument)
|
||||
: mSink(aSink), mBindingDocument(aBindingDocument)
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
mXBLService = aXBLService;
|
||||
mBoundDocument = do_GetWeakReference(aBoundDocument);
|
||||
}
|
||||
|
||||
@ -248,7 +226,7 @@ nsXBLStreamListener::~nsXBLStreamListener()
|
||||
{
|
||||
for (PRUint32 i = 0; i < mBindingRequests.Length(); i++) {
|
||||
nsXBLBindingRequest* req = mBindingRequests.ElementAt(i);
|
||||
nsXBLBindingRequest::Destroy(mXBLService->mPool, req);
|
||||
nsXBLBindingRequest::Destroy(nsXBLService::GetInstance()->mPool, req);
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,7 +390,6 @@ nsXBLStreamListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
// Implementation /////////////////////////////////////////////////////////////////
|
||||
|
||||
// Static member variable initialization
|
||||
PRUint32 nsXBLService::gRefCnt = 0;
|
||||
bool nsXBLService::gAllowDataURIs = false;
|
||||
|
||||
nsHashtable* nsXBLService::gClassTable = nsnull;
|
||||
@ -422,38 +399,45 @@ PRUint32 nsXBLService::gClassLRUListLength = 0;
|
||||
PRUint32 nsXBLService::gClassLRUListQuota = 64;
|
||||
|
||||
// Implement our nsISupports methods
|
||||
NS_IMPL_ISUPPORTS3(nsXBLService, nsIXBLService, nsIObserver, nsISupportsWeakReference)
|
||||
NS_IMPL_ISUPPORTS2(nsXBLService, nsIObserver, nsISupportsWeakReference)
|
||||
|
||||
void
|
||||
nsXBLService::Init()
|
||||
{
|
||||
gInstance = new nsXBLService();
|
||||
NS_ADDREF(gInstance);
|
||||
|
||||
// Register the first (and only) nsXBLService as a memory pressure observer
|
||||
// so it can flush the LRU list in low-memory situations.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->AddObserver(gInstance, "memory-pressure", true);
|
||||
}
|
||||
|
||||
// Constructors/Destructors
|
||||
nsXBLService::nsXBLService(void)
|
||||
{
|
||||
mPool.Init("XBL Binding Requests", kBucketSizes, kNumBuckets, kInitialSize);
|
||||
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
gClassTable = new nsHashtable();
|
||||
}
|
||||
gClassTable = new nsHashtable();
|
||||
|
||||
Preferences::AddBoolVarCache(&gAllowDataURIs, "layout.debug.enable_data_xbl");
|
||||
}
|
||||
|
||||
nsXBLService::~nsXBLService(void)
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
// Walk the LRU list removing and deleting the nsXBLJSClasses.
|
||||
FlushMemory();
|
||||
// Walk the LRU list removing and deleting the nsXBLJSClasses.
|
||||
FlushMemory();
|
||||
|
||||
// Any straggling nsXBLJSClass instances held by unfinalized JS objects
|
||||
// created for bindings will be deleted when those objects are finalized
|
||||
// (and not put on gClassLRUList, because length >= quota).
|
||||
gClassLRUListLength = gClassLRUListQuota = 0;
|
||||
// Any straggling nsXBLJSClass instances held by unfinalized JS objects
|
||||
// created for bindings will be deleted when those objects are finalized
|
||||
// (and not put on gClassLRUList, because length >= quota).
|
||||
gClassLRUListLength = gClassLRUListQuota = 0;
|
||||
|
||||
// At this point, the only hash table entries should be for referenced
|
||||
// XBL class structs held by unfinalized JS binding objects.
|
||||
delete gClassTable;
|
||||
gClassTable = nsnull;
|
||||
}
|
||||
// At this point, the only hash table entries should be for referenced
|
||||
// XBL class structs held by unfinalized JS binding objects.
|
||||
delete gClassTable;
|
||||
gClassTable = nsnull;
|
||||
}
|
||||
|
||||
// static
|
||||
@ -471,7 +455,7 @@ nsXBLService::IsChromeOrResourceURI(nsIURI* aURI)
|
||||
|
||||
// This function loads a particular XBL file and installs all of the bindings
|
||||
// onto the element.
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal, bool aAugmentFlag,
|
||||
nsXBLBinding** aBinding, bool* aResolveStyle)
|
||||
@ -610,18 +594,6 @@ nsXBLService::FlushStyleBindings(nsIContent* aContent)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXBLService::ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID,
|
||||
nsIAtom** aResult)
|
||||
{
|
||||
nsIDocument* document = aContent->OwnerDoc();
|
||||
*aResult = document->BindingManager()->ResolveTag(aContent, aNameSpaceID);
|
||||
NS_IF_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// AttachGlobalKeyHandler
|
||||
//
|
||||
@ -629,7 +601,7 @@ nsXBLService::ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID,
|
||||
// event receiver (either a document or an content node). If the receiver is content,
|
||||
// then extra work needs to be done to hook it up to the document (XXX WHY??)
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsXBLService::AttachGlobalKeyHandler(nsIDOMEventTarget* aTarget)
|
||||
{
|
||||
// check if the receiver is a content node (not a document), and hook
|
||||
@ -686,7 +658,7 @@ nsXBLService::AttachGlobalKeyHandler(nsIDOMEventTarget* aTarget)
|
||||
//
|
||||
// Removes a key handler added by DeatchGlobalKeyHandler.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsXBLService::DetachGlobalKeyHandler(nsIDOMEventTarget* aTarget)
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventTarget> piTarget = aTarget;
|
||||
@ -749,9 +721,10 @@ nsXBLService::FlushMemory()
|
||||
|
||||
// Internal helper methods ////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP nsXBLService::BindingReady(nsIContent* aBoundElement,
|
||||
nsIURI* aURI,
|
||||
bool* aIsReady)
|
||||
nsresult
|
||||
nsXBLService::BindingReady(nsIContent* aBoundElement,
|
||||
nsIURI* aURI,
|
||||
bool* aIsReady)
|
||||
{
|
||||
// Don't do a security check here; we know this binding is set to go.
|
||||
return GetBinding(aBoundElement, aURI, true, nsnull, aIsReady, nsnull);
|
||||
@ -921,7 +894,7 @@ IsSystemOrChromeURLPrincipal(nsIPrincipal* aPrincipal)
|
||||
return NS_SUCCEEDED(uri->SchemeIs("chrome", &isChrome)) && isChrome;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsresult
|
||||
nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement,
|
||||
nsIDocument* aBoundDocument,
|
||||
nsIURI* aBindingURI,
|
||||
@ -1130,7 +1103,7 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
|
||||
if (!aForceSyncLoad) {
|
||||
// We can be asynchronous
|
||||
nsXBLStreamListener* xblListener =
|
||||
new nsXBLStreamListener(this, aBoundDocument, xblSink, doc);
|
||||
new nsXBLStreamListener(aBoundDocument, xblSink, doc);
|
||||
NS_ENSURE_TRUE(xblListener,NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// Add ourselves to the list of loading docs.
|
||||
@ -1183,25 +1156,3 @@ nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoun
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Creation Routine ///////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult NS_NewXBLService(nsIXBLService** aResult);
|
||||
|
||||
nsresult
|
||||
NS_NewXBLService(nsIXBLService** aResult)
|
||||
{
|
||||
nsXBLService* result = new nsXBLService;
|
||||
if (! result)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aResult = result);
|
||||
|
||||
// Register the first (and only) nsXBLService as a memory pressure observer
|
||||
// so it can flush the LRU list in low-memory situations.
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->AddObserver(result, "memory-pressure", true);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "jsapi.h" // nsXBLJSClass derives from JSClass
|
||||
@ -17,49 +17,56 @@ class nsXBLBinding;
|
||||
class nsXBLDocumentInfo;
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIAtom;
|
||||
class nsString;
|
||||
class nsIURI;
|
||||
class nsIPrincipal;
|
||||
class nsSupportsHashtable;
|
||||
class nsHashtable;
|
||||
class nsIDOMEventTarget;
|
||||
|
||||
class nsXBLService : public nsIXBLService,
|
||||
public nsIObserver,
|
||||
class nsXBLService : public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
static nsXBLService* gInstance;
|
||||
|
||||
static void Init();
|
||||
|
||||
static void Shutdown() {
|
||||
NS_IF_RELEASE(gInstance);
|
||||
}
|
||||
|
||||
static nsXBLService* GetInstance() { return gInstance; }
|
||||
|
||||
static bool IsChromeOrResourceURI(nsIURI* aURI);
|
||||
|
||||
// This function loads a particular XBL file and installs all of the bindings
|
||||
// onto the element. aOriginPrincipal must not be null here.
|
||||
NS_IMETHOD LoadBindings(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal, bool aAugmentFlag,
|
||||
nsXBLBinding** aBinding, bool* aResolveStyle);
|
||||
nsresult LoadBindings(nsIContent* aContent, nsIURI* aURL,
|
||||
nsIPrincipal* aOriginPrincipal, bool aAugmentFlag,
|
||||
nsXBLBinding** aBinding, bool* aResolveStyle);
|
||||
|
||||
// Indicates whether or not a binding is fully loaded.
|
||||
NS_IMETHOD BindingReady(nsIContent* aBoundElement, nsIURI* aURI, bool* aIsReady);
|
||||
|
||||
// Gets the object's base class type.
|
||||
NS_IMETHOD ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID, nsIAtom** aResult);
|
||||
nsresult BindingReady(nsIContent* aBoundElement, nsIURI* aURI, bool* aIsReady);
|
||||
|
||||
// This method checks the hashtable and then calls FetchBindingDocument on a
|
||||
// miss. aOriginPrincipal or aBoundDocument may be null to bypass security
|
||||
// checks.
|
||||
NS_IMETHOD LoadBindingDocumentInfo(nsIContent* aBoundElement,
|
||||
nsIDocument* aBoundDocument,
|
||||
nsIURI* aBindingURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
bool aForceSyncLoad,
|
||||
nsXBLDocumentInfo** aResult);
|
||||
nsresult LoadBindingDocumentInfo(nsIContent* aBoundElement,
|
||||
nsIDocument* aBoundDocument,
|
||||
nsIURI* aBindingURI,
|
||||
nsIPrincipal* aOriginPrincipal,
|
||||
bool aForceSyncLoad,
|
||||
nsXBLDocumentInfo** aResult);
|
||||
|
||||
// Used by XUL key bindings and for window XBL.
|
||||
NS_IMETHOD AttachGlobalKeyHandler(nsIDOMEventTarget* aTarget);
|
||||
NS_IMETHOD DetachGlobalKeyHandler(nsIDOMEventTarget* aTarget);
|
||||
static nsresult AttachGlobalKeyHandler(nsIDOMEventTarget* aTarget);
|
||||
static nsresult DetachGlobalKeyHandler(nsIDOMEventTarget* aTarget);
|
||||
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
public:
|
||||
private:
|
||||
nsXBLService();
|
||||
virtual ~nsXBLService();
|
||||
|
||||
@ -106,8 +113,6 @@ protected:
|
||||
|
||||
// MEMBER VARIABLES
|
||||
public:
|
||||
static PRUint32 gRefCnt; // A count of XBLservice instances.
|
||||
|
||||
static bool gDisableChromeCache;
|
||||
|
||||
static nsHashtable* gClassTable; // A table of nsXBLJSClass objects.
|
||||
|
@ -71,10 +71,8 @@ void nsXBLSpecialDocInfo::LoadDocInfo()
|
||||
return;
|
||||
mInitialized = true;
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIXBLService> xblService =
|
||||
do_GetService("@mozilla.org/xbl;1", &rv);
|
||||
if (NS_FAILED(rv) || !xblService)
|
||||
nsXBLService* xblService = nsXBLService::GetInstance();
|
||||
if (!xblService)
|
||||
return;
|
||||
|
||||
// Obtain the platform doc info
|
||||
|
@ -14,7 +14,6 @@ class nsIDOMElement;
|
||||
class nsIDOMEventTarget;
|
||||
class nsIDOMKeyEvent;
|
||||
class nsIDOMEventTarget;
|
||||
class nsIXBLDocumentInfo;
|
||||
class nsXBLSpecialDocInfo;
|
||||
class nsXBLPrototypeHandler;
|
||||
|
||||
|
@ -59,7 +59,6 @@
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIXULDocument.h"
|
||||
#include "nsIXULTemplateBuilder.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsRDFCID.h"
|
||||
@ -105,9 +104,6 @@
|
||||
|
||||
namespace css = mozilla::css;
|
||||
|
||||
// Global object maintenance
|
||||
nsIXBLService * nsXULElement::gXBLService = nsnull;
|
||||
|
||||
/**
|
||||
* A tearoff class for nsXULElement to implement nsIScriptEventHandlerOwner.
|
||||
*/
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "nsIURI.h"
|
||||
#include "nsIXULTemplateBuilder.h"
|
||||
#include "nsIBoxObject.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsAttrAndChildArray.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@ -389,20 +388,6 @@ public:
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
public:
|
||||
static nsIXBLService* GetXBLService() {
|
||||
if (!gXBLService)
|
||||
CallGetService("@mozilla.org/xbl;1", &gXBLService);
|
||||
return gXBLService;
|
||||
}
|
||||
static void ReleaseGlobals() {
|
||||
NS_IF_RELEASE(gXBLService);
|
||||
}
|
||||
|
||||
protected:
|
||||
// pseudo-constants
|
||||
static nsIXBLService* gXBLService;
|
||||
|
||||
public:
|
||||
nsXULElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
||||
#include "rdf.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsXBLService.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
@ -1699,10 +1699,7 @@ nsXULDocument::AddElementToDocumentPost(Element* aElement)
|
||||
// We need to pay special attention to the keyset tag to set up a listener
|
||||
if (aElement->NodeInfo()->Equals(nsGkAtoms::keyset, kNameSpaceID_XUL)) {
|
||||
// Create our XUL key listener and hook it up.
|
||||
nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
|
||||
if (xblService) {
|
||||
xblService->AttachGlobalKeyHandler(aElement);
|
||||
}
|
||||
nsXBLService::AttachGlobalKeyHandler(aElement);
|
||||
}
|
||||
|
||||
// See if we need to attach a XUL template to this node
|
||||
@ -1775,10 +1772,7 @@ nsXULDocument::RemoveSubtreeFromDocument(nsIContent* aContent)
|
||||
nsresult rv;
|
||||
|
||||
if (aElement->NodeInfo()->Equals(nsGkAtoms::keyset, kNameSpaceID_XUL)) {
|
||||
nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
|
||||
if (xblService) {
|
||||
xblService->DetachGlobalKeyHandler(aElement);
|
||||
}
|
||||
nsXBLService::DetachGlobalKeyHandler(aElement);
|
||||
}
|
||||
|
||||
// 1. Remove any children from the document.
|
||||
|
@ -8595,7 +8595,18 @@ nsDocShell::InternalLoad(nsIURI * aURI,
|
||||
// (bug#331040)
|
||||
nsCOMPtr<nsIDocShell> kungFuDeathGrip(this);
|
||||
|
||||
rv = MaybeInitTiming();
|
||||
// Don't init timing for javascript:, since it generally doesn't
|
||||
// actually start a load or anything. If it does, we'll init
|
||||
// timing then, from OnStateChange.
|
||||
|
||||
// XXXbz mTiming should know what channel it's for, so we don't
|
||||
// need this hackery. Note that this is still broken in cases
|
||||
// when we're loading something that's not javascript: and the
|
||||
// beforeunload handler denies the load. That will screw up
|
||||
// timing for the next load!
|
||||
if (!bIsJavascript) {
|
||||
MaybeInitTiming();
|
||||
}
|
||||
if (mTiming) {
|
||||
mTiming->NotifyBeforeUnload();
|
||||
}
|
||||
|
@ -77,9 +77,12 @@ DIRS += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
# bindings/test is here, because it needs to build after bindings/, and
|
||||
# we build subdirectories before ourselves.
|
||||
TEST_DIRS += \
|
||||
tests \
|
||||
imptests \
|
||||
bindings/test \
|
||||
$(NULL)
|
||||
|
||||
ifneq (,$(filter gtk2 cocoa windows android qt os2,$(MOZ_WIDGET_TOOLKIT)))
|
||||
|
@ -9,6 +9,15 @@ let Ci = Components.interfaces;
|
||||
let Cc = Components.classes;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
// Event whitelisted for bubbling.
|
||||
let whitelistedEvents = [
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE, // Back button.
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_CONTEXT_MENU,
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_F5, // Search button.
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP, // Volume up.
|
||||
Ci.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN // Volume down.
|
||||
];
|
||||
|
||||
function debug(msg) {
|
||||
//dump("BrowserElementChild - " + msg + "\n");
|
||||
}
|
||||
@ -32,6 +41,8 @@ function sendSyncMsg(msg, data) {
|
||||
* the parent process.
|
||||
*/
|
||||
|
||||
var global = this;
|
||||
|
||||
function BrowserElementChild() {
|
||||
this._init();
|
||||
};
|
||||
@ -57,7 +68,7 @@ BrowserElementChild.prototype = {
|
||||
// Get the app manifest from the parent, if our frame has one.
|
||||
let appManifestURL = sendSyncMsg('get-mozapp-manifest-url')[0];
|
||||
let windowUtils = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
if (!!appManifestURL) {
|
||||
windowUtils.setIsApp(true);
|
||||
@ -78,6 +89,21 @@ BrowserElementChild.prototype = {
|
||||
|
||||
addMessageListener("browser-element-api:get-screenshot",
|
||||
this._recvGetScreenshot.bind(this));
|
||||
|
||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(Ci.nsIEventListenerService);
|
||||
|
||||
// We are using the system group for those events so if something in the
|
||||
// content called .stopPropagation() this will still be called.
|
||||
els.addSystemEventListener(global, 'keydown',
|
||||
this._keyEventHandler.bind(this),
|
||||
/* useCapture = */ true);
|
||||
els.addSystemEventListener(global, 'keypress',
|
||||
this._keyEventHandler.bind(this),
|
||||
/* useCapture = */ true);
|
||||
els.addSystemEventListener(global, 'keyup',
|
||||
this._keyEventHandler.bind(this),
|
||||
/* useCapture = */ true);
|
||||
},
|
||||
|
||||
_titleChangedHandler: function(e) {
|
||||
@ -129,6 +155,16 @@ BrowserElementChild.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
_keyEventHandler: function(e) {
|
||||
if (whitelistedEvents.indexOf(e.keyCode) != -1 && !e.defaultPrevented) {
|
||||
sendAsyncMsg('keyevent', {
|
||||
type: e.type,
|
||||
code: e.keyCode,
|
||||
charCode: e.charCode,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// The docShell keeps a weak reference to the progress listener, so we need
|
||||
// to keep a strong ref to it ourselves.
|
||||
_progressListener: {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user