mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Merge mozilla-central & fx-team
This commit is contained in:
commit
e16349cfc4
41
.gitignore
vendored
Normal file
41
.gitignore
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# .gitignore - List of filenames git should ignore
|
||||||
|
|
||||||
|
# Filenames that should be ignored wherever they appear
|
||||||
|
*~
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
TAGS
|
||||||
|
tags
|
||||||
|
ID
|
||||||
|
.DS_Store*
|
||||||
|
|
||||||
|
# Vim swap files.
|
||||||
|
.*.sw[a-z]
|
||||||
|
|
||||||
|
# User files that may appear at the root
|
||||||
|
.mozconfig
|
||||||
|
mozconfig
|
||||||
|
configure
|
||||||
|
config.cache
|
||||||
|
config.log
|
||||||
|
|
||||||
|
# Empty marker file that's generated when we check out NSS
|
||||||
|
security/manager/.nss.checkout
|
||||||
|
|
||||||
|
# Build directories
|
||||||
|
obj/*
|
||||||
|
|
||||||
|
# Build directories for js shell
|
||||||
|
*/_DBG.OBJ/
|
||||||
|
*/_OPT.OBJ/
|
||||||
|
|
||||||
|
# SpiderMonkey configury
|
||||||
|
js/src/configure
|
||||||
|
js/src/autom4te.cache
|
||||||
|
# SpiderMonkey test result logs
|
||||||
|
js/src/tests/results-*.html
|
||||||
|
js/src/tests/results-*.txt
|
||||||
|
|
||||||
|
# Java HTML5 parser classes
|
||||||
|
parser/html/java/htmlparser/
|
||||||
|
parser/html/java/javaparser/
|
@ -59,7 +59,7 @@ interface nsIDOMNode;
|
|||||||
* if (NS_SUCCEEDED(rv))
|
* if (NS_SUCCEEDED(rv))
|
||||||
* rv = observerService->AddObserver(this, "accessible-event", PR_TRUE);
|
* rv = observerService->AddObserver(this, "accessible-event", PR_TRUE);
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(fd1378c5-c606-4a5e-a321-8e7fc107e5cf)]
|
[scriptable, uuid(7f66a33a-9ed7-4fd4-87a8-e431b0f43368)]
|
||||||
interface nsIAccessibleEvent : nsISupports
|
interface nsIAccessibleEvent : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -280,7 +280,12 @@ interface nsIAccessibleEvent : nsISupports
|
|||||||
const unsigned long EVENT_DOCUMENT_CONTENT_CHANGED = 0x002B;
|
const unsigned long EVENT_DOCUMENT_CONTENT_CHANGED = 0x002B;
|
||||||
|
|
||||||
const unsigned long EVENT_PROPERTY_CHANGED = 0x002C;
|
const unsigned long EVENT_PROPERTY_CHANGED = 0x002C;
|
||||||
const unsigned long EVENT_SELECTION_CHANGED = 0x002D;
|
|
||||||
|
/**
|
||||||
|
* A slide changed in a presentation document or a page boundary was
|
||||||
|
* crossed in a word processing document.
|
||||||
|
*/
|
||||||
|
const unsigned long EVENT_PAGE_CHANGED = 0x002D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A text object's attributes changed.
|
* A text object's attributes changed.
|
||||||
@ -436,16 +441,10 @@ interface nsIAccessibleEvent : nsISupports
|
|||||||
*/
|
*/
|
||||||
const unsigned long EVENT_OBJECT_ATTRIBUTE_CHANGED = 0x0055;
|
const unsigned long EVENT_OBJECT_ATTRIBUTE_CHANGED = 0x0055;
|
||||||
|
|
||||||
/**
|
|
||||||
* A slide changed in a presentation document or a page boundary was
|
|
||||||
* crossed in a word processing document.
|
|
||||||
*/
|
|
||||||
const unsigned long EVENT_PAGE_CHANGED = 0x0056;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Help make sure event map does not get out-of-line.
|
* Help make sure event map does not get out-of-line.
|
||||||
*/
|
*/
|
||||||
const unsigned long EVENT_LAST_ENTRY = 0x0057;
|
const unsigned long EVENT_LAST_ENTRY = 0x0056;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of event, based on the enumerated event values
|
* The type of event, based on the enumerated event values
|
||||||
|
@ -1089,10 +1089,24 @@ nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case nsIAccessibleEvent::EVENT_SELECTION_CHANGED:
|
case nsIAccessibleEvent::EVENT_SELECTION:
|
||||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_SELECTION_CHANGED\n"));
|
case nsIAccessibleEvent::EVENT_SELECTION_ADD:
|
||||||
g_signal_emit_by_name(atkObj, "selection_changed");
|
case nsIAccessibleEvent::EVENT_SELECTION_REMOVE:
|
||||||
break;
|
{
|
||||||
|
// XXX: dupe events may be fired
|
||||||
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_SELECTION_CHANGED\n"));
|
||||||
|
AccSelChangeEvent* selChangeEvent = downcast_accEvent(aEvent);
|
||||||
|
g_signal_emit_by_name(nsAccessibleWrap::GetAtkObject(selChangeEvent->Widget()),
|
||||||
|
"selection_changed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nsIAccessibleEvent::EVENT_SELECTION_WITHIN:
|
||||||
|
{
|
||||||
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_SELECTION_CHANGED\n"));
|
||||||
|
g_signal_emit_by_name(atkObj, "selection_changed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
|
case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
|
||||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_SELECTION_CHANGED\n"));
|
MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_SELECTION_CHANGED\n"));
|
||||||
|
@ -330,6 +330,28 @@ AccCaretMoveEvent::CreateXPCOMObject()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// AccSelChangeEvent
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
AccSelChangeEvent::
|
||||||
|
AccSelChangeEvent(nsAccessible* aWidget, nsAccessible* aItem,
|
||||||
|
SelChangeType aSelChangeType) :
|
||||||
|
AccEvent(0, aItem, eAutoDetect, eCoalesceSelectionChange),
|
||||||
|
mWidget(aWidget), mItem(aItem), mSelChangeType(aSelChangeType),
|
||||||
|
mPreceedingCount(0), mPackedEvent(nsnull)
|
||||||
|
{
|
||||||
|
if (aSelChangeType == eSelectionAdd) {
|
||||||
|
if (mWidget->GetSelectedItem(1))
|
||||||
|
mEventType = nsIAccessibleEvent::EVENT_SELECTION_ADD;
|
||||||
|
else
|
||||||
|
mEventType = nsIAccessibleEvent::EVENT_SELECTION;
|
||||||
|
} else {
|
||||||
|
mEventType = nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// AccTableChangeEvent
|
// AccTableChangeEvent
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -82,6 +82,9 @@ public:
|
|||||||
// will be processed.
|
// will be processed.
|
||||||
eCoalesceOfSameType,
|
eCoalesceOfSameType,
|
||||||
|
|
||||||
|
// eCoalesceSelectionChange: coalescence of selection change events.
|
||||||
|
eCoalesceSelectionChange,
|
||||||
|
|
||||||
// eRemoveDupes : For repeat events, only the newest event in queue
|
// eRemoveDupes : For repeat events, only the newest event in queue
|
||||||
// will be emitted.
|
// will be emitted.
|
||||||
eRemoveDupes,
|
eRemoveDupes,
|
||||||
@ -125,6 +128,7 @@ public:
|
|||||||
eHideEvent,
|
eHideEvent,
|
||||||
eShowEvent,
|
eShowEvent,
|
||||||
eCaretMoveEvent,
|
eCaretMoveEvent,
|
||||||
|
eSelectionChangeEvent,
|
||||||
eTableChangeEvent
|
eTableChangeEvent
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -327,10 +331,37 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Accessible widget selection change event.
|
* Accessible widget selection change event.
|
||||||
*/
|
*/
|
||||||
class AccSelectionChangeEvent : public AccEvent
|
class AccSelChangeEvent : public AccEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum SelChangeType {
|
||||||
|
eSelectionAdd,
|
||||||
|
eSelectionRemove
|
||||||
|
};
|
||||||
|
|
||||||
|
AccSelChangeEvent(nsAccessible* aWidget, nsAccessible* aItem,
|
||||||
|
SelChangeType aSelChangeType);
|
||||||
|
|
||||||
|
virtual ~AccSelChangeEvent() { }
|
||||||
|
|
||||||
|
// AccEvent
|
||||||
|
static const EventGroup kEventGroup = eSelectionChangeEvent;
|
||||||
|
virtual unsigned int GetEventGroups() const
|
||||||
|
{
|
||||||
|
return AccEvent::GetEventGroups() | (1U << eSelectionChangeEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccSelChangeEvent
|
||||||
|
nsAccessible* Widget() const { return mWidget; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsRefPtr<nsAccessible> mWidget;
|
||||||
|
nsRefPtr<nsAccessible> mItem;
|
||||||
|
SelChangeType mSelChangeType;
|
||||||
|
PRUint32 mPreceedingCount;
|
||||||
|
AccSelChangeEvent* mPackedEvent;
|
||||||
|
|
||||||
|
friend class NotificationController;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,6 +51,10 @@
|
|||||||
|
|
||||||
using namespace mozilla::a11y;
|
using namespace mozilla::a11y;
|
||||||
|
|
||||||
|
// Defines the number of selection add/remove events in the queue when they
|
||||||
|
// aren't packed into single selection within event.
|
||||||
|
const unsigned int kSelChangeCountToPack = 5;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// NotificationCollector
|
// NotificationCollector
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -491,6 +495,26 @@ NotificationController::CoalesceEvents()
|
|||||||
}
|
}
|
||||||
} break; // case eRemoveDupes
|
} break; // case eRemoveDupes
|
||||||
|
|
||||||
|
case AccEvent::eCoalesceSelectionChange:
|
||||||
|
{
|
||||||
|
AccSelChangeEvent* tailSelChangeEvent = downcast_accEvent(tailEvent);
|
||||||
|
PRInt32 index = tail - 1;
|
||||||
|
for (; index >= 0; index--) {
|
||||||
|
AccEvent* thisEvent = mEvents[index];
|
||||||
|
if (thisEvent->mEventRule == tailEvent->mEventRule) {
|
||||||
|
AccSelChangeEvent* thisSelChangeEvent =
|
||||||
|
downcast_accEvent(thisEvent);
|
||||||
|
|
||||||
|
// Coalesce selection change events within same control.
|
||||||
|
if (tailSelChangeEvent->mWidget == thisSelChangeEvent->mWidget) {
|
||||||
|
CoalesceSelChangeEvents(tailSelChangeEvent, thisSelChangeEvent, index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} break; // eCoalesceSelectionChange
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break; // case eAllowDupes, eDoNotEmit
|
break; // case eAllowDupes, eDoNotEmit
|
||||||
} // switch
|
} // switch
|
||||||
@ -511,6 +535,86 @@ NotificationController::ApplyToSiblings(PRUint32 aStart, PRUint32 aEnd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
|
||||||
|
AccSelChangeEvent* aThisEvent,
|
||||||
|
PRInt32 aThisIndex)
|
||||||
|
{
|
||||||
|
aTailEvent->mPreceedingCount = aThisEvent->mPreceedingCount + 1;
|
||||||
|
|
||||||
|
// Pack all preceding events into single selection within event
|
||||||
|
// when we receive too much selection add/remove events.
|
||||||
|
if (aTailEvent->mPreceedingCount >= kSelChangeCountToPack) {
|
||||||
|
aTailEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION_WITHIN;
|
||||||
|
aTailEvent->mAccessible = aTailEvent->mWidget;
|
||||||
|
aThisEvent->mEventRule = AccEvent::eDoNotEmit;
|
||||||
|
|
||||||
|
// Do not emit any preceding selection events for same widget if they
|
||||||
|
// weren't coalesced yet.
|
||||||
|
if (aThisEvent->mEventType != nsIAccessibleEvent::EVENT_SELECTION_WITHIN) {
|
||||||
|
for (PRInt32 jdx = aThisIndex - 1; jdx >= 0; jdx--) {
|
||||||
|
AccEvent* prevEvent = mEvents[jdx];
|
||||||
|
if (prevEvent->mEventRule == aTailEvent->mEventRule) {
|
||||||
|
AccSelChangeEvent* prevSelChangeEvent =
|
||||||
|
downcast_accEvent(prevEvent);
|
||||||
|
if (prevSelChangeEvent->mWidget == aTailEvent->mWidget)
|
||||||
|
prevSelChangeEvent->mEventRule = AccEvent::eDoNotEmit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pack sequential selection remove and selection add events into
|
||||||
|
// single selection change event.
|
||||||
|
if (aTailEvent->mPreceedingCount == 1 &&
|
||||||
|
aTailEvent->mItem != aThisEvent->mItem) {
|
||||||
|
if (aTailEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd &&
|
||||||
|
aThisEvent->mSelChangeType == AccSelChangeEvent::eSelectionRemove) {
|
||||||
|
aThisEvent->mEventRule = AccEvent::eDoNotEmit;
|
||||||
|
aTailEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION;
|
||||||
|
aTailEvent->mPackedEvent = aThisEvent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aThisEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd &&
|
||||||
|
aTailEvent->mSelChangeType == AccSelChangeEvent::eSelectionRemove) {
|
||||||
|
aTailEvent->mEventRule = AccEvent::eDoNotEmit;
|
||||||
|
aThisEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION;
|
||||||
|
aThisEvent->mPackedEvent = aThisEvent;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack the packed selection change event because we've got one
|
||||||
|
// more selection add/remove.
|
||||||
|
if (aThisEvent->mEventType == nsIAccessibleEvent::EVENT_SELECTION) {
|
||||||
|
if (aThisEvent->mPackedEvent) {
|
||||||
|
aThisEvent->mPackedEvent->mEventType =
|
||||||
|
aThisEvent->mPackedEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd ?
|
||||||
|
nsIAccessibleEvent::EVENT_SELECTION_ADD :
|
||||||
|
nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
|
||||||
|
|
||||||
|
aThisEvent->mPackedEvent->mEventRule =
|
||||||
|
AccEvent::eCoalesceSelectionChange;
|
||||||
|
|
||||||
|
aThisEvent->mPackedEvent = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
aThisEvent->mEventType =
|
||||||
|
aThisEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd ?
|
||||||
|
nsIAccessibleEvent::EVENT_SELECTION_ADD :
|
||||||
|
nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert into selection add since control has single selection but other
|
||||||
|
// selection events for this control are queued.
|
||||||
|
if (aTailEvent->mEventType == nsIAccessibleEvent::EVENT_SELECTION)
|
||||||
|
aTailEvent->mEventType = nsIAccessibleEvent::EVENT_SELECTION_ADD;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NotificationController::CoalesceTextChangeEventsFor(AccHideEvent* aTailEvent,
|
NotificationController::CoalesceTextChangeEventsFor(AccHideEvent* aTailEvent,
|
||||||
AccHideEvent* aThisEvent)
|
AccHideEvent* aThisEvent)
|
||||||
|
@ -251,11 +251,11 @@ private:
|
|||||||
AccEvent::EEventRule aEventRule);
|
AccEvent::EEventRule aEventRule);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not emit one of two given reorder events fired for DOM nodes in the case
|
* Coalesce two selection change events within the same select control.
|
||||||
* when one DOM node is in parent chain of second one.
|
|
||||||
*/
|
*/
|
||||||
void CoalesceReorderEventsFromSameTree(AccEvent* aAccEvent,
|
void CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
|
||||||
AccEvent* aDescendantAccEvent);
|
AccSelChangeEvent* aThisEvent,
|
||||||
|
PRInt32 aThisIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Coalesce text change events caused by sibling hide events.
|
* Coalesce text change events caused by sibling hide events.
|
||||||
|
@ -473,7 +473,7 @@ static const char kEventTypeNames[][40] = {
|
|||||||
"document attributes changed", // EVENT_DOCUMENT_ATTRIBUTES_CHANGED
|
"document attributes changed", // EVENT_DOCUMENT_ATTRIBUTES_CHANGED
|
||||||
"document content changed", // EVENT_DOCUMENT_CONTENT_CHANGED
|
"document content changed", // EVENT_DOCUMENT_CONTENT_CHANGED
|
||||||
"property changed", // EVENT_PROPERTY_CHANGED
|
"property changed", // EVENT_PROPERTY_CHANGED
|
||||||
"selection changed", // EVENT_SELECTION_CHANGED
|
"page changed", // EVENT_PAGE_CHANGED
|
||||||
"text attribute changed", // EVENT_TEXT_ATTRIBUTE_CHANGED
|
"text attribute changed", // EVENT_TEXT_ATTRIBUTE_CHANGED
|
||||||
"text caret moved", // EVENT_TEXT_CARET_MOVED
|
"text caret moved", // EVENT_TEXT_CARET_MOVED
|
||||||
"text changed", // EVENT_TEXT_CHANGED
|
"text changed", // EVENT_TEXT_CHANGED
|
||||||
@ -514,7 +514,6 @@ static const char kEventTypeNames[][40] = {
|
|||||||
"hypertext changed", // EVENT_HYPERTEXT_CHANGED
|
"hypertext changed", // EVENT_HYPERTEXT_CHANGED
|
||||||
"hypertext links count changed", // EVENT_HYPERTEXT_NLINKS_CHANGED
|
"hypertext links count changed", // EVENT_HYPERTEXT_NLINKS_CHANGED
|
||||||
"object attribute changed", // EVENT_OBJECT_ATTRIBUTE_CHANGED
|
"object attribute changed", // EVENT_OBJECT_ATTRIBUTE_CHANGED
|
||||||
"page changed" // EVENT_PAGE_CHANGED
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1042,32 +1042,23 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aAttribute == nsGkAtoms::selected ||
|
// ARIA or XUL selection
|
||||||
|
if ((aContent->IsXUL() && aAttribute == nsGkAtoms::selected) ||
|
||||||
aAttribute == nsGkAtoms::aria_selected) {
|
aAttribute == nsGkAtoms::aria_selected) {
|
||||||
// ARIA or XUL selection
|
nsAccessible* item = GetAccessible(aContent);
|
||||||
|
nsAccessible* widget =
|
||||||
|
nsAccUtils::GetSelectableContainer(item, item->State());
|
||||||
|
if (widget) {
|
||||||
|
AccSelChangeEvent::SelChangeType selChangeType =
|
||||||
|
aContent->AttrValueIs(aNameSpaceID, aAttribute,
|
||||||
|
nsGkAtoms::_true, eCaseMatters) ?
|
||||||
|
AccSelChangeEvent::eSelectionAdd : AccSelChangeEvent::eSelectionRemove;
|
||||||
|
|
||||||
nsAccessible *multiSelect =
|
nsRefPtr<AccEvent> event =
|
||||||
nsAccUtils::GetMultiSelectableContainer(aContent);
|
new AccSelChangeEvent(widget, item, selChangeType);
|
||||||
// XXX: Multi selects are handled here only (bug 414302).
|
FireDelayedAccessibleEvent(event);
|
||||||
if (multiSelect) {
|
|
||||||
// Need to find the right event to use here, SELECTION_WITHIN would
|
|
||||||
// seem right but we had started using it for something else
|
|
||||||
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
|
|
||||||
multiSelect->GetNode(),
|
|
||||||
AccEvent::eAllowDupes);
|
|
||||||
|
|
||||||
static nsIContent::AttrValuesArray strings[] =
|
|
||||||
{&nsGkAtoms::_empty, &nsGkAtoms::_false, nsnull};
|
|
||||||
if (aContent->FindAttrValueIn(kNameSpaceID_None, aAttribute,
|
|
||||||
strings, eCaseMatters) >= 0) {
|
|
||||||
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SELECTION_REMOVE,
|
|
||||||
aContent);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SELECTION_ADD,
|
|
||||||
aContent);
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aAttribute == nsGkAtoms::contenteditable) {
|
if (aAttribute == nsGkAtoms::contenteditable) {
|
||||||
@ -1209,7 +1200,18 @@ void nsDocAccessible::ContentStateChanged(nsIDocument* aDocument,
|
|||||||
nsEventStates aStateMask)
|
nsEventStates aStateMask)
|
||||||
{
|
{
|
||||||
if (aStateMask.HasState(NS_EVENT_STATE_CHECKED)) {
|
if (aStateMask.HasState(NS_EVENT_STATE_CHECKED)) {
|
||||||
nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent);
|
nsAccessible* item = GetAccessible(aContent);
|
||||||
|
if (item) {
|
||||||
|
nsAccessible* widget = item->ContainerWidget();
|
||||||
|
if (widget && widget->IsSelect()) {
|
||||||
|
AccSelChangeEvent::SelChangeType selChangeType =
|
||||||
|
aContent->AsElement()->State().HasState(NS_EVENT_STATE_CHECKED) ?
|
||||||
|
AccSelChangeEvent::eSelectionAdd : AccSelChangeEvent::eSelectionRemove;
|
||||||
|
nsRefPtr<AccEvent> event = new AccSelChangeEvent(widget, item,
|
||||||
|
selChangeType);
|
||||||
|
FireDelayedAccessibleEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aStateMask.HasState(NS_EVENT_STATE_INVALID)) {
|
if (aStateMask.HasState(NS_EVENT_STATE_INVALID)) {
|
||||||
|
@ -473,6 +473,8 @@ nsRootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (treeItemAccessible && eventType.EqualsLiteral("select")) {
|
if (treeItemAccessible && eventType.EqualsLiteral("select")) {
|
||||||
|
// XXX: We shouldn't be based on DOM select event which doesn't provide us
|
||||||
|
// any context info. We should integrate into nsTreeSelection instead.
|
||||||
// If multiselect tree, we should fire selectionadd or selection removed
|
// If multiselect tree, we should fire selectionadd or selection removed
|
||||||
if (FocusMgr()->HasDOMFocus(targetNode)) {
|
if (FocusMgr()->HasDOMFocus(targetNode)) {
|
||||||
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSel =
|
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSel =
|
||||||
|
@ -416,59 +416,7 @@ nsHTMLSelectOptionAccessible::SetSelected(bool aSelect)
|
|||||||
nsAccessible*
|
nsAccessible*
|
||||||
nsHTMLSelectOptionAccessible::ContainerWidget() const
|
nsHTMLSelectOptionAccessible::ContainerWidget() const
|
||||||
{
|
{
|
||||||
if (mParent && mParent->IsListControl()) {
|
return mParent && mParent->IsListControl() ? mParent : nsnull;
|
||||||
nsAccessible* grandParent = mParent->Parent();
|
|
||||||
if (grandParent && grandParent->IsCombobox())
|
|
||||||
return grandParent;
|
|
||||||
|
|
||||||
return mParent;
|
|
||||||
}
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// nsHTMLSelectOptionAccessible: static methods
|
|
||||||
|
|
||||||
void
|
|
||||||
nsHTMLSelectOptionAccessible::SelectionChangedIfOption(nsIContent *aPossibleOptionNode)
|
|
||||||
{
|
|
||||||
if (!aPossibleOptionNode ||
|
|
||||||
aPossibleOptionNode->Tag() != nsGkAtoms::option ||
|
|
||||||
!aPossibleOptionNode->IsHTML()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAccessible *multiSelect =
|
|
||||||
nsAccUtils::GetMultiSelectableContainer(aPossibleOptionNode);
|
|
||||||
if (!multiSelect)
|
|
||||||
return;
|
|
||||||
|
|
||||||
nsAccessible *option = GetAccService()->GetAccessible(aPossibleOptionNode);
|
|
||||||
if (!option)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
nsRefPtr<AccEvent> selWithinEvent =
|
|
||||||
new AccEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN, multiSelect);
|
|
||||||
|
|
||||||
if (!selWithinEvent)
|
|
||||||
return;
|
|
||||||
|
|
||||||
option->GetDocAccessible()->FireDelayedAccessibleEvent(selWithinEvent);
|
|
||||||
|
|
||||||
PRUint64 state = option->State();
|
|
||||||
PRUint32 eventType;
|
|
||||||
if (state & states::SELECTED) {
|
|
||||||
eventType = nsIAccessibleEvent::EVENT_SELECTION_ADD;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
eventType = nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<AccEvent> selAddRemoveEvent = new AccEvent(eventType, option);
|
|
||||||
|
|
||||||
if (selAddRemoveEvent)
|
|
||||||
option->GetDocAccessible()->FireDelayedAccessibleEvent(selAddRemoveEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -738,26 +686,22 @@ nsHTMLComboboxAccessible::AreItemsOperable() const
|
|||||||
nsAccessible*
|
nsAccessible*
|
||||||
nsHTMLComboboxAccessible::CurrentItem()
|
nsHTMLComboboxAccessible::CurrentItem()
|
||||||
{
|
{
|
||||||
// No current item for collapsed combobox.
|
return AreItemsOperable() ? mListAccessible->CurrentItem() : nsnull;
|
||||||
return SelectedOption(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// nsHTMLComboboxAccessible: protected
|
// nsHTMLComboboxAccessible: protected
|
||||||
|
|
||||||
nsAccessible*
|
nsAccessible*
|
||||||
nsHTMLComboboxAccessible::SelectedOption(bool aIgnoreIfCollapsed) const
|
nsHTMLComboboxAccessible::SelectedOption() const
|
||||||
{
|
{
|
||||||
nsIFrame* frame = GetFrame();
|
nsIFrame* frame = GetFrame();
|
||||||
nsIComboboxControlFrame* comboboxFrame = do_QueryFrame(frame);
|
nsIComboboxControlFrame* comboboxFrame = do_QueryFrame(frame);
|
||||||
if (comboboxFrame) {
|
if (!comboboxFrame)
|
||||||
if (aIgnoreIfCollapsed && !comboboxFrame->IsDroppedDown())
|
return nsnull;
|
||||||
return nsnull;
|
|
||||||
|
|
||||||
frame = comboboxFrame->GetDropDown();
|
nsIListControlFrame* listControlFrame =
|
||||||
}
|
do_QueryFrame(comboboxFrame->GetDropDown());
|
||||||
|
|
||||||
nsIListControlFrame* listControlFrame = do_QueryFrame(frame);
|
|
||||||
if (listControlFrame) {
|
if (listControlFrame) {
|
||||||
nsCOMPtr<nsIContent> activeOptionNode = listControlFrame->GetCurrentOption();
|
nsCOMPtr<nsIContent> activeOptionNode = listControlFrame->GetCurrentOption();
|
||||||
if (activeOptionNode) {
|
if (activeOptionNode) {
|
||||||
@ -858,3 +802,19 @@ void nsHTMLComboboxListAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBo
|
|||||||
*aBoundingFrame = frame->GetParent();
|
*aBoundingFrame = frame->GetParent();
|
||||||
aBounds = (*aBoundingFrame)->GetRect();
|
aBounds = (*aBoundingFrame)->GetRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsHTMLComboboxListAccessible: Widgets
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsHTMLComboboxListAccessible::IsActiveWidget() const
|
||||||
|
{
|
||||||
|
return mParent && mParent->IsActiveWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsHTMLComboboxListAccessible::AreItemsOperable() const
|
||||||
|
{
|
||||||
|
return mParent && mParent->AreItemsOperable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -130,8 +130,6 @@ public:
|
|||||||
// Widgets
|
// Widgets
|
||||||
virtual nsAccessible* ContainerWidget() const;
|
virtual nsAccessible* ContainerWidget() const;
|
||||||
|
|
||||||
static void SelectionChangedIfOption(nsIContent *aPossibleOption);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
virtual nsIFrame* GetBoundsFrame();
|
virtual nsIFrame* GetBoundsFrame();
|
||||||
@ -219,7 +217,7 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* Return selected option.
|
* Return selected option.
|
||||||
*/
|
*/
|
||||||
nsAccessible* SelectedOption(bool aIgnoreIfCollapsed = false) const;
|
nsAccessible* SelectedOption() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsRefPtr<nsHTMLComboboxListAccessible> mListAccessible;
|
nsRefPtr<nsHTMLComboboxListAccessible> mListAccessible;
|
||||||
@ -246,6 +244,10 @@ public:
|
|||||||
// nsAccessible
|
// nsAccessible
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
|
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
|
||||||
|
|
||||||
|
// Widgets
|
||||||
|
virtual bool IsActiveWidget() const;
|
||||||
|
virtual bool AreItemsOperable() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -190,9 +190,7 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||||||
NSAccessibilityTitleAttribute,
|
NSAccessibilityTitleAttribute,
|
||||||
NSAccessibilityValueAttribute,
|
NSAccessibilityValueAttribute,
|
||||||
NSAccessibilitySubroleAttribute,
|
NSAccessibilitySubroleAttribute,
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
NSAccessibilityRoleDescriptionAttribute,
|
NSAccessibilityRoleDescriptionAttribute,
|
||||||
#endif
|
|
||||||
NSAccessibilityPositionAttribute,
|
NSAccessibilityPositionAttribute,
|
||||||
NSAccessibilityEnabledAttribute,
|
NSAccessibilityEnabledAttribute,
|
||||||
NSAccessibilitySizeAttribute,
|
NSAccessibilitySizeAttribute,
|
||||||
@ -236,10 +234,8 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||||||
return [NSNumber numberWithBool:[self isEnabled]];
|
return [NSNumber numberWithBool:[self isEnabled]];
|
||||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
|
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
|
||||||
return [self value];
|
return [self value];
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute])
|
if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute])
|
||||||
return NSAccessibilityRoleDescription([self role], nil);
|
return NSAccessibilityRoleDescription([self role], nil);
|
||||||
#endif
|
|
||||||
if ([attribute isEqualToString: (NSString*) kInstanceDescriptionAttribute])
|
if ([attribute isEqualToString: (NSString*) kInstanceDescriptionAttribute])
|
||||||
return [self customDescription];
|
return [self customDescription];
|
||||||
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
|
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
|
||||||
|
@ -226,9 +226,7 @@ enum CheckboxValue {
|
|||||||
|
|
||||||
if ([self isEnabled]) {
|
if ([self isEnabled]) {
|
||||||
return [NSArray arrayWithObjects:NSAccessibilityPressAction,
|
return [NSArray arrayWithObjects:NSAccessibilityPressAction,
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
NSAccessibilityShowMenuAction,
|
NSAccessibilityShowMenuAction,
|
||||||
#endif
|
|
||||||
nil];
|
nil];
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
@ -240,10 +238,8 @@ enum CheckboxValue {
|
|||||||
{
|
{
|
||||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
||||||
return @"show menu";
|
return @"show menu";
|
||||||
#endif
|
|
||||||
return [super accessibilityActionDescription:action];
|
return [super accessibilityActionDescription:action];
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||||
|
@ -49,9 +49,7 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||||||
NSAccessibilityTitleAttribute,
|
NSAccessibilityTitleAttribute,
|
||||||
NSAccessibilityValueAttribute, // required
|
NSAccessibilityValueAttribute, // required
|
||||||
NSAccessibilitySubroleAttribute,
|
NSAccessibilitySubroleAttribute,
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
NSAccessibilityRoleDescriptionAttribute,
|
NSAccessibilityRoleDescriptionAttribute,
|
||||||
#endif
|
|
||||||
NSAccessibilityPositionAttribute, // required
|
NSAccessibilityPositionAttribute, // required
|
||||||
NSAccessibilitySizeAttribute, // required
|
NSAccessibilitySizeAttribute, // required
|
||||||
NSAccessibilityWindowAttribute, // required
|
NSAccessibilityWindowAttribute, // required
|
||||||
@ -249,9 +247,7 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||||||
NSAccessibilityTitleAttribute,
|
NSAccessibilityTitleAttribute,
|
||||||
NSAccessibilityValueAttribute, // required
|
NSAccessibilityValueAttribute, // required
|
||||||
NSAccessibilityHelpAttribute,
|
NSAccessibilityHelpAttribute,
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
NSAccessibilityRoleDescriptionAttribute,
|
NSAccessibilityRoleDescriptionAttribute,
|
||||||
#endif
|
|
||||||
NSAccessibilityPositionAttribute, // required
|
NSAccessibilityPositionAttribute, // required
|
||||||
NSAccessibilitySizeAttribute, // required
|
NSAccessibilitySizeAttribute, // required
|
||||||
NSAccessibilityWindowAttribute, // required
|
NSAccessibilityWindowAttribute, // required
|
||||||
@ -281,9 +277,7 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||||||
|
|
||||||
if ([self isEnabled]) {
|
if ([self isEnabled]) {
|
||||||
return [NSArray arrayWithObjects:NSAccessibilityConfirmAction,
|
return [NSArray arrayWithObjects:NSAccessibilityConfirmAction,
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
NSAccessibilityShowMenuAction,
|
NSAccessibilityShowMenuAction,
|
||||||
#endif
|
|
||||||
nil];
|
nil];
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
@ -295,10 +289,8 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||||||
{
|
{
|
||||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
||||||
return @"show menu";
|
return @"show menu";
|
||||||
#endif
|
|
||||||
if ([action isEqualToString:NSAccessibilityConfirmAction])
|
if ([action isEqualToString:NSAccessibilityConfirmAction])
|
||||||
return @"confirm";
|
return @"confirm";
|
||||||
|
|
||||||
@ -313,10 +305,8 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
|
|||||||
|
|
||||||
// both the ShowMenu and Click action do the same thing.
|
// both the ShowMenu and Click action do the same thing.
|
||||||
if ([self isEnabled]) {
|
if ([self isEnabled]) {
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
|
||||||
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
||||||
[self showMenu];
|
[self showMenu];
|
||||||
#endif
|
|
||||||
if ([action isEqualToString:NSAccessibilityConfirmAction])
|
if ([action isEqualToString:NSAccessibilityConfirmAction])
|
||||||
[self confirm];
|
[self confirm];
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ static const PRUint32 gWinEventMap[] = {
|
|||||||
IA2_EVENT_DOCUMENT_ATTRIBUTE_CHANGED, // nsIAccessibleEvent::EVENT_DOCUMENT_ATTRIBUTES_CHANGED
|
IA2_EVENT_DOCUMENT_ATTRIBUTE_CHANGED, // nsIAccessibleEvent::EVENT_DOCUMENT_ATTRIBUTES_CHANGED
|
||||||
IA2_EVENT_DOCUMENT_CONTENT_CHANGED, // nsIAccessibleEvent::EVENT_DOCUMENT_CONTENT_CHANGED
|
IA2_EVENT_DOCUMENT_CONTENT_CHANGED, // nsIAccessibleEvent::EVENT_DOCUMENT_CONTENT_CHANGED
|
||||||
kEVENT_WIN_UNKNOWN, // nsIAccessibleEvent::EVENT_PROPERTY_CHANGED
|
kEVENT_WIN_UNKNOWN, // nsIAccessibleEvent::EVENT_PROPERTY_CHANGED
|
||||||
kEVENT_WIN_UNKNOWN, // nsIAccessibleEvent::EVENT_SELECTION_CHANGED
|
IA2_EVENT_PAGE_CHANGED, // nsIAccessibleEvent::IA2_EVENT_PAGE_CHANGED
|
||||||
IA2_EVENT_TEXT_ATTRIBUTE_CHANGED, // nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED
|
IA2_EVENT_TEXT_ATTRIBUTE_CHANGED, // nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED
|
||||||
IA2_EVENT_TEXT_CARET_MOVED, // nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED
|
IA2_EVENT_TEXT_CARET_MOVED, // nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED
|
||||||
IA2_EVENT_TEXT_CHANGED, // nsIAccessibleEvent::EVENT_TEXT_CHANGED
|
IA2_EVENT_TEXT_CHANGED, // nsIAccessibleEvent::EVENT_TEXT_CHANGED
|
||||||
@ -131,7 +131,6 @@ static const PRUint32 gWinEventMap[] = {
|
|||||||
IA2_EVENT_HYPERTEXT_CHANGED, // nsIAccessibleEvent::EVENT_HYPERTEXT_CHANGED
|
IA2_EVENT_HYPERTEXT_CHANGED, // nsIAccessibleEvent::EVENT_HYPERTEXT_CHANGED
|
||||||
IA2_EVENT_HYPERTEXT_NLINKS_CHANGED, // nsIAccessibleEvent::EVENT_HYPERTEXT_NLINKS_CHANGED
|
IA2_EVENT_HYPERTEXT_NLINKS_CHANGED, // nsIAccessibleEvent::EVENT_HYPERTEXT_NLINKS_CHANGED
|
||||||
IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED, // nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED
|
IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED, // nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED
|
||||||
IA2_EVENT_PAGE_CHANGED, // nsIAccessibleEvent::EVENT_PAGE_CHANGED
|
|
||||||
kEVENT_LAST_ENTRY // nsIAccessibleEvent::EVENT_LAST_ENTRY
|
kEVENT_LAST_ENTRY // nsIAccessibleEvent::EVENT_LAST_ENTRY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,7 +15,9 @@ const EVENT_MENUPOPUP_END = nsIAccessibleEvent.EVENT_MENUPOPUP_END;
|
|||||||
const EVENT_OBJECT_ATTRIBUTE_CHANGED = nsIAccessibleEvent.EVENT_OBJECT_ATTRIBUTE_CHANGED;
|
const EVENT_OBJECT_ATTRIBUTE_CHANGED = nsIAccessibleEvent.EVENT_OBJECT_ATTRIBUTE_CHANGED;
|
||||||
const EVENT_REORDER = nsIAccessibleEvent.EVENT_REORDER;
|
const EVENT_REORDER = nsIAccessibleEvent.EVENT_REORDER;
|
||||||
const EVENT_SCROLLING_START = nsIAccessibleEvent.EVENT_SCROLLING_START;
|
const EVENT_SCROLLING_START = nsIAccessibleEvent.EVENT_SCROLLING_START;
|
||||||
|
const EVENT_SELECTION = nsIAccessibleEvent.EVENT_SELECTION;
|
||||||
const EVENT_SELECTION_ADD = nsIAccessibleEvent.EVENT_SELECTION_ADD;
|
const EVENT_SELECTION_ADD = nsIAccessibleEvent.EVENT_SELECTION_ADD;
|
||||||
|
const EVENT_SELECTION_REMOVE = nsIAccessibleEvent.EVENT_SELECTION_REMOVE;
|
||||||
const EVENT_SELECTION_WITHIN = nsIAccessibleEvent.EVENT_SELECTION_WITHIN;
|
const EVENT_SELECTION_WITHIN = nsIAccessibleEvent.EVENT_SELECTION_WITHIN;
|
||||||
const EVENT_SHOW = nsIAccessibleEvent.EVENT_SHOW;
|
const EVENT_SHOW = nsIAccessibleEvent.EVENT_SHOW;
|
||||||
const EVENT_STATE_CHANGE = nsIAccessibleEvent.EVENT_STATE_CHANGE;
|
const EVENT_STATE_CHANGE = nsIAccessibleEvent.EVENT_STATE_CHANGE;
|
||||||
|
@ -82,7 +82,9 @@ _TEST_FILES =\
|
|||||||
test_mutation.html \
|
test_mutation.html \
|
||||||
test_mutation.xhtml \
|
test_mutation.xhtml \
|
||||||
test_scroll.xul \
|
test_scroll.xul \
|
||||||
|
test_selection_aria.html \
|
||||||
test_selection.html \
|
test_selection.html \
|
||||||
|
test_selection.xul \
|
||||||
test_statechange.html \
|
test_statechange.html \
|
||||||
test_text_alg.html \
|
test_text_alg.html \
|
||||||
test_text.html \
|
test_text.html \
|
||||||
|
@ -22,39 +22,45 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Invokers
|
// Invokers
|
||||||
|
|
||||||
function addSelection(aNode, aOption)
|
|
||||||
{
|
|
||||||
this.DOMNode = aNode;
|
|
||||||
this.optionNode = aOption;
|
|
||||||
|
|
||||||
this.eventSeq = [
|
|
||||||
new invokerChecker(EVENT_SELECTION_WITHIN, getAccessible(this.DOMNode)),
|
|
||||||
new invokerChecker(EVENT_SELECTION_ADD, getAccessible(this.optionNode))
|
|
||||||
];
|
|
||||||
|
|
||||||
this.invoke = function addselection_invoke() {
|
|
||||||
synthesizeMouse(this.optionNode, 1, 1, {});
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getID = function addselection_getID() {
|
|
||||||
return prettyName(this.optionNode) + " added to selection";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Do tests
|
// Do tests
|
||||||
|
|
||||||
|
//gA11yEventDumpToConsole = true; // debuggin
|
||||||
|
|
||||||
var gQueue = null;
|
var gQueue = null;
|
||||||
|
|
||||||
//var gA11yEventDumpID = "eventdump"; // debug stuff
|
|
||||||
|
|
||||||
function doTests()
|
function doTests()
|
||||||
{
|
{
|
||||||
gQueue = new eventQueue();
|
gQueue = new eventQueue();
|
||||||
|
|
||||||
var select = document.getElementById("toppings");
|
// open combobox
|
||||||
var option = document.getElementById("onions");
|
gQueue.push(new synthClick("combobox",
|
||||||
gQueue.push(new addSelection(select, option));
|
new invokerChecker(EVENT_FOCUS, "cb1_item1")));
|
||||||
|
gQueue.push(new synthDownKey("cb1_item1",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "cb1_item2")));
|
||||||
|
|
||||||
|
// closed combobox
|
||||||
|
gQueue.push(new synthEscapeKey("combobox",
|
||||||
|
new invokerChecker(EVENT_FOCUS, "combobox")));
|
||||||
|
gQueue.push(new synthDownKey("cb1_item2",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "cb1_item3")));
|
||||||
|
|
||||||
|
// listbox
|
||||||
|
gQueue.push(new synthClick("lb1_item1",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "lb1_item1")));
|
||||||
|
gQueue.push(new synthDownKey("lb1_item1",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "lb1_item2")));
|
||||||
|
|
||||||
|
// multiselectable listbox
|
||||||
|
gQueue.push(new synthClick("lb2_item1",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "lb2_item1")));
|
||||||
|
gQueue.push(new synthDownKey("lb2_item1",
|
||||||
|
new invokerChecker(EVENT_SELECTION_ADD, "lb2_item2"),
|
||||||
|
{ shiftKey: true }));
|
||||||
|
gQueue.push(new synthUpKey("lb2_item2",
|
||||||
|
new invokerChecker(EVENT_SELECTION_REMOVE, "lb2_item2"),
|
||||||
|
{ shiftKey: true }));
|
||||||
|
gQueue.push(new synthKey("lb2_item1", " ", { ctrlKey: true },
|
||||||
|
new invokerChecker(EVENT_SELECTION_REMOVE, "lb2_item1")));
|
||||||
|
|
||||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||||
}
|
}
|
||||||
@ -67,9 +73,9 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<a target="_blank"
|
<a target="_blank"
|
||||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=569653"
|
href="https://bugzilla.mozilla.org/show_bug.cgi?id=414302"
|
||||||
title="Make selection events async">
|
title="Incorrect selection events in HTML, XUL and ARIA">
|
||||||
Mozilla Bug 569653
|
Mozilla Bug 414302
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<p id="display"></p>
|
<p id="display"></p>
|
||||||
@ -77,18 +83,31 @@
|
|||||||
<pre id="test">
|
<pre id="test">
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Pizza</p>
|
<select id="combobox">
|
||||||
<select id="toppings" name="toppings" multiple size=5>
|
<option id="cb1_item1" value="mushrooms">mushrooms
|
||||||
<option value="mushrooms">mushrooms
|
<option id="cb1_item2" value="greenpeppers">green peppers
|
||||||
<option value="greenpeppers">green peppers
|
<option id="cb1_item3" value="onions" id="onions">onions
|
||||||
<option value="onions" id="onions">onions
|
<option id="cb1_item4" value="tomatoes">tomatoes
|
||||||
<option value="tomatoes">tomatoes
|
<option id="cb1_item5" value="olives">olives
|
||||||
<option value="olives">olives
|
</select>
|
||||||
|
|
||||||
|
<select id="listbox" size=5>
|
||||||
|
<option id="lb1_item1" value="mushrooms">mushrooms
|
||||||
|
<option id="lb1_item2" value="greenpeppers">green peppers
|
||||||
|
<option id="lb1_item3" value="onions" id="onions">onions
|
||||||
|
<option id="lb1_item4" value="tomatoes">tomatoes
|
||||||
|
<option id="lb1_item5" value="olives">olives
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<p>Pizza</p>
|
||||||
|
<select id="listbox2" multiple size=5>
|
||||||
|
<option id="lb2_item1" value="mushrooms">mushrooms
|
||||||
|
<option id="lb2_item2" value="greenpeppers">green peppers
|
||||||
|
<option id="lb2_item3" value="onions" id="onions">onions
|
||||||
|
<option id="lb2_item4" value="tomatoes">tomatoes
|
||||||
|
<option id="lb2_item5" value="olives">olives
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<div id="testContainer">
|
|
||||||
<iframe id="iframe"></iframe>
|
|
||||||
</div>
|
|
||||||
<div id="eventdump"></div>
|
<div id="eventdump"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
244
accessible/tests/mochitest/events/test_selection.xul
Normal file
244
accessible/tests/mochitest/events/test_selection.xul
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||||
|
type="text/css"?>
|
||||||
|
|
||||||
|
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
title="Selection event tests">
|
||||||
|
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||||
|
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../common.js" />
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../states.js" />
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../events.js" />
|
||||||
|
|
||||||
|
<script type="application/javascript">
|
||||||
|
function advanceTab(aTabsID, aDirection, aNextTabID)
|
||||||
|
{
|
||||||
|
this.eventSeq = [
|
||||||
|
new invokerChecker(EVENT_SELECTION, aNextTabID)
|
||||||
|
];
|
||||||
|
|
||||||
|
this.invoke = function advanceTab_invoke()
|
||||||
|
{
|
||||||
|
getNode(aTabsID).advanceSelectedTab(aDirection, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function synthFocus_getID()
|
||||||
|
{
|
||||||
|
return "advanceTab on " + prettyName(aTabsID) + " to " + prettyName(aNextTabID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function select4FirstItems(aID)
|
||||||
|
{
|
||||||
|
this.listboxNode = getNode(aID);
|
||||||
|
this.eventSeq = [
|
||||||
|
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(0)),
|
||||||
|
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(1)),
|
||||||
|
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(2)),
|
||||||
|
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(3))
|
||||||
|
];
|
||||||
|
|
||||||
|
this.invoke = function select4FirstItems_invoke()
|
||||||
|
{
|
||||||
|
synthesizeKey("VK_DOWN", { shiftKey: true }); // selects two items
|
||||||
|
synthesizeKey("VK_DOWN", { shiftKey: true });
|
||||||
|
synthesizeKey("VK_DOWN", { shiftKey: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function select4FirstItems_getID()
|
||||||
|
{
|
||||||
|
return "select 4 first items for " + prettyName(aID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function unselect4FirstItems(aID)
|
||||||
|
{
|
||||||
|
this.listboxNode = getNode(aID);
|
||||||
|
this.eventSeq = [
|
||||||
|
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(3)),
|
||||||
|
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(2)),
|
||||||
|
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(1)),
|
||||||
|
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(0))
|
||||||
|
];
|
||||||
|
|
||||||
|
this.invoke = function unselect4FirstItems_invoke()
|
||||||
|
{
|
||||||
|
synthesizeKey("VK_UP", { shiftKey: true });
|
||||||
|
synthesizeKey("VK_UP", { shiftKey: true });
|
||||||
|
synthesizeKey("VK_UP", { shiftKey: true });
|
||||||
|
synthesizeKey(" ", { ctrlKey: true }); // unselect first item
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function unselect4FirstItems_getID()
|
||||||
|
{
|
||||||
|
return "unselect 4 first items for " + prettyName(aID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectAllItems(aID)
|
||||||
|
{
|
||||||
|
this.listboxNode = getNode(aID);
|
||||||
|
this.eventSeq = [
|
||||||
|
new invokerChecker(EVENT_SELECTION_WITHIN, getAccessible(this.listboxNode))
|
||||||
|
];
|
||||||
|
|
||||||
|
this.invoke = function selectAllItems_invoke()
|
||||||
|
{
|
||||||
|
synthesizeKey("VK_END", { shiftKey: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function selectAllItems_getID()
|
||||||
|
{
|
||||||
|
return "select all items for " + prettyName(aID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function unselectAllItemsButFirst(aID)
|
||||||
|
{
|
||||||
|
this.listboxNode = getNode(aID);
|
||||||
|
this.eventSeq = [
|
||||||
|
new invokerChecker(EVENT_SELECTION_WITHIN, getAccessible(this.listboxNode))
|
||||||
|
];
|
||||||
|
|
||||||
|
this.invoke = function unselectAllItemsButFirst_invoke()
|
||||||
|
{
|
||||||
|
synthesizeKey("VK_HOME", { shiftKey: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function unselectAllItemsButFirst_getID()
|
||||||
|
{
|
||||||
|
return "unselect all items for " + prettyName(aID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function unselectSelectItem(aID)
|
||||||
|
{
|
||||||
|
this.listboxNode = getNode(aID);
|
||||||
|
this.eventSeq = [
|
||||||
|
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(0)),
|
||||||
|
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(0))
|
||||||
|
];
|
||||||
|
|
||||||
|
this.invoke = function unselectSelectItem_invoke()
|
||||||
|
{
|
||||||
|
synthesizeKey(" ", { ctrlKey: true }); // select item
|
||||||
|
synthesizeKey(" ", { ctrlKey: true }); // unselect item
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function unselectSelectItem_getID()
|
||||||
|
{
|
||||||
|
return "unselect and then select first item for " + prettyName(aID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do tests.
|
||||||
|
*/
|
||||||
|
var gQueue = null;
|
||||||
|
|
||||||
|
//gA11yEventDumpToConsole = true; // debuggin
|
||||||
|
|
||||||
|
function doTests()
|
||||||
|
{
|
||||||
|
gQueue = new eventQueue();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// tabbox
|
||||||
|
gQueue.push(new advanceTab("tabs", 1, "tab3"));
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// listbox
|
||||||
|
gQueue.push(new synthClick("lb1_item1",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "lb1_item1")));
|
||||||
|
gQueue.push(new synthDownKey("lb1_item1",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "lb1_item2")));
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// multiselectable listbox
|
||||||
|
gQueue.push(new synthClick("lb2_item1",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "lb2_item1")));
|
||||||
|
gQueue.push(new synthDownKey("lb2_item1",
|
||||||
|
new invokerChecker(EVENT_SELECTION_ADD, "lb2_item2"),
|
||||||
|
{ shiftKey: true }));
|
||||||
|
gQueue.push(new synthUpKey("lb2_item2",
|
||||||
|
new invokerChecker(EVENT_SELECTION_REMOVE, "lb2_item2"),
|
||||||
|
{ shiftKey: true }));
|
||||||
|
gQueue.push(new synthKey("lb2_item1", " ", { ctrlKey: true },
|
||||||
|
new invokerChecker(EVENT_SELECTION_REMOVE, "lb2_item1")));
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
// selection event coalescence
|
||||||
|
|
||||||
|
// fire 4 selection_add events
|
||||||
|
gQueue.push(new select4FirstItems("listbox2"));
|
||||||
|
// fire 4 selection_remove events
|
||||||
|
gQueue.push(new unselect4FirstItems("listbox2"));
|
||||||
|
// fire selection_within event
|
||||||
|
gQueue.push(new selectAllItems("listbox2"));
|
||||||
|
// fire selection_within event
|
||||||
|
gQueue.push(new unselectAllItemsButFirst("listbox2"));
|
||||||
|
// fire selection_remove/add events
|
||||||
|
gQueue.push(new unselectSelectItem("listbox2"));
|
||||||
|
|
||||||
|
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
addA11yLoadEvent(doTests);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<hbox flex="1" style="overflow: auto;">
|
||||||
|
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://bugzilla.mozilla.org/show_bug.cgi?id=414302"
|
||||||
|
title="Incorrect selection events in HTML, XUL and ARIA">
|
||||||
|
Mozilla Bug 414302
|
||||||
|
</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none"></div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<tabbox id="tabbox" selectedIndex="1">
|
||||||
|
<tabs id="tabs">
|
||||||
|
<tab id="tab1" label="tab1"/>
|
||||||
|
<tab id="tab2" label="tab2"/>
|
||||||
|
<tab id="tab3" label="tab3"/>
|
||||||
|
<tab id="tab4" label="tab4"/>
|
||||||
|
</tabs>
|
||||||
|
<tabpanels>
|
||||||
|
<tabpanel><!-- tabpanel First elements go here --></tabpanel>
|
||||||
|
<tabpanel><button id="b1" label="b1"/></tabpanel>
|
||||||
|
<tabpanel><button id="b2" label="b2"/></tabpanel>
|
||||||
|
<tabpanel></tabpanel>
|
||||||
|
</tabpanels>
|
||||||
|
</tabbox>
|
||||||
|
|
||||||
|
<listbox id="listbox">
|
||||||
|
<listitem id="lb1_item1" label="item1"/>
|
||||||
|
<listitem id="lb1_item2" label="item2"/>
|
||||||
|
</listbox>
|
||||||
|
|
||||||
|
<listbox id="listbox2" seltype="multiple">
|
||||||
|
<listitem id="lb2_item1" label="item1"/>
|
||||||
|
<listitem id="lb2_item2" label="item2"/>
|
||||||
|
<listitem id="lb2_item3" label="item3"/>
|
||||||
|
<listitem id="lb2_item4" label="item4"/>
|
||||||
|
<listitem id="lb2_item5" label="item5"/>
|
||||||
|
<listitem id="lb2_item6" label="item6"/>
|
||||||
|
<listitem id="lb2_item7" label="item7"/>
|
||||||
|
</listbox>
|
||||||
|
|
||||||
|
</hbox>
|
||||||
|
</window>
|
112
accessible/tests/mochitest/events/test_selection_aria.html
Normal file
112
accessible/tests/mochitest/events/test_selection_aria.html
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>ARIA selection event testing</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css"
|
||||||
|
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||||
|
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||||
|
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../common.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../events.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../states.js"></script>
|
||||||
|
|
||||||
|
<script type="application/javascript">
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Invokers
|
||||||
|
|
||||||
|
function selectTreeItem(aTreeID, aItemID)
|
||||||
|
{
|
||||||
|
this.treeNode = getNode(aTreeID);
|
||||||
|
this.itemNode = getNode(aItemID);
|
||||||
|
|
||||||
|
this.eventSeq = [
|
||||||
|
new invokerChecker(EVENT_SELECTION, aItemID)
|
||||||
|
];
|
||||||
|
|
||||||
|
this.invoke = function selectTreeItem_invoke() {
|
||||||
|
var itemNode = this.treeNode.querySelector("*[aria-selected='true']");
|
||||||
|
if (itemNode)
|
||||||
|
itemNode.removeAttribute("aria-selected", "true");
|
||||||
|
|
||||||
|
this.itemNode.setAttribute("aria-selected", "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getID = function selectTreeItem_getID()
|
||||||
|
{
|
||||||
|
return "selectTreeItem " + prettyName(aItemID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Do tests
|
||||||
|
|
||||||
|
var gQueue = null;
|
||||||
|
|
||||||
|
//var gA11yEventDumpID = "eventdump"; // debug stuff
|
||||||
|
|
||||||
|
function doTests()
|
||||||
|
{
|
||||||
|
gQueue = new eventQueue();
|
||||||
|
|
||||||
|
gQueue.push(new selectTreeItem("tree", "treeitem1"));
|
||||||
|
gQueue.push(new selectTreeItem("tree", "treeitem1a"));
|
||||||
|
gQueue.push(new selectTreeItem("tree", "treeitem1a1"));
|
||||||
|
|
||||||
|
gQueue.push(new selectTreeItem("tree2", "tree2item1"));
|
||||||
|
gQueue.push(new selectTreeItem("tree2", "tree2item1a"));
|
||||||
|
gQueue.push(new selectTreeItem("tree2", "tree2item1a1"));
|
||||||
|
|
||||||
|
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
addA11yLoadEvent(doTests);
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<a target="_blank"
|
||||||
|
href="https://bugzilla.mozilla.org/show_bug.cgi?id=569653"
|
||||||
|
title="Make selection events async">
|
||||||
|
Mozilla Bug 569653
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none"></div>
|
||||||
|
<pre id="test">
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<div id="tree" role="tree">
|
||||||
|
<div id="treeitem1" role="treeitem">Canada
|
||||||
|
<div id="treeitem1a" role="treeitem">- Ontario
|
||||||
|
<div id="treeitem1a1" role="treeitem">-- Toronto</div>
|
||||||
|
</div>
|
||||||
|
<div id="treeitem1b" role="treeitem">- Manitoba</div>
|
||||||
|
</div>
|
||||||
|
<div id="treeitem2" role="treeitem">Germany</div>
|
||||||
|
<div id="treeitem3" role="treeitem">Russia</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="tree2" role="tree" aria-multiselectable="true">
|
||||||
|
<div id="tree2item1" role="treeitem">Canada
|
||||||
|
<div id="tree2item1a" role="treeitem">- Ontario
|
||||||
|
<div id="tree2item1a1" role="treeitem">-- Toronto</div>
|
||||||
|
</div>
|
||||||
|
<div id="tree2item1b" role="treeitem">- Manitoba</div>
|
||||||
|
</div>
|
||||||
|
<div id="tree2item2" role="treeitem">Germany</div>
|
||||||
|
<div id="tree2item3" role="treeitem">Russia</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="eventdump"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,7 +1,4 @@
|
|||||||
# Don't use the standard mozconfig. We don't want universal for a debug build.
|
. $topsrcdir/build/macosx/mozconfig.leopard
|
||||||
#. $topsrcdir/build/macosx/universal/mozconfig
|
|
||||||
|
|
||||||
ac_add_options --with-macos-sdk=/Developer/SDKs/MacOSX10.5.sdk
|
|
||||||
ac_add_options --enable-debug
|
ac_add_options --enable-debug
|
||||||
ac_add_options --enable-trace-malloc
|
ac_add_options --enable-trace-malloc
|
||||||
|
|
||||||
|
@ -135,6 +135,7 @@
|
|||||||
@BINPATH@/components/docshell.xpt
|
@BINPATH@/components/docshell.xpt
|
||||||
@BINPATH@/components/dom.xpt
|
@BINPATH@/components/dom.xpt
|
||||||
@BINPATH@/components/dom_base.xpt
|
@BINPATH@/components/dom_base.xpt
|
||||||
|
@BINPATH@/components/dom_battery.xpt
|
||||||
@BINPATH@/components/dom_canvas.xpt
|
@BINPATH@/components/dom_canvas.xpt
|
||||||
@BINPATH@/components/dom_core.xpt
|
@BINPATH@/components/dom_core.xpt
|
||||||
@BINPATH@/components/dom_css.xpt
|
@BINPATH@/components/dom_css.xpt
|
||||||
|
@ -584,6 +584,7 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
|||||||
if loc.scheme == "https" and "nocert" not in loc.options:
|
if loc.scheme == "https" and "nocert" not in loc.options:
|
||||||
customCertRE = re.compile("^cert=(?P<nickname>[0-9a-zA-Z_ ]+)")
|
customCertRE = re.compile("^cert=(?P<nickname>[0-9a-zA-Z_ ]+)")
|
||||||
clientAuthRE = re.compile("^clientauth=(?P<clientauth>[a-z]+)")
|
clientAuthRE = re.compile("^clientauth=(?P<clientauth>[a-z]+)")
|
||||||
|
redirRE = re.compile("^redir=(?P<redirhost>[0-9a-zA-Z_ .]+)")
|
||||||
for option in loc.options:
|
for option in loc.options:
|
||||||
match = customCertRE.match(option)
|
match = customCertRE.match(option)
|
||||||
if match:
|
if match:
|
||||||
@ -597,6 +598,12 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
|||||||
sslTunnelConfig.write("clientauth:%s:%s:%s:%s\n" %
|
sslTunnelConfig.write("clientauth:%s:%s:%s:%s\n" %
|
||||||
(loc.host, loc.port, self.sslPort, clientauth))
|
(loc.host, loc.port, self.sslPort, clientauth))
|
||||||
|
|
||||||
|
match = redirRE.match(option)
|
||||||
|
if match:
|
||||||
|
redirhost = match.group("redirhost")
|
||||||
|
sslTunnelConfig.write("redirhost:%s:%s:%s:%s\n" %
|
||||||
|
(loc.host, loc.port, self.sslPort, redirhost))
|
||||||
|
|
||||||
sslTunnelConfig.close()
|
sslTunnelConfig.close()
|
||||||
|
|
||||||
# Pre-create the certification database for the profile
|
# Pre-create the certification database for the profile
|
||||||
@ -739,52 +746,52 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
|||||||
def killPid(self, pid):
|
def killPid(self, pid):
|
||||||
os.kill(pid, signal.SIGKILL)
|
os.kill(pid, signal.SIGKILL)
|
||||||
|
|
||||||
def dumpScreen(self, utilityPath):
|
def dumpScreen(self, utilityPath):
|
||||||
self.haveDumpedScreen = True;
|
self.haveDumpedScreen = True;
|
||||||
|
|
||||||
# Need to figure out what tool and whether it write to a file or stdout
|
# Need to figure out what tool and whether it write to a file or stdout
|
||||||
if self.UNIXISH:
|
if self.UNIXISH:
|
||||||
utility = [os.path.join(utilityPath, "screentopng")]
|
utility = [os.path.join(utilityPath, "screentopng")]
|
||||||
imgoutput = 'stdout'
|
imgoutput = 'stdout'
|
||||||
elif self.IS_MAC:
|
elif self.IS_MAC:
|
||||||
utility = ['/usr/sbin/screencapture', '-C', '-x', '-t', 'png']
|
utility = ['/usr/sbin/screencapture', '-C', '-x', '-t', 'png']
|
||||||
imgoutput = 'file'
|
imgoutput = 'file'
|
||||||
elif self.IS_WIN32:
|
elif self.IS_WIN32:
|
||||||
self.log.info("If you fixed bug 589668, you'd get a screenshot here")
|
self.log.info("If you fixed bug 589668, you'd get a screenshot here")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Run the capture correctly for the type of capture
|
# Run the capture correctly for the type of capture
|
||||||
try:
|
try:
|
||||||
if imgoutput == 'file':
|
if imgoutput == 'file':
|
||||||
tmpfd, imgfilename = tempfile.mkstemp(prefix='mozilla-test-fail_')
|
tmpfd, imgfilename = tempfile.mkstemp(prefix='mozilla-test-fail_')
|
||||||
os.close(tmpfd)
|
os.close(tmpfd)
|
||||||
dumper = self.Process(utility + [imgfilename])
|
dumper = self.Process(utility + [imgfilename])
|
||||||
elif imgoutput == 'stdout':
|
elif imgoutput == 'stdout':
|
||||||
dumper = self.Process(utility, bufsize=-1,
|
dumper = self.Process(utility, bufsize=-1,
|
||||||
stdout=subprocess.PIPE, close_fds=True)
|
stdout=subprocess.PIPE, close_fds=True)
|
||||||
except OSError, err:
|
except OSError, err:
|
||||||
self.log.info("Failed to start %s for screenshot: %s",
|
self.log.info("Failed to start %s for screenshot: %s",
|
||||||
utility[0], err.strerror)
|
utility[0], err.strerror)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check whether the capture utility ran successfully
|
# Check whether the capture utility ran successfully
|
||||||
dumper_out, dumper_err = dumper.communicate()
|
dumper_out, dumper_err = dumper.communicate()
|
||||||
if dumper.returncode != 0:
|
if dumper.returncode != 0:
|
||||||
self.log.info("%s exited with code %d", utility, dumper.returncode)
|
self.log.info("%s exited with code %d", utility, dumper.returncode)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if imgoutput == 'stdout':
|
if imgoutput == 'stdout':
|
||||||
image = dumper_out
|
image = dumper_out
|
||||||
elif imgoutput == 'file':
|
elif imgoutput == 'file':
|
||||||
with open(imgfilename) as imgfile:
|
with open(imgfilename) as imgfile:
|
||||||
image = imgfile.read()
|
image = imgfile.read()
|
||||||
except IOError, err:
|
except IOError, err:
|
||||||
self.log.info("Failed to read image from %s", imgoutput)
|
self.log.info("Failed to read image from %s", imgoutput)
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
encoded = base64.b64encode(image)
|
encoded = base64.b64encode(image)
|
||||||
self.log.info("SCREENSHOT: data:image/png;base64,%s", encoded)
|
self.log.info("SCREENSHOT: data:image/png;base64,%s", encoded)
|
||||||
|
|
||||||
def killAndGetStack(self, proc, utilityPath, debuggerInfo):
|
def killAndGetStack(self, proc, utilityPath, debuggerInfo):
|
||||||
"""Kill the process, preferrably in a way that gets us a stack trace."""
|
"""Kill the process, preferrably in a way that gets us a stack trace."""
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
# number is the default for the protocol.
|
# number is the default for the protocol.
|
||||||
#
|
#
|
||||||
# Unrecognized options are ignored. Recognized options are "primary" and
|
# Unrecognized options are ignored. Recognized options are "primary" and
|
||||||
# "privileged", "nocert", "cert=some_cert_nickname".
|
# "privileged", "nocert", "cert=some_cert_nickname", "redir=hostname".
|
||||||
#
|
#
|
||||||
# "primary" denotes a location which is the canonical location of
|
# "primary" denotes a location which is the canonical location of
|
||||||
# the server; this location is the one assumed for requests which don't
|
# the server; this location is the one assumed for requests which don't
|
||||||
@ -71,6 +71,12 @@
|
|||||||
# directory. When new certificate is added to this dir pgo/ssltunnel
|
# directory. When new certificate is added to this dir pgo/ssltunnel
|
||||||
# must be builded then.
|
# must be builded then.
|
||||||
#
|
#
|
||||||
|
# "redir=hostname" tells the pgo server is only used for https://
|
||||||
|
# hosts while processing the CONNECT tunnel request. It responds
|
||||||
|
# to the CONNECT with a 302 and redirection to the hostname instead
|
||||||
|
# of connecting to the real back end and replying with a 200. This
|
||||||
|
# mode exists primarily to ensure we don't allow a proxy to do that.
|
||||||
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# This is the primary location from which tests run.
|
# This is the primary location from which tests run.
|
||||||
@ -175,3 +181,10 @@ http://malware.example.com:80
|
|||||||
# Bug 483437, 484111
|
# Bug 483437, 484111
|
||||||
https://www.bank1.com:443 privileged,cert=escapeattack1
|
https://www.bank1.com:443 privileged,cert=escapeattack1
|
||||||
https://www.bank2.com:443 privileged,cert=escapeattack2
|
https://www.bank2.com:443 privileged,cert=escapeattack2
|
||||||
|
|
||||||
|
#
|
||||||
|
# CONNECT for redirproxy results in a 302 redirect to
|
||||||
|
# test1.example.com
|
||||||
|
#
|
||||||
|
https://redirproxy.example.com:443 privileged,redir=test1.example.com
|
||||||
|
|
||||||
|
@ -207,20 +207,36 @@ nsPrincipal::GetOrigin(char **aOrigin)
|
|||||||
bool isChrome;
|
bool isChrome;
|
||||||
nsresult rv = origin->SchemeIs("chrome", &isChrome);
|
nsresult rv = origin->SchemeIs("chrome", &isChrome);
|
||||||
if (NS_SUCCEEDED(rv) && !isChrome) {
|
if (NS_SUCCEEDED(rv) && !isChrome) {
|
||||||
rv = origin->GetHostPort(hostPort);
|
rv = origin->GetAsciiHost(hostPort);
|
||||||
|
// Some implementations return an empty string, treat it as no support
|
||||||
|
// for asciiHost by that implementation.
|
||||||
|
if (hostPort.IsEmpty())
|
||||||
|
rv = NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRInt32 port;
|
||||||
|
if (NS_SUCCEEDED(rv) && !isChrome) {
|
||||||
|
rv = origin->GetPort(&port);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && !isChrome) {
|
if (NS_SUCCEEDED(rv) && !isChrome) {
|
||||||
|
if (port != -1) {
|
||||||
|
hostPort.AppendLiteral(":");
|
||||||
|
hostPort.AppendInt(port, 10);
|
||||||
|
}
|
||||||
|
|
||||||
nsCAutoString scheme;
|
nsCAutoString scheme;
|
||||||
rv = origin->GetScheme(scheme);
|
rv = origin->GetScheme(scheme);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
*aOrigin = ToNewCString(scheme + NS_LITERAL_CSTRING("://") + hostPort);
|
*aOrigin = ToNewCString(scheme + NS_LITERAL_CSTRING("://") + hostPort);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Some URIs (e.g., nsSimpleURI) don't support host. Just
|
// Some URIs (e.g., nsSimpleURI) don't support asciiHost. Just
|
||||||
// get the full spec.
|
// get the full spec.
|
||||||
nsCAutoString spec;
|
nsCAutoString spec;
|
||||||
rv = origin->GetSpec(spec);
|
// XXX nsMozIconURI and nsJARURI don't implement this correctly, they
|
||||||
|
// both fall back to GetSpec. That needs to be fixed.
|
||||||
|
rv = origin->GetAsciiSpec(spec);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
*aOrigin = ToNewCString(spec);
|
*aOrigin = ToNewCString(spec);
|
||||||
}
|
}
|
||||||
|
@ -4266,7 +4266,7 @@ MOZ_ARG_WITH_BOOL(system-nss,
|
|||||||
_USE_SYSTEM_NSS=1 )
|
_USE_SYSTEM_NSS=1 )
|
||||||
|
|
||||||
if test -n "$_USE_SYSTEM_NSS"; then
|
if test -n "$_USE_SYSTEM_NSS"; then
|
||||||
AM_PATH_NSS(3.12.10, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
|
AM_PATH_NSS(3.13.1, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -n "$MOZ_NATIVE_NSS"; then
|
if test -n "$MOZ_NATIVE_NSS"; then
|
||||||
|
@ -51,6 +51,13 @@
|
|||||||
#include "jspubtd.h"
|
#include "jspubtd.h"
|
||||||
#include "nsDOMMemoryReporter.h"
|
#include "nsDOMMemoryReporter.h"
|
||||||
|
|
||||||
|
// Including 'windows.h' will #define GetClassInfo to something else.
|
||||||
|
#ifdef XP_WIN
|
||||||
|
#ifdef GetClassInfo
|
||||||
|
#undef GetClassInfo
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
class nsIContent;
|
class nsIContent;
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
class nsIDOMEvent;
|
class nsIDOMEvent;
|
||||||
|
@ -218,6 +218,14 @@ nsAttrAndChildArray::InsertChildAt(nsIContent* aChild, PRUint32 aPos)
|
|||||||
|
|
||||||
void
|
void
|
||||||
nsAttrAndChildArray::RemoveChildAt(PRUint32 aPos)
|
nsAttrAndChildArray::RemoveChildAt(PRUint32 aPos)
|
||||||
|
{
|
||||||
|
// Just store the return value of TakeChildAt in an nsCOMPtr to
|
||||||
|
// trigger a release.
|
||||||
|
nsCOMPtr<nsIContent> child = TakeChildAt(aPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIContent>
|
||||||
|
nsAttrAndChildArray::TakeChildAt(PRUint32 aPos)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aPos < ChildCount(), "out-of-bounds");
|
NS_ASSERTION(aPos < ChildCount(), "out-of-bounds");
|
||||||
|
|
||||||
@ -232,9 +240,10 @@ nsAttrAndChildArray::RemoveChildAt(PRUint32 aPos)
|
|||||||
}
|
}
|
||||||
child->mPreviousSibling = child->mNextSibling = nsnull;
|
child->mPreviousSibling = child->mNextSibling = nsnull;
|
||||||
|
|
||||||
NS_RELEASE(child);
|
|
||||||
memmove(pos, pos + 1, (childCount - aPos - 1) * sizeof(nsIContent*));
|
memmove(pos, pos + 1, (childCount - aPos - 1) * sizeof(nsIContent*));
|
||||||
SetChildCount(childCount - 1);
|
SetChildCount(childCount - 1);
|
||||||
|
|
||||||
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRInt32
|
PRInt32
|
||||||
|
@ -95,6 +95,9 @@ public:
|
|||||||
}
|
}
|
||||||
nsresult InsertChildAt(nsIContent* aChild, PRUint32 aPos);
|
nsresult InsertChildAt(nsIContent* aChild, PRUint32 aPos);
|
||||||
void RemoveChildAt(PRUint32 aPos);
|
void RemoveChildAt(PRUint32 aPos);
|
||||||
|
// Like RemoveChildAt but hands the reference to the child being
|
||||||
|
// removed back to the caller instead of just releasing it.
|
||||||
|
already_AddRefed<nsIContent> TakeChildAt(PRUint32 aPos);
|
||||||
PRInt32 IndexOfChild(nsINode* aPossibleChild) const;
|
PRInt32 IndexOfChild(nsINode* aPossibleChild) const;
|
||||||
|
|
||||||
PRUint32 AttrCount() const;
|
PRUint32 AttrCount() const;
|
||||||
|
@ -5813,7 +5813,9 @@ nsContentUtils::IsFullScreenApiEnabled()
|
|||||||
|
|
||||||
bool nsContentUtils::IsRequestFullScreenAllowed()
|
bool nsContentUtils::IsRequestFullScreenAllowed()
|
||||||
{
|
{
|
||||||
return !sTrustedFullScreenOnly || nsEventStateManager::IsHandlingUserInput();
|
return !sTrustedFullScreenOnly ||
|
||||||
|
nsEventStateManager::IsHandlingUserInput() ||
|
||||||
|
IsCallerChrome();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -8606,6 +8606,14 @@ nsDocument::GetMozFullScreenEnabled(bool *aFullScreen)
|
|||||||
NS_ENSURE_ARG_POINTER(aFullScreen);
|
NS_ENSURE_ARG_POINTER(aFullScreen);
|
||||||
*aFullScreen = false;
|
*aFullScreen = false;
|
||||||
|
|
||||||
|
if (nsContentUtils::IsCallerChrome() &&
|
||||||
|
nsContentUtils::IsFullScreenApiEnabled()) {
|
||||||
|
// Chrome code can always use the full-screen API, provided it's not
|
||||||
|
// explicitly disabled.
|
||||||
|
*aFullScreen = true;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!nsContentUtils::IsFullScreenApiEnabled() ||
|
if (!nsContentUtils::IsFullScreenApiEnabled() ||
|
||||||
nsContentUtils::HasPluginWithUncontrolledEventDispatch(this) ||
|
nsContentUtils::HasPluginWithUncontrolledEventDispatch(this) ||
|
||||||
!IsVisible()) {
|
!IsVisible()) {
|
||||||
|
@ -4234,10 +4234,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericElement)
|
|||||||
// Once we have XPCOMGC we shouldn't need to call UnbindFromTree.
|
// Once we have XPCOMGC we shouldn't need to call UnbindFromTree.
|
||||||
// We could probably do a non-deep unbind here when IsInDoc is false
|
// We could probably do a non-deep unbind here when IsInDoc is false
|
||||||
// for better performance.
|
// for better performance.
|
||||||
tmp->mAttrsAndChildren.ChildAt(childCount)->UnbindFromTree();
|
|
||||||
tmp->mAttrsAndChildren.RemoveChildAt(childCount);
|
// Hold a strong ref to the node when we remove it, because we may be
|
||||||
|
// the last reference to it. We need to call TakeChildAt() and
|
||||||
|
// update mFirstChild before calling UnbindFromTree, since this last
|
||||||
|
// can notify various observers and they should really see consistent
|
||||||
|
// tree state.
|
||||||
|
nsCOMPtr<nsIContent> child = tmp->mAttrsAndChildren.TakeChildAt(childCount);
|
||||||
|
if (childCount == 0) {
|
||||||
|
tmp->mFirstChild = nsnull;
|
||||||
|
}
|
||||||
|
child->UnbindFromTree();
|
||||||
}
|
}
|
||||||
tmp->mFirstChild = nsnull;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ _CHROME_FILES = \
|
|||||||
test_bug571390.xul \
|
test_bug571390.xul \
|
||||||
test_bug574596.html \
|
test_bug574596.html \
|
||||||
test_bug683852.xul \
|
test_bug683852.xul \
|
||||||
|
test_bug599295.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
libs:: $(_TEST_FILES)
|
libs:: $(_TEST_FILES)
|
||||||
|
81
content/base/test/chrome/test_bug599295.html
Normal file
81
content/base/test/chrome/test_bug599295.html
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=599295
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>Test for Bug 599295</title>
|
||||||
|
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||||
|
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=599295">Mozilla Bug 599295</a>
|
||||||
|
<style type="text/css">
|
||||||
|
#link1 a { -moz-user-select:none; }
|
||||||
|
</style>
|
||||||
|
<div id="link1"><a href="http://www.mozilla.org/">link1</a></div>
|
||||||
|
<div id="link2"><a href="http://www.mozilla.org/">link2</a></div>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
/** Test for Bug 599295 **/
|
||||||
|
|
||||||
|
/* Do not allow a response to a CONNECT method, used to establish an
|
||||||
|
SSL tunnel over an HTTP proxy, to contain a redirect */
|
||||||
|
|
||||||
|
const BinaryInputStream =
|
||||||
|
Components.Constructor("@mozilla.org/binaryinputstream;1",
|
||||||
|
"nsIBinaryInputStream",
|
||||||
|
"setInputStream");
|
||||||
|
var listener = {
|
||||||
|
_httpstatus : 0,
|
||||||
|
|
||||||
|
onStartRequest: function(request, context) {
|
||||||
|
request.QueryInterface(Components.interfaces.nsIHttpChannel);
|
||||||
|
_httpstatus = request.responseStatus;
|
||||||
|
},
|
||||||
|
|
||||||
|
onDataAvailable: function(request, context, stream, offset, count) {
|
||||||
|
new BinaryInputStream(stream).readByteArray(count);
|
||||||
|
},
|
||||||
|
|
||||||
|
onStopRequest: function(request, context, status) {
|
||||||
|
/* testing here that the redirect was not followed. If it was followed
|
||||||
|
we would see a http status of 200 and status of NS_OK */
|
||||||
|
|
||||||
|
is(_httpstatus, 302, "http status 302");
|
||||||
|
is(status, Components.results.NS_ERROR_CONNECTION_REFUSED, "raised refused");
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
var ios = Components.classes["@mozilla.org/network/io-service;1"].
|
||||||
|
getService(Components.interfaces.nsIIOService);
|
||||||
|
var uri = ios.newURI("https://redirproxy.example.com/test", "", null);
|
||||||
|
var channel = ios.newChannelFromURI(uri);
|
||||||
|
|
||||||
|
/* Previously, necko would allow a 302 as part of a CONNECT response
|
||||||
|
if the LOAD_DOCUMENT_URI flag was set and the original document
|
||||||
|
URI had not yet been changed. */
|
||||||
|
|
||||||
|
channel.loadFlags |= Components.interfaces.nsIChannel.LOAD_DOCUMENT_URI;
|
||||||
|
channel.QueryInterface(Components.interfaces.nsIHttpChannelInternal);
|
||||||
|
channel.documentURI = uri;
|
||||||
|
channel.asyncOpen(listener, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
SimpleTest.waitForFocus(runTest);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -608,9 +608,17 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
|||||||
format.minAlpha = 0;
|
format.minAlpha = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mOptions.antialias) {
|
bool forceMSAA =
|
||||||
PRUint32 msaaLevel = Preferences::GetUint("webgl.msaa-level", 2);
|
Preferences::GetBool("webgl.msaa-force", false);
|
||||||
format.samples = msaaLevel*msaaLevel;
|
|
||||||
|
PRInt32 status;
|
||||||
|
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||||
|
if (mOptions.antialias &&
|
||||||
|
NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_MSAA, &status))) {
|
||||||
|
if (status == nsIGfxInfo::FEATURE_NO_INFO || forceMSAA) {
|
||||||
|
PRUint32 msaaLevel = Preferences::GetUint("webgl.msaa-level", 2);
|
||||||
|
format.samples = msaaLevel*msaaLevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PR_GetEnv("MOZ_WEBGL_PREFER_EGL")) {
|
if (PR_GetEnv("MOZ_WEBGL_PREFER_EGL")) {
|
||||||
@ -621,9 +629,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
|||||||
bool useOpenGL = true;
|
bool useOpenGL = true;
|
||||||
bool useANGLE = true;
|
bool useANGLE = true;
|
||||||
|
|
||||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
|
||||||
if (gfxInfo && !forceEnabled) {
|
if (gfxInfo && !forceEnabled) {
|
||||||
PRInt32 status;
|
|
||||||
if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_OPENGL, &status))) {
|
if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_OPENGL, &status))) {
|
||||||
if (status != nsIGfxInfo::FEATURE_NO_INFO) {
|
if (status != nsIGfxInfo::FEATURE_NO_INFO) {
|
||||||
useOpenGL = false;
|
useOpenGL = false;
|
||||||
|
@ -733,6 +733,7 @@ public:
|
|||||||
|
|
||||||
friend class WebGLTexture;
|
friend class WebGLTexture;
|
||||||
friend class WebGLFramebuffer;
|
friend class WebGLFramebuffer;
|
||||||
|
friend class WebGLProgram;
|
||||||
};
|
};
|
||||||
|
|
||||||
// this class is a mixin for the named type wrappers, and is used
|
// this class is a mixin for the named type wrappers, and is used
|
||||||
@ -1421,21 +1422,43 @@ public:
|
|||||||
WebGLShader(WebGLContext *context, WebGLuint name, WebGLenum stype) :
|
WebGLShader(WebGLContext *context, WebGLuint name, WebGLenum stype) :
|
||||||
WebGLContextBoundObject(context),
|
WebGLContextBoundObject(context),
|
||||||
mName(name), mDeleted(false), mType(stype),
|
mName(name), mDeleted(false), mType(stype),
|
||||||
mNeedsTranslation(true), mAttachCount(0)
|
mNeedsTranslation(true), mAttachCount(0),
|
||||||
|
mDeletePending(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
void DetachedFromProgram() {
|
||||||
|
DecrementAttachCount();
|
||||||
|
if (mDeletePending && AttachCount() <= 0) {
|
||||||
|
DeleteWhenNotAttached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteWhenNotAttached() {
|
||||||
|
if (mDeleted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (AttachCount() > 0) {
|
||||||
|
mDeletePending = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Delete();
|
||||||
|
}
|
||||||
|
|
||||||
void Delete() {
|
void Delete() {
|
||||||
if (mDeleted)
|
if (mDeleted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ZeroOwners();
|
ZeroOwners();
|
||||||
mDeleted = true;
|
mDeleted = true;
|
||||||
|
mDeletePending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deleted() { return mDeleted && mAttachCount == 0; }
|
bool Deleted() { return mDeleted; }
|
||||||
WebGLuint GLName() { return mName; }
|
WebGLuint GLName() { return mName; }
|
||||||
WebGLenum ShaderType() { return mType; }
|
WebGLenum ShaderType() { return mType; }
|
||||||
|
|
||||||
PRUint32 AttachCount() { return mAttachCount; }
|
PRInt32 AttachCount() { return mAttachCount; }
|
||||||
void IncrementAttachCount() { mAttachCount++; }
|
void IncrementAttachCount() { mAttachCount++; }
|
||||||
void DecrementAttachCount() { mAttachCount--; }
|
void DecrementAttachCount() { mAttachCount--; }
|
||||||
|
|
||||||
@ -1469,7 +1492,8 @@ protected:
|
|||||||
nsString mSource;
|
nsString mSource;
|
||||||
nsCString mTranslationLog;
|
nsCString mTranslationLog;
|
||||||
bool mNeedsTranslation;
|
bool mNeedsTranslation;
|
||||||
PRUint32 mAttachCount;
|
PRInt32 mAttachCount;
|
||||||
|
bool mDeletePending;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(WebGLShader, WEBGLSHADER_PRIVATE_IID)
|
NS_DEFINE_STATIC_IID_ACCESSOR(WebGLShader, WEBGLSHADER_PRIVATE_IID)
|
||||||
@ -1496,22 +1520,45 @@ public:
|
|||||||
mMapUniformLocations.Init();
|
mMapUniformLocations.Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeleteWhenNotCurrent() {
|
||||||
|
if (mDeleted)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mContext->mCurrentProgram == this) {
|
||||||
|
mDeletePending = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Delete();
|
||||||
|
}
|
||||||
|
|
||||||
void Delete() {
|
void Delete() {
|
||||||
if (mDeleted)
|
if (mDeleted)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
DetachShaders();
|
||||||
ZeroOwners();
|
ZeroOwners();
|
||||||
mDeleted = true;
|
mDeleted = true;
|
||||||
|
mDeletePending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DetachShaders() {
|
void DetachShaders() {
|
||||||
for (PRUint32 i = 0; i < mAttachedShaders.Length(); ++i) {
|
for (PRUint32 i = 0; i < mAttachedShaders.Length(); ++i) {
|
||||||
if (mAttachedShaders[i])
|
WebGLShader* shader = mAttachedShaders[i];
|
||||||
mAttachedShaders[i]->DecrementAttachCount();
|
if (shader)
|
||||||
|
shader->DetachedFromProgram();
|
||||||
}
|
}
|
||||||
mAttachedShaders.Clear();
|
mAttachedShaders.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deleted() { return mDeleted && !mDeletePending; }
|
void NoLongerCurrent() {
|
||||||
|
if (mDeletePending) {
|
||||||
|
DetachShaders();
|
||||||
|
DeleteWhenNotCurrent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Deleted() { return mDeleted; }
|
||||||
void SetDeletePending() { mDeletePending = true; }
|
void SetDeletePending() { mDeletePending = true; }
|
||||||
void ClearDeletePending() { mDeletePending = false; }
|
void ClearDeletePending() { mDeletePending = false; }
|
||||||
bool HasDeletePending() { return mDeletePending; }
|
bool HasDeletePending() { return mDeletePending; }
|
||||||
@ -1538,7 +1585,7 @@ public:
|
|||||||
// return true if the shader was found and removed
|
// return true if the shader was found and removed
|
||||||
bool DetachShader(WebGLShader *shader) {
|
bool DetachShader(WebGLShader *shader) {
|
||||||
if (mAttachedShaders.RemoveElement(shader)) {
|
if (mAttachedShaders.RemoveElement(shader)) {
|
||||||
shader->DecrementAttachCount();
|
shader->DetachedFromProgram();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1265,13 +1265,7 @@ WebGLContext::DeleteProgram(nsIWebGLProgram *pobj)
|
|||||||
|
|
||||||
gl->fDeleteProgram(progname);
|
gl->fDeleteProgram(progname);
|
||||||
|
|
||||||
if (prog == mCurrentProgram) {
|
prog->DeleteWhenNotCurrent();
|
||||||
prog->SetDeletePending();
|
|
||||||
} else {
|
|
||||||
prog->DetachShaders();
|
|
||||||
}
|
|
||||||
|
|
||||||
prog->Delete();
|
|
||||||
mMapPrograms.Remove(progname);
|
mMapPrograms.Remove(progname);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -1295,7 +1289,7 @@ WebGLContext::DeleteShader(nsIWebGLShader *sobj)
|
|||||||
MakeContextCurrent();
|
MakeContextCurrent();
|
||||||
|
|
||||||
gl->fDeleteShader(shadername);
|
gl->fDeleteShader(shadername);
|
||||||
shader->Delete();
|
shader->DeleteWhenNotAttached();
|
||||||
mMapShaders.Remove(shadername);
|
mMapShaders.Remove(shadername);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -1324,6 +1318,8 @@ WebGLContext::DetachShader(nsIWebGLProgram *pobj, nsIWebGLShader *shobj)
|
|||||||
|
|
||||||
gl->fDetachShader(progname, shadername);
|
gl->fDetachShader(progname, shadername);
|
||||||
|
|
||||||
|
shader->DetachedFromProgram();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2636,6 +2632,12 @@ WebGLContext::GetProgramParameter(nsIWebGLProgram *pobj, PRUint32 pname, nsIVari
|
|||||||
break;
|
break;
|
||||||
case LOCAL_GL_DELETE_STATUS:
|
case LOCAL_GL_DELETE_STATUS:
|
||||||
case LOCAL_GL_LINK_STATUS:
|
case LOCAL_GL_LINK_STATUS:
|
||||||
|
{
|
||||||
|
GLint i = 0;
|
||||||
|
gl->fGetProgramiv(progname, pname, &i);
|
||||||
|
wrval->SetAsBool(bool(i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case LOCAL_GL_VALIDATE_STATUS:
|
case LOCAL_GL_VALIDATE_STATUS:
|
||||||
{
|
{
|
||||||
GLint i = 0;
|
GLint i = 0;
|
||||||
@ -3014,8 +3016,11 @@ WebGLContext::GetVertexAttrib(WebGLuint index, WebGLenum pname, nsIVariant **ret
|
|||||||
wrval->SetAsISupports(mAttribBuffers[index].buf);
|
wrval->SetAsISupports(mAttribBuffers[index].buf);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE:
|
|
||||||
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE:
|
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE:
|
||||||
|
wrval->SetAsInt32(mAttribBuffers[index].stride);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE:
|
||||||
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE:
|
case LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE:
|
||||||
{
|
{
|
||||||
GLint i = 0;
|
GLint i = 0;
|
||||||
@ -4326,13 +4331,12 @@ WebGLContext::UseProgram(nsIWebGLProgram *pobj)
|
|||||||
|
|
||||||
gl->fUseProgram(progname);
|
gl->fUseProgram(progname);
|
||||||
|
|
||||||
if (mCurrentProgram && mCurrentProgram->HasDeletePending()) {
|
WebGLProgram* previous = mCurrentProgram;
|
||||||
mCurrentProgram->DetachShaders();
|
|
||||||
mCurrentProgram->ClearDeletePending();
|
|
||||||
}
|
|
||||||
|
|
||||||
mCurrentProgram = prog;
|
mCurrentProgram = prog;
|
||||||
|
|
||||||
|
if (previous)
|
||||||
|
previous->NoLongerCurrent();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4568,7 +4572,6 @@ WebGLContext::GetShaderParameter(nsIWebGLShader *sobj, WebGLenum pname, nsIVaria
|
|||||||
wrval->SetAsBool(bool(i));
|
wrval->SetAsBool(bool(i));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
@ -115,15 +115,12 @@
|
|||||||
#include "mozilla/ipc/DocumentRendererParent.h"
|
#include "mozilla/ipc/DocumentRendererParent.h"
|
||||||
|
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
|
#include "mozilla/gfx/PathHelpers.h"
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#include "gfxWindowsPlatform.h"
|
#include "gfxWindowsPlatform.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef M_PI
|
|
||||||
#define M_PI 3.14159265358979323846
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// windows.h (included by chromium code) defines this, in its infinite wisdom
|
// windows.h (included by chromium code) defines this, in its infinite wisdom
|
||||||
#undef DrawText
|
#undef DrawText
|
||||||
|
|
||||||
@ -440,6 +437,9 @@ public:
|
|||||||
STYLE_FILL,
|
STYLE_FILL,
|
||||||
STYLE_MAX
|
STYLE_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nsresult LineTo(const Point& aPoint);
|
||||||
|
nsresult BezierTo(const Point& aCP1, const Point& aCP2, const Point& aCP3);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsresult InitializeWithTarget(DrawTarget *surface, PRInt32 width, PRInt32 height);
|
nsresult InitializeWithTarget(DrawTarget *surface, PRInt32 width, PRInt32 height);
|
||||||
@ -988,15 +988,15 @@ PRUint8 (*nsCanvasRenderingContext2DAzure::sPremultiplyTable)[256] = nsnull;
|
|||||||
nsresult
|
nsresult
|
||||||
NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
|
NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
|
||||||
{
|
{
|
||||||
#ifndef XP_WIN
|
#ifdef XP_WIN
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
|
if (gfxWindowsPlatform::GetPlatform()->GetRenderMode() !=
|
||||||
gfxWindowsPlatform::RENDER_DIRECT2D ||
|
gfxWindowsPlatform::RENDER_DIRECT2D ||
|
||||||
!gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) {
|
!gfxWindowsPlatform::GetPlatform()->DWriteEnabled()) {
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
#elif !defined(XP_MACOSX) && !defined(ANDROID)
|
||||||
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
#endif
|
||||||
|
|
||||||
nsRefPtr<nsIDOMCanvasRenderingContext2D> ctx = new nsCanvasRenderingContext2DAzure();
|
nsRefPtr<nsIDOMCanvasRenderingContext2D> ctx = new nsCanvasRenderingContext2DAzure();
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
@ -1004,7 +1004,6 @@ NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
|
|||||||
|
|
||||||
*aResult = ctx.forget().get();
|
*aResult = ctx.forget().get();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCanvasRenderingContext2DAzure::nsCanvasRenderingContext2DAzure()
|
nsCanvasRenderingContext2DAzure::nsCanvasRenderingContext2DAzure()
|
||||||
@ -1253,7 +1252,7 @@ nsCanvasRenderingContext2DAzure::SetDimensions(PRInt32 width, PRInt32 height)
|
|||||||
if (layerManager) {
|
if (layerManager) {
|
||||||
target = layerManager->CreateDrawTarget(size, format);
|
target = layerManager->CreateDrawTarget(size, format);
|
||||||
} else {
|
} else {
|
||||||
target = Factory::CreateDrawTarget(BACKEND_DIRECT2D, size, format);
|
target = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(size, format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1293,7 +1292,7 @@ nsCanvasRenderingContext2DAzure::InitializeWithTarget(DrawTarget *target, PRInt3
|
|||||||
*/
|
*/
|
||||||
if (!target)
|
if (!target)
|
||||||
{
|
{
|
||||||
mTarget = Factory::CreateDrawTarget(BACKEND_DIRECT2D, IntSize(1, 1), FORMAT_B8G8R8A8);
|
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1, 1), FORMAT_B8G8R8A8);
|
||||||
} else {
|
} else {
|
||||||
mValid = true;
|
mValid = true;
|
||||||
}
|
}
|
||||||
@ -2315,10 +2314,16 @@ nsCanvasRenderingContext2DAzure::LineTo(float x, float y)
|
|||||||
|
|
||||||
EnsureWritablePath();
|
EnsureWritablePath();
|
||||||
|
|
||||||
|
return LineTo(Point(x, y));;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsCanvasRenderingContext2DAzure::LineTo(const Point& aPoint)
|
||||||
|
{
|
||||||
if (mPathBuilder) {
|
if (mPathBuilder) {
|
||||||
mPathBuilder->LineTo(Point(x, y));
|
mPathBuilder->LineTo(aPoint);
|
||||||
} else {
|
} else {
|
||||||
mDSPathBuilder->LineTo(mTarget->GetTransform() * Point(x, y));
|
mDSPathBuilder->LineTo(mTarget->GetTransform() * aPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -2354,13 +2359,21 @@ nsCanvasRenderingContext2DAzure::BezierCurveTo(float cp1x, float cp1y,
|
|||||||
|
|
||||||
EnsureWritablePath();
|
EnsureWritablePath();
|
||||||
|
|
||||||
|
return BezierTo(Point(cp1x, cp1y), Point(cp2x, cp2y), Point(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsCanvasRenderingContext2DAzure::BezierTo(const Point& aCP1,
|
||||||
|
const Point& aCP2,
|
||||||
|
const Point& aCP3)
|
||||||
|
{
|
||||||
if (mPathBuilder) {
|
if (mPathBuilder) {
|
||||||
mPathBuilder->BezierTo(Point(cp1x, cp1y), Point(cp2x, cp2y), Point(x, y));
|
mPathBuilder->BezierTo(aCP1, aCP2, aCP3);
|
||||||
} else {
|
} else {
|
||||||
Matrix transform = mTarget->GetTransform();
|
Matrix transform = mTarget->GetTransform();
|
||||||
mDSPathBuilder->BezierTo(transform * Point(cp1x, cp1y),
|
mDSPathBuilder->BezierTo(transform * aCP1,
|
||||||
transform * Point(cp2x, cp2y),
|
transform * aCP2,
|
||||||
transform * Point(x, y));
|
transform * aCP3);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -2461,83 +2474,7 @@ nsCanvasRenderingContext2DAzure::Arc(float x, float y,
|
|||||||
|
|
||||||
EnsureWritablePath();
|
EnsureWritablePath();
|
||||||
|
|
||||||
// We convert to Bezier curve here, since we need to be able to write in
|
ArcToBezier(this, Point(x, y), r, startAngle, endAngle, ccw);
|
||||||
// device space, but a transformed arc is no longer representable by an arc.
|
|
||||||
|
|
||||||
Point startPoint(x + cos(startAngle) * r, y + sin(startAngle) * r);
|
|
||||||
|
|
||||||
if (mPathBuilder) {
|
|
||||||
mPathBuilder->LineTo(startPoint);
|
|
||||||
} else {
|
|
||||||
mDSPathBuilder->LineTo(mTarget->GetTransform() * startPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clockwise we always sweep from the smaller to the larger angle, ccw
|
|
||||||
// it's vice versa.
|
|
||||||
if (!ccw && (endAngle < startAngle)) {
|
|
||||||
Float correction = ceil((startAngle - endAngle) / (2.0f * M_PI));
|
|
||||||
endAngle += correction * 2.0f * M_PI;
|
|
||||||
} else if (ccw && (startAngle < endAngle)) {
|
|
||||||
Float correction = ceil((endAngle - startAngle) / (2.0f * M_PI));
|
|
||||||
startAngle += correction * 2.0f * M_PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sweeping more than 2 * pi is a full circle.
|
|
||||||
if (!ccw && (endAngle - startAngle > 2 * M_PI)) {
|
|
||||||
endAngle = startAngle + 2.0f * M_PI;
|
|
||||||
} else if (ccw && (startAngle - endAngle > 2.0f * M_PI)) {
|
|
||||||
endAngle = startAngle - 2.0f * M_PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the total arc we're going to sweep.
|
|
||||||
Float arcSweepLeft = abs(endAngle - startAngle);
|
|
||||||
|
|
||||||
Float sweepDirection = ccw ? -1.0f : 1.0f;
|
|
||||||
|
|
||||||
Float currentStartAngle = startAngle;
|
|
||||||
|
|
||||||
while (arcSweepLeft > 0) {
|
|
||||||
// We guarantee here the current point is the start point of the next
|
|
||||||
// curve segment.
|
|
||||||
Float currentEndAngle;
|
|
||||||
|
|
||||||
if (arcSweepLeft > M_PI / 2.0f) {
|
|
||||||
currentEndAngle = currentStartAngle + M_PI / 2.0f * sweepDirection;
|
|
||||||
} else {
|
|
||||||
currentEndAngle = currentStartAngle + arcSweepLeft * sweepDirection;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point currentStartPoint(x + cos(currentStartAngle) * r,
|
|
||||||
y + sin(currentStartAngle) * r);
|
|
||||||
Point currentEndPoint(x + cos(currentEndAngle) * r,
|
|
||||||
y + sin(currentEndAngle) * r);
|
|
||||||
|
|
||||||
// Calculate kappa constant for partial curve. The sign of angle in the
|
|
||||||
// tangent will actually ensure this is negative for a counter clockwise
|
|
||||||
// sweep, so changing signs later isn't needed.
|
|
||||||
Float kappa = (4.0f / 3.0f) * tan((currentEndAngle - currentStartAngle) / 4.0f) * r;
|
|
||||||
|
|
||||||
Point tangentStart(-sin(currentStartAngle), cos(currentStartAngle));
|
|
||||||
Point cp1 = currentStartPoint;
|
|
||||||
cp1 += tangentStart * kappa;
|
|
||||||
|
|
||||||
Point revTangentEnd(sin(currentEndAngle), -cos(currentEndAngle));
|
|
||||||
Point cp2 = currentEndPoint;
|
|
||||||
cp2 += revTangentEnd * kappa;
|
|
||||||
|
|
||||||
if (mPathBuilder) {
|
|
||||||
mPathBuilder->BezierTo(cp1, cp2, currentEndPoint);
|
|
||||||
} else {
|
|
||||||
mDSPathBuilder->BezierTo(mTarget->GetTransform() * cp1,
|
|
||||||
mTarget->GetTransform() * cp2,
|
|
||||||
mTarget->GetTransform() * currentEndPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
arcSweepLeft -= M_PI / 2.0f;
|
|
||||||
currentStartAngle = currentEndAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
This is a local copy of the WebGL conformance suite, SVN revision 15892
|
This is a local copy of the WebGL conformance suite, SVN revision 15981
|
||||||
|
|
||||||
The canonical location for this testsuite is:
|
The canonical location for this testsuite is:
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
description("tests that turning on attribs that have no buffer bound fails to draw");
|
||||||
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
||||||
gl.viewport(0, 0, 50, 50);
|
|
||||||
|
|
||||||
var vertexObject = gl.createBuffer();
|
var vertexObject = gl.createBuffer();
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||||
|
@ -27,7 +27,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Rendering Test</title>
|
<title>vertexattribpointer offsets test</title>
|
||||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||||
<script src="../../resources/js-test-pre.js"></script>
|
<script src="../../resources/js-test-pre.js"></script>
|
||||||
<script src="../resources/webgl-test.js"> </script>
|
<script src="../resources/webgl-test.js"> </script>
|
||||||
@ -74,6 +74,7 @@ There is supposed to be an example drawing here, but it's not important.
|
|||||||
if (window.initNonKhronosFramework) {
|
if (window.initNonKhronosFramework) {
|
||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
description("test vertexattribpointer offsets work");
|
||||||
|
|
||||||
wtu = WebGLTestUtils;
|
wtu = WebGLTestUtils;
|
||||||
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
||||||
|
@ -19,7 +19,7 @@ found in the LICENSE file.
|
|||||||
<div id="description"></div>
|
<div id="description"></div>
|
||||||
<div id="console"></div>
|
<div id="console"></div>
|
||||||
<script>
|
<script>
|
||||||
debug("Tests that resources can not be shared.");
|
description("Tests that resources can not be shared.");
|
||||||
debug("");
|
debug("");
|
||||||
|
|
||||||
var gl1 = create3DContext(document.getElementById("example1"));
|
var gl1 = create3DContext(document.getElementById("example1"));
|
||||||
|
@ -2,5 +2,7 @@ functions/00_test_list.txt
|
|||||||
implicit/00_test_list.txt
|
implicit/00_test_list.txt
|
||||||
misc/00_test_list.txt
|
misc/00_test_list.txt
|
||||||
reserved/00_test_list.txt
|
reserved/00_test_list.txt
|
||||||
|
# commented out for version 1.0.1 of the conforamnce tests.
|
||||||
|
#samplers/00_test_list.txt
|
||||||
variables/00_test_list.txt
|
variables/00_test_list.txt
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
attrib-location-length-limits.html
|
||||||
|
embedded-struct-definitions-forbidden.html
|
||||||
#glsl-2types-of-textures-on-same-unit.html
|
#glsl-2types-of-textures-on-same-unit.html
|
||||||
glsl-function-nodes.html
|
glsl-function-nodes.html
|
||||||
glsl-long-variable-names.html
|
glsl-long-variable-names.html
|
||||||
@ -9,6 +11,7 @@ shader-with-_webgl-identifier.vert.html
|
|||||||
shader-with-arbitrary-indexing.frag.html
|
shader-with-arbitrary-indexing.frag.html
|
||||||
shader-with-arbitrary-indexing.vert.html
|
shader-with-arbitrary-indexing.vert.html
|
||||||
shader-with-attrib-array.vert.html
|
shader-with-attrib-array.vert.html
|
||||||
|
shader-with-attrib-struct.vert.html
|
||||||
shader-with-clipvertex.vert.html
|
shader-with-clipvertex.vert.html
|
||||||
shader-with-default-precision.frag.html
|
shader-with-default-precision.frag.html
|
||||||
shader-with-default-precision.vert.html
|
shader-with-default-precision.vert.html
|
||||||
@ -49,3 +52,6 @@ shader-with-version-130.vert.html
|
|||||||
shader-with-webgl-identifier.vert.html
|
shader-with-webgl-identifier.vert.html
|
||||||
shader-without-precision.frag.html
|
shader-without-precision.frag.html
|
||||||
shared.html
|
shared.html
|
||||||
|
struct-nesting-exceeds-maximum.html
|
||||||
|
struct-nesting-under-maximum.html
|
||||||
|
uniform-location-length-limits.html
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebGL attrib location length tests</title>
|
||||||
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
|
<script src="../../../resources/js-test-pre.js"></script>
|
||||||
|
<script src="../../resources/webgl-test.js"> </script>
|
||||||
|
<script src="../../resources/webgl-test-utils.js"> </script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="example" width="50" height="50">
|
||||||
|
There is supposed to be an example drawing here, but it's not important.
|
||||||
|
</canvas>
|
||||||
|
<div id="description">Verify limits on the lengths of attribute locations per WebGL spec, "Maximum Uniform and Attribute Location Lengths".</div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<script id="goodVertexShader" type="x-shader/x-vertex">
|
||||||
|
// A vertex shader where the needed attrib location is exactly 256 characters.
|
||||||
|
attribute vec4 vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="badVertexShader" type="x-shader/x-vertex">
|
||||||
|
// A vertex shader where the needed attrib location is 257 characters.
|
||||||
|
attribute vec4 vPosition01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vPosition01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="fragmentShader" type="x-shader/x-fragment">
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
if (window.initNonKhronosFramework) {
|
||||||
|
window.initNonKhronosFramework(false);
|
||||||
|
}
|
||||||
|
description("test attrib location length limit");
|
||||||
|
|
||||||
|
var wtu = WebGLTestUtils;
|
||||||
|
var gl = wtu.create3DContext(document.getElementById("example"));
|
||||||
|
|
||||||
|
debug("Test attrib location underneath the length limit");
|
||||||
|
var program = wtu.loadProgramFromScript(gl, "goodVertexShader", "fragmentShader");
|
||||||
|
shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
|
||||||
|
var attribLoc = gl.getAttribLocation(program, "vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456");
|
||||||
|
if (attribLoc == -1) {
|
||||||
|
testFailed("attrib location was -1, should not be");
|
||||||
|
} else {
|
||||||
|
testPassed("attrib location should not be -1");
|
||||||
|
}
|
||||||
|
wtu.glErrorShouldBe(gl, gl.NONE);
|
||||||
|
|
||||||
|
debug("Test attrib location over the length limit");
|
||||||
|
debug("Shader compilation should fail");
|
||||||
|
shouldBe('wtu.loadShaderFromScript(gl, "badVertexShader", gl.VERTEX_SHADER, function (err) {})', 'null');
|
||||||
|
wtu.glErrorShouldBe(gl, gl.NONE);
|
||||||
|
|
||||||
|
debug("Attempt to bind too-long attrib location should produce error");
|
||||||
|
program = gl.createProgram();
|
||||||
|
gl.bindAttribLocation(program, 0, "vPosition01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567");
|
||||||
|
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
|
||||||
|
|
||||||
|
debug("Attempt to fetch too-long attrib location should produce error");
|
||||||
|
program = wtu.loadStandardProgram(gl);
|
||||||
|
shouldBe('gl.getAttribLocation(program, "vPosition01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567")', '-1');
|
||||||
|
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
|
||||||
|
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
<script src="../../../resources/js-test-post.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,38 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||||
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
|
found in the LICENSE file.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebGL GLSL Conformance Tests</title>
|
||||||
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
|
<script src="../../../resources/js-test-pre.js"></script>
|
||||||
|
<script src="../../resources/webgl-test-utils.js"></script>
|
||||||
|
<script src="../../resources/glsl-conformance-test.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<script id="vertexShader" type="text/something-not-javascript">
|
||||||
|
// embedded structure definitions are forbidden per GLSL ES section 4.1.8, "Structures", and should fail
|
||||||
|
struct nesting1 {
|
||||||
|
struct nesting2 {
|
||||||
|
vec4 vector;
|
||||||
|
} field2;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform nesting1 uniform1;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = uniform1.field2.vector;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
GLSLConformanceTester.runTest();
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -49,10 +49,10 @@ function init()
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Tests that using 2 types of textures on the same texture unit");
|
description(
|
||||||
debug("and referencing them both in the same program fails as per");
|
"Tests that using 2 types of textures on the same texture unit" +
|
||||||
debug("OpenGL ES 2.0.24 spec section 2.10.4, Samplers subsection.");
|
"and referencing them both in the same program fails as per" +
|
||||||
debug("");
|
"OpenGL ES 2.0.24 spec section 2.10.4, Samplers subsection.");
|
||||||
|
|
||||||
var canvas2d = document.getElementById("canvas2d");
|
var canvas2d = document.getElementById("canvas2d");
|
||||||
var ctx2d = canvas2d.getContext("2d");
|
var ctx2d = canvas2d.getContext("2d");
|
||||||
|
@ -112,6 +112,8 @@ function init()
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description("tests function nodes");
|
||||||
|
|
||||||
var bufFunction = new Uint8Array(width * height * 4);
|
var bufFunction = new Uint8Array(width * height * 4);
|
||||||
var bufMacro = new Uint8Array(width * height * 4);
|
var bufMacro = new Uint8Array(width * height * 4);
|
||||||
|
|
||||||
@ -120,7 +122,8 @@ function init()
|
|||||||
testFailed("Setup failed");
|
testFailed("Setup failed");
|
||||||
} else {
|
} else {
|
||||||
if (compareRendering(bufFunction, bufMacro, 4) == false)
|
if (compareRendering(bufFunction, bufMacro, 4) == false)
|
||||||
testFailed("Rendering results are different");
|
testFailedRender("Rendering results are different", bufMacro,
|
||||||
|
bufFunction, width, height);
|
||||||
else
|
else
|
||||||
testPassed("Rendering results are the same");
|
testPassed("Rendering results are the same");
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<canvas id="example" width="50" height="50">
|
<canvas id="example" width="50" height="50">
|
||||||
There is supposed to be an example drawing here, but it's not important.
|
There is supposed to be an example drawing here, but it's not important.
|
||||||
</canvas>
|
</canvas>
|
||||||
<div id="description">Verify that shader long variable names works fine if they are within 256 characters.</div>
|
<div id="description"></div>
|
||||||
<div id="console"></div>
|
<div id="console"></div>
|
||||||
<script id="vshader" type="x-shader/x-vertex">
|
<script id="vshader" type="x-shader/x-vertex">
|
||||||
attribute vec4 vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
|
attribute vec4 vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456;
|
||||||
@ -53,6 +53,8 @@
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description("Verify that shader long variable names works fine if they are within 256 characters.");
|
||||||
|
|
||||||
gl = initWebGL("example", "vshader", "fshader", [ "vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456"], [ 0, 0, 0, 1 ], 1);
|
gl = initWebGL("example", "vshader", "fshader", [ "vPosition0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456"], [ 0, 0, 0, 1 ], 1);
|
||||||
|
|
||||||
var prog = gl.getParameter(gl.CURRENT_PROGRAM);
|
var prog = gl.getParameter(gl.CURRENT_PROGRAM);
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||||
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
|
found in the LICENSE file.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebGL GLSL Conformance Tests</title>
|
||||||
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
|
<script src="../../../resources/js-test-pre.js"></script>
|
||||||
|
<script src="../../resources/webgl-test-utils.js"></script>
|
||||||
|
<script src="../../resources/glsl-conformance-test.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<script id="vertexShader" type="text/something-not-javascript">
|
||||||
|
// vertex shader that uses attribute struct should fail per GLSL ES section 4.4.3, "Attribute", p. 30
|
||||||
|
struct UserType {
|
||||||
|
attribute vec4 position;
|
||||||
|
};
|
||||||
|
|
||||||
|
attribute UserType userAttr;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = userAttr.position;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
GLSLConformanceTester.runTest();
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||||
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
|
found in the LICENSE file.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebGL GLSL Conformance Tests</title>
|
||||||
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
|
<script src="../../../resources/js-test-pre.js"></script>
|
||||||
|
<script src="../../resources/webgl-test-utils.js"></script>
|
||||||
|
<script src="../../resources/glsl-conformance-test.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<script id="vertexShader" type="text/something-not-javascript">
|
||||||
|
// shader with too-deep struct nesting should fail per WebGL spec
|
||||||
|
struct nesting4 {
|
||||||
|
vec4 vector;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nesting3 {
|
||||||
|
nesting4 field4;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nesting2 {
|
||||||
|
nesting3 field3;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nesting1 {
|
||||||
|
nesting2 field2;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform nesting1 uniform1;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = uniform1.field2.field3.field4.vector;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
GLSLConformanceTester.runTest();
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,44 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||||
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
|
found in the LICENSE file.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebGL GLSL Conformance Tests</title>
|
||||||
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
|
<script src="../../../resources/js-test-pre.js"></script>
|
||||||
|
<script src="../../resources/webgl-test-utils.js"></script>
|
||||||
|
<script src="../../resources/glsl-conformance-test.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<script id="vertexShader" type="text/something-not-javascript">
|
||||||
|
// shader with struct nesting less than maximum in WebGL spec should succeed
|
||||||
|
struct nesting3 {
|
||||||
|
vec4 vector;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nesting2 {
|
||||||
|
nesting3 field3;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nesting1 {
|
||||||
|
nesting2 field2;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform nesting1 uniform1;
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = uniform1.field2.field3.vector;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
GLSLConformanceTester.runTest();
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,84 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebGL uniform location length tests</title>
|
||||||
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
|
<script src="../../../resources/js-test-pre.js"></script>
|
||||||
|
<script src="../../resources/webgl-test.js"> </script>
|
||||||
|
<script src="../../resources/webgl-test-utils.js"> </script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="example" width="50" height="50">
|
||||||
|
There is supposed to be an example drawing here, but it's not important.
|
||||||
|
</canvas>
|
||||||
|
<div id="description">Verify limits on the lengths of uniform locations per WebGL spec, "Maximum Uniform and Attribute Location Lengths".</div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<script id="goodVertexShader" type="x-shader/x-vertex">
|
||||||
|
// A vertex shader where the needed uniform location is exactly 256 characters.
|
||||||
|
struct Nesting2 {
|
||||||
|
vec4 identifier62CharactersLong_01234567890123456789012345678901234;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Nesting1 {
|
||||||
|
Nesting2 identifier64CharactersLong_0123456789012345678901234567890123456;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform Nesting1 identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.identifier64CharactersLong_0123456789012345678901234567890123456.identifier62CharactersLong_01234567890123456789012345678901234;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="badVertexShader" type="x-shader/x-vertex">
|
||||||
|
// A vertex shader where the needed uniform location is 257 characters.
|
||||||
|
struct Nesting2 {
|
||||||
|
vec4 identifier63CharactersLong_012345678901234567890123456789012345;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Nesting1 {
|
||||||
|
Nesting2 identifier64CharactersLong_0123456789012345678901234567890123456;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform Nesting1 identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
Nesting2 temp = identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.identifier64CharactersLong_0123456789012345678901234567890123456;
|
||||||
|
gl_Position = temp.identifier63CharactersLong_012345678901234567890123456789012345;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="fragmentShader" type="x-shader/x-fragment">
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
if (window.initNonKhronosFramework) {
|
||||||
|
window.initNonKhronosFramework(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
var wtu = WebGLTestUtils;
|
||||||
|
var gl = wtu.create3DContext(document.getElementById("example"));
|
||||||
|
|
||||||
|
debug("Test uniform location underneath the length limit");
|
||||||
|
var program = wtu.loadProgramFromScript(gl, "goodVertexShader", "fragmentShader");
|
||||||
|
shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
|
||||||
|
var uniformLoc = gl.getUniformLocation(program, "identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.identifier64CharactersLong_0123456789012345678901234567890123456.identifier62CharactersLong_01234567890123456789012345678901234");
|
||||||
|
shouldBeNonNull('uniformLoc');
|
||||||
|
wtu.glErrorShouldBe(gl, gl.NONE);
|
||||||
|
|
||||||
|
debug("Test uniform location over the length limit");
|
||||||
|
program = wtu.loadProgramFromScript(gl, "badVertexShader", "fragmentShader");
|
||||||
|
wtu.glErrorShouldBe(gl, gl.NONE);
|
||||||
|
shouldBe('gl.getProgramParameter(program, gl.LINK_STATUS)', 'true');
|
||||||
|
var uniformLoc = gl.getUniformLocation(program, "identifier128CharactersLong_0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.identifier64CharactersLong_0123456789012345678901234567890123456.identifier63CharactersLong_012345678901234567890123456789012345");
|
||||||
|
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE);
|
||||||
|
shouldBeNull('uniformLoc');
|
||||||
|
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
<script src="../../../resources/js-test-post.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,4 @@
|
|||||||
|
glsl-function-texture2d-bias.html
|
||||||
|
glsl-function-texture2dlod.html
|
||||||
|
glsl-function-texture2dproj.html
|
||||||
|
|
@ -0,0 +1,104 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||||
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
|
found in the LICENSE file.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebGL texture2D GLSL conformance test.</title>
|
||||||
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
|
<script src="../../../resources/js-test-pre.js"></script>
|
||||||
|
<script src="../../resources/webgl-test.js"> </script>
|
||||||
|
<script src="../../resources/webgl-test-utils.js"> </script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="example" width="256" height="256" style="width: 16px; height: 16px;"></canvas>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<script id="vshader2d" type="x-shader/x-vertex">
|
||||||
|
attribute vec4 vPosition;
|
||||||
|
attribute vec2 texCoord0;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
void main() {
|
||||||
|
gl_Position = vPosition;
|
||||||
|
texCoord = texCoord0;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="fshader2d" type="x-shader/x-vertex">
|
||||||
|
precision mediump float;
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform float bias;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
void main() {
|
||||||
|
gl_FragData[0] = texture2D(tex, texCoord, bias);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
description("tests GLSL texture2D function with bias");
|
||||||
|
|
||||||
|
var wtu = WebGLTestUtils;
|
||||||
|
var canvas = document.getElementById("example");
|
||||||
|
|
||||||
|
shouldBe("canvas.width", "256");
|
||||||
|
shouldBe("canvas.height", "256");
|
||||||
|
|
||||||
|
var gl = wtu.create3DContext(canvas);
|
||||||
|
var program = wtu.setupProgram(
|
||||||
|
gl,
|
||||||
|
[wtu.loadShaderFromScript(gl, 'vshader2d', gl.VERTEX_SHADER),
|
||||||
|
wtu.loadShaderFromScript(gl, 'fshader2d', gl.FRAGMENT_SHADER)],
|
||||||
|
['vPosition', 'texCoord0'], [0, 1]);
|
||||||
|
wtu.setupUnitQuad(gl, 0, 1);
|
||||||
|
|
||||||
|
var colors = [
|
||||||
|
{name: 'red', color:[255, 0, 0, 255]},
|
||||||
|
{name: 'green', color:[0, 255, 0, 255]},
|
||||||
|
{name: 'blue', color:[0, 0, 255, 255]},
|
||||||
|
{name: 'yellow', color:[255, 255, 0, 255]},
|
||||||
|
{name: 'magenta', color:[255, 0, 255, 255]},
|
||||||
|
{name: 'cyan', color:[0, 255, 255, 255]},
|
||||||
|
{name: 'pink', color:[255, 128, 128, 255]},
|
||||||
|
{name: 'gray', color:[128, 128, 128, 255]},
|
||||||
|
{name: 'light green', color:[128, 255, 128, 255]},
|
||||||
|
];
|
||||||
|
|
||||||
|
shouldBe("colors.length", "9");
|
||||||
|
|
||||||
|
var tex = gl.createTexture();
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||||
|
gl.texParameteri(
|
||||||
|
gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||||
|
|
||||||
|
for (var ii = 0; ii < colors.length; ++ii) {
|
||||||
|
var color = colors[ii];
|
||||||
|
var size = Math.pow(2, colors.length - ii - 1);
|
||||||
|
wtu.fillTexture(gl, tex, size, size, color.color, ii);
|
||||||
|
}
|
||||||
|
|
||||||
|
var loc = gl.getUniformLocation(program, "bias");
|
||||||
|
|
||||||
|
for (var ii = 0; ii < colors.length; ++ii) {
|
||||||
|
gl.uniform1f(loc, ii);
|
||||||
|
var color = colors[ii];
|
||||||
|
wtu.drawQuad(gl);
|
||||||
|
wtu.checkCanvas(
|
||||||
|
gl, color.color,
|
||||||
|
"256x256 texture drawn to 256x256 dest with bias = " + ii +
|
||||||
|
" should be " + color.name);
|
||||||
|
}
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
|
||||||
|
|
||||||
|
successfullyParsed = true;
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<script src="../../../resources/js-test-post.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||||
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
|
found in the LICENSE file.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebGL texture2D GLSL conformance test.</title>
|
||||||
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
|
<script src="../../../resources/js-test-pre.js"></script>
|
||||||
|
<script src="../../resources/webgl-test.js"> </script>
|
||||||
|
<script src="../../resources/webgl-test-utils.js"> </script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="example" width="256" height="256" style="width: 16px; height: 16px;"></canvas>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<script id="vshader2d" type="x-shader/x-vertex">
|
||||||
|
attribute vec4 vPosition;
|
||||||
|
attribute vec2 texCoord0;
|
||||||
|
varying vec4 color;
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform float lod;
|
||||||
|
void main() {
|
||||||
|
gl_Position = vPosition;
|
||||||
|
color = texture2DLod(tex, texCoord0, lod);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="fshader2d" type="x-shader/x-vertex">
|
||||||
|
precision mediump float;
|
||||||
|
varying vec4 color;
|
||||||
|
void main() {
|
||||||
|
gl_FragData[0] = color;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
description("tests GLSL texture2DLod function");
|
||||||
|
|
||||||
|
var wtu = WebGLTestUtils;
|
||||||
|
var canvas = document.getElementById("example");
|
||||||
|
|
||||||
|
shouldBe("canvas.width", "256");
|
||||||
|
shouldBe("canvas.height", "256");
|
||||||
|
|
||||||
|
var gl = wtu.create3DContext(canvas);
|
||||||
|
var program = wtu.setupProgram(
|
||||||
|
gl,
|
||||||
|
[wtu.loadShaderFromScript(gl, 'vshader2d', gl.VERTEX_SHADER),
|
||||||
|
wtu.loadShaderFromScript(gl, 'fshader2d', gl.FRAGMENT_SHADER)],
|
||||||
|
['vPosition', 'texCoord0'], [0, 1]);
|
||||||
|
wtu.setupUnitQuad(gl, 0, 1);
|
||||||
|
|
||||||
|
var colors = [
|
||||||
|
{name: 'red', color:[255, 0, 0, 255]},
|
||||||
|
{name: 'green', color:[0, 255, 0, 255]},
|
||||||
|
{name: 'blue', color:[0, 0, 255, 255]},
|
||||||
|
{name: 'yellow', color:[255, 255, 0, 255]},
|
||||||
|
{name: 'magenta', color:[255, 0, 255, 255]},
|
||||||
|
{name: 'cyan', color:[0, 255, 255, 255]},
|
||||||
|
{name: 'pink', color:[255, 128, 128, 255]},
|
||||||
|
{name: 'gray', color:[128, 128, 128, 255]},
|
||||||
|
{name: 'light green', color:[128, 255, 128, 255]},
|
||||||
|
];
|
||||||
|
|
||||||
|
shouldBe("colors.length", "9");
|
||||||
|
|
||||||
|
var tex = gl.createTexture();
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||||
|
gl.texParameteri(
|
||||||
|
gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||||
|
|
||||||
|
for (var ii = 0; ii < colors.length; ++ii) {
|
||||||
|
var color = colors[ii];
|
||||||
|
var size = Math.pow(2, colors.length - ii - 1);
|
||||||
|
wtu.fillTexture(gl, tex, size, size, color.color, ii);
|
||||||
|
}
|
||||||
|
|
||||||
|
var loc = gl.getUniformLocation(program, "lod");
|
||||||
|
|
||||||
|
for (var ii = 0; ii < colors.length; ++ii) {
|
||||||
|
gl.uniform1f(loc, ii);
|
||||||
|
var color = colors[ii];
|
||||||
|
wtu.drawQuad(gl);
|
||||||
|
wtu.checkCanvas(
|
||||||
|
gl, color.color,
|
||||||
|
"256x256 texture drawn to 256x256 dest with lod = " + ii +
|
||||||
|
" should be " + color.name);
|
||||||
|
}
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
|
||||||
|
|
||||||
|
successfullyParsed = true;
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<script src="../../../resources/js-test-post.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
@ -0,0 +1,120 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||||
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
|
found in the LICENSE file.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>WebGL texture2D GLSL conformance test.</title>
|
||||||
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
|
<script src="../../../resources/js-test-pre.js"></script>
|
||||||
|
<script src="../../resources/webgl-test.js"> </script>
|
||||||
|
<script src="../../resources/webgl-test-utils.js"> </script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="example" width="32" height="32"></canvas>
|
||||||
|
<div id="description"></div>
|
||||||
|
<div id="console"></div>
|
||||||
|
<script id="vshader0" type="x-shader/x-vertex">
|
||||||
|
attribute vec4 vPosition;
|
||||||
|
attribute vec2 texCoord0;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
void main() {
|
||||||
|
gl_Position = vPosition;
|
||||||
|
texCoord = texCoord0;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="fshader0" type="x-shader/x-vertex">
|
||||||
|
precision mediump float;
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform float divisor;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
void main() {
|
||||||
|
gl_FragData[0] = texture2DProj(tex, vec3(texCoord, divisor));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="vshader1" type="x-shader/x-vertex">
|
||||||
|
attribute vec4 vPosition;
|
||||||
|
attribute vec2 texCoord0;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
void main() {
|
||||||
|
gl_Position = vPosition;
|
||||||
|
texCoord = texCoord0;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script id="fshader1" type="x-shader/x-vertex">
|
||||||
|
precision mediump float;
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform float divisor;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
void main() {
|
||||||
|
gl_FragData[0] = texture2DProj(tex, vec4(texCoord, 123.0, divisor));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>
|
||||||
|
description("tests GLSL texture2DProj function with");
|
||||||
|
|
||||||
|
var wtu = WebGLTestUtils;
|
||||||
|
var canvas = document.getElementById("example");
|
||||||
|
|
||||||
|
var gl = wtu.create3DContext(canvas, {antialias: false});
|
||||||
|
|
||||||
|
wtu.setupUnitQuad(gl, 0, 1);
|
||||||
|
var tex = gl.createTexture();
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||||
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||||
|
|
||||||
|
var c = document.createElement("canvas");
|
||||||
|
c.width = 16;
|
||||||
|
c.height = 16;
|
||||||
|
var ctx = c.getContext("2d");
|
||||||
|
ctx.fillStyle = "rgb(0,255,0)";
|
||||||
|
ctx.fillRect(0, 0, 16, 16);
|
||||||
|
ctx.fillStyle = "rgb(0,0,255)";
|
||||||
|
ctx.fillRect(0, 0, 8, 8);
|
||||||
|
ctx.fillRect(8, 8, 8, 8);
|
||||||
|
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
|
||||||
|
|
||||||
|
for (var ss = 0; ss < 2; ++ss) {
|
||||||
|
debug("");
|
||||||
|
debug(ss ? "testing vec4 version" : "testing vec3 version");
|
||||||
|
var program = wtu.setupProgram(
|
||||||
|
gl,
|
||||||
|
[wtu.loadShaderFromScript(gl, 'vshader' + ss, gl.VERTEX_SHADER),
|
||||||
|
wtu.loadShaderFromScript(gl, 'fshader' + ss, gl.FRAGMENT_SHADER)],
|
||||||
|
['vPosition', 'texCoord0'], [0, 1]);
|
||||||
|
gl.useProgram(program);
|
||||||
|
var loc = gl.getUniformLocation(program, "divisor");
|
||||||
|
|
||||||
|
for (var ii = 0; ii < 3; ++ii) {
|
||||||
|
var denominator = Math.pow(2, ii);
|
||||||
|
gl.uniform1f(loc, 1 / denominator);
|
||||||
|
wtu.drawQuad(gl);
|
||||||
|
var size = 16 / denominator;
|
||||||
|
for (var yy = 0; yy < 32; yy += size) {
|
||||||
|
for (var xx = 0; xx < 32; xx += size) {
|
||||||
|
var odd = (xx / size + yy / size) % 2;
|
||||||
|
var color = odd ? [0, 255, 0, 255] : [0, 0, 255, 255];
|
||||||
|
var msg = "" + xx + ", " + yy + ", " + size + ", " + size + " should be " + (odd ? "green" : "blue");
|
||||||
|
wtu.checkCanvasRect(gl, xx, yy, size, size, color, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
|
||||||
|
|
||||||
|
successfullyParsed = true;
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<script src="../../../resources/js-test-post.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
@ -45,6 +45,8 @@ found in the LICENSE file.
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description("tests gl_FragCoord");
|
||||||
|
|
||||||
wtu = WebGLTestUtils;
|
wtu = WebGLTestUtils;
|
||||||
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ found in the LICENSE file.
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description("tests gl_FrontFacing");
|
||||||
|
|
||||||
wtu = WebGLTestUtils;
|
wtu = WebGLTestUtils;
|
||||||
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ void main()
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
|
description(document.title);
|
||||||
var wtu = WebGLTestUtils;
|
var wtu = WebGLTestUtils;
|
||||||
var canvas = document.getElementById("example");
|
var canvas = document.getElementById("example");
|
||||||
var gl = wtu.create3DContext(canvas);
|
var gl = wtu.create3DContext(canvas);
|
||||||
|
@ -43,6 +43,7 @@ void main()
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
|
description(document.title);
|
||||||
var wtu = WebGLTestUtils;
|
var wtu = WebGLTestUtils;
|
||||||
var canvas = document.getElementById("example");
|
var canvas = document.getElementById("example");
|
||||||
var gl = wtu.create3DContext(canvas);
|
var gl = wtu.create3DContext(canvas);
|
||||||
|
@ -28,7 +28,7 @@ void main()
|
|||||||
<script id="fshader" type="x-shader/x-fragment">
|
<script id="fshader" type="x-shader/x-fragment">
|
||||||
#define NUM_TEXTURES 8 // See spec
|
#define NUM_TEXTURES 8 // See spec
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
uniform sampler2D uni[8];
|
uniform sampler2D uni[NUM_TEXTURES];
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 c = vec4(0,0,0,0);
|
vec4 c = vec4(0,0,0,0);
|
||||||
@ -39,6 +39,7 @@ void main()
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
|
description(document.title);
|
||||||
var wtu = WebGLTestUtils;
|
var wtu = WebGLTestUtils;
|
||||||
var canvas = document.getElementById("example");
|
var canvas = document.getElementById("example");
|
||||||
var gl = wtu.create3DContext(canvas);
|
var gl = wtu.create3DContext(canvas);
|
||||||
@ -62,7 +63,7 @@ for (var ii = 0; ii < 8; ++ii) {
|
|||||||
wtu.drawQuad(gl);
|
wtu.drawQuad(gl);
|
||||||
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
|
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
|
||||||
wtu.checkCanvas(gl, [255, 128, 64, 252],
|
wtu.checkCanvas(gl, [255, 128, 64, 252],
|
||||||
"Should render using all texture units");
|
"Should render using all texture units", 1);
|
||||||
|
|
||||||
successfullyParsed = true;
|
successfullyParsed = true;
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ void main()
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
|
description(document.title);
|
||||||
var wtu = WebGLTestUtils;
|
var wtu = WebGLTestUtils;
|
||||||
var canvas = document.getElementById("example");
|
var canvas = document.getElementById("example");
|
||||||
var gl = wtu.create3DContext(canvas);
|
var gl = wtu.create3DContext(canvas);
|
||||||
|
@ -1,91 +1,92 @@
|
|||||||
<!--
|
<!--
|
||||||
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||||||
Use of this source code is governed by a BSD-style license that can be
|
Use of this source code is governed by a BSD-style license that can be
|
||||||
found in the LICENSE file.
|
found in the LICENSE file.
|
||||||
-->
|
-->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>WebGL instanceof test.</title>
|
<title>WebGL instanceof test.</title>
|
||||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||||
<script src="../../resources/js-test-pre.js"></script>
|
<script src="../../resources/js-test-pre.js"></script>
|
||||||
<script src="../resources/webgl-test.js"> </script>
|
<script src="../resources/webgl-test.js"> </script>
|
||||||
<script src="../resources/webgl-test-utils.js"> </script>
|
<script src="../resources/webgl-test-utils.js"> </script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="canvas" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
|
<canvas id="canvas" width="2" height="2" style="width: 40px; height: 40px;"></canvas>
|
||||||
<div id="description"></div>
|
<div id="description"></div>
|
||||||
<div id="console"></div>
|
<div id="console"></div>
|
||||||
<script id="vshader" type="x-shader/x-vertex">
|
<script id="vshader" type="x-shader/x-vertex">
|
||||||
attribute vec4 vPosition;
|
attribute vec4 vPosition;
|
||||||
varying vec2 texCoord;
|
varying vec2 texCoord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = vPosition;
|
gl_Position = vPosition;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script id="fshader" type="x-shader/x-fragment">
|
<script id="fshader" type="x-shader/x-fragment">
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
uniform vec4 color;
|
uniform vec4 color;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
var wtu = WebGLTestUtils;
|
var wtu = WebGLTestUtils;
|
||||||
debug("Tests that instanceof works on WebGL objects.");
|
description(document.title);
|
||||||
debug("");
|
debug("Tests that instanceof works on WebGL objects.");
|
||||||
var gl = create3DContext(document.getElementById("canvas"));
|
debug("");
|
||||||
shouldBeTrue('gl instanceof WebGLRenderingContext');
|
var gl = create3DContext(document.getElementById("canvas"));
|
||||||
shouldBeTrue('gl.createBuffer() instanceof WebGLBuffer');
|
shouldBeTrue('gl instanceof WebGLRenderingContext');
|
||||||
shouldBeTrue('gl.createFramebuffer() instanceof WebGLFramebuffer');
|
shouldBeTrue('gl.createBuffer() instanceof WebGLBuffer');
|
||||||
shouldBeTrue('gl.createProgram() instanceof WebGLProgram');
|
shouldBeTrue('gl.createFramebuffer() instanceof WebGLFramebuffer');
|
||||||
shouldBeTrue('gl.createRenderbuffer() instanceof WebGLRenderbuffer');
|
shouldBeTrue('gl.createProgram() instanceof WebGLProgram');
|
||||||
shouldBeTrue('gl.createShader(gl.VERTEX_SHADER) instanceof WebGLShader');
|
shouldBeTrue('gl.createRenderbuffer() instanceof WebGLRenderbuffer');
|
||||||
shouldBeTrue('gl.createTexture() instanceof WebGLTexture');
|
shouldBeTrue('gl.createShader(gl.VERTEX_SHADER) instanceof WebGLShader');
|
||||||
|
shouldBeTrue('gl.createTexture() instanceof WebGLTexture');
|
||||||
var program = wtu.setupProgram(
|
|
||||||
gl,
|
var program = wtu.setupProgram(
|
||||||
[wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER),
|
gl,
|
||||||
wtu.loadShaderFromScript(gl, 'fshader', gl.FRAGMENT_SHADER)],
|
[wtu.loadShaderFromScript(gl, 'vshader', gl.VERTEX_SHADER),
|
||||||
['vPosition'], [0]);
|
wtu.loadShaderFromScript(gl, 'fshader', gl.FRAGMENT_SHADER)],
|
||||||
|
['vPosition'], [0]);
|
||||||
shouldBeTrue('gl.getUniformLocation(program, "color") instanceof WebGLUniformLocation');
|
|
||||||
shouldBeTrue('gl.getActiveAttrib(program, 0) instanceof WebGLActiveInfo');
|
shouldBeTrue('gl.getUniformLocation(program, "color") instanceof WebGLUniformLocation');
|
||||||
shouldBeTrue('gl.getActiveUniform(program, 0) instanceof WebGLActiveInfo');
|
shouldBeTrue('gl.getActiveAttrib(program, 0) instanceof WebGLActiveInfo');
|
||||||
|
shouldBeTrue('gl.getActiveUniform(program, 0) instanceof WebGLActiveInfo');
|
||||||
debug("");
|
|
||||||
debug("Tests that those WebGL objects can not be constructed through new operator");
|
debug("");
|
||||||
debug("");
|
debug("Tests that those WebGL objects can not be constructed through new operator");
|
||||||
|
debug("");
|
||||||
function shouldThrowWithNew(objectType, objectName)
|
|
||||||
{
|
function shouldThrowWithNew(objectType, objectName)
|
||||||
try {
|
{
|
||||||
new objectType;
|
try {
|
||||||
testFailed('new ' + objectName + ' did not throw');
|
new objectType;
|
||||||
} catch (e) {
|
testFailed('new ' + objectName + ' did not throw');
|
||||||
testPassed('new ' + objectName + ' threw an error');
|
} catch (e) {
|
||||||
}
|
testPassed('new ' + objectName + ' threw an error');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
shouldThrowWithNew(WebGLRenderingContext, 'WebGLRenderingContext');
|
|
||||||
shouldThrowWithNew(WebGLActiveInfo, 'WebGLActiveInfo');
|
shouldThrowWithNew(WebGLRenderingContext, 'WebGLRenderingContext');
|
||||||
shouldThrowWithNew(WebGLBuffer, 'WebGLBuffer');
|
shouldThrowWithNew(WebGLActiveInfo, 'WebGLActiveInfo');
|
||||||
shouldThrowWithNew(WebGLFramebuffer, 'WebGLFramebuffer');
|
shouldThrowWithNew(WebGLBuffer, 'WebGLBuffer');
|
||||||
shouldThrowWithNew(WebGLProgram, 'WebGLProgram');
|
shouldThrowWithNew(WebGLFramebuffer, 'WebGLFramebuffer');
|
||||||
shouldThrowWithNew(WebGLRenderbuffer, 'WebGLRenderbuffer');
|
shouldThrowWithNew(WebGLProgram, 'WebGLProgram');
|
||||||
shouldThrowWithNew(WebGLShader, 'WebGLShader');
|
shouldThrowWithNew(WebGLRenderbuffer, 'WebGLRenderbuffer');
|
||||||
shouldThrowWithNew(WebGLTexture, 'WebGLTexture');
|
shouldThrowWithNew(WebGLShader, 'WebGLShader');
|
||||||
shouldThrowWithNew(WebGLUniformLocation, 'WebGLUniformLocation');
|
shouldThrowWithNew(WebGLTexture, 'WebGLTexture');
|
||||||
|
shouldThrowWithNew(WebGLUniformLocation, 'WebGLUniformLocation');
|
||||||
successfullyParsed = true;
|
|
||||||
</script>
|
successfullyParsed = true;
|
||||||
<script src="../../resources/js-test-post.js"></script>
|
</script>
|
||||||
|
<script src="../../resources/js-test-post.js"></script>
|
||||||
</body>
|
|
||||||
</html>
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +61,9 @@ function checkNonZeroPixels(texture, texWidth, texHeight, skipX, skipY, skipWidt
|
|||||||
var index = (y * texWidth + x) * 4;
|
var index = (y * texWidth + x) * 4;
|
||||||
if (x >= skipX && x < skipX + skipWidth && y >= skipY && y < skipY + skipHeight) {
|
if (x >= skipX && x < skipX + skipWidth && y >= skipY && y < skipY + skipHeight) {
|
||||||
if (data[index] != skipR || data[index + 1] != skipG || data[index + 2] != skipB || data[index + 3] != skipA) {
|
if (data[index] != skipR || data[index + 1] != skipG || data[index + 2] != skipB || data[index + 3] != skipA) {
|
||||||
testFailed("non-zero pixel values are wrong");
|
testFailed("non-zero pixel values are wrong at (" + x + ", " + y + "), data was (" +
|
||||||
|
data[index] + "," + data[index + 1] + "," + data[index + 2] + "," + data[index + 3] +
|
||||||
|
") should have been (" + skipR + "," + skipG + "," + skipB + "," + skipA + ")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -10,13 +10,14 @@ found in the LICENSE file.
|
|||||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||||
<script src="../../resources/js-test-pre.js"></script>
|
<script src="../../resources/js-test-pre.js"></script>
|
||||||
<script src="../resources/webgl-test.js"></script>
|
<script src="../resources/webgl-test.js"></script>
|
||||||
|
<script src="../resources/webgl-test-utils.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="description"></div>
|
<div id="description"></div>
|
||||||
<div id="console"></div>
|
<div id="console"></div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
var wtu = WebGLTestUtils;
|
||||||
var gl;
|
var gl;
|
||||||
var fbo;
|
var fbo;
|
||||||
var depthBuffer;
|
var depthBuffer;
|
||||||
@ -111,6 +112,7 @@ for (width = 0; width <= 2; width += 2)
|
|||||||
{
|
{
|
||||||
for (height = 0; height <= 2; height += 2)
|
for (height = 0; height <= 2; height += 2)
|
||||||
{
|
{
|
||||||
|
debug("");
|
||||||
debug("Dimensions " + width + " x " + height);
|
debug("Dimensions " + width + " x " + height);
|
||||||
|
|
||||||
debug("Create renderbuffers");
|
debug("Create renderbuffers");
|
||||||
@ -178,6 +180,209 @@ for (width = 0; width <= 2; width += 2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine if we can attach both color and depth or color and depth_stencil
|
||||||
|
var depthFormat;
|
||||||
|
var depthAttachment;
|
||||||
|
|
||||||
|
function checkValidColorDepthCombination() {
|
||||||
|
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||||
|
shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
|
||||||
|
|
||||||
|
shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
|
||||||
|
|
||||||
|
return tryDepth(gl.DEPTH_COMPONENT16, gl.DEPTH_ATTACHMENT) || tryDepth(gl.DEPTH_STENCIL, gl.DEPTH_STENCIL_ATTACHMENT);
|
||||||
|
|
||||||
|
function tryDepth(try_format, try_attachment) {
|
||||||
|
if (depthAttachment) {
|
||||||
|
// If we've tried once unattach the old one.
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, null);
|
||||||
|
}
|
||||||
|
depthFormat = try_format;
|
||||||
|
depthAttachment = try_attachment;
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
return gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkValidColorDepthCombination()) {
|
||||||
|
testFramebufferIncompleteDimensions();
|
||||||
|
testFramebufferIncompleteAttachment();
|
||||||
|
testFramebufferIncompleteMissingAttachment();
|
||||||
|
testUsingIncompleteFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
function CheckFramebuffer(expected) {
|
||||||
|
var actual = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
||||||
|
var msg = "gl.checkFramebufferStatus(gl.FRAMEBUFFER) should be " + wtu.glEnumToString(gl, expected) + " was " + wtu.glEnumToString(gl, actual);
|
||||||
|
if (expected != gl.FRAMEBUFFER_COMPLETE) {
|
||||||
|
msg += " or FRAMEBUFFER_UNSUPPORTED";
|
||||||
|
}
|
||||||
|
if (actual == expected ||
|
||||||
|
(expected != gl.FRAMEBUFFER_COMPLETE &&
|
||||||
|
actual == gl.FRAMBUFFER_UNSUPPORTED)) {
|
||||||
|
testPassed(msg);
|
||||||
|
} else {
|
||||||
|
testFailed(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testUsingIncompleteFramebuffer() {
|
||||||
|
debug("");
|
||||||
|
debug("Test drawing or reading from an incomplete framebuffer");
|
||||||
|
var program = wtu.setupTexturedQuad(gl);
|
||||||
|
var tex = gl.createTexture();
|
||||||
|
wtu.fillTexture(gl, tex, 1, 1, [0,255,0,255]);
|
||||||
|
|
||||||
|
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||||
|
shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
|
||||||
|
|
||||||
|
shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
|
||||||
|
|
||||||
|
// We pick this combination because it works on desktop OpenGL but should not work on OpenGL ES 2.0
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
|
||||||
|
debug("");
|
||||||
|
debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
|
||||||
|
testRenderingAndReading();
|
||||||
|
|
||||||
|
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
|
||||||
|
debug("");
|
||||||
|
debug("Drawing or reading from an incomplete framebuffer should generate INVALID_FRAMEBUFFER_OPERATION");
|
||||||
|
testRenderingAndReading();
|
||||||
|
|
||||||
|
function testRenderingAndReading() {
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
wtu.drawQuad(gl);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "drawArrays with incomplete framebuffer");
|
||||||
|
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "readPixels from incomplete framebuffer");
|
||||||
|
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D from incomplete framebuffer");
|
||||||
|
gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 1, 1, 0);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D from incomplete framebuffer");
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
|
glErrorShouldBe(gl, gl.INVALID_FRAMEBUFFER_OPERATION, "clear with incomplete framebuffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFramebufferIncompleteAttachment() {
|
||||||
|
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||||
|
shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
|
||||||
|
|
||||||
|
debug("");
|
||||||
|
debug("Wrong storage type for type of attachment be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)");
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
|
||||||
|
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
|
||||||
|
|
||||||
|
debug("");
|
||||||
|
debug("0 size attachment should be FRAMEBUFFER_INCOMPLETE_ATTACHMENT (OpenGL ES 2.0 4.4.5)");
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 0, 0);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
|
||||||
|
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFramebufferIncompleteMissingAttachment() {
|
||||||
|
debug("");
|
||||||
|
debug("No attachments should be INCOMPLETE_FRAMEBUFFER_MISSING_ATTACHMENT (OpenGL ES 2.0 4.4.5)");
|
||||||
|
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
|
||||||
|
|
||||||
|
shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
|
||||||
|
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
|
||||||
|
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFramebufferIncompleteDimensions() {
|
||||||
|
debug("");
|
||||||
|
debug("Attachments of different sizes should be FRAMEBUFFER_INCOMPLETE_DIMENSIONS (OpenGL ES 2.0 4.4.5)");
|
||||||
|
|
||||||
|
shouldBeNonNull("fbo = gl.createFramebuffer()");
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||||
|
shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
|
||||||
|
|
||||||
|
shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
|
||||||
|
gl.framebufferRenderbuffer(
|
||||||
|
gl.FRAMEBUFFER, depthAttachment, gl.RENDERBUFFER, depthBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
|
||||||
|
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 32, 16);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, depthFormat, 16, 16);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 32);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 16, 16);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
|
||||||
|
var tex = gl.createTexture();
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||||
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
|
||||||
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||||
|
CheckFramebuffer(gl.FRAMEBUFFER_COMPLETE);
|
||||||
|
|
||||||
|
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
successfullyParsed = true;
|
successfullyParsed = true;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ found in the LICENSE file.
|
|||||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||||
<script src="../../resources/js-test-pre.js"></script>
|
<script src="../../resources/js-test-pre.js"></script>
|
||||||
<script src="../resources/webgl-test.js"></script>
|
<script src="../resources/webgl-test.js"></script>
|
||||||
|
<script src="../../resources/desktop-gl-constants.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="description"></div>
|
<div id="description"></div>
|
||||||
@ -97,7 +98,7 @@ if (!gl) {
|
|||||||
glErrorShouldBe(gl, gl.NO_ERROR,
|
glErrorShouldBe(gl, gl.NO_ERROR,
|
||||||
"binding a newly created framebuffer should succeed.");
|
"binding a newly created framebuffer should succeed.");
|
||||||
|
|
||||||
var target = 0x8CA8; // GL_READ_FRAMEBUFFER
|
var target = desktopGL.READ_FRAMEBUFFER
|
||||||
gl.getFramebufferAttachmentParameter(
|
gl.getFramebufferAttachmentParameter(
|
||||||
target,
|
target,
|
||||||
gl.COLOR_ATTACHMENT0,
|
gl.COLOR_ATTACHMENT0,
|
||||||
@ -123,7 +124,7 @@ if (!gl) {
|
|||||||
glErrorShouldBe(gl, gl.INVALID_ENUM,
|
glErrorShouldBe(gl, gl.INVALID_ENUM,
|
||||||
"calling framebufferRenderbuffer with target = READ_FRAMEBUFFER should generate INVALID_ENUM.");
|
"calling framebufferRenderbuffer with target = READ_FRAMEBUFFER should generate INVALID_ENUM.");
|
||||||
|
|
||||||
var attachment = 0x8CE1; // GL_COLOR_ATTACHMENT1
|
var attachment = desktopGL.COLOR_ATTACHMENT1
|
||||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, fbtex, 0);
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, fbtex, 0);
|
||||||
glErrorShouldBe(gl, gl.INVALID_ENUM,
|
glErrorShouldBe(gl, gl.INVALID_ENUM,
|
||||||
"calling framebufferTexImage2D with attachment = COLOR_ATTACHMENT1 should generate INVALID_ENUM.");
|
"calling framebufferTexImage2D with attachment = COLOR_ATTACHMENT1 should generate INVALID_ENUM.");
|
||||||
@ -133,7 +134,7 @@ if (!gl) {
|
|||||||
|
|
||||||
gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER,
|
gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER,
|
||||||
gl.COLOR_ATTACHMENT0,
|
gl.COLOR_ATTACHMENT0,
|
||||||
0x8210); // GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
|
desktopGL.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
|
||||||
glErrorShouldBe(gl, gl.INVALID_ENUM,
|
glErrorShouldBe(gl, gl.INVALID_ENUM,
|
||||||
"calling getFramebufferAttachmentParameter with pname = GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING should generate INVALID_ENUM.");
|
"calling getFramebufferAttachmentParameter with pname = GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING should generate INVALID_ENUM.");
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@ found in the LICENSE file.
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description(document.title);
|
||||||
|
|
||||||
function checkDrawElements(mode, count, type, expect, msg) {
|
function checkDrawElements(mode, count, type, expect, msg) {
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
gl.drawElements(mode, count, type, 0);
|
gl.drawElements(mode, count, type, 0);
|
||||||
|
@ -72,6 +72,8 @@ There is supposed to be an example drawing here, but it's not important.
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description(document.title);
|
||||||
|
|
||||||
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
gl = initWebGL("example", "vshader", "fshader", [ "vPosition"], [ 0, 0, 0, 1 ], 1);
|
||||||
|
|
||||||
var vertexObject = gl.createBuffer();
|
var vertexObject = gl.createBuffer();
|
||||||
|
@ -394,11 +394,19 @@ var checkCanvasRect = function(gl, x, y, width, height, color, msg, errorRange)
|
|||||||
var offset = i * 4;
|
var offset = i * 4;
|
||||||
for (var j = 0; j < color.length; ++j) {
|
for (var j = 0; j < color.length; ++j) {
|
||||||
if (Math.abs(buf[offset + j] - color[j]) > errorRange) {
|
if (Math.abs(buf[offset + j] - color[j]) > errorRange) {
|
||||||
testFailed(msg);
|
|
||||||
var was = buf[offset + 0].toString();
|
var was = buf[offset + 0].toString();
|
||||||
for (j = 1; j < color.length; ++j) {
|
for (j = 1; j < color.length; ++j) {
|
||||||
was += "," + buf[offset + j];
|
was += "," + buf[offset + j];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cv = document.createElement('canvas');
|
||||||
|
cv.height = height;
|
||||||
|
cv.width = width;
|
||||||
|
var ctx = cv.getContext('2d');
|
||||||
|
ctx.fillStyle="rgba(" + color[0] + ", " + color[1] + ", " + color[2] + ", 255)";
|
||||||
|
ctx.fillRect(0, 0, width, height);
|
||||||
|
testFailedRender(msg, ctx, buf, width, height);
|
||||||
|
|
||||||
debug('at (' + (i % width) + ', ' + Math.floor(i / width) +
|
debug('at (' + (i % width) + ', ' + Math.floor(i / width) +
|
||||||
') expected: ' + color + ' was ' + was);
|
') expected: ' + color + ' was ' + was);
|
||||||
return;
|
return;
|
||||||
@ -591,8 +599,6 @@ var linkProgram = function(gl, program, opt_errorCallback) {
|
|||||||
testFailed("Error in program linking:" + error);
|
testFailed("Error in program linking:" + error);
|
||||||
|
|
||||||
gl.deleteProgram(program);
|
gl.deleteProgram(program);
|
||||||
//gl.deleteProgram(fragmentShader);
|
|
||||||
//gl.deleteProgram(vertexShader);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,10 +46,9 @@ function pass(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
debug("There should be 5 red triangles on 5 black squares above");
|
description("This test checks that drawImage and readPixels are not effected by gl.Pixelstorei(gl.PACK_ALIGNMENT) and visa versa");
|
||||||
debug("");
|
|
||||||
|
|
||||||
debug("This test checks that drawImage and readPixels are not effected by gl.Pixelstorei(gl.PACK_ALIGNMENT) and visa versa");
|
debug("There should be 5 red triangles on 5 black squares above");
|
||||||
debug("");
|
debug("");
|
||||||
|
|
||||||
var canvas3d = document.getElementById("example");
|
var canvas3d = document.getElementById("example");
|
||||||
|
@ -47,7 +47,7 @@ function init()
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Tests TexParameter works as expected");
|
description("Tests TexParameter works as expected");
|
||||||
debug("");
|
debug("");
|
||||||
|
|
||||||
var canvas2d = document.getElementById("canvas2d");
|
var canvas2d = document.getElementById("canvas2d");
|
||||||
|
@ -55,10 +55,10 @@ function init()
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Tests that binding both TEXTURE_2D and TEXTURE_CUBE_MAP to the same");
|
description(
|
||||||
debug("active texture unit works as long as they are not used");
|
"Tests that binding both TEXTURE_2D and TEXTURE_CUBE_MAP to the same" +
|
||||||
debug("simultaneously in the same shader program.");
|
"active texture unit works as long as they are not used" +
|
||||||
debug("");
|
"simultaneously in the same shader program.");
|
||||||
|
|
||||||
var canvas2d = document.getElementById("canvas2d");
|
var canvas2d = document.getElementById("canvas2d");
|
||||||
var ctx2d = canvas2d.getContext("2d");
|
var ctx2d = canvas2d.getContext("2d");
|
||||||
|
@ -38,9 +38,9 @@ function init()
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Tests that glActiveTexture and glBindTexture work as expected");
|
description(
|
||||||
debug("Specifically texture targets are per active texture unit.");
|
"Tests that glActiveTexture and glBindTexture work as expected" +
|
||||||
debug("");
|
"Specifically texture targets are per active texture unit.");
|
||||||
|
|
||||||
var canvas2d = document.getElementById("canvas2d");
|
var canvas2d = document.getElementById("canvas2d");
|
||||||
var ctx2d = canvas2d.getContext("2d");
|
var ctx2d = canvas2d.getContext("2d");
|
||||||
|
@ -25,9 +25,9 @@ function init()
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Checks that a texture that is not -texture-complete- does not draw if"+
|
description(
|
||||||
" filtering needs mips");
|
"Checks that a texture that is not -texture-complete- does not draw if"+
|
||||||
debug("");
|
" filtering needs mips");
|
||||||
|
|
||||||
var canvas2d = document.getElementById("canvas2d");
|
var canvas2d = document.getElementById("canvas2d");
|
||||||
var ctx2d = canvas2d.getContext("2d");
|
var ctx2d = canvas2d.getContext("2d");
|
||||||
|
@ -47,8 +47,7 @@ function init()
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Checks mip issues");
|
description("Checks mip issues");
|
||||||
debug("");
|
|
||||||
|
|
||||||
canvas = document.getElementById("example");
|
canvas = document.getElementById("example");
|
||||||
shouldBe("canvas.width", "2");
|
shouldBe("canvas.width", "2");
|
||||||
|
@ -38,6 +38,7 @@ void main()
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
|
description(document.title);
|
||||||
var wtu = WebGLTestUtils;
|
var wtu = WebGLTestUtils;
|
||||||
var canvas = document.getElementById("example");
|
var canvas = document.getElementById("example");
|
||||||
var gl = wtu.create3DContext(canvas);
|
var gl = wtu.create3DContext(canvas);
|
||||||
|
@ -25,9 +25,9 @@ function init()
|
|||||||
window.initNonKhronosFramework(false);
|
window.initNonKhronosFramework(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Tests that only Uniform1i and Uniform1iv can be used to set");
|
description(
|
||||||
debug("sampler uniforms.");
|
"Tests that only Uniform1i and Uniform1iv can be used to set" +
|
||||||
debug("");
|
"sampler uniforms.");
|
||||||
|
|
||||||
var canvas2d = document.getElementById("canvas2d");
|
var canvas2d = document.getElementById("canvas2d");
|
||||||
|
|
||||||
|
@ -8,3 +8,6 @@ conformance/textures/texture-mips.html
|
|||||||
conformance/uniforms/gl-uniform-bool.html
|
conformance/uniforms/gl-uniform-bool.html
|
||||||
conformance/more/conformance/quickCheckAPI-S_V.html
|
conformance/more/conformance/quickCheckAPI-S_V.html
|
||||||
conformance/more/functions/uniformfArrayLen1.html
|
conformance/more/functions/uniformfArrayLen1.html
|
||||||
|
conformance/glsl/misc/attrib-location-length-limits.html
|
||||||
|
conformance/glsl/misc/uniform-location-length-limits.html
|
||||||
|
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||||
|
@ -3,10 +3,11 @@ conformance/glsl/misc/glsl-function-nodes.html
|
|||||||
conformance/glsl/misc/glsl-long-variable-names.html
|
conformance/glsl/misc/glsl-long-variable-names.html
|
||||||
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
||||||
conformance/glsl/misc/shader-with-long-line.html
|
conformance/glsl/misc/shader-with-long-line.html
|
||||||
conformance/programs/program-test.html
|
|
||||||
conformance/state/gl-object-get-calls.html
|
|
||||||
conformance/textures/texture-mips.html
|
conformance/textures/texture-mips.html
|
||||||
conformance/textures/texture-npot.html
|
conformance/textures/texture-npot.html
|
||||||
conformance/more/conformance/quickCheckAPI-S_V.html
|
conformance/more/conformance/quickCheckAPI-S_V.html
|
||||||
conformance/more/functions/uniformfBadArgs.html
|
conformance/more/functions/uniformfBadArgs.html
|
||||||
conformance/more/functions/uniformiBadArgs.html
|
conformance/more/functions/uniformiBadArgs.html
|
||||||
|
conformance/glsl/misc/attrib-location-length-limits.html
|
||||||
|
conformance/glsl/misc/uniform-location-length-limits.html
|
||||||
|
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||||
|
@ -7,3 +7,7 @@ conformance/glsl/misc/shader-with-256-character-identifier.frag.html
|
|||||||
conformance/glsl/misc/shader-with-long-line.html
|
conformance/glsl/misc/shader-with-long-line.html
|
||||||
conformance/more/conformance/quickCheckAPI-S_V.html
|
conformance/more/conformance/quickCheckAPI-S_V.html
|
||||||
conformance/more/functions/uniformfArrayLen1.html
|
conformance/more/functions/uniformfArrayLen1.html
|
||||||
|
conformance/glsl/misc/attrib-location-length-limits.html
|
||||||
|
conformance/glsl/misc/struct-nesting-under-maximum.html
|
||||||
|
conformance/glsl/misc/uniform-location-length-limits.html
|
||||||
|
conformance/renderbuffers/framebuffer-object-attachment.html
|
||||||
|
@ -0,0 +1,181 @@
|
|||||||
|
# HG changeset patch
|
||||||
|
# Parent 2dbd71999fe8a8da476ab6cc97716f7b7c294fb8
|
||||||
|
# User Doug Sherk <dsherk@mozilla.com>
|
||||||
|
Bug 693703: added additional logging information for mochitests, incl. image reference differences r=bjacob
|
||||||
|
|
||||||
|
Added some code to print to dump output of WebGL mochitest failures. Also added
|
||||||
|
special code to handle incorrect reference images. It will now provide the user
|
||||||
|
with a way to compare the reference and actual drawings.
|
||||||
|
|
||||||
|
diff --git a/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html b/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
|
||||||
|
--- a/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
|
||||||
|
+++ b/content/canvas/test/webgl/conformance/glsl/misc/glsl-function-nodes.html
|
||||||
|
@@ -115,17 +115,18 @@ function init()
|
||||||
|
var bufFunction = new Uint8Array(width * height * 4);
|
||||||
|
var bufMacro = new Uint8Array(width * height * 4);
|
||||||
|
|
||||||
|
if (drawAndRead("canvasFunction", "vshaderFunction", bufFunction) == false ||
|
||||||
|
drawAndRead("canvasMacro", "vshaderMacro", bufMacro) == false) {
|
||||||
|
testFailed("Setup failed");
|
||||||
|
} else {
|
||||||
|
if (compareRendering(bufFunction, bufMacro, 4) == false)
|
||||||
|
- testFailed("Rendering results are different");
|
||||||
|
+ testFailedRender("Rendering results are different", bufMacro,
|
||||||
|
+ bufFunction, width, height);
|
||||||
|
else
|
||||||
|
testPassed("Rendering results are the same");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
successfullyParsed = true;
|
||||||
|
</script>
|
||||||
|
diff --git a/content/canvas/test/webgl/conformance/misc/uninitialized-test.html b/content/canvas/test/webgl/conformance/misc/uninitialized-test.html
|
||||||
|
--- a/content/canvas/test/webgl/conformance/misc/uninitialized-test.html
|
||||||
|
+++ b/content/canvas/test/webgl/conformance/misc/uninitialized-test.html
|
||||||
|
@@ -56,17 +56,19 @@ function checkNonZeroPixels(texture, tex
|
||||||
|
gl.readPixels(0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
||||||
|
|
||||||
|
var k = 0;
|
||||||
|
for (var y = 0; y < texHeight; ++y) {
|
||||||
|
for (var x = 0; x < texWidth; ++x) {
|
||||||
|
var index = (y * texWidth + x) * 4;
|
||||||
|
if (x >= skipX && x < skipX + skipWidth && y >= skipY && y < skipY + skipHeight) {
|
||||||
|
if (data[index] != skipR || data[index + 1] != skipG || data[index + 2] != skipB || data[index + 3] != skipA) {
|
||||||
|
- testFailed("non-zero pixel values are wrong");
|
||||||
|
+ testFailed("non-zero pixel values are wrong at (" + x + ", " + y + "), data was (" +
|
||||||
|
+ data[index] + "," + data[index + 1] + "," + data[index + 2] + "," + data[index + 3] +
|
||||||
|
+ ") should have been (" + skipR + "," + skipG + "," + skipB + "," + skipA + ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < 4; ++i) {
|
||||||
|
if (data[index + i] != 0)
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/content/canvas/test/webgl/conformance/resources/webgl-test-utils.js b/content/canvas/test/webgl/conformance/resources/webgl-test-utils.js
|
||||||
|
--- a/content/canvas/test/webgl/conformance/resources/webgl-test-utils.js
|
||||||
|
+++ b/content/canvas/test/webgl/conformance/resources/webgl-test-utils.js
|
||||||
|
@@ -389,21 +389,29 @@ var drawQuad = function(gl, opt_color) {
|
||||||
|
var checkCanvasRect = function(gl, x, y, width, height, color, msg, errorRange) {
|
||||||
|
errorRange = errorRange || 0;
|
||||||
|
var buf = new Uint8Array(width * height * 4);
|
||||||
|
gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
|
||||||
|
for (var i = 0; i < width * height; ++i) {
|
||||||
|
var offset = i * 4;
|
||||||
|
for (var j = 0; j < color.length; ++j) {
|
||||||
|
if (Math.abs(buf[offset + j] - color[j]) > errorRange) {
|
||||||
|
- testFailed(msg);
|
||||||
|
var was = buf[offset + 0].toString();
|
||||||
|
for (j = 1; j < color.length; ++j) {
|
||||||
|
was += "," + buf[offset + j];
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ var cv = document.createElement('canvas');
|
||||||
|
+ cv.height = height;
|
||||||
|
+ cv.width = width;
|
||||||
|
+ var ctx = cv.getContext('2d');
|
||||||
|
+ ctx.fillStyle="rgba(" + color[0] + ", " + color[1] + ", " + color[2] + ", 255)";
|
||||||
|
+ ctx.fillRect(0, 0, width, height);
|
||||||
|
+ testFailedRender(msg, ctx, buf, width, height);
|
||||||
|
+
|
||||||
|
debug('at (' + (i % width) + ', ' + Math.floor(i / width) +
|
||||||
|
') expected: ' + color + ' was ' + was);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testPassed(msg);
|
||||||
|
};
|
||||||
|
diff --git a/content/canvas/test/webgl/resources/js-test-pre.js b/content/canvas/test/webgl/resources/js-test-pre.js
|
||||||
|
--- a/content/canvas/test/webgl/resources/js-test-pre.js
|
||||||
|
+++ b/content/canvas/test/webgl/resources/js-test-pre.js
|
||||||
|
@@ -81,16 +81,87 @@ function testPassed(msg)
|
||||||
|
reportTestResultsToHarness(true, msg);
|
||||||
|
debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFailed(msg)
|
||||||
|
{
|
||||||
|
reportTestResultsToHarness(false, msg);
|
||||||
|
debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
|
||||||
|
+ dump('FAIL: ' + msg + '\n');
|
||||||
|
+
|
||||||
|
+ var stack = (new Error).stack.split('\n');
|
||||||
|
+ if (!stack.length) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dump('STACK TRACE: \n');
|
||||||
|
+
|
||||||
|
+ stack.pop();
|
||||||
|
+ var index = 0, frame, messages = new Array();
|
||||||
|
+ // Match all .html files and print out the line in them.
|
||||||
|
+ while (stack.length && index != -1) {
|
||||||
|
+ frame = stack.pop();
|
||||||
|
+ index = frame.indexOf(".html:");
|
||||||
|
+ if (index != -1) {
|
||||||
|
+ messages.unshift(frame);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Print out the first stack frame in JS and then stop.
|
||||||
|
+ if (stack.length) {
|
||||||
|
+ messages.unshift(stack.pop());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (message in messages) {
|
||||||
|
+ dump(messages[message] + '\n');
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function testFailedRender(msg, ref, test, width, height)
|
||||||
|
+{
|
||||||
|
+ var refData;
|
||||||
|
+ if (typeof ref.getImageData == 'function') {
|
||||||
|
+ refData = ref.canvas.toDataURL();
|
||||||
|
+ } else {
|
||||||
|
+ refData = arrayToURLData(ref, width, height);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ var testData;
|
||||||
|
+ if (typeof test.getImageData == 'function') {
|
||||||
|
+ testData = test.canvas.toDataURL();
|
||||||
|
+ } else {
|
||||||
|
+ testData = arrayToURLData(test, width, height);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ testFailed(msg);
|
||||||
|
+
|
||||||
|
+ var data = 'REFTEST TEST-UNEXPECTED-FAIL | ' + msg + ' | image comparison (==)\n' +
|
||||||
|
+ 'REFTEST IMAGE 1 (TEST): ' + testData + '\n' +
|
||||||
|
+ 'REFTEST IMAGE 2 (REFERENCE): ' + refData;
|
||||||
|
+ dump('FAIL: ' + data + '\n');
|
||||||
|
+ dump('To view the differences between these image renderings, go to the following link: https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/tools/reftest/reftest-analyzer.xhtml#log=' +
|
||||||
|
+ encodeURIComponent(encodeURIComponent(data)) + '\n');
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+function arrayToURLData(buf, width, height)
|
||||||
|
+{
|
||||||
|
+ var cv = document.createElement('canvas');
|
||||||
|
+ cv.height = height;
|
||||||
|
+ cv.width = width;
|
||||||
|
+ var ctx = cv.getContext('2d');
|
||||||
|
+ var imgd = ctx.getImageData(0, 0, width, height);
|
||||||
|
+ for (i = 0; i < height * width; ++i) {
|
||||||
|
+ offset = i * 4;
|
||||||
|
+ for (j = 0; j < 4; j++) {
|
||||||
|
+ imgd.data[offset + j] = buf[offset + j];
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ ctx.putImageData(imgd, 0, 0);
|
||||||
|
+ return cv.toDataURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
function areArraysEqual(_a, _b)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (_a.length !== _b.length)
|
||||||
|
return false;
|
||||||
|
for (var i = 0; i < _a.length; i++)
|
@ -86,6 +86,77 @@ function testFailed(msg)
|
|||||||
{
|
{
|
||||||
reportTestResultsToHarness(false, msg);
|
reportTestResultsToHarness(false, msg);
|
||||||
debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
|
debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
|
||||||
|
dump('FAIL: ' + msg + '\n');
|
||||||
|
|
||||||
|
var stack = (new Error).stack.split('\n');
|
||||||
|
if (!stack.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dump('STACK TRACE: \n');
|
||||||
|
|
||||||
|
stack.pop();
|
||||||
|
var index = 0, frame, messages = new Array();
|
||||||
|
// Match all .html files and print out the line in them.
|
||||||
|
while (stack.length && index != -1) {
|
||||||
|
frame = stack.pop();
|
||||||
|
index = frame.indexOf(".html:");
|
||||||
|
if (index != -1) {
|
||||||
|
messages.unshift(frame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print out the first stack frame in JS and then stop.
|
||||||
|
if (stack.length) {
|
||||||
|
messages.unshift(stack.pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (message in messages) {
|
||||||
|
dump(messages[message] + '\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFailedRender(msg, ref, test, width, height)
|
||||||
|
{
|
||||||
|
var refData;
|
||||||
|
if (typeof ref.getImageData == 'function') {
|
||||||
|
refData = ref.canvas.toDataURL();
|
||||||
|
} else {
|
||||||
|
refData = arrayToURLData(ref, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
var testData;
|
||||||
|
if (typeof test.getImageData == 'function') {
|
||||||
|
testData = test.canvas.toDataURL();
|
||||||
|
} else {
|
||||||
|
testData = arrayToURLData(test, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
testFailed(msg);
|
||||||
|
|
||||||
|
var data = 'REFTEST TEST-UNEXPECTED-FAIL | ' + msg + ' | image comparison (==)\n' +
|
||||||
|
'REFTEST IMAGE 1 (TEST): ' + testData + '\n' +
|
||||||
|
'REFTEST IMAGE 2 (REFERENCE): ' + refData;
|
||||||
|
dump('FAIL: ' + data + '\n');
|
||||||
|
dump('To view the differences between these image renderings, go to the following link: https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/tools/reftest/reftest-analyzer.xhtml#log=' +
|
||||||
|
encodeURIComponent(encodeURIComponent(data)) + '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrayToURLData(buf, width, height)
|
||||||
|
{
|
||||||
|
var cv = document.createElement('canvas');
|
||||||
|
cv.height = height;
|
||||||
|
cv.width = width;
|
||||||
|
var ctx = cv.getContext('2d');
|
||||||
|
var imgd = ctx.getImageData(0, 0, width, height);
|
||||||
|
for (i = 0; i < height * width; ++i) {
|
||||||
|
offset = i * 4;
|
||||||
|
for (j = 0; j < 4; j++) {
|
||||||
|
imgd.data[offset + j] = buf[offset + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.putImageData(imgd, 0, 0);
|
||||||
|
return cv.toDataURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
function areArraysEqual(_a, _b)
|
function areArraysEqual(_a, _b)
|
||||||
|
@ -211,10 +211,14 @@ function start() {
|
|||||||
|
|
||||||
Reporter.prototype.startPage = function(url) {
|
Reporter.prototype.startPage = function(url) {
|
||||||
dump('WebGL mochitest: starting page ' + url + '\n');
|
dump('WebGL mochitest: starting page ' + url + '\n');
|
||||||
if (kIsLinux) {
|
|
||||||
dump('Calling garbageCollect()\n');
|
// Calling garbageCollect before each test page fixes intermittent failures with
|
||||||
SpecialPowers.DOMWindowUtils.garbageCollect();
|
// out-of-memory errors, often failing to create a WebGL context.
|
||||||
}
|
// The explanation is that the JS engine keeps unreferenced WebGL contexts around
|
||||||
|
// for too long before GCing (bug 617453), so that during this mochitest dozens of unreferenced
|
||||||
|
// WebGL contexts can accumulate at a given time.
|
||||||
|
SpecialPowers.DOMWindowUtils.garbageCollect();
|
||||||
|
|
||||||
var page = this.pagesByURL[url];
|
var page = this.pagesByURL[url];
|
||||||
this.currentPage = page;
|
this.currentPage = page;
|
||||||
statusTextNode.textContent = 'Running URL: ' + url;
|
statusTextNode.textContent = 'Running URL: ' + url;
|
||||||
|
@ -294,6 +294,12 @@ function start() {
|
|||||||
this.contextInfo["ALPHA_BITS"] = ctx.getParameter(ctx.ALPHA_BITS);
|
this.contextInfo["ALPHA_BITS"] = ctx.getParameter(ctx.ALPHA_BITS);
|
||||||
this.contextInfo["DEPTH_BITS"] = ctx.getParameter(ctx.DEPTH_BITS);
|
this.contextInfo["DEPTH_BITS"] = ctx.getParameter(ctx.DEPTH_BITS);
|
||||||
this.contextInfo["STENCIL_BITS"] = ctx.getParameter(ctx.STENCIL_BITS);
|
this.contextInfo["STENCIL_BITS"] = ctx.getParameter(ctx.STENCIL_BITS);
|
||||||
|
|
||||||
|
var ext = ctx.getExtension("WEBGL_debug_renderer_info");
|
||||||
|
if (ext) {
|
||||||
|
this.contextInfo["UNMASKED_VENDOR"] = ctx.getParameter(ext.UNMASKED_VENDOR_WEBGL);
|
||||||
|
this.contextInfo["UNMASKED_RENDERER"] = ctx.getParameter(ext.UNMASKED_RENDERER_WEBGL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -364,6 +370,8 @@ function start() {
|
|||||||
tx += "WebGL VENDOR: " + this.contextInfo["VENDOR"] + "\n";
|
tx += "WebGL VENDOR: " + this.contextInfo["VENDOR"] + "\n";
|
||||||
tx += "WebGL VERSION: " + this.contextInfo["VERSION"] + "\n";
|
tx += "WebGL VERSION: " + this.contextInfo["VERSION"] + "\n";
|
||||||
tx += "WebGL RENDERER: " + this.contextInfo["RENDERER"] + "\n";
|
tx += "WebGL RENDERER: " + this.contextInfo["RENDERER"] + "\n";
|
||||||
|
tx += "Unmasked VENDOR: " + this.contextInfo["UNMASKED_VENDOR"] + "\n";
|
||||||
|
tx += "Unmasked RENDERER: " + this.contextInfo["UNMASKED_RENDERER"] + "\n";
|
||||||
tx += "WebGL R/G/B/A/Depth/Stencil bits (default config): " + this.contextInfo["RED_BITS"] + "/" + this.contextInfo["GREEN_BITS"] + "/" + this.contextInfo["BLUE_BITS"] + "/" + this.contextInfo["ALPHA_BITS"] + "/" + this.contextInfo["DEPTH_BITS"] + "/" + this.contextInfo["STENCIL_BITS"] + "\n";
|
tx += "WebGL R/G/B/A/Depth/Stencil bits (default config): " + this.contextInfo["RED_BITS"] + "/" + this.contextInfo["GREEN_BITS"] + "/" + this.contextInfo["BLUE_BITS"] + "/" + this.contextInfo["ALPHA_BITS"] + "/" + this.contextInfo["DEPTH_BITS"] + "/" + this.contextInfo["STENCIL_BITS"] + "\n";
|
||||||
tx += "\n";
|
tx += "\n";
|
||||||
tx += "-------------------\n\n";
|
tx += "-------------------\n\n";
|
||||||
|
@ -95,6 +95,21 @@ SVGPathSegListSMILType::IsEqual(const nsSMILValue& aLeft,
|
|||||||
*static_cast<const SVGPathDataAndOwner*>(aRight.mU.mPtr);
|
*static_cast<const SVGPathDataAndOwner*>(aRight.mU.mPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ArcFlagsDiffer(SVGPathDataAndOwner::const_iterator aPathData1,
|
||||||
|
SVGPathDataAndOwner::const_iterator aPathData2)
|
||||||
|
{
|
||||||
|
NS_ABORT_IF_FALSE
|
||||||
|
(SVGPathSegUtils::IsArcType(SVGPathSegUtils::DecodeType(aPathData1[0])),
|
||||||
|
"ArcFlagsDiffer called with non-arc segment");
|
||||||
|
NS_ABORT_IF_FALSE
|
||||||
|
(SVGPathSegUtils::IsArcType(SVGPathSegUtils::DecodeType(aPathData2[0])),
|
||||||
|
"ArcFlagsDiffer called with non-arc segment");
|
||||||
|
|
||||||
|
return aPathData1[LARGE_ARC_FLAG_IDX] != aPathData2[LARGE_ARC_FLAG_IDX] ||
|
||||||
|
aPathData1[SWEEP_FLAG_IDX] != aPathData2[SWEEP_FLAG_IDX];
|
||||||
|
}
|
||||||
|
|
||||||
enum PathInterpolationResult {
|
enum PathInterpolationResult {
|
||||||
eCannotInterpolate,
|
eCannotInterpolate,
|
||||||
eRequiresConversion,
|
eRequiresConversion,
|
||||||
@ -124,6 +139,12 @@ CanInterpolate(const SVGPathDataAndOwner& aStart,
|
|||||||
PRUint32 startType = SVGPathSegUtils::DecodeType(*pStart);
|
PRUint32 startType = SVGPathSegUtils::DecodeType(*pStart);
|
||||||
PRUint32 endType = SVGPathSegUtils::DecodeType(*pEnd);
|
PRUint32 endType = SVGPathSegUtils::DecodeType(*pEnd);
|
||||||
|
|
||||||
|
if (SVGPathSegUtils::IsArcType(startType) &&
|
||||||
|
SVGPathSegUtils::IsArcType(endType) &&
|
||||||
|
ArcFlagsDiffer(pStart, pEnd)) {
|
||||||
|
return eCannotInterpolate;
|
||||||
|
}
|
||||||
|
|
||||||
if (startType != endType) {
|
if (startType != endType) {
|
||||||
if (!SVGPathSegUtils::SameTypeModuloRelativeness(startType, endType)) {
|
if (!SVGPathSegUtils::SameTypeModuloRelativeness(startType, endType)) {
|
||||||
return eCannotInterpolate;
|
return eCannotInterpolate;
|
||||||
@ -194,22 +215,25 @@ AddWeightedPathSegs(double aCoeff1,
|
|||||||
NS_ABORT_IF_FALSE(!aSeg1 || SVGPathSegUtils::DecodeType(*aSeg1) == segType,
|
NS_ABORT_IF_FALSE(!aSeg1 || SVGPathSegUtils::DecodeType(*aSeg1) == segType,
|
||||||
"unexpected segment type");
|
"unexpected segment type");
|
||||||
|
|
||||||
|
// FIRST: Directly copy the arguments that don't make sense to add.
|
||||||
aResultSeg[0] = aSeg2[0]; // encoded segment type
|
aResultSeg[0] = aSeg2[0]; // encoded segment type
|
||||||
|
|
||||||
// FIRST: Add all the arguments.
|
bool isArcType = SVGPathSegUtils::IsArcType(segType);
|
||||||
|
if (isArcType) {
|
||||||
|
// Copy boolean arc flags.
|
||||||
|
NS_ABORT_IF_FALSE(!aSeg1 || !ArcFlagsDiffer(aSeg1, aSeg2),
|
||||||
|
"Expecting arc flags to match");
|
||||||
|
aResultSeg[LARGE_ARC_FLAG_IDX] = aSeg2[LARGE_ARC_FLAG_IDX];
|
||||||
|
aResultSeg[SWEEP_FLAG_IDX] = aSeg2[SWEEP_FLAG_IDX];
|
||||||
|
}
|
||||||
|
|
||||||
|
// SECOND: Add the arguments that are supposed to be added.
|
||||||
// (The 1's below are to account for segment type)
|
// (The 1's below are to account for segment type)
|
||||||
PRUint32 numArgs = SVGPathSegUtils::ArgCountForType(segType);
|
PRUint32 numArgs = SVGPathSegUtils::ArgCountForType(segType);
|
||||||
for (PRUint32 i = 1; i < 1 + numArgs; ++i) {
|
for (PRUint32 i = 1; i < 1 + numArgs; ++i) {
|
||||||
aResultSeg[i] = (aSeg1 ? aCoeff1 * aSeg1[i] : 0.0) + aCoeff2 * aSeg2[i];
|
// Need to skip arc flags for arc-type segments. (already handled them)
|
||||||
}
|
if (!(isArcType && (i == LARGE_ARC_FLAG_IDX || i == SWEEP_FLAG_IDX))) {
|
||||||
|
aResultSeg[i] = (aSeg1 ? aCoeff1 * aSeg1[i] : 0.0) + aCoeff2 * aSeg2[i];
|
||||||
// SECOND: ensure non-zero flags become 1.
|
|
||||||
if (SVGPathSegUtils::IsArcType(segType)) {
|
|
||||||
if (aResultSeg[LARGE_ARC_FLAG_IDX] != 0.0f) {
|
|
||||||
aResultSeg[LARGE_ARC_FLAG_IDX] = 1.0f;
|
|
||||||
}
|
|
||||||
if (aResultSeg[SWEEP_FLAG_IDX] != 0.0f) {
|
|
||||||
aResultSeg[SWEEP_FLAG_IDX] = 1.0f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,10 +138,10 @@ var gSuffixes = {
|
|||||||
[40, 50, 60, 70, 80, 90], [50, 70, 90, 110, 130, 150]],
|
[40, 50, 60, 70, 80, 90], [50, 70, 90, 110, 130, 150]],
|
||||||
QQ: [[10, 20, 30, 40], [50, 60, 70, 80], [30, 40, 50, 60], [40, 60, 80, 100]],
|
QQ: [[10, 20, 30, 40], [50, 60, 70, 80], [30, 40, 50, 60], [40, 60, 80, 100]],
|
||||||
qq: [[10, 20, 30, 40], [50, 60, 70, 80], [30, 40, 50, 60], [40, 60, 80, 100]],
|
qq: [[10, 20, 30, 40], [50, 60, 70, 80], [30, 40, 50, 60], [40, 60, 80, 100]],
|
||||||
AA: [[10, 20, 30, 1, 0, 40, 50], [60, 70, 80, 0, 0, 90, 100],
|
AA: [[10, 20, 30, 0, 0, 40, 50], [60, 70, 80, 0, 0, 90, 100],
|
||||||
[35, 45, 55, 1, 0, 65, 75], [45, 65, 85, 1, 0, 105, 125]],
|
[35, 45, 55, 0, 0, 65, 75], [45, 65, 85, 0, 0, 105, 125]],
|
||||||
aa: [[10, 20, 30, 0, 1, 40, 50], [60, 70, 80, 0, 0, 90, 100],
|
aa: [[10, 20, 30, 0, 0, 40, 50], [60, 70, 80, 0, 0, 90, 100],
|
||||||
[35, 45, 55, 0, 1, 65, 75], [45, 65, 85, 0, 1, 105, 125]],
|
[35, 45, 55, 0, 0, 65, 75], [45, 65, 85, 0, 0, 105, 125]],
|
||||||
HH: [[10], [20], [15], [25]],
|
HH: [[10], [20], [15], [25]],
|
||||||
hh: [[10], [20], [15], [25]],
|
hh: [[10], [20], [15], [25]],
|
||||||
VV: [[10], [20], [15], [25]],
|
VV: [[10], [20], [15], [25]],
|
||||||
@ -286,6 +286,17 @@ function run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test that differences in arc flag parameters cause the
|
||||||
|
// interpolation/addition not to occur.
|
||||||
|
addTest(1, "M100,100",
|
||||||
|
"A", [10, 20, 30, 0, 0, 40, 50],
|
||||||
|
"a", [60, 70, 80, 0, 1, 90, 100],
|
||||||
|
"a", [60, 70, 80, 0, 1, 90, 100], additive);
|
||||||
|
addTest(1, "M100,100",
|
||||||
|
"A", [10, 20, 30, 0, 0, 40, 50],
|
||||||
|
"a", [60, 70, 80, 1, 0, 90, 100],
|
||||||
|
"a", [60, 70, 80, 1, 0, 90, 100], additive);
|
||||||
|
|
||||||
// Test all pairs of segment types that cannot be interpolated between.
|
// Test all pairs of segment types that cannot be interpolated between.
|
||||||
for each (let fromType in gTypes) {
|
for each (let fromType in gTypes) {
|
||||||
let fromArguments = generatePathSegmentArguments(fromType, 0);
|
let fromArguments = generatePathSegmentArguments(fromType, 0);
|
||||||
|
@ -72,6 +72,7 @@ endif
|
|||||||
|
|
||||||
DIRS += \
|
DIRS += \
|
||||||
base \
|
base \
|
||||||
|
battery \
|
||||||
src \
|
src \
|
||||||
locales \
|
locales \
|
||||||
plugins/base \
|
plugins/base \
|
||||||
|
@ -122,6 +122,7 @@ CPPSRCS = \
|
|||||||
nsDOMNavigationTiming.cpp \
|
nsDOMNavigationTiming.cpp \
|
||||||
nsPerformance.cpp \
|
nsPerformance.cpp \
|
||||||
nsDOMMemoryReporter.cpp \
|
nsDOMMemoryReporter.cpp \
|
||||||
|
Navigator.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/dom/dom-config.mk
|
include $(topsrcdir)/dom/dom-config.mk
|
||||||
|
891
dom/base/Navigator.cpp
Normal file
891
dom/base/Navigator.cpp
Normal file
@ -0,0 +1,891 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set sw=2 ts=2 et tw=78: */
|
||||||
|
/* ***** 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 mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Travis Bogard <travis@netscape.com>
|
||||||
|
* Brendan Eich <brendan@mozilla.org>
|
||||||
|
* David Hyatt (hyatt@netscape.com)
|
||||||
|
* Dan Rosen <dr@netscape.com>
|
||||||
|
* Vidur Apparao <vidur@netscape.com>
|
||||||
|
* Johnny Stenback <jst@netscape.com>
|
||||||
|
* Mark Hammond <mhammond@skippinet.com.au>
|
||||||
|
* Ryan Jones <sciguyryan@gmail.com>
|
||||||
|
* Jeff Walden <jwalden+code@mit.edu>
|
||||||
|
* Ben Bucksch <ben.bucksch beonex.com>
|
||||||
|
* Emanuele Costa <emanuele.costa@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of 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 ***** */
|
||||||
|
|
||||||
|
// Needs to be first.
|
||||||
|
#include "base/basictypes.h"
|
||||||
|
|
||||||
|
#include "Navigator.h"
|
||||||
|
#include "nsIXULAppInfo.h"
|
||||||
|
#include "nsPluginArray.h"
|
||||||
|
#include "nsMimeTypeArray.h"
|
||||||
|
#include "nsDesktopNotification.h"
|
||||||
|
#include "nsGeolocation.h"
|
||||||
|
#include "nsIHttpProtocolHandler.h"
|
||||||
|
#include "nsICachingChannel.h"
|
||||||
|
#include "nsIDocShell.h"
|
||||||
|
#include "nsIWebContentHandlerRegistrar.h"
|
||||||
|
#include "nsICookiePermission.h"
|
||||||
|
#include "nsIScriptSecurityManager.h"
|
||||||
|
#include "nsIJSContextStack.h"
|
||||||
|
#include "nsCharSeparatedTokenizer.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsUnicharUtils.h"
|
||||||
|
#include "mozilla/Preferences.h"
|
||||||
|
#include "mozilla/Telemetry.h"
|
||||||
|
#include "BatteryManager.h"
|
||||||
|
|
||||||
|
// This should not be in the namespace.
|
||||||
|
DOMCI_DATA(Navigator, mozilla::dom::Navigator)
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
static const char sJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
|
||||||
|
bool Navigator::sDoNotTrackEnabled = false;
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
void
|
||||||
|
Navigator::Init()
|
||||||
|
{
|
||||||
|
Preferences::AddBoolVarCache(&sDoNotTrackEnabled,
|
||||||
|
"privacy.donottrackheader.enabled",
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator::Navigator(nsIDocShell* aDocShell)
|
||||||
|
: mDocShell(aDocShell)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator::~Navigator()
|
||||||
|
{
|
||||||
|
if (mMimeTypes) {
|
||||||
|
mMimeTypes->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPlugins) {
|
||||||
|
mPlugins->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBatteryManager) {
|
||||||
|
mBatteryManager->Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN(Navigator)
|
||||||
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorBattery)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorDesktopNotification)
|
||||||
|
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
|
||||||
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF(Navigator)
|
||||||
|
NS_IMPL_RELEASE(Navigator)
|
||||||
|
|
||||||
|
void
|
||||||
|
Navigator::SetDocShell(nsIDocShell* aDocShell)
|
||||||
|
{
|
||||||
|
mDocShell = aDocShell;
|
||||||
|
|
||||||
|
if (mPlugins) {
|
||||||
|
mPlugins->SetDocShell(aDocShell);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is a page transition, make sure delete the geolocation object.
|
||||||
|
if (mGeolocation) {
|
||||||
|
mGeolocation->Shutdown();
|
||||||
|
mGeolocation = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNotification) {
|
||||||
|
mNotification->Shutdown();
|
||||||
|
mNotification = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBatteryManager) {
|
||||||
|
mBatteryManager->Shutdown();
|
||||||
|
mBatteryManager = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Navigator::nsIDOMNavigator
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetUserAgent(nsAString& aUserAgent)
|
||||||
|
{
|
||||||
|
return NS_GetNavigatorUserAgent(aUserAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetAppCodeName(nsAString& aAppCodeName)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpProtocolHandler>
|
||||||
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCAutoString appName;
|
||||||
|
rv = service->GetAppName(appName);
|
||||||
|
CopyASCIItoUTF16(appName, aAppCodeName);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetAppVersion(nsAString& aAppVersion)
|
||||||
|
{
|
||||||
|
return NS_GetNavigatorAppVersion(aAppVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetAppName(nsAString& aAppName)
|
||||||
|
{
|
||||||
|
return NS_GetNavigatorAppName(aAppName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JS property navigator.language, exposed to web content.
|
||||||
|
* Take first value from Accept-Languages (HTTP header), which is
|
||||||
|
* the "content language" freely set by the user in the Pref window.
|
||||||
|
*
|
||||||
|
* Do not use UI language (chosen app locale) here.
|
||||||
|
* See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers"
|
||||||
|
*
|
||||||
|
* "en", "en-US" and "i-cherokee" and "" are valid.
|
||||||
|
* Fallback in case of invalid pref should be "" (empty string), to
|
||||||
|
* let site do fallback, e.g. to site's local language.
|
||||||
|
*/
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetLanguage(nsAString& aLanguage)
|
||||||
|
{
|
||||||
|
// E.g. "de-de, en-us,en".
|
||||||
|
const nsAdoptingString& acceptLang =
|
||||||
|
Preferences::GetLocalizedString("intl.accept_languages");
|
||||||
|
|
||||||
|
// Take everything before the first "," or ";", without trailing space.
|
||||||
|
nsCharSeparatedTokenizer langTokenizer(acceptLang, ',');
|
||||||
|
const nsSubstring &firstLangPart = langTokenizer.nextToken();
|
||||||
|
nsCharSeparatedTokenizer qTokenizer(firstLangPart, ';');
|
||||||
|
aLanguage.Assign(qTokenizer.nextToken());
|
||||||
|
|
||||||
|
// Checks and fixups:
|
||||||
|
// replace "_" with "-" to avoid POSIX/Windows "en_US" notation.
|
||||||
|
if (aLanguage.Length() > 2 && aLanguage[2] == PRUnichar('_')) {
|
||||||
|
aLanguage.Replace(2, 1, PRUnichar('-')); // TODO replace all
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use uppercase for country part, e.g. "en-US", not "en-us", see BCP47
|
||||||
|
// only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe".
|
||||||
|
if (aLanguage.Length() <= 2) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCharSeparatedTokenizer localeTokenizer(aLanguage, '-');
|
||||||
|
PRInt32 pos = 0;
|
||||||
|
bool first = true;
|
||||||
|
while (localeTokenizer.hasMoreTokens()) {
|
||||||
|
const nsSubstring& code = localeTokenizer.nextToken();
|
||||||
|
|
||||||
|
if (code.Length() == 2 && !first) {
|
||||||
|
nsAutoString upper(code);
|
||||||
|
ToUpperCase(upper);
|
||||||
|
aLanguage.Replace(pos, code.Length(), upper);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += code.Length() + 1; // 1 is the separator
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetPlatform(nsAString& aPlatform)
|
||||||
|
{
|
||||||
|
return NS_GetNavigatorPlatform(aPlatform);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetOscpu(nsAString& aOSCPU)
|
||||||
|
{
|
||||||
|
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
|
const nsAdoptingString& override =
|
||||||
|
Preferences::GetString("general.oscpu.override");
|
||||||
|
|
||||||
|
if (override) {
|
||||||
|
aOSCPU = override;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpProtocolHandler>
|
||||||
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCAutoString oscpu;
|
||||||
|
rv = service->GetOscpu(oscpu);
|
||||||
|
CopyASCIItoUTF16(oscpu, aOSCPU);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetVendor(nsAString& aVendor)
|
||||||
|
{
|
||||||
|
aVendor.Truncate();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetVendorSub(nsAString& aVendorSub)
|
||||||
|
{
|
||||||
|
aVendorSub.Truncate();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetProduct(nsAString& aProduct)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpProtocolHandler>
|
||||||
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCAutoString product;
|
||||||
|
rv = service->GetProduct(product);
|
||||||
|
CopyASCIItoUTF16(product, aProduct);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetProductSub(nsAString& aProductSub)
|
||||||
|
{
|
||||||
|
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
|
const nsAdoptingString& override =
|
||||||
|
Preferences::GetString("general.productSub.override");
|
||||||
|
|
||||||
|
if (override) {
|
||||||
|
aProductSub = override;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'general.useragent.productSub' backwards compatible with 1.8 branch.
|
||||||
|
const nsAdoptingString& override2 =
|
||||||
|
Preferences::GetString("general.useragent.productSub");
|
||||||
|
|
||||||
|
if (override2) {
|
||||||
|
aProductSub = override2;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpProtocolHandler>
|
||||||
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCAutoString productSub;
|
||||||
|
rv = service->GetProductSub(productSub);
|
||||||
|
CopyASCIItoUTF16(productSub, aProductSub);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetMimeTypes(nsIDOMMimeTypeArray** aMimeTypes)
|
||||||
|
{
|
||||||
|
if (!mMimeTypes) {
|
||||||
|
mMimeTypes = new nsMimeTypeArray(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ADDREF(*aMimeTypes = mMimeTypes);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetPlugins(nsIDOMPluginArray** aPlugins)
|
||||||
|
{
|
||||||
|
if (!mPlugins) {
|
||||||
|
mPlugins = new nsPluginArray(this, mDocShell);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ADDREF(*aPlugins = mPlugins);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values for the network.cookie.cookieBehavior pref are documented in
|
||||||
|
// nsCookieService.cpp.
|
||||||
|
#define COOKIE_BEHAVIOR_REJECT 2
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetCookieEnabled(bool* aCookieEnabled)
|
||||||
|
{
|
||||||
|
*aCookieEnabled =
|
||||||
|
(Preferences::GetInt("network.cookie.cookieBehavior",
|
||||||
|
COOKIE_BEHAVIOR_REJECT) != COOKIE_BEHAVIOR_REJECT);
|
||||||
|
|
||||||
|
// Check whether an exception overrides the global cookie behavior
|
||||||
|
// Note that the code for getting the URI here matches that in
|
||||||
|
// nsHTMLDocument::SetCookie.
|
||||||
|
nsCOMPtr<nsIDocument> doc = do_GetInterface(mDocShell);
|
||||||
|
if (!doc) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> codebaseURI;
|
||||||
|
doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));
|
||||||
|
|
||||||
|
if (!codebaseURI) {
|
||||||
|
// Not a codebase, so technically can't set cookies, but let's
|
||||||
|
// just return the default value.
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsICookiePermission> permMgr =
|
||||||
|
do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
|
||||||
|
NS_ENSURE_TRUE(permMgr, NS_OK);
|
||||||
|
|
||||||
|
// Pass null for the channel, just like the cookie service does.
|
||||||
|
nsCookieAccess access;
|
||||||
|
nsresult rv = permMgr->CanAccess(codebaseURI, nsnull, &access);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||||
|
|
||||||
|
if (access != nsICookiePermission::ACCESS_DEFAULT) {
|
||||||
|
*aCookieEnabled = access != nsICookiePermission::ACCESS_DENY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetOnLine(bool* aOnline)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aOnline, "Null out param");
|
||||||
|
|
||||||
|
*aOnline = !NS_IsOffline();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetBuildID(nsAString& aBuildID)
|
||||||
|
{
|
||||||
|
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
|
const nsAdoptingString& override =
|
||||||
|
Preferences::GetString("general.buildID.override");
|
||||||
|
|
||||||
|
if (override) {
|
||||||
|
aBuildID = override;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIXULAppInfo> appInfo =
|
||||||
|
do_GetService("@mozilla.org/xre/app-info;1");
|
||||||
|
if (!appInfo) {
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCAutoString buildID;
|
||||||
|
nsresult rv = appInfo->GetAppBuildID(buildID);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
aBuildID.Truncate();
|
||||||
|
AppendASCIItoUTF16(buildID, aBuildID);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetDoNotTrack(nsAString &aResult)
|
||||||
|
{
|
||||||
|
if (sDoNotTrackEnabled) {
|
||||||
|
aResult.AssignLiteral("yes");
|
||||||
|
} else {
|
||||||
|
aResult.AssignLiteral("unspecified");
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::JavaEnabled(bool* aReturn)
|
||||||
|
{
|
||||||
|
Telemetry::AutoTimer<Telemetry::CHECK_JAVA_ENABLED> telemetryTimer;
|
||||||
|
// Return true if we have a handler for "application/x-java-vm",
|
||||||
|
// otherwise return false.
|
||||||
|
*aReturn = false;
|
||||||
|
|
||||||
|
if (!mMimeTypes) {
|
||||||
|
mMimeTypes = new nsMimeTypeArray(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshMIMEArray();
|
||||||
|
|
||||||
|
PRUint32 count;
|
||||||
|
mMimeTypes->GetLength(&count);
|
||||||
|
for (PRUint32 i = 0; i < count; i++) {
|
||||||
|
nsresult rv;
|
||||||
|
nsIDOMMimeType* type = mMimeTypes->GetItemAt(i, &rv);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv) || !type) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsAutoString mimeString;
|
||||||
|
if (NS_FAILED(type->GetType(mimeString))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mimeString.EqualsLiteral("application/x-java-vm")) {
|
||||||
|
*aReturn = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Navigator::LoadingNewDocument()
|
||||||
|
{
|
||||||
|
// Release these so that they will be recreated for the
|
||||||
|
// new document (if requested). The plugins or mime types
|
||||||
|
// arrays may have changed. See bug 150087.
|
||||||
|
if (mMimeTypes) {
|
||||||
|
mMimeTypes->Invalidate();
|
||||||
|
mMimeTypes = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPlugins) {
|
||||||
|
mPlugins->Invalidate();
|
||||||
|
mPlugins = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGeolocation) {
|
||||||
|
mGeolocation->Shutdown();
|
||||||
|
mGeolocation = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNotification) {
|
||||||
|
mNotification->Shutdown();
|
||||||
|
mNotification = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mBatteryManager) {
|
||||||
|
mBatteryManager->Shutdown();
|
||||||
|
mBatteryManager = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
Navigator::RefreshMIMEArray()
|
||||||
|
{
|
||||||
|
if (mMimeTypes) {
|
||||||
|
return mMimeTypes->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Navigator::HasDesktopNotificationSupport()
|
||||||
|
{
|
||||||
|
return Preferences::GetBool("notification.feature.enabled", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Navigator::nsIDOMClientInformation
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::RegisterContentHandler(const nsAString& aMIMEType,
|
||||||
|
const nsAString& aURI,
|
||||||
|
const nsAString& aTitle)
|
||||||
|
{
|
||||||
|
if (!mDocShell) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
|
||||||
|
do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
|
||||||
|
if (!registrar) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMWindow> contentDOMWindow = do_GetInterface(mDocShell);
|
||||||
|
if (!contentDOMWindow) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return registrar->RegisterContentHandler(aMIMEType, aURI, aTitle,
|
||||||
|
contentDOMWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::RegisterProtocolHandler(const nsAString& aProtocol,
|
||||||
|
const nsAString& aURI,
|
||||||
|
const nsAString& aTitle)
|
||||||
|
{
|
||||||
|
if (!mDocShell) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
|
||||||
|
do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
|
||||||
|
if (!registrar) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMWindow> contentDOMWindow = do_GetInterface(mDocShell);
|
||||||
|
if (!contentDOMWindow) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return registrar->RegisterProtocolHandler(aProtocol, aURI, aTitle,
|
||||||
|
contentDOMWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::MozIsLocallyAvailable(const nsAString &aURI,
|
||||||
|
bool aWhenOffline,
|
||||||
|
bool* aIsAvailable)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIURI> uri;
|
||||||
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// This method of checking the cache will only work for http/https urls.
|
||||||
|
bool match;
|
||||||
|
rv = uri->SchemeIs("http", &match);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
rv = uri->SchemeIs("https", &match);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
if (!match) {
|
||||||
|
return NS_ERROR_DOM_BAD_URI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same origin check.
|
||||||
|
nsCOMPtr<nsIJSContextStack> stack = do_GetService(sJSStackContractID);
|
||||||
|
NS_ENSURE_TRUE(stack, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
JSContext* cx = nsnull;
|
||||||
|
rv = stack->Peek(&cx);
|
||||||
|
NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
rv = nsContentUtils::GetSecurityManager()->CheckSameOrigin(cx, uri);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// These load flags cause an error to be thrown if there is no
|
||||||
|
// valid cache entry, and skip the load if there is.
|
||||||
|
// If the cache is busy, assume that it is not yet available rather
|
||||||
|
// than waiting for it to become available.
|
||||||
|
PRUint32 loadFlags = nsIChannel::INHIBIT_CACHING |
|
||||||
|
nsICachingChannel::LOAD_NO_NETWORK_IO |
|
||||||
|
nsICachingChannel::LOAD_ONLY_IF_MODIFIED |
|
||||||
|
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
|
||||||
|
|
||||||
|
if (aWhenOffline) {
|
||||||
|
loadFlags |= nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE |
|
||||||
|
nsICachingChannel::LOAD_ONLY_FROM_CACHE |
|
||||||
|
nsIRequest::LOAD_FROM_CACHE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIChannel> channel;
|
||||||
|
rv = NS_NewChannel(getter_AddRefs(channel), uri,
|
||||||
|
nsnull, nsnull, nsnull, loadFlags);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> stream;
|
||||||
|
rv = channel->Open(getter_AddRefs(stream));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
stream->Close();
|
||||||
|
|
||||||
|
nsresult status;
|
||||||
|
rv = channel->GetStatus(&status);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (NS_FAILED(status)) {
|
||||||
|
*aIsAvailable = false;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
||||||
|
return httpChannel->GetRequestSucceeded(aIsAvailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Navigator::nsIDOMNavigatorGeolocation
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
NS_IMETHODIMP Navigator::GetGeolocation(nsIDOMGeoGeolocation** _retval)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(_retval);
|
||||||
|
*_retval = nsnull;
|
||||||
|
|
||||||
|
if (!Preferences::GetBool("geo.enabled", true)) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGeolocation) {
|
||||||
|
NS_ADDREF(*_retval = mGeolocation);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mDocShell) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMWindow> contentDOMWindow = do_GetInterface(mDocShell);
|
||||||
|
if (!contentDOMWindow) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mGeolocation = new nsGeolocation();
|
||||||
|
if (!mGeolocation) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_FAILED(mGeolocation->Init(contentDOMWindow))) {
|
||||||
|
mGeolocation = nsnull;
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ADDREF(*_retval = mGeolocation);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Navigator::nsIDOMNavigatorDesktopNotification
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
NS_IMETHODIMP Navigator::GetMozNotification(nsIDOMDesktopNotificationCenter** aRetVal)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aRetVal);
|
||||||
|
*aRetVal = nsnull;
|
||||||
|
|
||||||
|
if (mNotification) {
|
||||||
|
NS_ADDREF(*aRetVal = mNotification);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(mDocShell);
|
||||||
|
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDocument> document = do_GetInterface(mDocShell);
|
||||||
|
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsIScriptGlobalObject* sgo = document->GetScopeObject();
|
||||||
|
NS_ENSURE_TRUE(sgo, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
nsIScriptContext* scx = sgo->GetContext();
|
||||||
|
NS_ENSURE_TRUE(scx, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
mNotification = new nsDesktopNotificationCenter(window->GetCurrentInnerWindow(),
|
||||||
|
scx);
|
||||||
|
|
||||||
|
NS_ADDREF(*aRetVal = mNotification);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Navigator::nsIDOMNavigatorBattery
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
Navigator::GetMozBattery(nsIDOMBatteryManager** aBattery)
|
||||||
|
{
|
||||||
|
if (!mBatteryManager) {
|
||||||
|
mBatteryManager = new battery::BatteryManager();
|
||||||
|
mBatteryManager->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ADDREF(*aBattery = mBatteryManager);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRInt64
|
||||||
|
Navigator::SizeOf() const
|
||||||
|
{
|
||||||
|
PRInt64 size = sizeof(*this);
|
||||||
|
|
||||||
|
// TODO: add SizeOf() to nsMimeTypeArray, bug 674113.
|
||||||
|
size += mMimeTypes ? sizeof(*mMimeTypes.get()) : 0;
|
||||||
|
// TODO: add SizeOf() to nsPluginArray, bug 674114.
|
||||||
|
size += mPlugins ? sizeof(*mPlugins.get()) : 0;
|
||||||
|
// TODO: add SizeOf() to nsGeolocation, bug 674115.
|
||||||
|
size += mGeolocation ? sizeof(*mGeolocation.get()) : 0;
|
||||||
|
// TODO: add SizeOf() to nsDesktopNotificationCenter, bug 674116.
|
||||||
|
size += mNotification ? sizeof(*mNotification.get()) : 0;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_GetNavigatorUserAgent(nsAString& aUserAgent)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpProtocolHandler>
|
||||||
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCAutoString ua;
|
||||||
|
rv = service->GetUserAgent(ua);
|
||||||
|
CopyASCIItoUTF16(ua, aUserAgent);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_GetNavigatorPlatform(nsAString& aPlatform)
|
||||||
|
{
|
||||||
|
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
|
const nsAdoptingString& override =
|
||||||
|
mozilla::Preferences::GetString("general.platform.override");
|
||||||
|
|
||||||
|
if (override) {
|
||||||
|
aPlatform = override;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpProtocolHandler>
|
||||||
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// Sorry for the #if platform ugliness, but Communicator is likewise
|
||||||
|
// hardcoded and we are seeking backward compatibility here (bug 47080).
|
||||||
|
#if defined(_WIN64)
|
||||||
|
aPlatform.AssignLiteral("Win64");
|
||||||
|
#elif defined(WIN32)
|
||||||
|
aPlatform.AssignLiteral("Win32");
|
||||||
|
#elif defined(XP_MACOSX) && defined(__ppc__)
|
||||||
|
aPlatform.AssignLiteral("MacPPC");
|
||||||
|
#elif defined(XP_MACOSX) && defined(__i386__)
|
||||||
|
aPlatform.AssignLiteral("MacIntel");
|
||||||
|
#elif defined(XP_MACOSX) && defined(__x86_64__)
|
||||||
|
aPlatform.AssignLiteral("MacIntel");
|
||||||
|
#elif defined(XP_OS2)
|
||||||
|
aPlatform.AssignLiteral("OS/2");
|
||||||
|
#else
|
||||||
|
// XXX Communicator uses compiled-in build-time string defines
|
||||||
|
// to indicate the platform it was compiled *for*, not what it is
|
||||||
|
// currently running *on* which is what this does.
|
||||||
|
nsCAutoString plat;
|
||||||
|
rv = service->GetOscpu(plat);
|
||||||
|
CopyASCIItoUTF16(plat, aPlatform);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
nsresult
|
||||||
|
NS_GetNavigatorAppVersion(nsAString& aAppVersion)
|
||||||
|
{
|
||||||
|
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
|
const nsAdoptingString& override =
|
||||||
|
mozilla::Preferences::GetString("general.appversion.override");
|
||||||
|
|
||||||
|
if (override) {
|
||||||
|
aAppVersion = override;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIHttpProtocolHandler>
|
||||||
|
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCAutoString str;
|
||||||
|
rv = service->GetAppVersion(str);
|
||||||
|
CopyASCIItoUTF16(str, aAppVersion);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
aAppVersion.AppendLiteral(" (");
|
||||||
|
|
||||||
|
rv = service->GetPlatform(str);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
AppendASCIItoUTF16(str, aAppVersion);
|
||||||
|
aAppVersion.Append(PRUnichar(')'));
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_GetNavigatorAppName(nsAString& aAppName)
|
||||||
|
{
|
||||||
|
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
||||||
|
const nsAdoptingString& override =
|
||||||
|
mozilla::Preferences::GetString("general.appname.override");
|
||||||
|
|
||||||
|
if (override) {
|
||||||
|
aAppName = override;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aAppName.AssignLiteral("Netscape");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
121
dom/base/Navigator.h
Normal file
121
dom/base/Navigator.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set ts=2 sw=2 et tw=80: */
|
||||||
|
/* ***** 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 mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Travis Bogard <travis@netscape.com>
|
||||||
|
* Dan Rosen <dr@netscape.com>
|
||||||
|
* Vidur Apparao <vidur@netscape.com>
|
||||||
|
* Johnny Stenback <jst@netscape.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of 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 ***** */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_Navigator_h
|
||||||
|
#define mozilla_dom_Navigator_h
|
||||||
|
|
||||||
|
#include "nsIDOMNavigator.h"
|
||||||
|
#include "nsIDOMNavigatorGeolocation.h"
|
||||||
|
#include "nsIDOMNavigatorDesktopNotification.h"
|
||||||
|
#include "nsIDOMClientInformation.h"
|
||||||
|
#include "nsIDOMNavigatorBattery.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
|
||||||
|
class nsPluginArray;
|
||||||
|
class nsMimeTypeArray;
|
||||||
|
class nsGeolocation;
|
||||||
|
class nsDesktopNotificationCenter;
|
||||||
|
class nsIDocShell;
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// Navigator: Script "navigator" object
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
namespace battery {
|
||||||
|
class BatteryManager;
|
||||||
|
} // namespace battery
|
||||||
|
|
||||||
|
class Navigator : public nsIDOMNavigator,
|
||||||
|
public nsIDOMClientInformation,
|
||||||
|
public nsIDOMNavigatorGeolocation,
|
||||||
|
public nsIDOMNavigatorDesktopNotification,
|
||||||
|
public nsIDOMNavigatorBattery
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Navigator(nsIDocShell *aDocShell);
|
||||||
|
virtual ~Navigator();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIDOMNAVIGATOR
|
||||||
|
NS_DECL_NSIDOMCLIENTINFORMATION
|
||||||
|
NS_DECL_NSIDOMNAVIGATORGEOLOCATION
|
||||||
|
NS_DECL_NSIDOMNAVIGATORDESKTOPNOTIFICATION
|
||||||
|
NS_DECL_NSIDOMNAVIGATORBATTERY
|
||||||
|
|
||||||
|
static void Init();
|
||||||
|
|
||||||
|
void SetDocShell(nsIDocShell *aDocShell);
|
||||||
|
nsIDocShell *GetDocShell()
|
||||||
|
{
|
||||||
|
return mDocShell;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadingNewDocument();
|
||||||
|
nsresult RefreshMIMEArray();
|
||||||
|
|
||||||
|
static bool HasDesktopNotificationSupport();
|
||||||
|
|
||||||
|
PRInt64 SizeOf() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool sDoNotTrackEnabled;
|
||||||
|
|
||||||
|
nsRefPtr<nsMimeTypeArray> mMimeTypes;
|
||||||
|
nsRefPtr<nsPluginArray> mPlugins;
|
||||||
|
nsRefPtr<nsGeolocation> mGeolocation;
|
||||||
|
nsRefPtr<nsDesktopNotificationCenter> mNotification;
|
||||||
|
nsRefPtr<battery::BatteryManager> mBatteryManager;
|
||||||
|
nsIDocShell* mDocShell; // weak reference
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
|
||||||
|
nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
|
||||||
|
nsresult NS_GetNavigatorAppVersion(nsAString& aAppVersion);
|
||||||
|
nsresult NS_GetNavigatorAppName(nsAString& aAppName);
|
||||||
|
|
||||||
|
#endif // mozilla_dom_Navigator_h
|
@ -470,6 +470,11 @@
|
|||||||
|
|
||||||
#include "nsIDOMDesktopNotification.h"
|
#include "nsIDOMDesktopNotification.h"
|
||||||
#include "nsIDOMNavigatorDesktopNotification.h"
|
#include "nsIDOMNavigatorDesktopNotification.h"
|
||||||
|
#include "nsIDOMNavigatorGeolocation.h"
|
||||||
|
#include "Navigator.h"
|
||||||
|
|
||||||
|
#include "nsPluginArray.h"
|
||||||
|
#include "nsMimeTypeArray.h"
|
||||||
|
|
||||||
// Simple gestures include
|
// Simple gestures include
|
||||||
#include "nsIDOMSimpleGestureEvent.h"
|
#include "nsIDOMSimpleGestureEvent.h"
|
||||||
@ -506,6 +511,8 @@
|
|||||||
#include "nsWrapperCacheInlines.h"
|
#include "nsWrapperCacheInlines.h"
|
||||||
#include "dombindings.h"
|
#include "dombindings.h"
|
||||||
|
|
||||||
|
#include "nsIDOMBatteryManager.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
@ -1380,7 +1387,10 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||||||
|
|
||||||
NS_DEFINE_CLASSINFO_DATA(GeoPositionError, nsDOMGenericSH,
|
NS_DEFINE_CLASSINFO_DATA(GeoPositionError, nsDOMGenericSH,
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
|
|
||||||
|
NS_DEFINE_CLASSINFO_DATA(BatteryManager, nsDOMGenericSH,
|
||||||
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
|
|
||||||
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
|
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
|
||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceStyleDecl, nsCSSStyleDeclSH,
|
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceStyleDecl, nsCSSStyleDeclSH,
|
||||||
@ -2278,8 +2288,9 @@ nsDOMClassInfo::Init()
|
|||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigator)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorGeolocation)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorGeolocation)
|
||||||
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMNavigatorDesktopNotification,
|
DOM_CLASSINFO_MAP_CONDITIONAL_ENTRY(nsIDOMNavigatorDesktopNotification,
|
||||||
nsNavigator::HasDesktopNotificationSupport())
|
Navigator::HasDesktopNotificationSupport())
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientInformation)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMClientInformation)
|
||||||
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNavigatorBattery)
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
DOM_CLASSINFO_MAP_BEGIN(Plugin, nsIDOMPlugin)
|
DOM_CLASSINFO_MAP_BEGIN(Plugin, nsIDOMPlugin)
|
||||||
@ -3859,6 +3870,11 @@ nsDOMClassInfo::Init()
|
|||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionError)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionError)
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
|
DOM_CLASSINFO_MAP_BEGIN(BatteryManager, nsIDOMBatteryManager)
|
||||||
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBatteryManager)
|
||||||
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||||
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
|
DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
@ -7131,7 +7147,7 @@ nsNavigatorSH::PreCreate(nsISupports *nativeObj, JSContext *cx,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsNavigator *nav = (nsNavigator *)safeNav.get();
|
Navigator *nav = static_cast<Navigator*>(safeNav.get());
|
||||||
nsIDocShell *ds = nav->GetDocShell();
|
nsIDocShell *ds = nav->GetDocShell();
|
||||||
if (!ds) {
|
if (!ds) {
|
||||||
NS_WARNING("Refusing to create a navigator in the wrong scope");
|
NS_WARNING("Refusing to create a navigator in the wrong scope");
|
||||||
|
@ -428,6 +428,8 @@ DOMCI_CLASS(GeoPositionCoords)
|
|||||||
DOMCI_CLASS(GeoPositionAddress)
|
DOMCI_CLASS(GeoPositionAddress)
|
||||||
DOMCI_CLASS(GeoPositionError)
|
DOMCI_CLASS(GeoPositionError)
|
||||||
|
|
||||||
|
DOMCI_CLASS(BatteryManager)
|
||||||
|
|
||||||
// @font-face in CSS
|
// @font-face in CSS
|
||||||
DOMCI_CLASS(CSSFontFaceRule)
|
DOMCI_CLASS(CSSFontFaceRule)
|
||||||
DOMCI_CLASS(CSSFontFaceStyleDecl)
|
DOMCI_CLASS(CSSFontFaceStyleDecl)
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
|
|
||||||
// Local Includes
|
// Local Includes
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
|
#include "Navigator.h"
|
||||||
#include "nsScreen.h"
|
#include "nsScreen.h"
|
||||||
#include "nsHistory.h"
|
#include "nsHistory.h"
|
||||||
#include "nsPerformance.h"
|
#include "nsPerformance.h"
|
||||||
@ -277,7 +278,6 @@ static bool gDragServiceDisabled = false;
|
|||||||
static FILE *gDumpFile = nsnull;
|
static FILE *gDumpFile = nsnull;
|
||||||
static PRUint64 gNextWindowID = 0;
|
static PRUint64 gNextWindowID = 0;
|
||||||
static PRUint32 gSerialCounter = 0;
|
static PRUint32 gSerialCounter = 0;
|
||||||
static bool gDoNotTrackEnabled = false;
|
|
||||||
|
|
||||||
#ifdef DEBUG_jst
|
#ifdef DEBUG_jst
|
||||||
PRInt32 gTimeoutCnt = 0;
|
PRInt32 gTimeoutCnt = 0;
|
||||||
@ -962,10 +962,6 @@ nsGlobalWindow::Init()
|
|||||||
NS_ASSERTION(gEntropyCollector,
|
NS_ASSERTION(gEntropyCollector,
|
||||||
"gEntropyCollector should have been initialized!");
|
"gEntropyCollector should have been initialized!");
|
||||||
|
|
||||||
mozilla::Preferences::AddBoolVarCache(&gDoNotTrackEnabled,
|
|
||||||
"privacy.donottrackheader.enabled",
|
|
||||||
false);
|
|
||||||
|
|
||||||
#ifdef PR_LOGGING
|
#ifdef PR_LOGGING
|
||||||
gDOMLeakPRLog = PR_NewLogModule("DOMLeak");
|
gDOMLeakPRLog = PR_NewLogModule("DOMLeak");
|
||||||
NS_ASSERTION(gDOMLeakPRLog, "gDOMLeakPRLog should have been initialized!");
|
NS_ASSERTION(gDOMLeakPRLog, "gDOMLeakPRLog should have been initialized!");
|
||||||
@ -1737,7 +1733,7 @@ public:
|
|||||||
|
|
||||||
WindowStateHolder(nsGlobalWindow *aWindow,
|
WindowStateHolder(nsGlobalWindow *aWindow,
|
||||||
nsIXPConnectJSObjectHolder *aHolder,
|
nsIXPConnectJSObjectHolder *aHolder,
|
||||||
nsNavigator *aNavigator,
|
Navigator *aNavigator,
|
||||||
nsIXPConnectJSObjectHolder *aOuterProto,
|
nsIXPConnectJSObjectHolder *aOuterProto,
|
||||||
nsIXPConnectJSObjectHolder *aOuterRealProto);
|
nsIXPConnectJSObjectHolder *aOuterRealProto);
|
||||||
|
|
||||||
@ -1745,7 +1741,7 @@ public:
|
|||||||
nsIXPConnectJSObjectHolder *GetInnerWindowHolder()
|
nsIXPConnectJSObjectHolder *GetInnerWindowHolder()
|
||||||
{ return mInnerWindowHolder; }
|
{ return mInnerWindowHolder; }
|
||||||
|
|
||||||
nsNavigator* GetNavigator() { return mNavigator; }
|
Navigator* GetNavigator() { return mNavigator; }
|
||||||
nsIXPConnectJSObjectHolder* GetOuterProto() { return mOuterProto; }
|
nsIXPConnectJSObjectHolder* GetOuterProto() { return mOuterProto; }
|
||||||
nsIXPConnectJSObjectHolder* GetOuterRealProto() { return mOuterRealProto; }
|
nsIXPConnectJSObjectHolder* GetOuterRealProto() { return mOuterRealProto; }
|
||||||
|
|
||||||
@ -1766,7 +1762,7 @@ protected:
|
|||||||
// We hold onto this to make sure the inner window doesn't go away. The outer
|
// We hold onto this to make sure the inner window doesn't go away. The outer
|
||||||
// window ends up recalculating it anyway.
|
// window ends up recalculating it anyway.
|
||||||
nsCOMPtr<nsIXPConnectJSObjectHolder> mInnerWindowHolder;
|
nsCOMPtr<nsIXPConnectJSObjectHolder> mInnerWindowHolder;
|
||||||
nsRefPtr<nsNavigator> mNavigator;
|
nsRefPtr<Navigator> mNavigator;
|
||||||
nsCOMPtr<nsIXPConnectJSObjectHolder> mOuterProto;
|
nsCOMPtr<nsIXPConnectJSObjectHolder> mOuterProto;
|
||||||
nsCOMPtr<nsIXPConnectJSObjectHolder> mOuterRealProto;
|
nsCOMPtr<nsIXPConnectJSObjectHolder> mOuterRealProto;
|
||||||
};
|
};
|
||||||
@ -1775,7 +1771,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(WindowStateHolder, WINDOWSTATEHOLDER_IID)
|
|||||||
|
|
||||||
WindowStateHolder::WindowStateHolder(nsGlobalWindow *aWindow,
|
WindowStateHolder::WindowStateHolder(nsGlobalWindow *aWindow,
|
||||||
nsIXPConnectJSObjectHolder *aHolder,
|
nsIXPConnectJSObjectHolder *aHolder,
|
||||||
nsNavigator *aNavigator,
|
Navigator *aNavigator,
|
||||||
nsIXPConnectJSObjectHolder *aOuterProto,
|
nsIXPConnectJSObjectHolder *aOuterProto,
|
||||||
nsIXPConnectJSObjectHolder *aOuterRealProto)
|
nsIXPConnectJSObjectHolder *aOuterRealProto)
|
||||||
: mInnerWindow(aWindow),
|
: mInnerWindow(aWindow),
|
||||||
@ -3009,10 +3005,7 @@ nsGlobalWindow::GetNavigator(nsIDOMNavigator** aNavigator)
|
|||||||
*aNavigator = nsnull;
|
*aNavigator = nsnull;
|
||||||
|
|
||||||
if (!mNavigator) {
|
if (!mNavigator) {
|
||||||
mNavigator = new nsNavigator(mDocShell);
|
mNavigator = new Navigator(mDocShell);
|
||||||
if (!mNavigator) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ADDREF(*aNavigator = mNavigator);
|
NS_ADDREF(*aNavigator = mNavigator);
|
||||||
@ -9366,25 +9359,27 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
|||||||
|
|
||||||
// If we're running pending timeouts because they've been temporarily
|
// If we're running pending timeouts because they've been temporarily
|
||||||
// disabled (!aTimeout), set the next interval to be relative to "now",
|
// disabled (!aTimeout), set the next interval to be relative to "now",
|
||||||
// and not to when the timeout that was pending should have fired. Also
|
// and not to when the timeout that was pending should have fired.
|
||||||
// check if the next interval timeout is overdue. If so, then restart
|
|
||||||
// the interval from now.
|
|
||||||
TimeStamp firingTime;
|
TimeStamp firingTime;
|
||||||
if (!aTimeout || timeout->mWhen + nextInterval <= now)
|
if (!aTimeout)
|
||||||
firingTime = now + nextInterval;
|
firingTime = now + nextInterval;
|
||||||
else
|
else
|
||||||
firingTime = timeout->mWhen + nextInterval;
|
firingTime = timeout->mWhen + nextInterval;
|
||||||
|
|
||||||
TimeDuration delay = firingTime - TimeStamp::Now();
|
TimeStamp currentNow = TimeStamp::Now();
|
||||||
|
TimeDuration delay = firingTime - currentNow;
|
||||||
|
|
||||||
// And make sure delay is nonnegative; that might happen if the timer
|
// And make sure delay is nonnegative; that might happen if the timer
|
||||||
// thread is firing our timers somewhat early.
|
// thread is firing our timers somewhat early or if they're taking a long
|
||||||
|
// time to run the callback.
|
||||||
if (delay < TimeDuration(0)) {
|
if (delay < TimeDuration(0)) {
|
||||||
delay = TimeDuration(0);
|
delay = TimeDuration(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout->mTimer) {
|
if (timeout->mTimer) {
|
||||||
timeout->mWhen = firingTime;
|
timeout->mWhen = currentNow + delay; // firingTime unless delay got
|
||||||
|
// clamped, in which case it's
|
||||||
|
// currentNow.
|
||||||
|
|
||||||
// Reschedule the OS timer. Don't bother returning any error
|
// Reschedule the OS timer. Don't bother returning any error
|
||||||
// codes if this fails since the callers of this method
|
// codes if this fails since the callers of this method
|
||||||
@ -10704,748 +10699,6 @@ NS_NewScriptGlobalObject(bool aIsChrome, bool aIsModalContentWindow,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
//*** nsNavigator: Object Management
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
nsNavigator::nsNavigator(nsIDocShell *aDocShell)
|
|
||||||
: mDocShell(aDocShell)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
nsNavigator::~nsNavigator()
|
|
||||||
{
|
|
||||||
if (mMimeTypes)
|
|
||||||
mMimeTypes->Invalidate();
|
|
||||||
if (mPlugins)
|
|
||||||
mPlugins->Invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// nsNavigator::nsISupports
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
|
|
||||||
DOMCI_DATA(Navigator, nsNavigator)
|
|
||||||
|
|
||||||
// QueryInterface implementation for nsNavigator
|
|
||||||
NS_INTERFACE_MAP_BEGIN(nsNavigator)
|
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMNavigator)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNavigator)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIDOMClientInformation)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorGeolocation)
|
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNavigatorDesktopNotification)
|
|
||||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Navigator)
|
|
||||||
NS_INTERFACE_MAP_END
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF(nsNavigator)
|
|
||||||
NS_IMPL_RELEASE(nsNavigator)
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
nsNavigator::SetDocShell(nsIDocShell *aDocShell)
|
|
||||||
{
|
|
||||||
mDocShell = aDocShell;
|
|
||||||
if (mPlugins)
|
|
||||||
mPlugins->SetDocShell(aDocShell);
|
|
||||||
|
|
||||||
// if there is a page transition, make sure delete the geolocation object
|
|
||||||
if (mGeolocation)
|
|
||||||
{
|
|
||||||
mGeolocation->Shutdown();
|
|
||||||
mGeolocation = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mNotification)
|
|
||||||
{
|
|
||||||
mNotification->Shutdown();
|
|
||||||
mNotification = nsnull;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// nsNavigator::nsIDOMNavigator
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_GetNavigatorUserAgent(nsAString& aUserAgent)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIHttpProtocolHandler>
|
|
||||||
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
nsCAutoString ua;
|
|
||||||
rv = service->GetUserAgent(ua);
|
|
||||||
CopyASCIItoUTF16(ua, aUserAgent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_GetNavigatorPlatform(nsAString& aPlatform)
|
|
||||||
{
|
|
||||||
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
|
||||||
const nsAdoptingString& override =
|
|
||||||
Preferences::GetString("general.platform.override");
|
|
||||||
|
|
||||||
if (override) {
|
|
||||||
aPlatform = override;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIHttpProtocolHandler>
|
|
||||||
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
// sorry for the #if platform ugliness, but Communicator is
|
|
||||||
// likewise hardcoded and we're seeking backward compatibility
|
|
||||||
// here (bug 47080)
|
|
||||||
#if defined(_WIN64)
|
|
||||||
aPlatform.AssignLiteral("Win64");
|
|
||||||
#elif defined(WIN32)
|
|
||||||
aPlatform.AssignLiteral("Win32");
|
|
||||||
#elif defined(XP_MACOSX) && defined(__ppc__)
|
|
||||||
aPlatform.AssignLiteral("MacPPC");
|
|
||||||
#elif defined(XP_MACOSX) && defined(__i386__)
|
|
||||||
aPlatform.AssignLiteral("MacIntel");
|
|
||||||
#elif defined(XP_MACOSX) && defined(__x86_64__)
|
|
||||||
aPlatform.AssignLiteral("MacIntel");
|
|
||||||
#elif defined(XP_OS2)
|
|
||||||
aPlatform.AssignLiteral("OS/2");
|
|
||||||
#else
|
|
||||||
// XXX Communicator uses compiled-in build-time string defines
|
|
||||||
// to indicate the platform it was compiled *for*, not what it is
|
|
||||||
// currently running *on* which is what this does.
|
|
||||||
nsCAutoString plat;
|
|
||||||
rv = service->GetOscpu(plat);
|
|
||||||
CopyASCIItoUTF16(plat, aPlatform);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
nsresult
|
|
||||||
NS_GetNavigatorAppVersion(nsAString& aAppVersion)
|
|
||||||
{
|
|
||||||
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
|
||||||
const nsAdoptingString& override =
|
|
||||||
Preferences::GetString("general.appversion.override");
|
|
||||||
|
|
||||||
if (override) {
|
|
||||||
aAppVersion = override;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIHttpProtocolHandler>
|
|
||||||
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
nsCAutoString str;
|
|
||||||
rv = service->GetAppVersion(str);
|
|
||||||
CopyASCIItoUTF16(str, aAppVersion);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
aAppVersion.AppendLiteral(" (");
|
|
||||||
|
|
||||||
rv = service->GetPlatform(str);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
AppendASCIItoUTF16(str, aAppVersion);
|
|
||||||
|
|
||||||
aAppVersion.Append(PRUnichar(')'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_GetNavigatorAppName(nsAString& aAppName)
|
|
||||||
{
|
|
||||||
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
|
||||||
const nsAdoptingString& override =
|
|
||||||
Preferences::GetString("general.appname.override");
|
|
||||||
|
|
||||||
if (override) {
|
|
||||||
aAppName = override;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aAppName.AssignLiteral("Netscape");
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetUserAgent(nsAString& aUserAgent)
|
|
||||||
{
|
|
||||||
return NS_GetNavigatorUserAgent(aUserAgent);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetAppCodeName(nsAString& aAppCodeName)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIHttpProtocolHandler>
|
|
||||||
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
nsCAutoString appName;
|
|
||||||
rv = service->GetAppName(appName);
|
|
||||||
CopyASCIItoUTF16(appName, aAppCodeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetAppVersion(nsAString& aAppVersion)
|
|
||||||
{
|
|
||||||
return NS_GetNavigatorAppVersion(aAppVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetAppName(nsAString& aAppName)
|
|
||||||
{
|
|
||||||
return NS_GetNavigatorAppName(aAppName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JS property navigator.language, exposed to web content.
|
|
||||||
* Take first value from Accept-Languages (HTTP header), which is
|
|
||||||
* the "content language" freely set by the user in the Pref window.
|
|
||||||
*
|
|
||||||
* Do not use UI language (chosen app locale) here.
|
|
||||||
* See RFC 2616, Section 15.1.4 "Privacy Issues Connected to Accept Headers"
|
|
||||||
*
|
|
||||||
* "en", "en-US" and "i-cherokee" and "" are valid.
|
|
||||||
* Fallback in case of invalid pref should be "" (empty string), to
|
|
||||||
* let site do fallback, e.g. to site's local language.
|
|
||||||
*/
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetLanguage(nsAString& aLanguage)
|
|
||||||
{
|
|
||||||
// e.g. "de-de, en-us,en"
|
|
||||||
const nsAdoptingString& acceptLang =
|
|
||||||
Preferences::GetLocalizedString("intl.accept_languages");
|
|
||||||
// take everything before the first "," or ";", without trailing space
|
|
||||||
nsCharSeparatedTokenizer langTokenizer(acceptLang, ',');
|
|
||||||
const nsSubstring &firstLangPart = langTokenizer.nextToken();
|
|
||||||
nsCharSeparatedTokenizer qTokenizer(firstLangPart, ';');
|
|
||||||
aLanguage.Assign(qTokenizer.nextToken());
|
|
||||||
|
|
||||||
// checks and fixups
|
|
||||||
// replace "_" with "-", to avoid POSIX/Windows "en_US" notation
|
|
||||||
if (aLanguage.Length() > 2 && aLanguage[2] == PRUnichar('_'))
|
|
||||||
aLanguage.Replace(2, 1, PRUnichar('-')); // TODO replace all
|
|
||||||
// use uppercase for country part, e.g. "en-US", not "en-us", see BCP47
|
|
||||||
// only uppercase 2-letter country codes, not "zh-Hant", "de-DE-x-goethe"
|
|
||||||
if (aLanguage.Length() > 2)
|
|
||||||
{
|
|
||||||
nsCharSeparatedTokenizer localeTokenizer(aLanguage, '-');
|
|
||||||
PRInt32 pos = 0;
|
|
||||||
bool first = true;
|
|
||||||
while (localeTokenizer.hasMoreTokens())
|
|
||||||
{
|
|
||||||
const nsSubstring &code = localeTokenizer.nextToken();
|
|
||||||
if (code.Length() == 2 && !first)
|
|
||||||
{
|
|
||||||
nsAutoString upper(code);
|
|
||||||
::ToUpperCase(upper);
|
|
||||||
aLanguage.Replace(pos, code.Length(), upper);
|
|
||||||
}
|
|
||||||
pos += code.Length() + 1; // 1 is the separator
|
|
||||||
if (first)
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetPlatform(nsAString& aPlatform)
|
|
||||||
{
|
|
||||||
return NS_GetNavigatorPlatform(aPlatform);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetOscpu(nsAString& aOSCPU)
|
|
||||||
{
|
|
||||||
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
|
||||||
const nsAdoptingString& override =
|
|
||||||
Preferences::GetString("general.oscpu.override");
|
|
||||||
|
|
||||||
if (override) {
|
|
||||||
aOSCPU = override;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIHttpProtocolHandler>
|
|
||||||
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
nsCAutoString oscpu;
|
|
||||||
rv = service->GetOscpu(oscpu);
|
|
||||||
CopyASCIItoUTF16(oscpu, aOSCPU);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetVendor(nsAString& aVendor)
|
|
||||||
{
|
|
||||||
aVendor.Truncate();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetVendorSub(nsAString& aVendorSub)
|
|
||||||
{
|
|
||||||
aVendorSub.Truncate();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetProduct(nsAString& aProduct)
|
|
||||||
{
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIHttpProtocolHandler>
|
|
||||||
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
nsCAutoString product;
|
|
||||||
rv = service->GetProduct(product);
|
|
||||||
CopyASCIItoUTF16(product, aProduct);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetProductSub(nsAString& aProductSub)
|
|
||||||
{
|
|
||||||
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
|
||||||
const nsAdoptingString& override =
|
|
||||||
Preferences::GetString("general.productSub.override");
|
|
||||||
|
|
||||||
if (override) {
|
|
||||||
aProductSub = override;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 'general.useragent.productSub' backwards compatible with 1.8 branch.
|
|
||||||
const nsAdoptingString& override2 =
|
|
||||||
Preferences::GetString("general.useragent.productSub");
|
|
||||||
|
|
||||||
if (override2) {
|
|
||||||
aProductSub = override2;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult rv;
|
|
||||||
nsCOMPtr<nsIHttpProtocolHandler>
|
|
||||||
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
nsCAutoString productSub;
|
|
||||||
rv = service->GetProductSub(productSub);
|
|
||||||
CopyASCIItoUTF16(productSub, aProductSub);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetMimeTypes(nsIDOMMimeTypeArray **aMimeTypes)
|
|
||||||
{
|
|
||||||
if (!mMimeTypes) {
|
|
||||||
mMimeTypes = new nsMimeTypeArray(this);
|
|
||||||
if (!mMimeTypes) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*aMimeTypes = mMimeTypes);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetPlugins(nsIDOMPluginArray **aPlugins)
|
|
||||||
{
|
|
||||||
if (!mPlugins) {
|
|
||||||
mPlugins = new nsPluginArray(this, mDocShell);
|
|
||||||
if (!mPlugins) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*aPlugins = mPlugins);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// values for the network.cookie.cookieBehavior pref are documented in
|
|
||||||
// nsCookieService.cpp.
|
|
||||||
#define COOKIE_BEHAVIOR_REJECT 2
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetCookieEnabled(bool *aCookieEnabled)
|
|
||||||
{
|
|
||||||
*aCookieEnabled =
|
|
||||||
(Preferences::GetInt("network.cookie.cookieBehavior",
|
|
||||||
COOKIE_BEHAVIOR_REJECT) != COOKIE_BEHAVIOR_REJECT);
|
|
||||||
|
|
||||||
// Check whether an exception overrides the global cookie behavior
|
|
||||||
// Note that the code for getting the URI here matches that in
|
|
||||||
// nsHTMLDocument::SetCookie.
|
|
||||||
nsCOMPtr<nsIDocument> doc = do_GetInterface(mDocShell);
|
|
||||||
if (!doc) {
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> codebaseURI;
|
|
||||||
doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));
|
|
||||||
|
|
||||||
if (!codebaseURI) {
|
|
||||||
// Not a codebase, so technically can't set cookies, but let's
|
|
||||||
// just return the default value.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsICookiePermission> permMgr =
|
|
||||||
do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE(permMgr, NS_OK);
|
|
||||||
|
|
||||||
// Pass null for the channel, just like the cookie service does
|
|
||||||
nsCookieAccess access;
|
|
||||||
nsresult rv = permMgr->CanAccess(codebaseURI, nsnull, &access);
|
|
||||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
|
||||||
|
|
||||||
if (access != nsICookiePermission::ACCESS_DEFAULT) {
|
|
||||||
*aCookieEnabled = access != nsICookiePermission::ACCESS_DENY;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetOnLine(bool* aOnline)
|
|
||||||
{
|
|
||||||
NS_PRECONDITION(aOnline, "Null out param");
|
|
||||||
|
|
||||||
*aOnline = !NS_IsOffline();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetBuildID(nsAString& aBuildID)
|
|
||||||
{
|
|
||||||
if (!nsContentUtils::IsCallerTrustedForRead()) {
|
|
||||||
const nsAdoptingString& override =
|
|
||||||
Preferences::GetString("general.buildID.override");
|
|
||||||
|
|
||||||
if (override) {
|
|
||||||
aBuildID = override;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIXULAppInfo> appInfo =
|
|
||||||
do_GetService("@mozilla.org/xre/app-info;1");
|
|
||||||
if (!appInfo)
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
|
|
||||||
nsCAutoString buildID;
|
|
||||||
nsresult rv = appInfo->GetAppBuildID(buildID);
|
|
||||||
if (NS_FAILED(rv))
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
aBuildID.Truncate();
|
|
||||||
AppendASCIItoUTF16(buildID, aBuildID);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::GetDoNotTrack(nsAString &aResult)
|
|
||||||
{
|
|
||||||
if (gDoNotTrackEnabled) {
|
|
||||||
aResult.AssignLiteral("yes");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aResult.AssignLiteral("unspecified");
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::JavaEnabled(bool *aReturn)
|
|
||||||
{
|
|
||||||
Telemetry::AutoTimer<Telemetry::CHECK_JAVA_ENABLED> telemetryTimer;
|
|
||||||
// Return true if we have a handler for "application/x-java-vm",
|
|
||||||
// otherwise return false.
|
|
||||||
*aReturn = false;
|
|
||||||
|
|
||||||
if (!mMimeTypes) {
|
|
||||||
mMimeTypes = new nsMimeTypeArray(this);
|
|
||||||
if (!mMimeTypes)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
RefreshMIMEArray();
|
|
||||||
|
|
||||||
PRUint32 count;
|
|
||||||
mMimeTypes->GetLength(&count);
|
|
||||||
for (PRUint32 i = 0; i < count; i++) {
|
|
||||||
nsresult rv;
|
|
||||||
nsIDOMMimeType* type = mMimeTypes->GetItemAt(i, &rv);
|
|
||||||
nsAutoString mimeString;
|
|
||||||
if (type && NS_SUCCEEDED(type->GetType(mimeString))) {
|
|
||||||
if (mimeString.EqualsLiteral("application/x-java-vm")) {
|
|
||||||
*aReturn = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsNavigator::LoadingNewDocument()
|
|
||||||
{
|
|
||||||
// Release these so that they will be recreated for the
|
|
||||||
// new document (if requested). The plugins or mime types
|
|
||||||
// arrays may have changed. See bug 150087.
|
|
||||||
if (mMimeTypes) {
|
|
||||||
mMimeTypes->Invalidate();
|
|
||||||
mMimeTypes = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPlugins) {
|
|
||||||
mPlugins->Invalidate();
|
|
||||||
mPlugins = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mGeolocation)
|
|
||||||
{
|
|
||||||
mGeolocation->Shutdown();
|
|
||||||
mGeolocation = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mNotification)
|
|
||||||
{
|
|
||||||
mNotification->Shutdown();
|
|
||||||
mNotification = nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsNavigator::RefreshMIMEArray()
|
|
||||||
{
|
|
||||||
nsresult rv = NS_OK;
|
|
||||||
if (mMimeTypes)
|
|
||||||
rv = mMimeTypes->Refresh();
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
nsNavigator::HasDesktopNotificationSupport()
|
|
||||||
{
|
|
||||||
return Preferences::GetBool("notification.feature.enabled", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// nsNavigator::nsIDOMClientInformation
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::RegisterContentHandler(const nsAString& aMIMEType,
|
|
||||||
const nsAString& aURI,
|
|
||||||
const nsAString& aTitle)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
|
|
||||||
do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
|
|
||||||
if (registrar && mDocShell) {
|
|
||||||
nsCOMPtr<nsIDOMWindow> contentDOMWindow(do_GetInterface(mDocShell));
|
|
||||||
if (contentDOMWindow)
|
|
||||||
return registrar->RegisterContentHandler(aMIMEType, aURI, aTitle,
|
|
||||||
contentDOMWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::RegisterProtocolHandler(const nsAString& aProtocol,
|
|
||||||
const nsAString& aURI,
|
|
||||||
const nsAString& aTitle)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIWebContentHandlerRegistrar> registrar =
|
|
||||||
do_GetService(NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID);
|
|
||||||
if (registrar && mDocShell) {
|
|
||||||
nsCOMPtr<nsIDOMWindow> contentDOMWindow(do_GetInterface(mDocShell));
|
|
||||||
if (contentDOMWindow)
|
|
||||||
return registrar->RegisterProtocolHandler(aProtocol, aURI, aTitle,
|
|
||||||
contentDOMWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsNavigator::MozIsLocallyAvailable(const nsAString &aURI,
|
|
||||||
bool aWhenOffline,
|
|
||||||
bool *aIsAvailable)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
|
||||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aURI);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// This method of checking the cache will only work for http/https urls
|
|
||||||
bool match;
|
|
||||||
rv = uri->SchemeIs("http", &match);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
if (!match) {
|
|
||||||
rv = uri->SchemeIs("https", &match);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
if (!match) return NS_ERROR_DOM_BAD_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same origin check
|
|
||||||
nsCOMPtr<nsIJSContextStack> stack = do_GetService(sJSStackContractID);
|
|
||||||
NS_ENSURE_TRUE(stack, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
JSContext *cx = nsnull;
|
|
||||||
rv = stack->Peek(&cx);
|
|
||||||
NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
rv = nsContentUtils::GetSecurityManager()->CheckSameOrigin(cx, uri);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
// these load flags cause an error to be thrown if there is no
|
|
||||||
// valid cache entry, and skip the load if there is.
|
|
||||||
// if the cache is busy, assume that it is not yet available rather
|
|
||||||
// than waiting for it to become available.
|
|
||||||
PRUint32 loadFlags = nsIChannel::INHIBIT_CACHING |
|
|
||||||
nsICachingChannel::LOAD_NO_NETWORK_IO |
|
|
||||||
nsICachingChannel::LOAD_ONLY_IF_MODIFIED |
|
|
||||||
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;
|
|
||||||
|
|
||||||
if (aWhenOffline) {
|
|
||||||
loadFlags |= nsICachingChannel::LOAD_CHECK_OFFLINE_CACHE |
|
|
||||||
nsICachingChannel::LOAD_ONLY_FROM_CACHE |
|
|
||||||
nsIRequest::LOAD_FROM_CACHE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> channel;
|
|
||||||
rv = NS_NewChannel(getter_AddRefs(channel), uri,
|
|
||||||
nsnull, nsnull, nsnull, loadFlags);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> stream;
|
|
||||||
rv = channel->Open(getter_AddRefs(stream));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
stream->Close();
|
|
||||||
|
|
||||||
nsresult status;
|
|
||||||
rv = channel->GetStatus(&status);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (NS_SUCCEEDED(status)) {
|
|
||||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
|
||||||
rv = httpChannel->GetRequestSucceeded(aIsAvailable);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
} else {
|
|
||||||
*aIsAvailable = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// nsNavigator::nsIDOMNavigatorGeolocation
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsNavigator::GetGeolocation(nsIDOMGeoGeolocation **_retval)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(_retval);
|
|
||||||
*_retval = nsnull;
|
|
||||||
|
|
||||||
if (!Preferences::GetBool("geo.enabled", true))
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
if (mGeolocation) {
|
|
||||||
NS_ADDREF(*_retval = mGeolocation);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mDocShell)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMWindow> contentDOMWindow(do_GetInterface(mDocShell));
|
|
||||||
if (!contentDOMWindow)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
mGeolocation = new nsGeolocation();
|
|
||||||
if (!mGeolocation)
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
if (NS_FAILED(mGeolocation->Init(contentDOMWindow))) {
|
|
||||||
mGeolocation = nsnull;
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*_retval = mGeolocation);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// nsNavigator::nsIDOMNavigatorDesktopNotification
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsNavigator::GetMozNotification(nsIDOMDesktopNotificationCenter **aRetVal)
|
|
||||||
{
|
|
||||||
NS_ENSURE_ARG_POINTER(aRetVal);
|
|
||||||
*aRetVal = nsnull;
|
|
||||||
|
|
||||||
if (mNotification) {
|
|
||||||
NS_ADDREF(*aRetVal = mNotification);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsPIDOMWindow> window(do_GetInterface(mDocShell));
|
|
||||||
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDocument> document = do_GetInterface(mDocShell);
|
|
||||||
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
nsIScriptGlobalObject *sgo = document->GetScopeObject();
|
|
||||||
NS_ENSURE_TRUE(sgo, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
nsIScriptContext *scx = sgo->GetContext();
|
|
||||||
NS_ENSURE_TRUE(scx, NS_ERROR_FAILURE);
|
|
||||||
|
|
||||||
mNotification = new nsDesktopNotificationCenter(window->GetCurrentInnerWindow(),
|
|
||||||
scx);
|
|
||||||
if (!mNotification) {
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_ADDREF(*aRetVal = mNotification);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EVENT(name_, id_, type_, struct_) \
|
#define EVENT(name_, id_, type_, struct_) \
|
||||||
NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx, \
|
NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx, \
|
||||||
jsval *vp) { \
|
jsval *vp) { \
|
||||||
@ -11477,20 +10730,3 @@ NS_IMETHODIMP nsNavigator::GetMozNotification(nsIDOMDesktopNotificationCenter **
|
|||||||
#undef WINDOW_ONLY_EVENT
|
#undef WINDOW_ONLY_EVENT
|
||||||
#undef EVENT
|
#undef EVENT
|
||||||
|
|
||||||
PRInt64
|
|
||||||
nsNavigator::SizeOf() const
|
|
||||||
{
|
|
||||||
PRInt64 size = sizeof(*this);
|
|
||||||
|
|
||||||
// TODO: add SizeOf() to nsMimeTypeArray, bug 674113.
|
|
||||||
size += mMimeTypes ? sizeof(*mMimeTypes.get()) : 0;
|
|
||||||
// TODO: add SizeOf() to nsPluginArray, bug 674114.
|
|
||||||
size += mPlugins ? sizeof(*mPlugins.get()) : 0;
|
|
||||||
// TODO: add SizeOf() to nsGeolocation, bug 674115.
|
|
||||||
size += mGeolocation ? sizeof(*mGeolocation.get()) : 0;
|
|
||||||
// TODO: add SizeOf() to nsDesktopNotificationCenter, bug 674116.
|
|
||||||
size += mNotification ? sizeof(*mNotification.get()) : 0;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -61,11 +61,7 @@
|
|||||||
#include "nsIBrowserDOMWindow.h"
|
#include "nsIBrowserDOMWindow.h"
|
||||||
#include "nsIDocShellTreeOwner.h"
|
#include "nsIDocShellTreeOwner.h"
|
||||||
#include "nsIDocShellTreeItem.h"
|
#include "nsIDocShellTreeItem.h"
|
||||||
#include "nsIDOMClientInformation.h"
|
|
||||||
#include "nsIDOMEventTarget.h"
|
#include "nsIDOMEventTarget.h"
|
||||||
#include "nsIDOMNavigator.h"
|
|
||||||
#include "nsIDOMNavigatorGeolocation.h"
|
|
||||||
#include "nsIDOMNavigatorDesktopNotification.h"
|
|
||||||
#include "nsIInterfaceRequestor.h"
|
#include "nsIInterfaceRequestor.h"
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
#include "nsIInterfaceRequestorUtils.h"
|
||||||
#include "nsIDOMJSWindow.h"
|
#include "nsIDOMJSWindow.h"
|
||||||
@ -85,8 +81,6 @@
|
|||||||
#include "nsIDOMCrypto.h"
|
#include "nsIDOMCrypto.h"
|
||||||
#endif
|
#endif
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsPluginArray.h"
|
|
||||||
#include "nsMimeTypeArray.h"
|
|
||||||
#include "nsIXPCScriptable.h"
|
#include "nsIXPCScriptable.h"
|
||||||
#include "nsPoint.h"
|
#include "nsPoint.h"
|
||||||
#include "nsSize.h"
|
#include "nsSize.h"
|
||||||
@ -130,7 +124,6 @@ class nsIControllers;
|
|||||||
|
|
||||||
class nsBarProp;
|
class nsBarProp;
|
||||||
class nsLocation;
|
class nsLocation;
|
||||||
class nsNavigator;
|
|
||||||
class nsScreen;
|
class nsScreen;
|
||||||
class nsHistory;
|
class nsHistory;
|
||||||
class nsPerformance;
|
class nsPerformance;
|
||||||
@ -143,14 +136,18 @@ class PostMessageEvent;
|
|||||||
class nsRunnable;
|
class nsRunnable;
|
||||||
|
|
||||||
class nsDOMOfflineResourceList;
|
class nsDOMOfflineResourceList;
|
||||||
class nsGeolocation;
|
|
||||||
class nsDesktopNotificationCenter;
|
|
||||||
class nsDOMMozURLProperty;
|
class nsDOMMozURLProperty;
|
||||||
|
|
||||||
#ifdef MOZ_DISABLE_DOMCRYPTO
|
#ifdef MOZ_DISABLE_DOMCRYPTO
|
||||||
class nsIDOMCrypto;
|
class nsIDOMCrypto;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
class Navigator;
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
extern nsresult
|
extern nsresult
|
||||||
NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
|
NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
|
||||||
bool *aIsInterval,
|
bool *aIsInterval,
|
||||||
@ -290,6 +287,7 @@ public:
|
|||||||
|
|
||||||
typedef mozilla::TimeStamp TimeStamp;
|
typedef mozilla::TimeStamp TimeStamp;
|
||||||
typedef mozilla::TimeDuration TimeDuration;
|
typedef mozilla::TimeDuration TimeDuration;
|
||||||
|
typedef mozilla::dom::Navigator Navigator;
|
||||||
typedef nsDataHashtable<nsUint64HashKey, nsGlobalWindow*> WindowByIdTable;
|
typedef nsDataHashtable<nsUint64HashKey, nsGlobalWindow*> WindowByIdTable;
|
||||||
|
|
||||||
// public methods
|
// public methods
|
||||||
@ -906,7 +904,7 @@ protected:
|
|||||||
nsCOMPtr<nsIArray> mArguments;
|
nsCOMPtr<nsIArray> mArguments;
|
||||||
nsCOMPtr<nsIArray> mArgumentsLast;
|
nsCOMPtr<nsIArray> mArgumentsLast;
|
||||||
nsCOMPtr<nsIPrincipal> mArgumentsOrigin;
|
nsCOMPtr<nsIPrincipal> mArgumentsOrigin;
|
||||||
nsRefPtr<nsNavigator> mNavigator;
|
nsRefPtr<Navigator> mNavigator;
|
||||||
nsRefPtr<nsScreen> mScreen;
|
nsRefPtr<nsScreen> mScreen;
|
||||||
nsRefPtr<nsPerformance> mPerformance;
|
nsRefPtr<nsPerformance> mPerformance;
|
||||||
nsRefPtr<nsDOMWindowList> mFrames;
|
nsRefPtr<nsDOMWindowList> mFrames;
|
||||||
@ -1073,52 +1071,6 @@ protected:
|
|||||||
nsCOMPtr<nsIVariant> mReturnValue;
|
nsCOMPtr<nsIVariant> mReturnValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//*****************************************************************************
|
|
||||||
// nsNavigator: Script "navigator" object
|
|
||||||
//*****************************************************************************
|
|
||||||
|
|
||||||
class nsNavigator : public nsIDOMNavigator,
|
|
||||||
public nsIDOMClientInformation,
|
|
||||||
public nsIDOMNavigatorGeolocation,
|
|
||||||
public nsIDOMNavigatorDesktopNotification
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
nsNavigator(nsIDocShell *aDocShell);
|
|
||||||
virtual ~nsNavigator();
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
NS_DECL_NSIDOMNAVIGATOR
|
|
||||||
NS_DECL_NSIDOMCLIENTINFORMATION
|
|
||||||
NS_DECL_NSIDOMNAVIGATORGEOLOCATION
|
|
||||||
NS_DECL_NSIDOMNAVIGATORDESKTOPNOTIFICATION
|
|
||||||
|
|
||||||
void SetDocShell(nsIDocShell *aDocShell);
|
|
||||||
nsIDocShell *GetDocShell()
|
|
||||||
{
|
|
||||||
return mDocShell;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadingNewDocument();
|
|
||||||
nsresult RefreshMIMEArray();
|
|
||||||
|
|
||||||
static bool HasDesktopNotificationSupport();
|
|
||||||
|
|
||||||
PRInt64 SizeOf() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
nsRefPtr<nsMimeTypeArray> mMimeTypes;
|
|
||||||
nsRefPtr<nsPluginArray> mPlugins;
|
|
||||||
nsRefPtr<nsGeolocation> mGeolocation;
|
|
||||||
nsRefPtr<nsDesktopNotificationCenter> mNotification;
|
|
||||||
nsIDocShell* mDocShell; // weak reference
|
|
||||||
};
|
|
||||||
|
|
||||||
nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
|
|
||||||
nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
|
|
||||||
nsresult NS_GetNavigatorAppVersion(nsAString& aAppVersion);
|
|
||||||
nsresult NS_GetNavigatorAppName(nsAString& aAppName);
|
|
||||||
|
|
||||||
/* factory function */
|
/* factory function */
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewScriptGlobalObject(bool aIsChrome, bool aIsModalContentWindow,
|
NS_NewScriptGlobalObject(bool aIsChrome, bool aIsModalContentWindow,
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
|
|
||||||
#include "nsPluginArray.h"
|
#include "nsPluginArray.h"
|
||||||
#include "nsMimeTypeArray.h"
|
#include "nsMimeTypeArray.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "Navigator.h"
|
||||||
#include "nsIScriptGlobalObject.h"
|
#include "nsIScriptGlobalObject.h"
|
||||||
#include "nsIDOMNavigator.h"
|
#include "nsIDOMNavigator.h"
|
||||||
#include "nsIDOMMimeType.h"
|
#include "nsIDOMMimeType.h"
|
||||||
@ -50,7 +50,10 @@
|
|||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsPluginHost.h"
|
#include "nsPluginHost.h"
|
||||||
|
|
||||||
nsPluginArray::nsPluginArray(nsNavigator* navigator,
|
using namespace mozilla;
|
||||||
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
|
nsPluginArray::nsPluginArray(Navigator* navigator,
|
||||||
nsIDocShell *aDocShell)
|
nsIDocShell *aDocShell)
|
||||||
{
|
{
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
@ -44,15 +44,20 @@
|
|||||||
#include "nsIPluginHost.h"
|
#include "nsIPluginHost.h"
|
||||||
#include "nsIURL.h"
|
#include "nsIURL.h"
|
||||||
|
|
||||||
class nsNavigator;
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
class Navigator;
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
class nsIDocShell;
|
class nsIDocShell;
|
||||||
|
|
||||||
// NB: Due to weak references, nsNavigator has intimate knowledge of our
|
// NB: Due to weak references, Navigator has intimate knowledge of our
|
||||||
// internals.
|
// internals.
|
||||||
class nsPluginArray : public nsIDOMPluginArray
|
class nsPluginArray : public nsIDOMPluginArray
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsPluginArray(nsNavigator* navigator, nsIDocShell *aDocShell);
|
nsPluginArray(mozilla::dom::Navigator* navigator, nsIDocShell *aDocShell);
|
||||||
virtual ~nsPluginArray();
|
virtual ~nsPluginArray();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
@ -91,7 +96,7 @@ public:
|
|||||||
void Invalidate();
|
void Invalidate();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsNavigator* mNavigator;
|
mozilla::dom::Navigator* mNavigator;
|
||||||
nsCOMPtr<nsIPluginHost> mPluginHost;
|
nsCOMPtr<nsIPluginHost> mPluginHost;
|
||||||
PRUint32 mPluginCount;
|
PRUint32 mPluginCount;
|
||||||
nsIDOMPlugin** mPluginArray;
|
nsIDOMPlugin** mPluginArray;
|
||||||
|
196
dom/battery/BatteryManager.cpp
Normal file
196
dom/battery/BatteryManager.cpp
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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 mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Mounir Lamouri <mounir.lamouri@mozilla.com> (Original Author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of 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 ***** */
|
||||||
|
|
||||||
|
#include "mozilla/Hal.h"
|
||||||
|
#include "BatteryManager.h"
|
||||||
|
#include "nsIDOMClassInfo.h"
|
||||||
|
#include "Constants.h"
|
||||||
|
#include "nsDOMEvent.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We have to use macros here because our leak analysis tool things we are
|
||||||
|
* leaking strings when we have |static const nsString|. Sad :(
|
||||||
|
*/
|
||||||
|
#define LEVELCHANGE_EVENT_NAME NS_LITERAL_STRING("levelchange")
|
||||||
|
#define CHARGINGCHANGE_EVENT_NAME NS_LITERAL_STRING("chargingchange")
|
||||||
|
|
||||||
|
DOMCI_DATA(BatteryManager, mozilla::dom::battery::BatteryManager)
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
namespace battery {
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_CLASS(BatteryManager)
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BatteryManager,
|
||||||
|
nsDOMEventTargetHelper)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLevelChangeListener)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnChargingChangeListener)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BatteryManager,
|
||||||
|
nsDOMEventTargetHelper)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLevelChangeListener)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnChargingChangeListener)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BatteryManager)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIDOMBatteryManager)
|
||||||
|
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BatteryManager)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(BatteryManager, nsDOMEventTargetHelper)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(BatteryManager, nsDOMEventTargetHelper)
|
||||||
|
|
||||||
|
BatteryManager::BatteryManager()
|
||||||
|
: mLevel(kDefaultLevel)
|
||||||
|
, mCharging(kDefaultCharging)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BatteryManager::~BatteryManager()
|
||||||
|
{
|
||||||
|
if (mListenerManager) {
|
||||||
|
mListenerManager->Disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BatteryManager::Init()
|
||||||
|
{
|
||||||
|
hal::RegisterBatteryObserver(this);
|
||||||
|
|
||||||
|
hal::BatteryInformation* batteryInfo = new hal::BatteryInformation();
|
||||||
|
hal::GetCurrentBatteryInformation(batteryInfo);
|
||||||
|
|
||||||
|
UpdateFromBatteryInfo(*batteryInfo);
|
||||||
|
|
||||||
|
delete batteryInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BatteryManager::Shutdown()
|
||||||
|
{
|
||||||
|
hal::UnregisterBatteryObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
BatteryManager::GetCharging(bool* aCharging)
|
||||||
|
{
|
||||||
|
*aCharging = mCharging;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
BatteryManager::GetLevel(float* aLevel)
|
||||||
|
{
|
||||||
|
*aLevel = mLevel;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
BatteryManager::GetOnlevelchange(nsIDOMEventListener** aOnlevelchange)
|
||||||
|
{
|
||||||
|
return GetInnerEventListener(mOnLevelChangeListener, aOnlevelchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
BatteryManager::SetOnlevelchange(nsIDOMEventListener* aOnlevelchange)
|
||||||
|
{
|
||||||
|
return RemoveAddEventListener(LEVELCHANGE_EVENT_NAME, mOnLevelChangeListener,
|
||||||
|
aOnlevelchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
BatteryManager::GetOnchargingchange(nsIDOMEventListener** aOnchargingchange)
|
||||||
|
{
|
||||||
|
return GetInnerEventListener(mOnChargingChangeListener, aOnchargingchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
BatteryManager::SetOnchargingchange(nsIDOMEventListener* aOnchargingchange)
|
||||||
|
{
|
||||||
|
return RemoveAddEventListener(CHARGINGCHANGE_EVENT_NAME,
|
||||||
|
mOnChargingChangeListener, aOnchargingchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
BatteryManager::DispatchTrustedEventToSelf(const nsAString& aEventName)
|
||||||
|
{
|
||||||
|
nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
|
||||||
|
nsresult rv = event->InitEvent(aEventName, false, false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = event->SetTrusted(PR_TRUE);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
bool dummy;
|
||||||
|
rv = DispatchEvent(event, &dummy);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BatteryManager::UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInfo)
|
||||||
|
{
|
||||||
|
mLevel = aBatteryInfo.level();
|
||||||
|
mCharging = aBatteryInfo.charging();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BatteryManager::Notify(const hal::BatteryInformation& aBatteryInfo)
|
||||||
|
{
|
||||||
|
float previousLevel = mLevel;
|
||||||
|
bool previousCharging = mCharging;
|
||||||
|
|
||||||
|
UpdateFromBatteryInfo(aBatteryInfo);
|
||||||
|
|
||||||
|
if (previousCharging != mCharging) {
|
||||||
|
DispatchTrustedEventToSelf(CHARGINGCHANGE_EVENT_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousLevel != mLevel) {
|
||||||
|
DispatchTrustedEventToSelf(LEVELCHANGE_EVENT_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace battery
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
100
dom/battery/BatteryManager.h
Normal file
100
dom/battery/BatteryManager.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** 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 mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Foundation
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Mounir Lamouri <mounir.lamouri@mozilla.com> (Original Author)
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of 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 ***** */
|
||||||
|
|
||||||
|
#ifndef mozilla_dom_battery_BatteryManager_h
|
||||||
|
#define mozilla_dom_battery_BatteryManager_h
|
||||||
|
|
||||||
|
#include "nsIDOMBatteryManager.h"
|
||||||
|
#include "nsDOMEventTargetHelper.h"
|
||||||
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "mozilla/Observer.h"
|
||||||
|
#include "Types.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
namespace hal {
|
||||||
|
class BatteryInformation;
|
||||||
|
} // namespace hal
|
||||||
|
|
||||||
|
namespace dom {
|
||||||
|
namespace battery {
|
||||||
|
|
||||||
|
class BatteryManager : public nsIDOMBatteryManager
|
||||||
|
, public nsDOMEventTargetHelper
|
||||||
|
, public BatteryObserver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIDOMBATTERYMANAGER
|
||||||
|
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
|
||||||
|
|
||||||
|
BatteryManager();
|
||||||
|
virtual ~BatteryManager();
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
// For IObserver.
|
||||||
|
void Notify(const hal::BatteryInformation& aBatteryInfo);
|
||||||
|
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BatteryManager,
|
||||||
|
nsDOMEventTargetHelper)
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Dispatch a trusted non-cancellable and non-bubbling event to itself.
|
||||||
|
*/
|
||||||
|
nsresult DispatchTrustedEventToSelf(const nsAString& aEventName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the battery information stored in the battery manager object using
|
||||||
|
* a battery information object.
|
||||||
|
*/
|
||||||
|
void UpdateFromBatteryInfo(const hal::BatteryInformation& aBatteryInfo);
|
||||||
|
|
||||||
|
float mLevel;
|
||||||
|
bool mCharging;
|
||||||
|
|
||||||
|
nsRefPtr<nsDOMEventListenerWrapper> mOnLevelChangeListener;
|
||||||
|
nsRefPtr<nsDOMEventListenerWrapper> mOnChargingChangeListener;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace battery
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
||||||
|
#endif // mozilla_dom_battery_BatteryManager_h
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user