Merge last PGO-green changeset of mozilla-inbound to mozilla-central

This commit is contained in:
Ed Morley 2012-05-24 15:48:20 +01:00
commit 3018aec902
335 changed files with 6680 additions and 2844 deletions

View File

@ -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);
};

View File

@ -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

View 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"));
}

View 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

View File

@ -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 \

View File

@ -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"

View File

@ -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?");

View File

@ -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;
};

View File

@ -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;

View File

@ -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_

View File

@ -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();

View File

@ -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();

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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.
}

View File

@ -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.

View File

@ -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);

View 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.
}

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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
////////////////////////////////////////////////////////////////////////////////

View File

@ -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.
*/

View File

@ -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;

View File

@ -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

View File

@ -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 = \

View File

@ -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 {

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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>

View File

@ -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);

View File

@ -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") {

View File

@ -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"

View File

@ -184,7 +184,6 @@
type="checkbox"
label="&viewTabsOnTop.label;"
accesskey="&viewTabsOnTop.accesskey;"/>
<menuseparator/>
<menuitem id="menu_customizeToolbars"
label="&viewCustomizeToolbar.label;"
accesskey="&viewCustomizeToolbar.accesskey;"

View File

@ -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() {

View File

@ -204,7 +204,6 @@
type="checkbox"
label="&viewTabsOnTop.label;"
accesskey="&viewTabsOnTop.accesskey;"/>
<menuseparator/>
<menuitem command="cmd_CustomizeToolbars"
label="&viewCustomizeToolbar.label;"
accesskey="&viewCustomizeToolbar.accesskey;"/>

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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
#

View File

@ -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();

View File

@ -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) { },
};

View File

@ -116,6 +116,7 @@ protected:
return !!uri;
}
nsIURI* GetCachedURI() const { return mCachedURI; }
bool HasCachedURI() const { return !!mCachedURI; }
private:

View File

@ -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 + "\"");
}
}
}

View File

@ -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;
}

View File

@ -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"

View File

@ -65,7 +65,6 @@
#include "nsBindingManager.h"
#include "nsXBLBinding.h"
#include "nsIXBLService.h"
#include "nsPIDOMWindow.h"
#include "nsPIBoxObject.h"
#include "nsClientRect.h"

View 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);
});
}

View File

@ -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]

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -2516,6 +2516,7 @@ nsCanvasRenderingContext2DAzure::EnsureWritablePath()
mPath->TransformedCopyToBuilder(mPathToDS, fillRule);
mPath = nsnull;
mPathBuilder = nsnull;
mPathTransformWillUpdate = false;
}
return;
}

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -36,7 +36,7 @@ GLSLGenerator.runReferenceImageTest({
args: "$(type) value",
testFunc: "$(func)($(type))",
gridRes: 8,
tolerance: 2,
tolerance: 3,
extra: piConstants,
tests: [
{

View File

@ -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),",

View File

@ -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,

View File

@ -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",

View File

@ -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();

View File

@ -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";

View File

@ -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);

View File

@ -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();
}

View File

@ -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;

View File

@ -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;
};
/**

View File

@ -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;

View File

@ -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

View File

@ -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];
}

View File

@ -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"

View File

@ -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;

View File

@ -10,7 +10,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
PARALLEL_DIRS = public src builtin
PARALLEL_DIRS = src builtin
TEST_DIRS += test

View File

@ -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

View File

@ -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__

View File

@ -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;

View File

@ -23,7 +23,6 @@ class nsIAtom;
class nsIDocument;
class nsIScriptContext;
class nsSupportsHashtable;
class nsIXBLService;
class nsFixedSizeAllocator;
class nsXBLProtoImplField;
class nsXBLBinding;

View File

@ -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"

View File

@ -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();

View File

@ -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;
}

View File

@ -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.

View File

@ -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

View File

@ -14,7 +14,6 @@ class nsIDOMElement;
class nsIDOMEventTarget;
class nsIDOMKeyEvent;
class nsIDOMEventTarget;
class nsIXBLDocumentInfo;
class nsXBLSpecialDocInfo;
class nsXBLPrototypeHandler;

View File

@ -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.
*/

View File

@ -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);

View File

@ -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.

View File

@ -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();
}

View File

@ -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)))

View File

@ -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