merge fx-team to m-c
|
|
@ -177,7 +177,7 @@ EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SYMBOL_INDEX_NAME = \
|
SYMBOL_INDEX_NAME = \
|
||||||
$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)$(EXTRA_BUILDID)-symbols.txt
|
$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)-$(CPU_ARCH)$(EXTRA_BUILDID)-symbols.txt
|
||||||
|
|
||||||
buildsymbols:
|
buildsymbols:
|
||||||
ifdef MOZ_CRASHREPORTER
|
ifdef MOZ_CRASHREPORTER
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
#include "Accessible-inl.h"
|
#include "Accessible-inl.h"
|
||||||
#include "nsAccUtils.h"
|
#include "nsAccUtils.h"
|
||||||
#include "nsHyperTextAccessible.h"
|
#include "nsHyperTextAccessible.h"
|
||||||
|
#include "nsDocAccessible.h"
|
||||||
#include "States.h"
|
#include "States.h"
|
||||||
|
|
||||||
#include "nsArrayUtils.h"
|
#include "nsArrayUtils.h"
|
||||||
|
|
@ -217,6 +218,10 @@ nsAccessiblePivot::MoveNext(nsIAccessibleTraversalRule* aRule, bool* aResult)
|
||||||
NS_ENSURE_ARG(aResult);
|
NS_ENSURE_ARG(aResult);
|
||||||
NS_ENSURE_ARG(aRule);
|
NS_ENSURE_ARG(aRule);
|
||||||
|
|
||||||
|
if (mPosition && (mPosition->IsDefunct() ||
|
||||||
|
!mPosition->Document()->IsInDocument(mPosition)))
|
||||||
|
return NS_ERROR_NOT_IN_TREE;
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
nsAccessible* accessible = SearchForward(mPosition, aRule, false, &rv);
|
nsAccessible* accessible = SearchForward(mPosition, aRule, false, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
@ -234,6 +239,10 @@ nsAccessiblePivot::MovePrevious(nsIAccessibleTraversalRule* aRule, bool* aResult
|
||||||
NS_ENSURE_ARG(aResult);
|
NS_ENSURE_ARG(aResult);
|
||||||
NS_ENSURE_ARG(aRule);
|
NS_ENSURE_ARG(aRule);
|
||||||
|
|
||||||
|
if (mPosition && (mPosition->IsDefunct() ||
|
||||||
|
!mPosition->Document()->IsInDocument(mPosition)))
|
||||||
|
return NS_ERROR_NOT_IN_TREE;
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
nsAccessible* accessible = SearchBackward(mPosition, aRule, false, &rv);
|
nsAccessible* accessible = SearchBackward(mPosition, aRule, false, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
@ -250,6 +259,10 @@ nsAccessiblePivot::MoveFirst(nsIAccessibleTraversalRule* aRule, bool* aResult)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG(aResult);
|
NS_ENSURE_ARG(aResult);
|
||||||
NS_ENSURE_ARG(aRule);
|
NS_ENSURE_ARG(aRule);
|
||||||
|
|
||||||
|
if (mRoot && mRoot->IsDefunct())
|
||||||
|
return NS_ERROR_NOT_IN_TREE;
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
nsAccessible* accessible = SearchForward(mRoot, aRule, true, &rv);
|
nsAccessible* accessible = SearchForward(mRoot, aRule, true, &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
@ -267,6 +280,9 @@ nsAccessiblePivot::MoveLast(nsIAccessibleTraversalRule* aRule, bool* aResult)
|
||||||
NS_ENSURE_ARG(aResult);
|
NS_ENSURE_ARG(aResult);
|
||||||
NS_ENSURE_ARG(aRule);
|
NS_ENSURE_ARG(aRule);
|
||||||
|
|
||||||
|
if (mRoot && mRoot->IsDefunct())
|
||||||
|
return NS_ERROR_NOT_IN_TREE;
|
||||||
|
|
||||||
*aResult = false;
|
*aResult = false;
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
nsAccessible* lastAccessible = mRoot;
|
nsAccessible* lastAccessible = mRoot;
|
||||||
|
|
@ -334,6 +350,9 @@ nsAccessiblePivot::RemoveObserver(nsIAccessiblePivotObserver* aObserver)
|
||||||
bool
|
bool
|
||||||
nsAccessiblePivot::IsRootDescendant(nsAccessible* aAccessible)
|
nsAccessiblePivot::IsRootDescendant(nsAccessible* aAccessible)
|
||||||
{
|
{
|
||||||
|
if (!mRoot || mRoot->IsDefunct())
|
||||||
|
return false;
|
||||||
|
|
||||||
nsAccessible* accessible = aAccessible;
|
nsAccessible* accessible = aAccessible;
|
||||||
do {
|
do {
|
||||||
if (accessible == mRoot)
|
if (accessible == mRoot)
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,10 @@
|
||||||
class nsAccessible;
|
class nsAccessible;
|
||||||
class nsIAccessibleTraversalRule;
|
class nsIAccessibleTraversalRule;
|
||||||
|
|
||||||
|
// raised when current pivot's position is needed but it is not in the tree.
|
||||||
|
#define NS_ERROR_NOT_IN_TREE \
|
||||||
|
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL, 0x26)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class represents an accessible pivot.
|
* Class represents an accessible pivot.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -88,9 +88,6 @@ nsHTMLSelectListAccessible::NativeState()
|
||||||
role
|
role
|
||||||
nsHTMLSelectListAccessible::NativeRole()
|
nsHTMLSelectListAccessible::NativeRole()
|
||||||
{
|
{
|
||||||
if (mParent && mParent->Role() == roles::COMBOBOX)
|
|
||||||
return roles::COMBOBOX_LIST;
|
|
||||||
|
|
||||||
return roles::LISTBOX;
|
return roles::LISTBOX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -710,6 +707,12 @@ nsHTMLComboboxListAccessible::IsPrimaryForNode() const
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// nsHTMLComboboxAccessible: nsAccessible
|
// nsHTMLComboboxAccessible: nsAccessible
|
||||||
|
|
||||||
|
role
|
||||||
|
nsHTMLComboboxListAccessible::NativeRole()
|
||||||
|
{
|
||||||
|
return roles::COMBOBOX_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
PRUint64
|
PRUint64
|
||||||
nsHTMLComboboxListAccessible::NativeState()
|
nsHTMLComboboxListAccessible::NativeState()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,7 @@ public:
|
||||||
virtual bool IsPrimaryForNode() const;
|
virtual bool IsPrimaryForNode() const;
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual mozilla::a11y::role NativeRole();
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
|
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,14 +48,14 @@ var AccessFu = {
|
||||||
} catch (x) {
|
} catch (x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.processPreferences(accessPref);
|
this._processPreferences(accessPref);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start AccessFu mode, this primarily means controlling the virtual cursor
|
* Start AccessFu mode, this primarily means controlling the virtual cursor
|
||||||
* with arrow keys.
|
* with arrow keys.
|
||||||
*/
|
*/
|
||||||
enable: function enable() {
|
_enable: function _enable() {
|
||||||
if (this._enabled)
|
if (this._enabled)
|
||||||
return;
|
return;
|
||||||
this._enabled = true;
|
this._enabled = true;
|
||||||
|
|
@ -79,7 +79,7 @@ var AccessFu = {
|
||||||
/**
|
/**
|
||||||
* Disable AccessFu and return to default interaction mode.
|
* Disable AccessFu and return to default interaction mode.
|
||||||
*/
|
*/
|
||||||
disable: function disable() {
|
_disable: function _disable() {
|
||||||
if (!this._enabled)
|
if (!this._enabled)
|
||||||
return;
|
return;
|
||||||
this._enabled = false;
|
this._enabled = false;
|
||||||
|
|
@ -98,7 +98,7 @@ var AccessFu = {
|
||||||
this.chromeWin.removeEventListener('TabOpen', this, true);
|
this.chromeWin.removeEventListener('TabOpen', this, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
processPreferences: function processPreferences(aPref) {
|
_processPreferences: function _processPreferences(aPref) {
|
||||||
if (Services.appinfo.OS == 'Android') {
|
if (Services.appinfo.OS == 'Android') {
|
||||||
if (aPref == ACCESSFU_AUTO) {
|
if (aPref == ACCESSFU_AUTO) {
|
||||||
if (!this._observingSystemSettings) {
|
if (!this._observingSystemSettings) {
|
||||||
|
|
@ -118,9 +118,9 @@ var AccessFu = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aPref == ACCESSFU_ENABLE)
|
if (aPref == ACCESSFU_ENABLE)
|
||||||
this.enable();
|
this._enable();
|
||||||
else
|
else
|
||||||
this.disable();
|
this._disable();
|
||||||
},
|
},
|
||||||
|
|
||||||
addPresenter: function addPresenter(presenter) {
|
addPresenter: function addPresenter(presenter) {
|
||||||
|
|
@ -171,19 +171,19 @@ var AccessFu = {
|
||||||
switch (aTopic) {
|
switch (aTopic) {
|
||||||
case 'Accessibility:Settings':
|
case 'Accessibility:Settings':
|
||||||
if (JSON.parse(aData).enabled)
|
if (JSON.parse(aData).enabled)
|
||||||
this.enable();
|
this._enable();
|
||||||
else
|
else
|
||||||
this.disable();
|
this._disable();
|
||||||
break;
|
break;
|
||||||
case 'nsPref:changed':
|
case 'nsPref:changed':
|
||||||
if (aData == 'accessfu')
|
if (aData == 'accessfu')
|
||||||
this.processPreferences(this.prefsBranch.getIntPref('accessfu'));
|
this._processPreferences(this.prefsBranch.getIntPref('accessfu'));
|
||||||
break;
|
break;
|
||||||
case 'accessible-event':
|
case 'accessible-event':
|
||||||
let event;
|
let event;
|
||||||
try {
|
try {
|
||||||
event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
|
event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
|
||||||
this.handleAccEvent(event);
|
this._handleAccEvent(event);
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
dump(ex);
|
dump(ex);
|
||||||
return;
|
return;
|
||||||
|
|
@ -191,7 +191,7 @@ var AccessFu = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleAccEvent: function handleAccEvent(aEvent) {
|
_handleAccEvent: function _handleAccEvent(aEvent) {
|
||||||
switch (aEvent.eventType) {
|
switch (aEvent.eventType) {
|
||||||
case Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED:
|
case Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED:
|
||||||
{
|
{
|
||||||
|
|
@ -199,6 +199,21 @@ var AccessFu = {
|
||||||
QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor;
|
QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor;
|
||||||
let event = aEvent.
|
let event = aEvent.
|
||||||
QueryInterface(Ci.nsIAccessibleVirtualCursorChangeEvent);
|
QueryInterface(Ci.nsIAccessibleVirtualCursorChangeEvent);
|
||||||
|
let position = pivot.position;
|
||||||
|
let doc = aEvent.DOMNode;
|
||||||
|
|
||||||
|
if (doc instanceof Ci.nsIDOMDocument && position.DOMNode) {
|
||||||
|
// Set the caret to the start of the pivot position, and move
|
||||||
|
// the focus in the same manner as browse with caret mode.
|
||||||
|
// This blurs the focus on the previous pivot position (if it
|
||||||
|
// was activated), and keeps us in a predictable spot for tab
|
||||||
|
// focus.
|
||||||
|
let sel = doc.getSelection();
|
||||||
|
sel.collapse(position.DOMNode, 0);
|
||||||
|
Cc["@mozilla.org/focus-manager;1"]
|
||||||
|
.getService(Ci.nsIFocusManager).moveFocus(
|
||||||
|
doc.defaultView, null, Ci.nsIFocusManager.MOVEFOCUS_CARET, 0);
|
||||||
|
}
|
||||||
|
|
||||||
let newContext = this.getNewContext(event.oldAccessible,
|
let newContext = this.getNewContext(event.oldAccessible,
|
||||||
pivot.position);
|
pivot.position);
|
||||||
|
|
@ -251,13 +266,13 @@ var AccessFu = {
|
||||||
let state = {};
|
let state = {};
|
||||||
docAcc.getState(state, {});
|
docAcc.getState(state, {});
|
||||||
if (state.value & Ci.nsIAccessibleStates.STATE_BUSY &&
|
if (state.value & Ci.nsIAccessibleStates.STATE_BUSY &&
|
||||||
this.isNotChromeDoc(docAcc))
|
this._isNotChromeDoc(docAcc))
|
||||||
this.presenters.forEach(
|
this.presenters.forEach(
|
||||||
function(p) { p.tabStateChanged(docAcc, 'loading'); }
|
function(p) { p.tabStateChanged(docAcc, 'loading'); }
|
||||||
);
|
);
|
||||||
delete this._pendingDocuments[aEvent.DOMNode];
|
delete this._pendingDocuments[aEvent.DOMNode];
|
||||||
}
|
}
|
||||||
if (this.isBrowserDoc(docAcc))
|
if (this._isBrowserDoc(docAcc))
|
||||||
// A new top-level content document has been attached
|
// A new top-level content document has been attached
|
||||||
this.presenters.forEach(
|
this.presenters.forEach(
|
||||||
function(p) { p.tabStateChanged(docAcc, 'newdoc'); }
|
function(p) { p.tabStateChanged(docAcc, 'newdoc'); }
|
||||||
|
|
@ -267,7 +282,7 @@ var AccessFu = {
|
||||||
}
|
}
|
||||||
case Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE:
|
case Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE:
|
||||||
{
|
{
|
||||||
if (this.isNotChromeDoc(aEvent.accessible)) {
|
if (this._isNotChromeDoc(aEvent.accessible)) {
|
||||||
this.presenters.forEach(
|
this.presenters.forEach(
|
||||||
function(p) {
|
function(p) {
|
||||||
p.tabStateChanged(aEvent.accessible, 'loaded');
|
p.tabStateChanged(aEvent.accessible, 'loaded');
|
||||||
|
|
@ -296,7 +311,7 @@ var AccessFu = {
|
||||||
}
|
}
|
||||||
case Ci.nsIAccessibleEvent.EVENT_FOCUS:
|
case Ci.nsIAccessibleEvent.EVENT_FOCUS:
|
||||||
{
|
{
|
||||||
if (this.isBrowserDoc(aEvent.accessible)) {
|
if (this._isBrowserDoc(aEvent.accessible)) {
|
||||||
// The document recieved focus, call tabSelected to present current tab.
|
// The document recieved focus, call tabSelected to present current tab.
|
||||||
this.presenters.forEach(
|
this.presenters.forEach(
|
||||||
function(p) { p.tabSelected(aEvent.accessible); });
|
function(p) { p.tabSelected(aEvent.accessible); });
|
||||||
|
|
@ -342,7 +357,7 @@ var AccessFu = {
|
||||||
* @param {nsIAccessible} aDocAcc the accessible to check.
|
* @param {nsIAccessible} aDocAcc the accessible to check.
|
||||||
* @return {boolean} true if this is a top-level content document.
|
* @return {boolean} true if this is a top-level content document.
|
||||||
*/
|
*/
|
||||||
isBrowserDoc: function isBrowserDoc(aDocAcc) {
|
_isBrowserDoc: function _isBrowserDoc(aDocAcc) {
|
||||||
let parent = aDocAcc.parent;
|
let parent = aDocAcc.parent;
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -360,7 +375,7 @@ var AccessFu = {
|
||||||
* @param {nsIDOMDocument} aDocument the document to check.
|
* @param {nsIDOMDocument} aDocument the document to check.
|
||||||
* @return {boolean} true if this is not a chrome document.
|
* @return {boolean} true if this is not a chrome document.
|
||||||
*/
|
*/
|
||||||
isNotChromeDoc: function isNotChromeDoc(aDocument) {
|
_isNotChromeDoc: function _isNotChromeDoc(aDocument) {
|
||||||
let location = aDocument.DOMNode.location;
|
let location = aDocument.DOMNode.location;
|
||||||
if (!location)
|
if (!location)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,9 @@ Presenter.prototype = {
|
||||||
/**
|
/**
|
||||||
* Text has changed, either by the user or by the system. TODO.
|
* Text has changed, either by the user or by the system. TODO.
|
||||||
*/
|
*/
|
||||||
textChanged: function textChanged(aIsInserted, aStartOffset, aLength, aText, aModifiedText) {},
|
textChanged: function textChanged(aIsInserted, aStartOffset,
|
||||||
|
aLength, aText,
|
||||||
|
aModifiedText) {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Text selection has changed. TODO.
|
* Text selection has changed. TODO.
|
||||||
|
|
@ -95,14 +97,15 @@ Presenter.prototype = {
|
||||||
|
|
||||||
function VisualPresenter() {}
|
function VisualPresenter() {}
|
||||||
|
|
||||||
VisualPresenter.prototype = new Presenter();
|
VisualPresenter.prototype = {
|
||||||
|
__proto__: Presenter.prototype,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The padding in pixels between the object and the highlight border.
|
* The padding in pixels between the object and the highlight border.
|
||||||
*/
|
*/
|
||||||
VisualPresenter.prototype.BORDER_PADDING = 2;
|
BORDER_PADDING: 2,
|
||||||
|
|
||||||
VisualPresenter.prototype.attach = function(aWindow) {
|
attach: function VisualPresenter_attach(aWindow) {
|
||||||
this.chromeWin = aWindow;
|
this.chromeWin = aWindow;
|
||||||
|
|
||||||
// Add stylesheet
|
// Add stylesheet
|
||||||
|
|
@ -123,61 +126,61 @@ VisualPresenter.prototype.attach = function(aWindow) {
|
||||||
inset.id = 'virtual-cursor-inset';
|
inset.id = 'virtual-cursor-inset';
|
||||||
|
|
||||||
this.highlightBox.appendChild(inset);
|
this.highlightBox.appendChild(inset);
|
||||||
};
|
},
|
||||||
|
|
||||||
VisualPresenter.prototype.detach = function() {
|
detach: function VisualPresenter_detach() {
|
||||||
this.chromeWin.document.removeChild(this.stylesheet);
|
this.chromeWin.document.removeChild(this.stylesheet);
|
||||||
this.highlightBox.parentNode.removeChild(this.highlightBox);
|
this.highlightBox.parentNode.removeChild(this.highlightBox);
|
||||||
this.highlightBox = this.stylesheet = null;
|
this.highlightBox = this.stylesheet = null;
|
||||||
};
|
},
|
||||||
|
|
||||||
VisualPresenter.prototype.viewportChanged = function() {
|
viewportChanged: function VisualPresenter_viewportChanged() {
|
||||||
if (this._currentObject)
|
if (this._currentObject)
|
||||||
this.highlight(this._currentObject);
|
this._highlight(this._currentObject);
|
||||||
};
|
},
|
||||||
|
|
||||||
VisualPresenter.prototype.pivotChanged = function(aObject, aNewContext) {
|
pivotChanged: function VisualPresenter_pivotChanged(aObject, aNewContext) {
|
||||||
this._currentObject = aObject;
|
this._currentObject = aObject;
|
||||||
|
|
||||||
if (!aObject) {
|
if (!aObject) {
|
||||||
this.hide();
|
this._hide();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
aObject.scrollTo(Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
|
aObject.scrollTo(Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
|
||||||
this.highlight(aObject);
|
this._highlight(aObject);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dump('Error getting bounds: ' + e);
|
dump('Error getting bounds: ' + e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
VisualPresenter.prototype.tabSelected = function(aDocObj) {
|
tabSelected: function VisualPresenter_tabSelected(aDocObj) {
|
||||||
let vcPos = aDocObj ?
|
let vcPos = aDocObj ? aDocObj.QueryInterface(Ci.nsIAccessibleCursorable).
|
||||||
aDocObj.QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor.position :
|
virtualCursor.position : null;
|
||||||
null;
|
|
||||||
|
|
||||||
this.pivotChanged(vcPos);
|
this.pivotChanged(vcPos);
|
||||||
};
|
},
|
||||||
|
|
||||||
VisualPresenter.prototype.tabStateChanged = function(aDocObj, aPageState) {
|
tabStateChanged: function VisualPresenter_tabStateChanged(aDocObj,
|
||||||
if (aPageState == "newdoc")
|
aPageState) {
|
||||||
|
if (aPageState == 'newdoc')
|
||||||
this.pivotChanged(null);
|
this.pivotChanged(null);
|
||||||
};
|
},
|
||||||
|
|
||||||
// Internals
|
// Internals
|
||||||
|
|
||||||
VisualPresenter.prototype.hide = function hide() {
|
_hide: function _hide() {
|
||||||
this.highlightBox.style.display = 'none';
|
this.highlightBox.style.display = 'none';
|
||||||
};
|
},
|
||||||
|
|
||||||
VisualPresenter.prototype.highlight = function(aObject) {
|
_highlight: function _highlight(aObject) {
|
||||||
let vp = (Services.appinfo.OS == 'Android') ?
|
let vp = (Services.appinfo.OS == 'Android') ?
|
||||||
this.chromeWin.BrowserApp.selectedTab.getViewport() :
|
this.chromeWin.BrowserApp.selectedTab.getViewport() :
|
||||||
{ zoom: 1.0, offsetY: 0 };
|
{ zoom: 1.0, offsetY: 0 };
|
||||||
|
|
||||||
let bounds = this.getBounds(aObject, vp.zoom);
|
let bounds = this._getBounds(aObject, vp.zoom);
|
||||||
|
|
||||||
// First hide it to avoid flickering when changing the style.
|
// First hide it to avoid flickering when changing the style.
|
||||||
this.highlightBox.style.display = 'none';
|
this.highlightBox.style.display = 'none';
|
||||||
|
|
@ -186,9 +189,9 @@ VisualPresenter.prototype.highlight = function(aObject) {
|
||||||
this.highlightBox.style.width = bounds.width + 'px';
|
this.highlightBox.style.width = bounds.width + 'px';
|
||||||
this.highlightBox.style.height = bounds.height + 'px';
|
this.highlightBox.style.height = bounds.height + 'px';
|
||||||
this.highlightBox.style.display = 'block';
|
this.highlightBox.style.display = 'block';
|
||||||
};
|
},
|
||||||
|
|
||||||
VisualPresenter.prototype.getBounds = function(aObject, aZoom, aStart, aEnd) {
|
_getBounds: function _getBounds(aObject, aZoom, aStart, aEnd) {
|
||||||
let objX = {}, objY = {}, objW = {}, objH = {};
|
let objX = {}, objY = {}, objW = {}, objH = {};
|
||||||
|
|
||||||
if (aEnd >= 0 && aStart >= 0 && aEnd != aStart) {
|
if (aEnd >= 0 && aStart >= 0 && aEnd != aStart) {
|
||||||
|
|
@ -211,24 +214,27 @@ VisualPresenter.prototype.getBounds = function(aObject, aZoom, aStart, aEnd) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Android presenter. Fires Android a11y events.
|
* Android presenter. Fires Android a11y events.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ANDROID_TYPE_VIEW_CLICKED = 0x01;
|
|
||||||
const ANDROID_TYPE_VIEW_LONG_CLICKED = 0x02;
|
|
||||||
const ANDROID_TYPE_VIEW_SELECTED = 0x04;
|
|
||||||
const ANDROID_TYPE_VIEW_FOCUSED = 0x08;
|
|
||||||
const ANDROID_TYPE_VIEW_TEXT_CHANGED = 0x10;
|
|
||||||
const ANDROID_TYPE_WINDOW_STATE_CHANGED = 0x20;
|
|
||||||
|
|
||||||
function AndroidPresenter() {}
|
function AndroidPresenter() {}
|
||||||
|
|
||||||
AndroidPresenter.prototype = new Presenter();
|
AndroidPresenter.prototype = {
|
||||||
|
__proto__: Presenter.prototype,
|
||||||
|
|
||||||
AndroidPresenter.prototype.pivotChanged = function(aObject, aNewContext) {
|
// Android AccessibilityEvent type constants.
|
||||||
|
ANDROID_VIEW_CLICKED: 0x01,
|
||||||
|
ANDROID_VIEW_LONG_CLICKED: 0x02,
|
||||||
|
ANDROID_VIEW_SELECTED: 0x04,
|
||||||
|
ANDROID_VIEW_FOCUSED: 0x08,
|
||||||
|
ANDROID_VIEW_TEXT_CHANGED: 0x10,
|
||||||
|
ANDROID_WINDOW_STATE_CHANGED: 0x20,
|
||||||
|
|
||||||
|
pivotChanged: function AndroidPresenter_pivotChanged(aObject, aNewContext) {
|
||||||
let output = [];
|
let output = [];
|
||||||
for (let i in aNewContext)
|
for (let i in aNewContext)
|
||||||
output.push.apply(output,
|
output.push.apply(output,
|
||||||
|
|
@ -240,23 +246,23 @@ AndroidPresenter.prototype.pivotChanged = function(aObject, aNewContext) {
|
||||||
this.sendMessageToJava({
|
this.sendMessageToJava({
|
||||||
gecko: {
|
gecko: {
|
||||||
type: 'Accessibility:Event',
|
type: 'Accessibility:Event',
|
||||||
eventType: ANDROID_TYPE_VIEW_FOCUSED,
|
eventType: this.ANDROID_VIEW_FOCUSED,
|
||||||
text: output
|
text: output
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
},
|
||||||
|
|
||||||
AndroidPresenter.prototype.actionInvoked = function(aObject, aActionName) {
|
actionInvoked: function AndroidPresenter_actionInvoked(aObject, aActionName) {
|
||||||
this.sendMessageToJava({
|
this.sendMessageToJava({
|
||||||
gecko: {
|
gecko: {
|
||||||
type: 'Accessibility:Event',
|
type: 'Accessibility:Event',
|
||||||
eventType: ANDROID_TYPE_VIEW_CLICKED,
|
eventType: this.ANDROID_VIEW_CLICKED,
|
||||||
text: UtteranceGenerator.genForAction(aObject, aActionName)
|
text: UtteranceGenerator.genForAction(aObject, aActionName)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
},
|
||||||
|
|
||||||
AndroidPresenter.prototype.tabSelected = function(aDocObj) {
|
tabSelected: function AndroidPresenter_tabSelected(aDocObj) {
|
||||||
// Send a pivot change message with the full context utterance for this doc.
|
// Send a pivot change message with the full context utterance for this doc.
|
||||||
let vcDoc = aDocObj.QueryInterface(Ci.nsIAccessibleCursorable);
|
let vcDoc = aDocObj.QueryInterface(Ci.nsIAccessibleCursorable);
|
||||||
let context = [];
|
let context = [];
|
||||||
|
|
@ -271,9 +277,10 @@ AndroidPresenter.prototype.tabSelected = function(aDocObj) {
|
||||||
context.reverse();
|
context.reverse();
|
||||||
|
|
||||||
this.pivotChanged(vcDoc.virtualCursor.position || aDocObj, context);
|
this.pivotChanged(vcDoc.virtualCursor.position || aDocObj, context);
|
||||||
};
|
},
|
||||||
|
|
||||||
AndroidPresenter.prototype.tabStateChanged = function(aDocObj, aPageState) {
|
tabStateChanged: function AndroidPresenter_tabStateChanged(aDocObj,
|
||||||
|
aPageState) {
|
||||||
let stateUtterance = UtteranceGenerator.
|
let stateUtterance = UtteranceGenerator.
|
||||||
genForTabStateChange(aDocObj, aPageState);
|
genForTabStateChange(aDocObj, aPageState);
|
||||||
|
|
||||||
|
|
@ -283,19 +290,21 @@ AndroidPresenter.prototype.tabStateChanged = function(aDocObj, aPageState) {
|
||||||
this.sendMessageToJava({
|
this.sendMessageToJava({
|
||||||
gecko: {
|
gecko: {
|
||||||
type: 'Accessibility:Event',
|
type: 'Accessibility:Event',
|
||||||
eventType: ANDROID_TYPE_VIEW_TEXT_CHANGED,
|
eventType: this.ANDROID_VIEW_TEXT_CHANGED,
|
||||||
text: stateUtterance,
|
text: stateUtterance,
|
||||||
addedCount: stateUtterance.join(' ').length,
|
addedCount: stateUtterance.join(' ').length,
|
||||||
removedCount: 0,
|
removedCount: 0,
|
||||||
fromIndex: 0
|
fromIndex: 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
},
|
||||||
|
|
||||||
AndroidPresenter.prototype.textChanged = function(aIsInserted, aStart, aLength, aText, aModifiedText) {
|
textChanged: function AndroidPresenter_textChanged(aIsInserted, aStart,
|
||||||
|
aLength, aText,
|
||||||
|
aModifiedText) {
|
||||||
let androidEvent = {
|
let androidEvent = {
|
||||||
type: 'Accessibility:Event',
|
type: 'Accessibility:Event',
|
||||||
eventType: ANDROID_TYPE_VIEW_TEXT_CHANGED,
|
eventType: this.ANDROID_VIEW_TEXT_CHANGED,
|
||||||
text: [aText],
|
text: [aText],
|
||||||
fromIndex: aStart
|
fromIndex: aStart
|
||||||
};
|
};
|
||||||
|
|
@ -311,12 +320,13 @@ AndroidPresenter.prototype.textChanged = function(aIsInserted, aStart, aLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendMessageToJava({gecko: androidEvent});
|
this.sendMessageToJava({gecko: androidEvent});
|
||||||
};
|
},
|
||||||
|
|
||||||
AndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
|
sendMessageToJava: function AndroidPresenter_sendMessageTojava(aMessage) {
|
||||||
return Cc['@mozilla.org/android/bridge;1'].
|
return Cc['@mozilla.org/android/bridge;1'].
|
||||||
getService(Ci.nsIAndroidBridge).
|
getService(Ci.nsIAndroidBridge).
|
||||||
handleGeckoMessage(JSON.stringify(aMessage));
|
handleGeckoMessage(JSON.stringify(aMessage));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -325,8 +335,10 @@ AndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
|
||||||
|
|
||||||
function DummyAndroidPresenter() {}
|
function DummyAndroidPresenter() {}
|
||||||
|
|
||||||
DummyAndroidPresenter.prototype = new AndroidPresenter();
|
DummyAndroidPresenter.prototype = {
|
||||||
|
__proto__: AndroidPresenter.prototype,
|
||||||
|
|
||||||
DummyAndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
|
sendMessageToJava: function DummyAndroidPresenter_sendMessageToJava(aMsg) {
|
||||||
dump(JSON.stringify(aMessage, null, 2) + '\n');
|
dump(JSON.stringify(aMsg, null, 2) + '\n');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -65,10 +65,10 @@ var UtteranceGenerator = {
|
||||||
* @return {Array} Two string array. The first string describes the object
|
* @return {Array} Two string array. The first string describes the object
|
||||||
* and its states. The second string is the object's name. Some object
|
* and its states. The second string is the object's name. Some object
|
||||||
* types may have the description or name omitted, instead an empty string
|
* types may have the description or name omitted, instead an empty string
|
||||||
* is returned as a placeholder. Whether the object's description or it's role
|
* is returned as a placeholder. Whether the object's description or it's
|
||||||
* is included is determined by {@link verbosityRoleMap}.
|
* role is included is determined by {@link verbosityRoleMap}.
|
||||||
*/
|
*/
|
||||||
genForObject: function(aAccessible, aForceName) {
|
genForObject: function genForObject(aAccessible, aForceName) {
|
||||||
let roleString = gAccRetrieval.getStringRole(aAccessible.role);
|
let roleString = gAccRetrieval.getStringRole(aAccessible.role);
|
||||||
|
|
||||||
let func = this.objectUtteranceFunctions[roleString] ||
|
let func = this.objectUtteranceFunctions[roleString] ||
|
||||||
|
|
@ -91,7 +91,7 @@ var UtteranceGenerator = {
|
||||||
* {@link gActionMap}.
|
* {@link gActionMap}.
|
||||||
* @return {Array} A one string array with the action.
|
* @return {Array} A one string array with the action.
|
||||||
*/
|
*/
|
||||||
genForAction: function(aObject, aActionName) {
|
genForAction: function genForAction(aObject, aActionName) {
|
||||||
return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])];
|
return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -103,7 +103,7 @@ var UtteranceGenerator = {
|
||||||
* {@link Presenter.tabStateChanged}.
|
* {@link Presenter.tabStateChanged}.
|
||||||
* @return {Array} The tab state utterace.
|
* @return {Array} The tab state utterace.
|
||||||
*/
|
*/
|
||||||
genForTabStateChange: function (aObject, aTabState) {
|
genForTabStateChange: function genForTabStateChange(aObject, aTabState) {
|
||||||
switch (aTabState) {
|
switch (aTabState) {
|
||||||
case 'newtab':
|
case 'newtab':
|
||||||
return [gStringBundle.GetStringFromName('tabNew')];
|
return [gStringBundle.GetStringFromName('tabNew')];
|
||||||
|
|
@ -177,7 +177,8 @@ var UtteranceGenerator = {
|
||||||
objectUtteranceFunctions: {
|
objectUtteranceFunctions: {
|
||||||
defaultFunc: function defaultFunc(aAccessible, aRoleStr, aFlags) {
|
defaultFunc: function defaultFunc(aAccessible, aRoleStr, aFlags) {
|
||||||
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
||||||
let desc = (aFlags & INCLUDE_ROLE) ? this._getLocalizedRole(aRoleStr) : '';
|
let desc = (aFlags & INCLUDE_ROLE) ?
|
||||||
|
this._getLocalizedRole(aRoleStr) : '';
|
||||||
|
|
||||||
let utterance = [];
|
let utterance = [];
|
||||||
|
|
||||||
|
|
@ -207,7 +208,7 @@ var UtteranceGenerator = {
|
||||||
return utterance;
|
return utterance;
|
||||||
},
|
},
|
||||||
|
|
||||||
heading: function(aAccessible, aRoleStr, aFlags) {
|
heading: function heading(aAccessible, aRoleStr, aFlags) {
|
||||||
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
||||||
let level = {};
|
let level = {};
|
||||||
aAccessible.groupPosition(level, {}, {});
|
aAccessible.groupPosition(level, {}, {});
|
||||||
|
|
@ -220,7 +221,7 @@ var UtteranceGenerator = {
|
||||||
return utterance;
|
return utterance;
|
||||||
},
|
},
|
||||||
|
|
||||||
listitem: function(aAccessible, aRoleStr, aFlags) {
|
listitem: function listitem(aAccessible, aRoleStr, aFlags) {
|
||||||
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
||||||
let localizedRole = this._getLocalizedRole(aRoleStr);
|
let localizedRole = this._getLocalizedRole(aRoleStr);
|
||||||
let itemno = {};
|
let itemno = {};
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,20 @@ var gAccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
|
||||||
getService(Ci.nsIAccessibleRetrieval);
|
getService(Ci.nsIAccessibleRetrieval);
|
||||||
|
|
||||||
var VirtualCursorController = {
|
var VirtualCursorController = {
|
||||||
|
NOT_EDITABLE: 0,
|
||||||
|
SINGLE_LINE_EDITABLE: 1,
|
||||||
|
MULTI_LINE_EDITABLE: 2,
|
||||||
|
|
||||||
attach: function attach(aWindow) {
|
attach: function attach(aWindow) {
|
||||||
this.chromeWin = aWindow;
|
this.chromeWin = aWindow;
|
||||||
this.chromeWin.document.addEventListener('keypress', this.onkeypress, true);
|
this.chromeWin.document.addEventListener('keypress', this, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
detach: function detach() {
|
detach: function detach() {
|
||||||
this.chromeWin.document.removeEventListener('keypress', this.onkeypress, true);
|
this.chromeWin.document.removeEventListener('keypress', this, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
getBrowserApp: function getBrowserApp() {
|
_getBrowserApp: function _getBrowserApp() {
|
||||||
switch (Services.appinfo.OS) {
|
switch (Services.appinfo.OS) {
|
||||||
case 'Android':
|
case 'Android':
|
||||||
return this.chromeWin.BrowserApp;
|
return this.chromeWin.BrowserApp;
|
||||||
|
|
@ -36,39 +40,49 @@ var VirtualCursorController = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onkeypress: function onkeypress(aEvent) {
|
handleEvent: function handleEvent(aEvent) {
|
||||||
let document = VirtualCursorController.getBrowserApp().
|
let document = this._getBrowserApp().selectedBrowser.contentDocument;
|
||||||
selectedBrowser.contentDocument;
|
let target = aEvent.target;
|
||||||
|
|
||||||
dump('keypress ' + aEvent.keyCode + '\n');
|
|
||||||
|
|
||||||
switch (aEvent.keyCode) {
|
switch (aEvent.keyCode) {
|
||||||
case aEvent.DOM_VK_END:
|
case aEvent.DOM_VK_END:
|
||||||
VirtualCursorController.moveForward(document, true);
|
this.moveForward(document, true);
|
||||||
break;
|
break;
|
||||||
case aEvent.DOM_VK_HOME:
|
case aEvent.DOM_VK_HOME:
|
||||||
VirtualCursorController.moveBackward(document, true);
|
this.moveBackward(document, true);
|
||||||
break;
|
break;
|
||||||
case aEvent.DOM_VK_RIGHT:
|
case aEvent.DOM_VK_RIGHT:
|
||||||
VirtualCursorController.moveForward(document, aEvent.shiftKey);
|
if (this._isEditableText(target) &&
|
||||||
|
target.selectionEnd != target.textLength)
|
||||||
|
// Don't move forward if caret is not at end of entry.
|
||||||
|
// XXX: Fix for rtl
|
||||||
|
return;
|
||||||
|
this.moveForward(document, aEvent.shiftKey);
|
||||||
break;
|
break;
|
||||||
case aEvent.DOM_VK_LEFT:
|
case aEvent.DOM_VK_LEFT:
|
||||||
VirtualCursorController.moveBackward(document, aEvent.shiftKey);
|
if (this._isEditableText(target) &&
|
||||||
|
target.selectionEnd != 0)
|
||||||
|
// Don't move backward if caret is not at start of entry.
|
||||||
|
// XXX: Fix for rtl
|
||||||
|
return;
|
||||||
|
this.moveBackward(document, aEvent.shiftKey);
|
||||||
break;
|
break;
|
||||||
case aEvent.DOM_VK_UP:
|
case aEvent.DOM_VK_UP:
|
||||||
|
if (this._isEditableText(target) == this.MULTI_LINE_EDITABLE &&
|
||||||
|
target.selectionEnd != 0)
|
||||||
|
// Don't blur content if caret is not at start of text area.
|
||||||
|
return;
|
||||||
if (Services.appinfo.OS == 'Android')
|
if (Services.appinfo.OS == 'Android')
|
||||||
// Return focus to browser chrome, which in Android is a native widget.
|
// Return focus to native Android browser chrome.
|
||||||
Cc['@mozilla.org/android/bridge;1'].
|
Cc['@mozilla.org/android/bridge;1'].
|
||||||
getService(Ci.nsIAndroidBridge).handleGeckoMessage(
|
getService(Ci.nsIAndroidBridge).handleGeckoMessage(
|
||||||
JSON.stringify({ gecko: { type: 'ToggleChrome:Focus' } }));
|
JSON.stringify({ gecko: { type: 'ToggleChrome:Focus' } }));
|
||||||
break;
|
break;
|
||||||
case aEvent.DOM_VK_RETURN:
|
case aEvent.DOM_VK_RETURN:
|
||||||
// XXX: It is true that desktop does not map the keypad enter key to
|
|
||||||
// DOM_VK_ENTER. So for desktop we require a ctrl+return instead.
|
|
||||||
if (Services.appinfo.OS == 'Android' || !aEvent.ctrlKey)
|
|
||||||
return;
|
|
||||||
case aEvent.DOM_VK_ENTER:
|
case aEvent.DOM_VK_ENTER:
|
||||||
VirtualCursorController.activateCurrent(document);
|
if (this._isEditableText(target))
|
||||||
|
return;
|
||||||
|
this.activateCurrent(document);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
|
@ -78,6 +92,18 @@ var VirtualCursorController = {
|
||||||
aEvent.stopPropagation();
|
aEvent.stopPropagation();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_isEditableText: function _isEditableText(aElement) {
|
||||||
|
// XXX: Support contentEditable and design mode
|
||||||
|
if (aElement instanceof Ci.nsIDOMHTMLInputElement &&
|
||||||
|
aElement.mozIsTextField(false))
|
||||||
|
return this.SINGLE_LINE_EDITABLE;
|
||||||
|
|
||||||
|
if (aElement instanceof Ci.nsIDOMHTMLTextAreaElement)
|
||||||
|
return this.MULTI_LINE_EDITABLE;
|
||||||
|
|
||||||
|
return this.NOT_EDITABLE;
|
||||||
|
},
|
||||||
|
|
||||||
moveForward: function moveForward(document, last) {
|
moveForward: function moveForward(document, last) {
|
||||||
let virtualCursor = this.getVirtualCursor(document);
|
let virtualCursor = this.getVirtualCursor(document);
|
||||||
if (last) {
|
if (last) {
|
||||||
|
|
@ -110,7 +136,7 @@ var VirtualCursorController = {
|
||||||
},
|
},
|
||||||
|
|
||||||
SimpleTraversalRule: {
|
SimpleTraversalRule: {
|
||||||
getMatchRoles: function(aRules) {
|
getMatchRoles: function SimpleTraversalRule_getmatchRoles(aRules) {
|
||||||
aRules.value = this._matchRoles;
|
aRules.value = this._matchRoles;
|
||||||
return this._matchRoles.length;
|
return this._matchRoles.length;
|
||||||
},
|
},
|
||||||
|
|
@ -118,7 +144,7 @@ var VirtualCursorController = {
|
||||||
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
|
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
|
||||||
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
|
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
|
||||||
|
|
||||||
match: function(aAccessible) {
|
match: function SimpleTraversalRule_match(aAccessible) {
|
||||||
switch (aAccessible.role) {
|
switch (aAccessible.role) {
|
||||||
case Ci.nsIAccessibleRole.ROLE_COMBOBOX:
|
case Ci.nsIAccessibleRole.ROLE_COMBOBOX:
|
||||||
// We don't want to ignore the subtree because this is often
|
// We don't want to ignore the subtree because this is often
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ const FILTER_MATCH = nsIAccessibleTraversalRule.FILTER_MATCH;
|
||||||
const FILTER_IGNORE = nsIAccessibleTraversalRule.FILTER_IGNORE;
|
const FILTER_IGNORE = nsIAccessibleTraversalRule.FILTER_IGNORE;
|
||||||
const FILTER_IGNORE_SUBTREE = nsIAccessibleTraversalRule.FILTER_IGNORE_SUBTREE;
|
const FILTER_IGNORE_SUBTREE = nsIAccessibleTraversalRule.FILTER_IGNORE_SUBTREE;
|
||||||
|
|
||||||
|
const NS_ERROR_NOT_IN_TREE = 0x80780026;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Traversal rules
|
// Traversal rules
|
||||||
|
|
||||||
|
|
@ -68,13 +70,13 @@ var ObjectTraversalRule =
|
||||||
/**
|
/**
|
||||||
* A checker for virtual cursor changed events.
|
* A checker for virtual cursor changed events.
|
||||||
*/
|
*/
|
||||||
function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
|
function VCChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
|
||||||
{
|
{
|
||||||
this.__proto__ = new invokerChecker(EVENT_VIRTUALCURSOR_CHANGED, aDocAcc);
|
this.__proto__ = new invokerChecker(EVENT_VIRTUALCURSOR_CHANGED, aDocAcc);
|
||||||
|
|
||||||
this.check = function virtualCursorChangedChecker_check(aEvent)
|
this.check = function VCChangedChecker_check(aEvent)
|
||||||
{
|
{
|
||||||
SimpleTest.info("virtualCursorChangedChecker_check");
|
SimpleTest.info("VCChangedChecker_check");
|
||||||
|
|
||||||
var event = null;
|
var event = null;
|
||||||
try {
|
try {
|
||||||
|
|
@ -100,7 +102,7 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
|
||||||
"wrong end offset");
|
"wrong end offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
var prevPosAndOffset = virtualCursorChangedChecker.
|
var prevPosAndOffset = VCChangedChecker.
|
||||||
getPreviousPosAndOffset(aDocAcc.virtualCursor);
|
getPreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||||
|
|
||||||
if (prevPosAndOffset) {
|
if (prevPosAndOffset) {
|
||||||
|
|
@ -114,36 +116,36 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
virtualCursorChangedChecker.prevPosAndOffset = {};
|
VCChangedChecker.prevPosAndOffset = {};
|
||||||
|
|
||||||
virtualCursorChangedChecker.storePreviousPosAndOffset =
|
VCChangedChecker.storePreviousPosAndOffset =
|
||||||
function storePreviousPosAndOffset(aPivot)
|
function storePreviousPosAndOffset(aPivot)
|
||||||
{
|
{
|
||||||
virtualCursorChangedChecker.prevPosAndOffset[aPivot] =
|
VCChangedChecker.prevPosAndOffset[aPivot] =
|
||||||
{position: aPivot.position,
|
{position: aPivot.position,
|
||||||
startOffset: aPivot.startOffset,
|
startOffset: aPivot.startOffset,
|
||||||
endOffset: aPivot.endOffset};
|
endOffset: aPivot.endOffset};
|
||||||
};
|
};
|
||||||
|
|
||||||
virtualCursorChangedChecker.getPreviousPosAndOffset =
|
VCChangedChecker.getPreviousPosAndOffset =
|
||||||
function getPreviousPosAndOffset(aPivot)
|
function getPreviousPosAndOffset(aPivot)
|
||||||
{
|
{
|
||||||
return virtualCursorChangedChecker.prevPosAndOffset[aPivot];
|
return VCChangedChecker.prevPosAndOffset[aPivot];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a text range in the pivot and wait for virtual cursor change event.
|
* Set a text range in the pivot and wait for virtual cursor change event.
|
||||||
*
|
*
|
||||||
* @param aDocAcc document that manages the virtual cursor
|
* @param aDocAcc [in] document that manages the virtual cursor
|
||||||
* @param aTextAccessible accessible to set to virtual cursor's position
|
* @param aTextAccessible [in] accessible to set to virtual cursor's position
|
||||||
* @param aTextOffsets start and end offsets of text range to set in virtual
|
* @param aTextOffsets [in] start and end offsets of text range to set in
|
||||||
* cursor
|
* virtual cursor.
|
||||||
*/
|
*/
|
||||||
function setVirtualCursorRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
|
function setVCRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||||
{
|
{
|
||||||
this.invoke = function virtualCursorChangedInvoker_invoke()
|
this.invoke = function virtualCursorChangedInvoker_invoke()
|
||||||
{
|
{
|
||||||
virtualCursorChangedChecker.
|
VCChangedChecker.
|
||||||
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||||
SimpleTest.info(prettyName(aTextAccessible) + " " + aTextOffsets);
|
SimpleTest.info(prettyName(aTextAccessible) + " " + aTextOffsets);
|
||||||
aDocAcc.virtualCursor.setTextRange(aTextAccessible,
|
aDocAcc.virtualCursor.setTextRange(aTextAccessible,
|
||||||
|
|
@ -151,45 +153,44 @@ function setVirtualCursorRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||||
aTextOffsets[1]);
|
aTextOffsets[1]);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getID = function setVirtualCursorRangeInvoker_getID()
|
this.getID = function setVCRangeInvoker_getID()
|
||||||
{
|
{
|
||||||
return "Set offset in " + prettyName(aTextAccessible) +
|
return "Set offset in " + prettyName(aTextAccessible) +
|
||||||
" to (" + aTextOffsets[0] + ", " + aTextOffsets[1] + ")";
|
" to (" + aTextOffsets[0] + ", " + aTextOffsets[1] + ")";
|
||||||
}
|
};
|
||||||
|
|
||||||
this.eventSeq = [
|
this.eventSeq = [
|
||||||
new virtualCursorChangedChecker(aDocAcc, aTextAccessible, aTextOffsets)
|
new VCChangedChecker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the pivot and wait for virtual cursor change event.
|
* Move the pivot and wait for virtual cursor change event.
|
||||||
*
|
*
|
||||||
* @param aDocAcc document that manages the virtual cursor
|
* @param aDocAcc [in] document that manages the virtual cursor
|
||||||
* @param aPivotMoveMethod method to test (ie. "moveNext", "moveFirst", etc.)
|
* @param aPivotMoveMethod [in] method to test (ie. "moveNext", "moveFirst", etc.)
|
||||||
* @param aRule traversal rule object
|
* @param aRule [in] traversal rule object
|
||||||
* @param aIdOrNameOrAcc id, accessivle or accessible name to expect virtual
|
* @param aIdOrNameOrAcc [in] id, accessivle or accessible name to expect
|
||||||
* cursor to land on after performing move method.
|
* virtual cursor to land on after performing move method.
|
||||||
*/
|
*/
|
||||||
function setVirtualCursorPosInvoker(aDocAcc, aPivotMoveMethod, aRule,
|
function setVCPosInvoker(aDocAcc, aPivotMoveMethod, aRule, aIdOrNameOrAcc)
|
||||||
aIdOrNameOrAcc)
|
|
||||||
{
|
{
|
||||||
this.invoke = function virtualCursorChangedInvoker_invoke()
|
this.invoke = function virtualCursorChangedInvoker_invoke()
|
||||||
{
|
{
|
||||||
virtualCursorChangedChecker.
|
VCChangedChecker.
|
||||||
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||||
var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
|
var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
|
||||||
SimpleTest.ok((aIdOrNameOrAcc && moved) || (!aIdOrNameOrAcc && !moved),
|
SimpleTest.ok((aIdOrNameOrAcc && moved) || (!aIdOrNameOrAcc && !moved),
|
||||||
"moved pivot");
|
"moved pivot");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getID = function setVirtualCursorPosInvoker_getID()
|
this.getID = function setVCPosInvoker_getID()
|
||||||
{
|
{
|
||||||
return "Do " + (aIdOrNameOrAcc ? "" : "no-op ") + aPivotMoveMethod;
|
return "Do " + (aIdOrNameOrAcc ? "" : "no-op ") + aPivotMoveMethod;
|
||||||
}
|
};
|
||||||
|
|
||||||
if (aIdOrNameOrAcc) {
|
if (aIdOrNameOrAcc) {
|
||||||
this.eventSeq = [ new virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc) ];
|
this.eventSeq = [ new VCChangedChecker(aDocAcc, aIdOrNameOrAcc) ];
|
||||||
} else {
|
} else {
|
||||||
this.eventSeq = [];
|
this.eventSeq = [];
|
||||||
this.unexpectedEventSeq = [
|
this.unexpectedEventSeq = [
|
||||||
|
|
@ -202,10 +203,10 @@ function setVirtualCursorPosInvoker(aDocAcc, aPivotMoveMethod, aRule,
|
||||||
* Add invokers to a queue to test a rule and an expected sequence of element ids
|
* Add invokers to a queue to test a rule and an expected sequence of element ids
|
||||||
* or accessible names for that rule in the given document.
|
* or accessible names for that rule in the given document.
|
||||||
*
|
*
|
||||||
* @param aQueue event queue in which to push invoker sequence.
|
* @param aQueue [in] event queue in which to push invoker sequence.
|
||||||
* @param aDocAcc the managing document of the virtual cursor we are testing
|
* @param aDocAcc [in] the managing document of the virtual cursor we are testing
|
||||||
* @param aRule the traversal rule to use in the invokers
|
* @param aRule [in] the traversal rule to use in the invokers
|
||||||
* @param aSequence a sequence of accessible names or elemnt ids to expect with
|
* @param aSequence [in] a sequence of accessible names or elemnt ids to expect with
|
||||||
* the given rule in the given document
|
* the given rule in the given document
|
||||||
*/
|
*/
|
||||||
function queueTraversalSequence(aQueue, aDocAcc, aRule, aSequence)
|
function queueTraversalSequence(aQueue, aDocAcc, aRule, aSequence)
|
||||||
|
|
@ -213,34 +214,126 @@ function queueTraversalSequence(aQueue, aDocAcc, aRule, aSequence)
|
||||||
aDocAcc.virtualCursor.position = null;
|
aDocAcc.virtualCursor.position = null;
|
||||||
|
|
||||||
for (var i = 0; i < aSequence.length; i++) {
|
for (var i = 0; i < aSequence.length; i++) {
|
||||||
var invoker = new setVirtualCursorPosInvoker(aDocAcc, "moveNext",
|
var invoker =
|
||||||
aRule, aSequence[i]);
|
new setVCPosInvoker(aDocAcc, "moveNext", aRule, aSequence[i]);
|
||||||
aQueue.push(invoker);
|
aQueue.push(invoker);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No further more matches for given rule, expect no virtual cursor changes.
|
// No further more matches for given rule, expect no virtual cursor changes.
|
||||||
aQueue.push(new setVirtualCursorPosInvoker(aDocAcc, "moveNext", aRule, null));
|
aQueue.push(new setVCPosInvoker(aDocAcc, "moveNext", aRule, null));
|
||||||
|
|
||||||
for (var i = aSequence.length-2; i >= 0; i--) {
|
for (var i = aSequence.length-2; i >= 0; i--) {
|
||||||
var invoker = new setVirtualCursorPosInvoker(aDocAcc, "movePrevious",
|
var invoker =
|
||||||
aRule, aSequence[i])
|
new setVCPosInvoker(aDocAcc, "movePrevious", aRule, aSequence[i]);
|
||||||
aQueue.push(invoker);
|
aQueue.push(invoker);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No previous more matches for given rule, expect no virtual cursor changes.
|
// No previous more matches for given rule, expect no virtual cursor changes.
|
||||||
aQueue.push(new setVirtualCursorPosInvoker(aDocAcc, "movePrevious", aRule, null));
|
aQueue.push(new setVCPosInvoker(aDocAcc, "movePrevious", aRule, null));
|
||||||
|
|
||||||
aQueue.push(new setVirtualCursorPosInvoker(
|
aQueue.push(new setVCPosInvoker(aDocAcc, "moveLast", aRule,
|
||||||
aDocAcc, "moveLast", aRule, aSequence[aSequence.length - 1]));
|
aSequence[aSequence.length - 1]));
|
||||||
|
|
||||||
// No further more matches for given rule, expect no virtual cursor changes.
|
// No further more matches for given rule, expect no virtual cursor changes.
|
||||||
aQueue.push(new setVirtualCursorPosInvoker(aDocAcc, "moveNext", aRule, null));
|
aQueue.push(new setVCPosInvoker(aDocAcc, "moveNext", aRule, null));
|
||||||
|
|
||||||
aQueue.push(new setVirtualCursorPosInvoker(
|
aQueue.push(new setVCPosInvoker(aDocAcc, "moveFirst", aRule, aSequence[0]));
|
||||||
aDocAcc, "moveFirst", aRule, aSequence[0]));
|
|
||||||
|
|
||||||
// No previous more matches for given rule, expect no virtual cursor changes.
|
// No previous more matches for given rule, expect no virtual cursor changes.
|
||||||
aQueue.push(new setVirtualCursorPosInvoker(aDocAcc, "movePrevious", aRule, null));
|
aQueue.push(new setVCPosInvoker(aDocAcc, "movePrevious", aRule, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A checker for removing an accessible while the virtual cursor is on it.
|
||||||
|
*/
|
||||||
|
function removeVCPositionChecker(aDocAcc, aHiddenParentAcc)
|
||||||
|
{
|
||||||
|
this.__proto__ = new invokerChecker(EVENT_REORDER, aHiddenParentAcc);
|
||||||
|
|
||||||
|
this.check = function removeVCPositionChecker_check(aEvent) {
|
||||||
|
var errorResult = 0;
|
||||||
|
try {
|
||||||
|
aDocAcc.virtualCursor.moveNext(ObjectTraversalRule);
|
||||||
|
} catch (x) {
|
||||||
|
errorResult = x.result;
|
||||||
|
}
|
||||||
|
SimpleTest.is(
|
||||||
|
errorResult, NS_ERROR_NOT_IN_TREE,
|
||||||
|
"Expecting NOT_IN_TREE error when moving pivot from invalid position.");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put the virtual cursor's position on an object, and then remove it.
|
||||||
|
*
|
||||||
|
* @param aDocAcc [in] document that manages the virtual cursor
|
||||||
|
* @param aPosNode [in] DOM node to hide after virtual cursor's position is
|
||||||
|
* set to it.
|
||||||
|
*/
|
||||||
|
function removeVCPositionInvoker(aDocAcc, aPosNode)
|
||||||
|
{
|
||||||
|
this.accessible = getAccessible(aPosNode);
|
||||||
|
this.invoke = function removeVCPositionInvoker_invoke()
|
||||||
|
{
|
||||||
|
aDocAcc.virtualCursor.position = this.accessible;
|
||||||
|
aPosNode.parentNode.removeChild(aPosNode);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getID = function removeVCPositionInvoker_getID()
|
||||||
|
{
|
||||||
|
return "Bring virtual cursor to accessible, and remove its DOM node.";
|
||||||
|
};
|
||||||
|
|
||||||
|
this.eventSeq = [
|
||||||
|
new removeVCPositionChecker(aDocAcc, this.accessible.parent)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A checker for removing the pivot root and then calling moveFirst, and
|
||||||
|
* checking that an exception is thrown.
|
||||||
|
*/
|
||||||
|
function removeVCRootChecker(aPivot)
|
||||||
|
{
|
||||||
|
this.__proto__ = new invokerChecker(EVENT_REORDER, aPivot.root.parent);
|
||||||
|
|
||||||
|
this.check = function removeVCRootChecker_check(aEvent) {
|
||||||
|
var errorResult = 0;
|
||||||
|
try {
|
||||||
|
aPivot.moveLast(ObjectTraversalRule);
|
||||||
|
} catch (x) {
|
||||||
|
errorResult = x.result;
|
||||||
|
}
|
||||||
|
SimpleTest.is(
|
||||||
|
errorResult, NS_ERROR_NOT_IN_TREE,
|
||||||
|
"Expecting NOT_IN_TREE error when moving pivot from invalid position.");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a pivot, remove its root, and perform an operation where the root is
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
* @param aRootNode [in] DOM node of which accessible will be the root of the
|
||||||
|
* pivot. Should have more than one child.
|
||||||
|
*/
|
||||||
|
function removeVCRootInvoker(aRootNode)
|
||||||
|
{
|
||||||
|
this.pivot = gAccRetrieval.createAccessiblePivot(getAccessible(aRootNode));
|
||||||
|
this.invoke = function removeVCRootInvoker_invoke()
|
||||||
|
{
|
||||||
|
this.pivot.position = this.pivot.root.firstChild;
|
||||||
|
aRootNode.parentNode.removeChild(aRootNode);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getID = function removeVCRootInvoker_getID()
|
||||||
|
{
|
||||||
|
return "Remove root of pivot from tree.";
|
||||||
|
};
|
||||||
|
|
||||||
|
this.eventSeq = [
|
||||||
|
new removeVCRootChecker(this.pivot)
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@
|
||||||
<iframe
|
<iframe
|
||||||
src="data:text/html,<html><body>An <i>embedded</i> document.</body></html>">
|
src="data:text/html,<html><body>An <i>embedded</i> document.</body></html>">
|
||||||
</iframe>
|
</iframe>
|
||||||
<p>
|
<div id="hide-me">Hide me</div>
|
||||||
|
<p id="links">
|
||||||
<a href="http://mozilla.org" title="Link 1 title">Link 1</a>
|
<a href="http://mozilla.org" title="Link 1 title">Link 1</a>
|
||||||
<a href="http://mozilla.org" title="Link 2 title">Link 2</a>
|
<a href="http://mozilla.org" title="Link 2 title">Link 2</a>
|
||||||
<a href="http://mozilla.org" title="Link 3 title">Link 3</a>
|
<a href="http://mozilla.org" title="Link 3 title">Link 3</a>
|
||||||
|
|
|
||||||
|
|
@ -60,15 +60,22 @@
|
||||||
'dolor', ' sit amet. Integer vitae urna leo, id ',
|
'dolor', ' sit amet. Integer vitae urna leo, id ',
|
||||||
'semper', ' nulla. ', 'Second Section Title',
|
'semper', ' nulla. ', 'Second Section Title',
|
||||||
'Sed accumsan luctus lacus, vitae mollis arcu tristique vulputate.',
|
'Sed accumsan luctus lacus, vitae mollis arcu tristique vulputate.',
|
||||||
'An ', 'embedded', ' document.', 'Link 1', 'Link 2', 'Link 3']);
|
'An ', 'embedded', ' document.', 'Hide me', 'Link 1', 'Link 2',
|
||||||
|
'Link 3']);
|
||||||
|
|
||||||
// Just a random smoke test to see if our setTextRange works.
|
// Just a random smoke test to see if our setTextRange works.
|
||||||
gQueue.push(
|
gQueue.push(
|
||||||
new setVirtualCursorRangeInvoker(
|
new setVCRangeInvoker(
|
||||||
docAcc,
|
docAcc,
|
||||||
getAccessible(doc.getElementById('paragraph-2'), nsIAccessibleText),
|
getAccessible(doc.getElementById('paragraph-2'), nsIAccessibleText),
|
||||||
[2,6]));
|
[2,6]));
|
||||||
|
|
||||||
|
gQueue.push(new removeVCPositionInvoker(
|
||||||
|
docAcc, doc.getElementById('hide-me')));
|
||||||
|
|
||||||
|
gQueue.push(new removeVCRootInvoker(
|
||||||
|
doc.getElementById('links')));
|
||||||
|
|
||||||
gQueue.invoke();
|
gQueue.invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,8 +186,6 @@ ifdef MOZ_DEBUG
|
||||||
MAC_APP_NAME := $(MAC_APP_NAME)Debug
|
MAC_APP_NAME := $(MAC_APP_NAME)Debug
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LOWER_MAC_APP_NAME = $(shell echo $(MAC_APP_NAME) | tr '[A-Z]' '[a-z]')
|
|
||||||
|
|
||||||
AB_CD = $(MOZ_UI_LOCALE)
|
AB_CD = $(MOZ_UI_LOCALE)
|
||||||
|
|
||||||
AB := $(firstword $(subst -, ,$(AB_CD)))
|
AB := $(firstword $(subst -, ,$(AB_CD)))
|
||||||
|
|
@ -201,6 +199,8 @@ else
|
||||||
APPFILES = MacOS
|
APPFILES = MacOS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/config/buildid)
|
||||||
|
|
||||||
libs-preqs = \
|
libs-preqs = \
|
||||||
$(call mkdir_deps,$(dist_dest)/Contents/MacOS) \
|
$(call mkdir_deps,$(dist_dest)/Contents/MacOS) \
|
||||||
$(call mkdir_deps,$(dist_dest)/Contents/Resources/$(AB).lproj) \
|
$(call mkdir_deps,$(dist_dest)/Contents/Resources/$(AB).lproj) \
|
||||||
|
|
@ -210,7 +210,7 @@ libs-preqs = \
|
||||||
libs repackage:: $(PROGRAM) $(libs-preqs)
|
libs repackage:: $(PROGRAM) $(libs-preqs)
|
||||||
rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents $(dist_dest) --exclude English.lproj
|
rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents $(dist_dest) --exclude English.lproj
|
||||||
rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(dist_dest)/Contents/Resources/$(AB).lproj
|
rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(dist_dest)/Contents/Resources/$(AB).lproj
|
||||||
sed -e "s/%APP_VERSION%/$(MOZ_APP_VERSION)/" -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" -e "s/%LOWER_MAC_APP_NAME%/$(LOWER_MAC_APP_NAME)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
|
sed -e "s/%APP_VERSION%/$(MOZ_APP_VERSION)/" -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" -e "s/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/" -e "s/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
|
||||||
sed -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(dist_dest)/Contents/Resources/$(AB).lproj/InfoPlist.strings
|
sed -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(dist_dest)/Contents/Resources/$(AB).lproj/InfoPlist.strings
|
||||||
rsync -a $(DIST)/bin/ $(dist_dest)/Contents/$(APPFILES)
|
rsync -a $(DIST)/bin/ $(dist_dest)/Contents/$(APPFILES)
|
||||||
ifdef LIBXUL_SDK
|
ifdef LIBXUL_SDK
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>firefox</string>
|
<string>firefox</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>org.mozilla.%LOWER_MAC_APP_NAME%</string>
|
<string>%MOZ_MACBUNDLE_ID%</string>
|
||||||
<key>CFBundleInfoDictionaryVersion</key>
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
<string>6.0</string>
|
<string>6.0</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
|
|
@ -200,7 +200,7 @@
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>%APP_VERSION%</string>
|
<string>%MAC_BUNDLE_VERSION%</string>
|
||||||
<key>NSAppleScriptEnabled</key>
|
<key>NSAppleScriptEnabled</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|
|
||||||
40
browser/app/macversion.py
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from optparse import OptionParser
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
o = OptionParser()
|
||||||
|
o.add_option("--buildid", dest="buildid")
|
||||||
|
o.add_option("--version", dest="version")
|
||||||
|
|
||||||
|
(options, args) = o.parse_args()
|
||||||
|
|
||||||
|
if not options.buildid:
|
||||||
|
print >>sys.stderr, "--buildid is required"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if not options.version:
|
||||||
|
print >>sys.stderr, "--version is required"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# We want to build a version number that matches the format allowed for
|
||||||
|
# CFBundleVersion (nnnnn[.nn[.nn]]). We'll incorporate both the version
|
||||||
|
# number as well as the date, so that it changes at least daily (for nightly
|
||||||
|
# builds), but also so that newly-built older versions (e.g. beta build) aren't
|
||||||
|
# considered "newer" than previously-built newer versions (e.g. a trunk nightly)
|
||||||
|
|
||||||
|
buildid = open(options.buildid, 'r').read()
|
||||||
|
|
||||||
|
# extract only the major version (i.e. "14" from "14.0b1")
|
||||||
|
majorVersion = re.match(r'^(\d+)[^\d].*', options.version).group(1)
|
||||||
|
# last two digits of the year
|
||||||
|
twodigityear = buildid[2:4]
|
||||||
|
month = buildid[4:6]
|
||||||
|
if month[0] == '0':
|
||||||
|
month = month[1]
|
||||||
|
day = buildid[6:8]
|
||||||
|
if day[0] == '0':
|
||||||
|
day = day[1]
|
||||||
|
|
||||||
|
print '%s.%s.%s' % (majorVersion + twodigityear, month, day)
|
||||||
|
|
@ -65,11 +65,6 @@
|
||||||
margin: 0 40px;
|
margin: 0 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-link:-moz-focusring,
|
|
||||||
.bottom-link:-moz-focusring {
|
|
||||||
outline: 1px dotted;
|
|
||||||
}
|
|
||||||
|
|
||||||
#currentChannel {
|
#currentChannel {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
||||||
|
|
@ -308,12 +308,30 @@
|
||||||
</menu>
|
</menu>
|
||||||
#include browser-charsetmenu.inc
|
#include browser-charsetmenu.inc
|
||||||
<menuseparator/>
|
<menuseparator/>
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
<menuitem id="enterFullScreenItem"
|
||||||
|
accesskey="&enterFullScreenCmd.accesskey;"
|
||||||
|
label="&enterFullScreenCmd.label;"
|
||||||
|
key="key_fullScreen">
|
||||||
|
<observes element="View:FullScreen" attribute="oncommand"/>
|
||||||
|
<observes element="View:FullScreen" attribute="disabled"/>
|
||||||
|
</menuitem>
|
||||||
|
<menuitem id="exitFullScreenItem"
|
||||||
|
accesskey="&exitFullScreenCmd.accesskey;"
|
||||||
|
label="&exitFullScreenCmd.label;"
|
||||||
|
key="key_fullScreen"
|
||||||
|
hidden="true">
|
||||||
|
<observes element="View:FullScreen" attribute="oncommand"/>
|
||||||
|
<observes element="View:FullScreen" attribute="disabled"/>
|
||||||
|
</menuitem>
|
||||||
|
#else
|
||||||
<menuitem id="fullScreenItem"
|
<menuitem id="fullScreenItem"
|
||||||
accesskey="&fullScreenCmd.accesskey;"
|
accesskey="&fullScreenCmd.accesskey;"
|
||||||
label="&fullScreenCmd.label;"
|
label="&fullScreenCmd.label;"
|
||||||
key="key_fullScreen"
|
key="key_fullScreen"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
observes="View:FullScreen"/>
|
observes="View:FullScreen"/>
|
||||||
|
#endif
|
||||||
<menuitem id="menu_showAllTabs"
|
<menuitem id="menu_showAllTabs"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
accesskey="&showAllTabsCmd.accesskey;"
|
accesskey="&showAllTabsCmd.accesskey;"
|
||||||
|
|
|
||||||
|
|
@ -341,7 +341,8 @@
|
||||||
<key keycode="VK_F6" command="Browser:FocusNextFrame" modifiers="shift"/>
|
<key keycode="VK_F6" command="Browser:FocusNextFrame" modifiers="shift"/>
|
||||||
<key id="key_fullScreen" keycode="VK_F11" command="View:FullScreen"/>
|
<key id="key_fullScreen" keycode="VK_F11" command="View:FullScreen"/>
|
||||||
#else
|
#else
|
||||||
<key id="key_fullScreen" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,shift"/>
|
<key id="key_fullScreen" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,control"/>
|
||||||
|
<key id="key_fullScreen_old" key="&fullScreenCmd.macCommandKey;" command="View:FullScreen" modifiers="accel,shift"/>
|
||||||
<key keycode="VK_F11" command="View:FullScreen"/>
|
<key keycode="VK_F11" command="View:FullScreen"/>
|
||||||
#endif
|
#endif
|
||||||
<key key="&reloadCmd.commandkey;" command="Browser:Reload" modifiers="accel" id="key_reload"/>
|
<key key="&reloadCmd.commandkey;" command="Browser:Reload" modifiers="accel" id="key_reload"/>
|
||||||
|
|
|
||||||
|
|
@ -3958,6 +3958,12 @@ var FullScreen = {
|
||||||
// fullscreen menuitem, menubars, and the appmenu.
|
// fullscreen menuitem, menubars, and the appmenu.
|
||||||
document.getElementById("View:FullScreen").setAttribute("checked", enterFS);
|
document.getElementById("View:FullScreen").setAttribute("checked", enterFS);
|
||||||
|
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
// Make sure the menu items are adjusted.
|
||||||
|
document.getElementById("enterFullScreenItem").hidden = enterFS;
|
||||||
|
document.getElementById("exitFullScreenItem").hidden = !enterFS;
|
||||||
|
#endif
|
||||||
|
|
||||||
// On OS X Lion we don't want to hide toolbars when entering fullscreen, unless
|
// On OS X Lion we don't want to hide toolbars when entering fullscreen, unless
|
||||||
// we're entering DOM fullscreen, in which case we should hide the toolbars.
|
// we're entering DOM fullscreen, in which case we should hide the toolbars.
|
||||||
// If we're leaving fullscreen, then we'll go through the exit code below to
|
// If we're leaving fullscreen, then we'll go through the exit code below to
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,25 @@ const dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManage
|
||||||
const bhist = Cc["@mozilla.org/browser/global-history;2"].getService(Ci.nsIBrowserHistory);
|
const bhist = Cc["@mozilla.org/browser/global-history;2"].getService(Ci.nsIBrowserHistory);
|
||||||
const formhist = Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
|
const formhist = Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
|
||||||
|
|
||||||
|
const kUsecPerMin = 60 * 1000000;
|
||||||
|
|
||||||
let tempScope = {};
|
let tempScope = {};
|
||||||
Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
|
Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
|
||||||
.loadSubScript("chrome://browser/content/sanitize.js", tempScope);
|
.loadSubScript("chrome://browser/content/sanitize.js", tempScope);
|
||||||
let Sanitizer = tempScope.Sanitizer;
|
let Sanitizer = tempScope.Sanitizer;
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
setupDownloads();
|
||||||
|
setupFormHistory();
|
||||||
|
setupHistory(onHistoryReady);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onHistoryReady() {
|
||||||
var hoursSinceMidnight = new Date().getHours();
|
var hoursSinceMidnight = new Date().getHours();
|
||||||
var minutesSinceMidnight = hoursSinceMidnight * 60 + new Date().getMinutes();
|
var minutesSinceMidnight = hoursSinceMidnight * 60 + new Date().getMinutes();
|
||||||
|
|
||||||
setupHistory();
|
|
||||||
setupFormHistory();
|
|
||||||
setupDownloads();
|
|
||||||
|
|
||||||
// Should test cookies here, but nsICookieManager/nsICookieService
|
// Should test cookies here, but nsICookieManager/nsICookieService
|
||||||
// doesn't let us fake creation times. bug 463127
|
// doesn't let us fake creation times. bug 463127
|
||||||
|
|
||||||
|
|
@ -271,37 +276,46 @@ function test() {
|
||||||
|
|
||||||
ok(!downloadExists(5555550), "Year old download should now be deleted");
|
ok(!downloadExists(5555550), "Year old download should now be deleted");
|
||||||
|
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupHistory() {
|
function setupHistory(aCallback) {
|
||||||
bhist.addPageWithDetails(makeURI("http://10minutes.com/"), "10 minutes ago", now_uSec - 10*60*1000000);
|
let places = [];
|
||||||
bhist.addPageWithDetails(makeURI("http://1hour.com/"), "Less than 1 hour ago", now_uSec - 45*60*1000000);
|
|
||||||
bhist.addPageWithDetails(makeURI("http://1hour10minutes.com/"), "1 hour 10 minutes ago", now_uSec - 70*60*1000000);
|
function addPlace(aURI, aTitle, aVisitDate) {
|
||||||
bhist.addPageWithDetails(makeURI("http://2hour.com/"), "Less than 2 hours ago", now_uSec - 90*60*1000000);
|
places.push({
|
||||||
bhist.addPageWithDetails(makeURI("http://2hour10minutes.com/"), "2 hours 10 minutes ago", now_uSec - 130*60*1000000);
|
uri: aURI,
|
||||||
bhist.addPageWithDetails(makeURI("http://4hour.com/"), "Less than 4 hours ago", now_uSec - 180*60*1000000);
|
title: aTitle,
|
||||||
bhist.addPageWithDetails(makeURI("http://4hour10minutes.com/"), "4 hours 10 minutesago", now_uSec - 250*60*1000000);
|
visits: [{
|
||||||
|
visitDate: aVisitDate,
|
||||||
|
transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addPlace(makeURI("http://10minutes.com/"), "10 minutes ago", now_uSec - 10 * kUsecPerMin);
|
||||||
|
addPlace(makeURI("http://1hour.com/"), "Less than 1 hour ago", now_uSec - 45 * kUsecPerMin);
|
||||||
|
addPlace(makeURI("http://1hour10minutes.com/"), "1 hour 10 minutes ago", now_uSec - 70 * kUsecPerMin);
|
||||||
|
addPlace(makeURI("http://2hour.com/"), "Less than 2 hours ago", now_uSec - 90 * kUsecPerMin);
|
||||||
|
addPlace(makeURI("http://2hour10minutes.com/"), "2 hours 10 minutes ago", now_uSec - 130 * kUsecPerMin);
|
||||||
|
addPlace(makeURI("http://4hour.com/"), "Less than 4 hours ago", now_uSec - 180 * kUsecPerMin);
|
||||||
|
addPlace(makeURI("http://4hour10minutes.com/"), "4 hours 10 minutesago", now_uSec - 250 * kUsecPerMin);
|
||||||
|
|
||||||
let today = new Date();
|
let today = new Date();
|
||||||
today.setHours(0);
|
today.setHours(0);
|
||||||
today.setMinutes(0);
|
today.setMinutes(0);
|
||||||
today.setSeconds(1);
|
today.setSeconds(1);
|
||||||
bhist.addPageWithDetails(makeURI("http://today.com/"), "Today", today.valueOf() * 1000);
|
addPlace(makeURI("http://today.com/"), "Today", today.getTime() * 1000);
|
||||||
|
|
||||||
let lastYear = new Date();
|
let lastYear = new Date();
|
||||||
lastYear.setFullYear(lastYear.getFullYear() - 1);
|
lastYear.setFullYear(lastYear.getFullYear() - 1);
|
||||||
bhist.addPageWithDetails(makeURI("http://before-today.com/"), "Before Today", lastYear.valueOf() * 1000);
|
addPlace(makeURI("http://before-today.com/"), "Before Today", lastYear.getTime() * 1000);
|
||||||
|
|
||||||
// Confirm everything worked
|
PlacesUtils.asyncHistory.updatePlaces(places, {
|
||||||
ok(bhist.isVisited(makeURI("http://10minutes.com/")), "Pretend visit to 10minutes.com should exist");
|
handleError: function () ok(false, "Unexpected error in adding visit."),
|
||||||
ok(bhist.isVisited(makeURI("http://1hour.com")), "Pretend visit to 1hour.com should exist");
|
handleResult: function () { },
|
||||||
ok(bhist.isVisited(makeURI("http://1hour10minutes.com/")), "Pretend visit to 1hour10minutes.com should exist");
|
handleCompletion: function () aCallback()
|
||||||
ok(bhist.isVisited(makeURI("http://2hour.com")), "Pretend visit to 2hour.com should exist");
|
});
|
||||||
ok(bhist.isVisited(makeURI("http://2hour10minutes.com/")), "Pretend visit to 2hour10minutes.com should exist");
|
|
||||||
ok(bhist.isVisited(makeURI("http://4hour.com")), "Pretend visit to 4hour.com should exist");
|
|
||||||
ok(bhist.isVisited(makeURI("http://4hour10minutes.com/")), "Pretend visit to 4hour10minutes.com should exist");
|
|
||||||
ok(bhist.isVisited(makeURI("http://today.com")), "Pretend visit to today.com should exist");
|
|
||||||
ok(bhist.isVisited(makeURI("http://before-today.com")), "Pretend visit to before-today.com should exist");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupFormHistory() {
|
function setupFormHistory() {
|
||||||
|
|
@ -321,25 +335,25 @@ function setupFormHistory() {
|
||||||
|
|
||||||
// Artifically age the entries to the proper vintage.
|
// Artifically age the entries to the proper vintage.
|
||||||
let db = formhist.DBConnection;
|
let db = formhist.DBConnection;
|
||||||
let timestamp = now_uSec - 10*60*1000000;
|
let timestamp = now_uSec - 10 * kUsecPerMin;
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = '10minutes'");
|
timestamp + " WHERE fieldname = '10minutes'");
|
||||||
timestamp = now_uSec - 45*60*1000000;
|
timestamp = now_uSec - 45 * kUsecPerMin;
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = '1hour'");
|
timestamp + " WHERE fieldname = '1hour'");
|
||||||
timestamp = now_uSec - 70*60*1000000;
|
timestamp = now_uSec - 70 * kUsecPerMin;
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = '1hour10minutes'");
|
timestamp + " WHERE fieldname = '1hour10minutes'");
|
||||||
timestamp = now_uSec - 90*60*1000000;
|
timestamp = now_uSec - 90 * kUsecPerMin;
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = '2hour'");
|
timestamp + " WHERE fieldname = '2hour'");
|
||||||
timestamp = now_uSec - 130*60*1000000;
|
timestamp = now_uSec - 130 * kUsecPerMin;
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = '2hour10minutes'");
|
timestamp + " WHERE fieldname = '2hour10minutes'");
|
||||||
timestamp = now_uSec - 180*60*1000000;
|
timestamp = now_uSec - 180 * kUsecPerMin;
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = '4hour'");
|
timestamp + " WHERE fieldname = '4hour'");
|
||||||
timestamp = now_uSec - 250*60*1000000;
|
timestamp = now_uSec - 250 * kUsecPerMin;
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = '4hour10minutes'");
|
timestamp + " WHERE fieldname = '4hour10minutes'");
|
||||||
|
|
||||||
|
|
@ -347,13 +361,13 @@ function setupFormHistory() {
|
||||||
today.setHours(0);
|
today.setHours(0);
|
||||||
today.setMinutes(0);
|
today.setMinutes(0);
|
||||||
today.setSeconds(1);
|
today.setSeconds(1);
|
||||||
timestamp = today.valueOf() * 1000;
|
timestamp = today.getTime() * 1000;
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = 'today'");
|
timestamp + " WHERE fieldname = 'today'");
|
||||||
|
|
||||||
let lastYear = new Date();
|
let lastYear = new Date();
|
||||||
lastYear.setFullYear(lastYear.getFullYear() - 1);
|
lastYear.setFullYear(lastYear.getFullYear() - 1);
|
||||||
timestamp = lastYear.valueOf() * 1000;
|
timestamp = lastYear.getTime() * 1000;
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = 'b4today'");
|
timestamp + " WHERE fieldname = 'b4today'");
|
||||||
|
|
||||||
|
|
@ -377,8 +391,8 @@ function setupDownloads() {
|
||||||
name: "fakefile-10-minutes",
|
name: "fakefile-10-minutes",
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||||
target: "fakefile-10-minutes",
|
target: "fakefile-10-minutes",
|
||||||
startTime: now_uSec - 10*60*1000000, // 10 minutes ago, in uSec
|
startTime: now_uSec - 10 * kUsecPerMin, // 10 minutes ago, in uSec
|
||||||
endTime: now_uSec - 11*60*1000000, // 1 minute later
|
endTime: now_uSec - 11 * kUsecPerMin, // 1 minute later
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
@ -404,8 +418,8 @@ function setupDownloads() {
|
||||||
name: "fakefile-1-hour",
|
name: "fakefile-1-hour",
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||||
target: "fakefile-1-hour",
|
target: "fakefile-1-hour",
|
||||||
startTime: now_uSec - 45*60*1000000, // 45 minutes ago, in uSec
|
startTime: now_uSec - 45 * kUsecPerMin, // 45 minutes ago, in uSec
|
||||||
endTime: now_uSec - 44*60*1000000, // 1 minute later
|
endTime: now_uSec - 44 * kUsecPerMin, // 1 minute later
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
@ -425,8 +439,8 @@ function setupDownloads() {
|
||||||
name: "fakefile-1-hour-10-minutes",
|
name: "fakefile-1-hour-10-minutes",
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||||
target: "fakefile-1-hour-10-minutes",
|
target: "fakefile-1-hour-10-minutes",
|
||||||
startTime: now_uSec - 70*60*1000000, // 70 minutes ago, in uSec
|
startTime: now_uSec - 70 * kUsecPerMin, // 70 minutes ago, in uSec
|
||||||
endTime: now_uSec - 71*60*1000000, // 1 minute later
|
endTime: now_uSec - 71 * kUsecPerMin, // 1 minute later
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
@ -446,8 +460,8 @@ function setupDownloads() {
|
||||||
name: "fakefile-2-hour",
|
name: "fakefile-2-hour",
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||||
target: "fakefile-2-hour",
|
target: "fakefile-2-hour",
|
||||||
startTime: now_uSec - 90*60*1000000, // 90 minutes ago, in uSec
|
startTime: now_uSec - 90 * kUsecPerMin, // 90 minutes ago, in uSec
|
||||||
endTime: now_uSec - 89*60*1000000, // 1 minute later
|
endTime: now_uSec - 89 * kUsecPerMin, // 1 minute later
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
@ -467,8 +481,8 @@ function setupDownloads() {
|
||||||
name: "fakefile-2-hour-10-minutes",
|
name: "fakefile-2-hour-10-minutes",
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||||
target: "fakefile-2-hour-10-minutes",
|
target: "fakefile-2-hour-10-minutes",
|
||||||
startTime: now_uSec - 130*60*1000000, // 130 minutes ago, in uSec
|
startTime: now_uSec - 130 * kUsecPerMin, // 130 minutes ago, in uSec
|
||||||
endTime: now_uSec - 131*60*1000000, // 1 minute later
|
endTime: now_uSec - 131 * kUsecPerMin, // 1 minute later
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
@ -488,8 +502,8 @@ function setupDownloads() {
|
||||||
name: "fakefile-4-hour",
|
name: "fakefile-4-hour",
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||||
target: "fakefile-4-hour",
|
target: "fakefile-4-hour",
|
||||||
startTime: now_uSec - 180*60*1000000, // 180 minutes ago, in uSec
|
startTime: now_uSec - 180 * kUsecPerMin, // 180 minutes ago, in uSec
|
||||||
endTime: now_uSec - 179*60*1000000, // 1 minute later
|
endTime: now_uSec - 179 * kUsecPerMin, // 1 minute later
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
@ -509,8 +523,8 @@ function setupDownloads() {
|
||||||
name: "fakefile-4-hour-10-minutes",
|
name: "fakefile-4-hour-10-minutes",
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||||
target: "fakefile-4-hour-10-minutes",
|
target: "fakefile-4-hour-10-minutes",
|
||||||
startTime: now_uSec - 250*60*1000000, // 250 minutes ago, in uSec
|
startTime: now_uSec - 250 * kUsecPerMin, // 250 minutes ago, in uSec
|
||||||
endTime: now_uSec - 251*60*1000000, // 1 minute later
|
endTime: now_uSec - 251 * kUsecPerMin, // 1 minute later
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
@ -535,8 +549,8 @@ function setupDownloads() {
|
||||||
name: "fakefile-today",
|
name: "fakefile-today",
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||||
target: "fakefile-today",
|
target: "fakefile-today",
|
||||||
startTime: today.valueOf() * 1000, // 12:00:30am this morning, in uSec
|
startTime: today.getTime() * 1000, // 12:00:30am this morning, in uSec
|
||||||
endTime: (today.valueOf() + 1000) * 1000, // 1 second later
|
endTime: (today.getTime() + 1000) * 1000, // 1 second later
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
@ -558,8 +572,8 @@ function setupDownloads() {
|
||||||
name: "fakefile-old",
|
name: "fakefile-old",
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||||
target: "fakefile-old",
|
target: "fakefile-old",
|
||||||
startTime: lastYear.valueOf() * 1000, // 1 year ago, in uSec
|
startTime: lastYear.getTime() * 1000, // 1 year ago, in uSec
|
||||||
endTime: (lastYear.valueOf() + 1000) * 1000, // 1 second later
|
endTime: (lastYear.getTime() + 1000) * 1000, // 1 second later
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ const dm = Cc["@mozilla.org/download-manager;1"].
|
||||||
const formhist = Cc["@mozilla.org/satchel/form-history;1"].
|
const formhist = Cc["@mozilla.org/satchel/form-history;1"].
|
||||||
getService(Ci.nsIFormHistory2);
|
getService(Ci.nsIFormHistory2);
|
||||||
|
|
||||||
|
const kUsecPerMin = 60 * 1000000;
|
||||||
|
|
||||||
// Add tests here. Each is a function that's called by doNextTest().
|
// Add tests here. Each is a function that's called by doNextTest().
|
||||||
var gAllTests = [
|
var gAllTests = [
|
||||||
|
|
||||||
|
|
@ -831,8 +833,8 @@ function addDownloadWithMinutesAgo(aMinutesAgo) {
|
||||||
name: name,
|
name: name,
|
||||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||||
target: name,
|
target: name,
|
||||||
startTime: now_uSec - (aMinutesAgo * 60 * 1000000),
|
startTime: now_uSec - (aMinutesAgo * kUsecPerMin),
|
||||||
endTime: now_uSec - ((aMinutesAgo + 1) *60 * 1000000),
|
endTime: now_uSec - ((aMinutesAgo + 1) * kUsecPerMin),
|
||||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||||
};
|
};
|
||||||
|
|
@ -872,7 +874,7 @@ function addFormEntryWithMinutesAgo(aMinutesAgo) {
|
||||||
|
|
||||||
// Artifically age the entry to the proper vintage.
|
// Artifically age the entry to the proper vintage.
|
||||||
let db = formhist.DBConnection;
|
let db = formhist.DBConnection;
|
||||||
let timestamp = now_uSec - (aMinutesAgo * 60 * 1000000);
|
let timestamp = now_uSec - (aMinutesAgo * kUsecPerMin);
|
||||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||||
timestamp + " WHERE fieldname = '" + name + "'");
|
timestamp + " WHERE fieldname = '" + name + "'");
|
||||||
|
|
||||||
|
|
@ -889,10 +891,12 @@ function addFormEntryWithMinutesAgo(aMinutesAgo) {
|
||||||
*/
|
*/
|
||||||
function addHistoryWithMinutesAgo(aMinutesAgo) {
|
function addHistoryWithMinutesAgo(aMinutesAgo) {
|
||||||
let pURI = makeURI("http://" + aMinutesAgo + "-minutes-ago.com/");
|
let pURI = makeURI("http://" + aMinutesAgo + "-minutes-ago.com/");
|
||||||
PlacesUtils.bhistory
|
PlacesUtils.history.addVisit(pURI,
|
||||||
.addPageWithDetails(pURI,
|
now_uSec - aMinutesAgo * kUsecPerMin,
|
||||||
aMinutesAgo + " minutes ago",
|
null,
|
||||||
now_uSec - (aMinutesAgo * 60 * 1000 * 1000));
|
Ci.nsINavHistoryService.TRANSITION_LINK,
|
||||||
|
false,
|
||||||
|
0);
|
||||||
is(PlacesUtils.bhistory.isVisited(pURI), true,
|
is(PlacesUtils.bhistory.isVisited(pURI), true,
|
||||||
"Sanity check: history visit " + pURI.spec +
|
"Sanity check: history visit " + pURI.spec +
|
||||||
" should exist after creating it");
|
" should exist after creating it");
|
||||||
|
|
|
||||||
|
|
@ -501,10 +501,12 @@ function addFormEntryWithMinutesAgo(aMinutesAgo) {
|
||||||
*/
|
*/
|
||||||
function addHistoryWithMinutesAgo(aMinutesAgo) {
|
function addHistoryWithMinutesAgo(aMinutesAgo) {
|
||||||
let pURI = makeURI("http://" + aMinutesAgo + "-minutes-ago.com/");
|
let pURI = makeURI("http://" + aMinutesAgo + "-minutes-ago.com/");
|
||||||
PlacesUtils.bhistory
|
PlacesUtils.history.addVisit(pURI,
|
||||||
.addPageWithDetails(pURI,
|
now_uSec - (aMinutesAgo * 60 * 1000 * 1000),
|
||||||
aMinutesAgo + " minutes ago",
|
null,
|
||||||
now_uSec - (aMinutesAgo * 60 * 1000 * 1000));
|
Ci.nsINavHistoryService.TRANSITION_LINK,
|
||||||
|
false,
|
||||||
|
0);
|
||||||
is(PlacesUtils.bhistory.isVisited(pURI), true,
|
is(PlacesUtils.bhistory.isVisited(pURI), true,
|
||||||
"Sanity check: history visit " + pURI.spec +
|
"Sanity check: history visit " + pURI.spec +
|
||||||
" should exist after creating it");
|
" should exist after creating it");
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ let bhist = Cc["@mozilla.org/browser/global-history;2"]
|
||||||
|
|
||||||
function runTests() {
|
function runTests() {
|
||||||
clearHistory();
|
clearHistory();
|
||||||
fillHistory();
|
yield fillHistory();
|
||||||
yield addNewTabPageTab();
|
yield addNewTabPageTab();
|
||||||
|
|
||||||
is(getCell(0).site.url, URL, "first site is our fake site");
|
is(getCell(0).site.url, URL, "first site is our fake site");
|
||||||
|
|
@ -29,9 +29,23 @@ function runTests() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillHistory() {
|
function fillHistory() {
|
||||||
let uri = makeURI(URL);
|
let visits = [];
|
||||||
for (let i = 59; i > 0; i--)
|
for (let i = 59; i > 0; i--) {
|
||||||
bhist.addPageWithDetails(uri, "fake site", NOW - i * 60 * 1000000);
|
visits.push({
|
||||||
|
visitDate: NOW - i * 60 * 1000000,
|
||||||
|
transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let place = {
|
||||||
|
uri: makeURI(URL),
|
||||||
|
title: "fake site",
|
||||||
|
visits: visits
|
||||||
|
};
|
||||||
|
PlacesUtils.asyncHistory.updatePlaces(place, {
|
||||||
|
handleError: function () do_throw("Unexpected error in adding visit."),
|
||||||
|
handleResult: function () { },
|
||||||
|
handleCompletion: function () TestRunner.next()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearHistory() {
|
function clearHistory() {
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,48 @@ function do_test()
|
||||||
|
|
||||||
do_test_pending();
|
do_test_pending();
|
||||||
waitForClearHistory(function () {
|
waitForClearHistory(function () {
|
||||||
PlacesUtils.bhistory.addPageWithDetails(TEST_URI, TITLE_1, Date.now() * 1000);
|
let place = {
|
||||||
|
uri: TEST_URI,
|
||||||
|
title: TITLE_1,
|
||||||
|
visits: [{
|
||||||
|
visitDate: Date.now() * 1000,
|
||||||
|
transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
PlacesUtils.asyncHistory.updatePlaces(place, {
|
||||||
|
handleError: function () do_throw("Unexpected error in adding visit."),
|
||||||
|
handleResult: function () { },
|
||||||
|
handleCompletion: function () afterAddFirstVisit()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function afterAddFirstVisit()
|
||||||
|
{
|
||||||
do_check_eq(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_1);
|
do_check_eq(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_1);
|
||||||
|
|
||||||
pb.privateBrowsingEnabled = true;
|
pb.privateBrowsingEnabled = true;
|
||||||
|
|
||||||
PlacesUtils.bhistory.addPageWithDetails(TEST_URI, TITLE_2, Date.now() * 2000);
|
let place = {
|
||||||
|
uri: TEST_URI,
|
||||||
|
title: TITLE_2,
|
||||||
|
visits: [{
|
||||||
|
visitDate: Date.now() * 2000,
|
||||||
|
transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
PlacesUtils.asyncHistory.updatePlaces(place, {
|
||||||
|
handleError: function (aResultCode) {
|
||||||
|
// We expect this error in Private Browsing mode.
|
||||||
|
do_check_eq(aResultCode, Cr.NS_ERROR_ILLEGAL_VALUE);
|
||||||
|
},
|
||||||
|
handleResult: function () do_throw("Unexpected success adding visit."),
|
||||||
|
handleCompletion: function () afterAddSecondVisit()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function afterAddSecondVisit()
|
||||||
|
{
|
||||||
do_check_eq(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_1);
|
do_check_eq(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_1);
|
||||||
|
|
||||||
pb.privateBrowsingEnabled = false;
|
pb.privateBrowsingEnabled = false;
|
||||||
|
|
@ -73,7 +109,7 @@ function do_test()
|
||||||
do_check_eq(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_1);
|
do_check_eq(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_1);
|
||||||
|
|
||||||
waitForClearHistory(do_test_finished);
|
waitForClearHistory(do_test_finished);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support running tests on both the service itself and its wrapper
|
// Support running tests on both the service itself and its wrapper
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//// Constants
|
//// Globals
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||||
|
|
||||||
let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
|
let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
|
||||||
getService(Ci.nsIPrivateBrowsingService);
|
getService(Ci.nsIPrivateBrowsingService);
|
||||||
|
|
@ -88,9 +90,9 @@ function uri(aURIString)
|
||||||
function add_visit(aURI)
|
function add_visit(aURI)
|
||||||
{
|
{
|
||||||
check_visited(aURI, false);
|
check_visited(aURI, false);
|
||||||
let bh = Cc["@mozilla.org/browser/global-history;2"].
|
PlacesUtils.history.addVisit(aURI, Date.now() * 1000, null,
|
||||||
getService(Ci.nsIBrowserHistory);
|
Ci.nsINavHistoryService.TRANSITION_LINK, false,
|
||||||
bh.addPageWithDetails(aURI, aURI.spec, Date.now() * 1000);
|
0);
|
||||||
check_visited(aURI, true);
|
check_visited(aURI, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,10 +106,8 @@ function add_visit(aURI)
|
||||||
*/
|
*/
|
||||||
function check_visited(aURI, aIsVisited)
|
function check_visited(aURI, aIsVisited)
|
||||||
{
|
{
|
||||||
let gh = Cc["@mozilla.org/browser/global-history;2"].
|
|
||||||
getService(Ci.nsIGlobalHistory2);
|
|
||||||
let checker = aIsVisited ? do_check_true : do_check_false;
|
let checker = aIsVisited ? do_check_true : do_check_false;
|
||||||
checker(gh.isVisited(aURI));
|
checker(PlacesUtils.ghistory2.isVisited(aURI));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -362,9 +362,7 @@ function test_history_not_cleared_with_uri_contains_domain()
|
||||||
check_visited(TEST_URI, true);
|
check_visited(TEST_URI, true);
|
||||||
|
|
||||||
// Clear history since we left something there from this test.
|
// Clear history since we left something there from this test.
|
||||||
let bh = Cc["@mozilla.org/browser/global-history;2"].
|
PlacesUtils.bhistory.removeAllPages();
|
||||||
getService(Ci.nsIBrowserHistory);
|
|
||||||
bh.removeAllPages();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cookie Service
|
// Cookie Service
|
||||||
|
|
|
||||||
18
browser/config/mozconfigs/linux32/debug-asan
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Use at least -O1 for optimization to avoid stack space
|
||||||
|
# exhaustions caused by Clang function inlining.
|
||||||
|
ac_add_options --enable-debug
|
||||||
|
ac_add_options --enable-optimize="-O1"
|
||||||
|
|
||||||
|
# ASan specific options on Linux
|
||||||
|
ac_add_options --enable-valgrind
|
||||||
|
|
||||||
|
. $topsrcdir/build/unix/mozconfig.asan
|
||||||
|
|
||||||
|
# Avoid dependency on libstdc++ 4.5
|
||||||
|
ac_add_options --enable-stdcxx-compat
|
||||||
|
|
||||||
|
# Enable parallel compiling
|
||||||
|
mk_add_options MOZ_MAKE_FLAGS="-j4"
|
||||||
|
|
||||||
|
# Package js shell.
|
||||||
|
export MOZ_PACKAGE_JSSHELL=1
|
||||||
20
browser/config/mozconfigs/linux32/nightly-asan
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# We still need to build with debug symbols
|
||||||
|
ac_add_options --disable-debug
|
||||||
|
ac_add_options --enable-optimize="-O2 -g"
|
||||||
|
|
||||||
|
# ASan specific options on Linux
|
||||||
|
ac_add_options --enable-valgrind
|
||||||
|
|
||||||
|
# Other options
|
||||||
|
ac_add_options --enable-codesighs
|
||||||
|
|
||||||
|
. $topsrcdir/build/unix/mozconfig.asan
|
||||||
|
|
||||||
|
# Avoid dependency on libstdc++ 4.5
|
||||||
|
ac_add_options --enable-stdcxx-compat
|
||||||
|
|
||||||
|
# Enable parallel compiling
|
||||||
|
mk_add_options MOZ_MAKE_FLAGS="-j4"
|
||||||
|
|
||||||
|
# Package js shell.
|
||||||
|
export MOZ_PACKAGE_JSSHELL=1
|
||||||
18
browser/config/mozconfigs/linux64/debug-asan
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Use at least -O1 for optimization to avoid stack space
|
||||||
|
# exhaustions caused by Clang function inlining.
|
||||||
|
ac_add_options --enable-debug
|
||||||
|
ac_add_options --enable-optimize="-O1"
|
||||||
|
|
||||||
|
# ASan specific options on Linux
|
||||||
|
ac_add_options --enable-valgrind
|
||||||
|
|
||||||
|
. $topsrcdir/build/unix/mozconfig.asan
|
||||||
|
|
||||||
|
# Avoid dependency on libstdc++ 4.5
|
||||||
|
ac_add_options --enable-stdcxx-compat
|
||||||
|
|
||||||
|
# Enable parallel compiling
|
||||||
|
mk_add_options MOZ_MAKE_FLAGS="-j4"
|
||||||
|
|
||||||
|
# Package js shell.
|
||||||
|
export MOZ_PACKAGE_JSSHELL=1
|
||||||
20
browser/config/mozconfigs/linux64/nightly-asan
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# We still need to build with debug symbols
|
||||||
|
ac_add_options --disable-debug
|
||||||
|
ac_add_options --enable-optimize="-O2 -g"
|
||||||
|
|
||||||
|
# ASan specific options on Linux
|
||||||
|
ac_add_options --enable-valgrind
|
||||||
|
|
||||||
|
# Other options
|
||||||
|
ac_add_options --enable-codesighs
|
||||||
|
|
||||||
|
. $topsrcdir/build/unix/mozconfig.asan
|
||||||
|
|
||||||
|
# Avoid dependency on libstdc++ 4.5
|
||||||
|
ac_add_options --enable-stdcxx-compat
|
||||||
|
|
||||||
|
# Enable parallel compiling
|
||||||
|
mk_add_options MOZ_MAKE_FLAGS="-j4"
|
||||||
|
|
||||||
|
# Package js shell.
|
||||||
|
export MOZ_PACKAGE_JSSHELL=1
|
||||||
|
|
@ -77,6 +77,12 @@ can reach it easily. -->
|
||||||
<!ENTITY pageInfoCmd.label "Page Info">
|
<!ENTITY pageInfoCmd.label "Page Info">
|
||||||
<!ENTITY pageInfoCmd.accesskey "I">
|
<!ENTITY pageInfoCmd.accesskey "I">
|
||||||
<!ENTITY pageInfoCmd.commandkey "i">
|
<!ENTITY pageInfoCmd.commandkey "i">
|
||||||
|
<!-- LOCALIZATION NOTE (enterFullScreenCmd.label, exitFullScreenCmd.label):
|
||||||
|
These should match what Safari and other Apple applications use on OS X Lion. -->
|
||||||
|
<!ENTITY enterFullScreenCmd.label "Enter Full Screen">
|
||||||
|
<!ENTITY enterFullScreenCmd.accesskey "F">
|
||||||
|
<!ENTITY exitFullScreenCmd.label "Exit Full Screen">
|
||||||
|
<!ENTITY exitFullScreenCmd.accesskey "F">
|
||||||
<!ENTITY fullScreenCmd.label "Full Screen">
|
<!ENTITY fullScreenCmd.label "Full Screen">
|
||||||
<!ENTITY fullScreenCmd.accesskey "F">
|
<!ENTITY fullScreenCmd.accesskey "F">
|
||||||
<!ENTITY fullScreenCmd.macCommandKey "f">
|
<!ENTITY fullScreenCmd.macCommandKey "f">
|
||||||
|
|
|
||||||
|
|
@ -588,10 +588,8 @@ MacNativeApp.prototype = {
|
||||||
<string>MOZB</string>\n\
|
<string>MOZB</string>\n\
|
||||||
<key>CFBundleVersion</key>\n\
|
<key>CFBundleVersion</key>\n\
|
||||||
<string>0</string>\n\
|
<string>0</string>\n\
|
||||||
#ifdef DEBUG
|
|
||||||
<key>FirefoxBinary</key>\n\
|
<key>FirefoxBinary</key>\n\
|
||||||
<string>org.mozilla.NightlyDebug</string>\n\
|
#expand <string>__MOZ_MACBUNDLE_ID__</string>\n\
|
||||||
#endif
|
|
||||||
</dict>\n\
|
</dict>\n\
|
||||||
</plist>';
|
</plist>';
|
||||||
|
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 900 B After Width: | Height: | Size: 708 B |
|
Before Width: | Height: | Size: 553 B After Width: | Height: | Size: 672 B |
|
Before Width: | Height: | Size: 541 B After Width: | Height: | Size: 520 B |
|
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 500 B |
|
Before Width: | Height: | Size: 900 B After Width: | Height: | Size: 708 B |
|
Before Width: | Height: | Size: 553 B After Width: | Height: | Size: 672 B |
|
|
@ -40,6 +40,7 @@ package com.mozilla.SUTAgentAndroid;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import org.apache.http.conn.util.InetAddressUtils;
|
||||||
import java.net.NetworkInterface;
|
import java.net.NetworkInterface;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
|
@ -665,7 +666,7 @@ public class SUTAgentAndroid extends Activity
|
||||||
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
|
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
|
||||||
{
|
{
|
||||||
InetAddress inetAddress = enumIpAddr.nextElement();
|
InetAddress inetAddress = enumIpAddr.nextElement();
|
||||||
if (!inetAddress.isLoopbackAddress())
|
if (!inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(inetAddress.getHostAddress()))
|
||||||
{
|
{
|
||||||
return inetAddress.getHostAddress().toString();
|
return inetAddress.getHostAddress().toString();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -277,5 +277,13 @@ build_one_stage({"PATH" : stage1_tool_inst_dir + "/bin:/bin:/usr/bin",
|
||||||
"RANLIB" : "true" },
|
"RANLIB" : "true" },
|
||||||
stage2_dir, False)
|
stage2_dir, False)
|
||||||
|
|
||||||
|
stage2_tool_inst_dir = stage2_dir + '/inst'
|
||||||
|
stage3_dir = build_dir + '/stage3'
|
||||||
|
build_one_stage({"PATH" : stage2_tool_inst_dir + "/bin:/bin:/usr/bin",
|
||||||
|
"CC" : "gcc -fgnu89-inline",
|
||||||
|
"CXX" : "g++",
|
||||||
|
"RANLIB" : "true" },
|
||||||
|
stage3_dir, False)
|
||||||
|
|
||||||
build_tar_package(aux_inst_dir + "/bin/tar",
|
build_tar_package(aux_inst_dir + "/bin/tar",
|
||||||
"toolchain.tar", stage2_dir, "inst")
|
"toolchain.tar", stage3_dir, "inst")
|
||||||
|
|
|
||||||
20
build/unix/mozconfig.asan
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Use Clang r155417
|
||||||
|
export CC="/tools/clang-3.0/bin/clang -fgnu89-inline"
|
||||||
|
export CXX="/tools/clang-3.0/bin/clang++"
|
||||||
|
|
||||||
|
# Mandatory flags for ASan
|
||||||
|
export ASANFLAGS="-faddress-sanitizer -Dxmalloc=myxmalloc -fPIC"
|
||||||
|
export CFLAGS="$ASANFLAGS"
|
||||||
|
export CXXFLAGS="$ASANFLAGS"
|
||||||
|
export LDFLAGS="-faddress-sanitizer"
|
||||||
|
|
||||||
|
# Enable ASan specific code and build workarounds
|
||||||
|
ac_add_options --enable-address-sanitizer
|
||||||
|
|
||||||
|
# Mandatory options required for ASan builds (both on Linux and Mac)
|
||||||
|
export MOZ_DEBUG_SYMBOLS=1
|
||||||
|
ac_add_options --enable-debug-symbols
|
||||||
|
ac_add_options --disable-install-strip
|
||||||
|
ac_add_options --disable-jemalloc
|
||||||
|
ac_add_options --disable-crashreporter
|
||||||
|
ac_add_options --disable-elf-hack
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
export INCLUDE=/c/tools/msvs10/vc/include:/c/tools/msvs10/vc/atlmfc/include:/c/tools/sdks/v7.0/include:/c/tools/sdks/v7.0/include/atl:/c/tools/sdks/dx10/include
|
export INCLUDE=/c/tools/msvs10/vc/include:/c/tools/msvs10/vc/atlmfc/include:/c/tools/sdks/v7.0/include:/c/tools/sdks/v7.0/include/atl:/c/tools/sdks/dx10/include
|
||||||
export LIBPATH=/c/tools/msvs10/vc/lib:/c/tools/msvs10/vc/atlmfc/lib
|
export LIBPATH=/c/tools/msvs10/vc/lib:/c/tools/msvs10/vc/atlmfc/lib
|
||||||
export LIB=/c/tools/msvs10/vc/lib:/c/tools/msvs10/vc/atlmfc/lib:/c/tools/sdks/v7.0/lib:/c/tools/sdks/dx10/lib
|
export LIB=/c/tools/msvs10/vc/lib:/c/tools/msvs10/vc/atlmfc/lib:/c/tools/sdks/v7.0/lib:/c/tools/sdks/dx10/lib
|
||||||
export PATH="/c/tools/msvs10/Common7/IDE:/c/tools/msvs10/VC/BIN:/c/tools/msvs10/Common7/Tools:/c/tools/msvs10/VC/VCPackages:${PATH}"
|
|
||||||
export WIN32_REDIST_DIR=/c/tools/msvs10/VC/redist/x86/Microsoft.VC100.CRT
|
export WIN32_REDIST_DIR=/c/tools/msvs10/VC/redist/x86/Microsoft.VC100.CRT
|
||||||
|
export MOZ_TOOLS=C:/mozilla-build/moztools
|
||||||
|
export PATH="/c/tools/msvs10/Common7/IDE:/c/tools/msvs10/VC/BIN:/c/tools/msvs10/Common7/Tools:/c/tools/msvs10/VC/VCPackages:/c/mozilla-build/moztools:/c/Tools/sdks/v7.0/bin:${PATH}"
|
||||||
|
|
||||||
mk_add_options "export LIB=$LIB"
|
mk_add_options "export LIB=$LIB"
|
||||||
mk_add_options "export LIBPATH=$LIBPATH"
|
mk_add_options "export LIBPATH=$LIBPATH"
|
||||||
mk_add_options "export PATH=$PATH"
|
mk_add_options "export PATH=$PATH"
|
||||||
mk_add_options "export INCLUDE=$INCLUDE"
|
mk_add_options "export INCLUDE=$INCLUDE"
|
||||||
mk_add_options "export WIN32_REDIST_DIR=$WIN32_REDIST_DIR"
|
mk_add_options "export WIN32_REDIST_DIR=$WIN32_REDIST_DIR"
|
||||||
|
mk_add_options "export MOZ_TOOLS=$MOZ_TOOLS"
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ MOZ_APP_UA_NAME = @MOZ_APP_UA_NAME@
|
||||||
MOZ_APP_VERSION = @MOZ_APP_VERSION@
|
MOZ_APP_VERSION = @MOZ_APP_VERSION@
|
||||||
MOZ_APP_MAXVERSION = @MOZ_APP_MAXVERSION@
|
MOZ_APP_MAXVERSION = @MOZ_APP_MAXVERSION@
|
||||||
MOZ_MACBUNDLE_NAME = @MOZ_MACBUNDLE_NAME@
|
MOZ_MACBUNDLE_NAME = @MOZ_MACBUNDLE_NAME@
|
||||||
|
MOZ_MACBUNDLE_ID = @MOZ_MACBUNDLE_ID@
|
||||||
MOZ_APP_STATIC_INI = @MOZ_APP_STATIC_INI@
|
MOZ_APP_STATIC_INI = @MOZ_APP_STATIC_INI@
|
||||||
|
|
||||||
MOZ_PKG_SPECIAL = @MOZ_PKG_SPECIAL@
|
MOZ_PKG_SPECIAL = @MOZ_PKG_SPECIAL@
|
||||||
|
|
@ -164,6 +165,7 @@ MOZ_ZIPWRITER = @MOZ_ZIPWRITER@
|
||||||
MOZ_OGG = @MOZ_OGG@
|
MOZ_OGG = @MOZ_OGG@
|
||||||
MOZ_RAW = @MOZ_RAW@
|
MOZ_RAW = @MOZ_RAW@
|
||||||
MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
|
MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
|
||||||
|
MOZ_SPEEX_RESAMPLER = @MOZ_SPEEX_RESAMPLER@
|
||||||
MOZ_CUBEB = @MOZ_CUBEB@
|
MOZ_CUBEB = @MOZ_CUBEB@
|
||||||
MOZ_WAVE = @MOZ_WAVE@
|
MOZ_WAVE = @MOZ_WAVE@
|
||||||
MOZ_MEDIA = @MOZ_MEDIA@
|
MOZ_MEDIA = @MOZ_MEDIA@
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ ifndef INCLUDED_VERSION_MK
|
||||||
include $(topsrcdir)/config/version.mk
|
include $(topsrcdir)/config/version.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
USE_AUTOTARGETS_MK = 1
|
||||||
include $(topsrcdir)/config/makefiles/makeutils.mk
|
include $(topsrcdir)/config/makefiles/makeutils.mk
|
||||||
include $(topsrcdir)/config/makefiles/autotargets.mk
|
|
||||||
|
|
||||||
ifdef SDK_XPIDLSRCS
|
ifdef SDK_XPIDLSRCS
|
||||||
XPIDLSRCS += $(SDK_XPIDLSRCS)
|
XPIDLSRCS += $(SDK_XPIDLSRCS)
|
||||||
|
|
@ -361,25 +361,25 @@ ifndef TARGETS
|
||||||
TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
|
TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
COBJS = $(CSRCS:.c=.$(OBJ_SUFFIX))
|
||||||
|
SOBJS = $(SSRCS:.S=.$(OBJ_SUFFIX))
|
||||||
|
CCOBJS = $(patsubst %.cc,%.$(OBJ_SUFFIX),$(filter %.cc,$(CPPSRCS)))
|
||||||
|
CPPOBJS = $(patsubst %.cpp,%.$(OBJ_SUFFIX),$(filter %.cpp,$(CPPSRCS)))
|
||||||
|
CMOBJS = $(CMSRCS:.m=.$(OBJ_SUFFIX))
|
||||||
|
CMMOBJS = $(CMMSRCS:.mm=.$(OBJ_SUFFIX))
|
||||||
|
ASOBJS = $(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX))
|
||||||
ifndef OBJS
|
ifndef OBJS
|
||||||
_OBJS = \
|
_OBJS = $(COBJS) $(SOBJS) $(CCOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS)
|
||||||
$(JRI_STUB_CFILES) \
|
|
||||||
$(addsuffix .$(OBJ_SUFFIX), $(JMC_GEN)) \
|
|
||||||
$(CSRCS:.c=.$(OBJ_SUFFIX)) \
|
|
||||||
$(SSRCS:.S=.$(OBJ_SUFFIX)) \
|
|
||||||
$(patsubst %.cc,%.$(OBJ_SUFFIX),$(CPPSRCS:.cpp=.$(OBJ_SUFFIX))) \
|
|
||||||
$(CMSRCS:.m=.$(OBJ_SUFFIX)) \
|
|
||||||
$(CMMSRCS:.mm=.$(OBJ_SUFFIX)) \
|
|
||||||
$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX))
|
|
||||||
OBJS = $(strip $(_OBJS))
|
OBJS = $(strip $(_OBJS))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
HOST_COBJS = $(addprefix host_,$(HOST_CSRCS:.c=.$(OBJ_SUFFIX)))
|
||||||
|
HOST_CCOBJS = $(addprefix host_,$(patsubst %.cc,%.$(OBJ_SUFFIX),$(filter %.cc,$(HOST_CPPSRCS))))
|
||||||
|
HOST_CPPOBJS = $(addprefix host_,$(patsubst %.cpp,%.$(OBJ_SUFFIX),$(filter %.cpp,$(HOST_CPPSRCS))))
|
||||||
|
HOST_CMOBJS = $(addprefix host_,$(HOST_CMSRCS:.m=.$(OBJ_SUFFIX)))
|
||||||
|
HOST_CMMOBJS = $(addprefix host_,$(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX)))
|
||||||
ifndef HOST_OBJS
|
ifndef HOST_OBJS
|
||||||
_HOST_OBJS = \
|
_HOST_OBJS = $(HOST_COBJS) $(HOST_CCOBJS) $(HOST_CPPOBJS) $(HOST_CMOBJS) $(HOST_CMMOBJS)
|
||||||
$(addprefix host_,$(HOST_CSRCS:.c=.$(OBJ_SUFFIX))) \
|
|
||||||
$(addprefix host_,$(patsubst %.cc,%.$(OBJ_SUFFIX),$(HOST_CPPSRCS:.cpp=.$(OBJ_SUFFIX)))) \
|
|
||||||
$(addprefix host_,$(HOST_CMSRCS:.m=.$(OBJ_SUFFIX))) \
|
|
||||||
$(addprefix host_,$(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX)))
|
|
||||||
HOST_OBJS = $(strip $(_HOST_OBJS))
|
HOST_OBJS = $(strip $(_HOST_OBJS))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
@ -1090,32 +1090,27 @@ endif # MOZ_AUTO_DEPS
|
||||||
$(OBJS) $(HOST_OBJS): $(GLOBAL_DEPS)
|
$(OBJS) $(HOST_OBJS): $(GLOBAL_DEPS)
|
||||||
|
|
||||||
# Rules for building native targets must come first because of the host_ prefix
|
# Rules for building native targets must come first because of the host_ prefix
|
||||||
host_%.$(OBJ_SUFFIX): %.c
|
$(HOST_COBJS): host_%.$(OBJ_SUFFIX): %.c
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||||
|
|
||||||
host_%.$(OBJ_SUFFIX): %.cpp
|
$(HOST_CPPOBJS): host_%.$(OBJ_SUFFIX): %.cpp
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||||
|
|
||||||
host_%.$(OBJ_SUFFIX): %.cc
|
$(HOST_CCOBJS): host_%.$(OBJ_SUFFIX): %.cc
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||||
|
|
||||||
host_%.$(OBJ_SUFFIX): %.m
|
$(HOST_CMOBJS): host_%.$(OBJ_SUFFIX): %.m
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||||
|
|
||||||
host_%.$(OBJ_SUFFIX): %.mm
|
$(HOST_CMMOBJS): host_%.$(OBJ_SUFFIX): %.mm
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||||
|
|
||||||
%:: %.c $(GLOBAL_DEPS)
|
$(COBJS): %.$(OBJ_SUFFIX): %.c
|
||||||
$(REPORT_BUILD)
|
|
||||||
@$(MAKE_DEPS_AUTO_CC)
|
|
||||||
$(ELOG) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTOPTION)$@ $(_VPATH_SRCS)
|
|
||||||
|
|
||||||
%.$(OBJ_SUFFIX): %.c
|
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
@$(MAKE_DEPS_AUTO_CC)
|
@$(MAKE_DEPS_AUTO_CC)
|
||||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
|
||||||
|
|
@ -1135,26 +1130,22 @@ qrc_%.cpp: %.qrc
|
||||||
ifdef ASFILES
|
ifdef ASFILES
|
||||||
# The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
|
# The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
|
||||||
# a '-c' flag.
|
# a '-c' flag.
|
||||||
%.$(OBJ_SUFFIX): %.$(ASM_SUFFIX)
|
$(ASOBJS): %.$(OBJ_SUFFIX): %.$(ASM_SUFFIX)
|
||||||
$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
|
$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
%.$(OBJ_SUFFIX): %.S
|
$(SOBJS): %.$(OBJ_SUFFIX): %.S
|
||||||
$(AS) -o $@ $(ASFLAGS) -c $<
|
$(AS) -o $@ $(ASFLAGS) -c $<
|
||||||
|
|
||||||
%:: %.cpp $(GLOBAL_DEPS)
|
|
||||||
@$(MAKE_DEPS_AUTO_CXX)
|
|
||||||
$(CCC) $(OUTOPTION)$@ $(CXXFLAGS) $(_VPATH_SRCS) $(LDFLAGS)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Please keep the next two rules in sync.
|
# Please keep the next two rules in sync.
|
||||||
#
|
#
|
||||||
%.$(OBJ_SUFFIX): %.cc
|
$(CCOBJS): %.$(OBJ_SUFFIX): %.cc
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
@$(MAKE_DEPS_AUTO_CXX)
|
@$(MAKE_DEPS_AUTO_CXX)
|
||||||
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
|
||||||
|
|
||||||
%.$(OBJ_SUFFIX): %.cpp
|
$(CPPOBJS): %.$(OBJ_SUFFIX): %.cpp
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
@$(MAKE_DEPS_AUTO_CXX)
|
@$(MAKE_DEPS_AUTO_CXX)
|
||||||
ifdef STRICT_CPLUSPLUS_SUFFIX
|
ifdef STRICT_CPLUSPLUS_SUFFIX
|
||||||
|
|
@ -1165,12 +1156,12 @@ else
|
||||||
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
|
||||||
endif #STRICT_CPLUSPLUS_SUFFIX
|
endif #STRICT_CPLUSPLUS_SUFFIX
|
||||||
|
|
||||||
$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm
|
$(CMMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
@$(MAKE_DEPS_AUTO_CXX)
|
@$(MAKE_DEPS_AUTO_CXX)
|
||||||
$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
|
||||||
|
|
||||||
$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m
|
$(CMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
@$(MAKE_DEPS_AUTO_CC)
|
@$(MAKE_DEPS_AUTO_CC)
|
||||||
$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
|
$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
|
||||||
|
|
@ -1605,8 +1596,7 @@ chrome::
|
||||||
$(LOOP_OVER_DIRS)
|
$(LOOP_OVER_DIRS)
|
||||||
$(LOOP_OVER_TOOL_DIRS)
|
$(LOOP_OVER_TOOL_DIRS)
|
||||||
|
|
||||||
$(FINAL_TARGET)/chrome:
|
$(FINAL_TARGET)/chrome: $(call mkdir_deps,$(FINAL_TARGET)/chrome)
|
||||||
$(NSINSTALL) -D $@
|
|
||||||
|
|
||||||
ifneq (,$(wildcard $(JAR_MANIFEST)))
|
ifneq (,$(wildcard $(JAR_MANIFEST)))
|
||||||
ifndef NO_DIST_INSTALL
|
ifndef NO_DIST_INSTALL
|
||||||
|
|
|
||||||
|
|
@ -1047,6 +1047,7 @@ vpx/vpx_codec.h
|
||||||
vpx/vpx_decoder.h
|
vpx/vpx_decoder.h
|
||||||
vpx/vp8dx.h
|
vpx/vp8dx.h
|
||||||
sydneyaudio/sydney_audio.h
|
sydneyaudio/sydney_audio.h
|
||||||
|
speex/speex_resampler.h
|
||||||
vorbis/codec.h
|
vorbis/codec.h
|
||||||
theora/theoradec.h
|
theora/theoradec.h
|
||||||
tremor/ivorbiscodec.h
|
tremor/ivorbiscodec.h
|
||||||
|
|
|
||||||
16
configure.in
|
|
@ -4548,6 +4548,7 @@ MOZ_AUTH_EXTENSION=1
|
||||||
MOZ_OGG=1
|
MOZ_OGG=1
|
||||||
MOZ_RAW=
|
MOZ_RAW=
|
||||||
MOZ_SYDNEYAUDIO=
|
MOZ_SYDNEYAUDIO=
|
||||||
|
MOZ_SPEEX_RESAMPLER=1
|
||||||
MOZ_CUBEB=
|
MOZ_CUBEB=
|
||||||
MOZ_VORBIS=
|
MOZ_VORBIS=
|
||||||
MOZ_TREMOR=
|
MOZ_TREMOR=
|
||||||
|
|
@ -5795,6 +5796,10 @@ if test -n "$MOZ_SYDNEYAUDIO"; then
|
||||||
AC_DEFINE(MOZ_SYDNEYAUDIO)
|
AC_DEFINE(MOZ_SYDNEYAUDIO)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test -n "$MOZ_SPEEX_RESAMPLER"; then
|
||||||
|
AC_DEFINE(MOZ_SPEEX_RESAMPLER)
|
||||||
|
fi
|
||||||
|
|
||||||
if test -n "$MOZ_CUBEB"; then
|
if test -n "$MOZ_CUBEB"; then
|
||||||
case "$target" in
|
case "$target" in
|
||||||
*-mingw*)
|
*-mingw*)
|
||||||
|
|
@ -8508,6 +8513,16 @@ else
|
||||||
fi
|
fi
|
||||||
AC_SUBST(MOZ_MACBUNDLE_NAME)
|
AC_SUBST(MOZ_MACBUNDLE_NAME)
|
||||||
|
|
||||||
|
dnl Mac bundle identifier (based on MOZ_APP_DISPLAYNAME)
|
||||||
|
MOZ_MACBUNDLE_ID=`echo $MOZ_APP_DISPLAYNAME | tr '[A-Z]' '[a-z]'`
|
||||||
|
MOZ_MACBUNDLE_ID=${MOZ_DISTRIBUTION_ID}.${MOZ_MACBUNDLE_ID}
|
||||||
|
if test "$MOZ_DEBUG"; then
|
||||||
|
MOZ_MACBUNDLE_ID=${MOZ_MACBUNDLE_ID}debug
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_DEFINE_UNQUOTED(MOZ_MACBUNDLE_ID,$MOZ_MACBUNDLE_ID)
|
||||||
|
AC_SUBST(MOZ_MACBUNDLE_ID)
|
||||||
|
|
||||||
# The following variables are available to branding and application
|
# The following variables are available to branding and application
|
||||||
# configuration ($BRANDING/configure.sh and $APPLICATION/confvars.sh):
|
# configuration ($BRANDING/configure.sh and $APPLICATION/confvars.sh):
|
||||||
# - MOZ_APP_VENDOR: Used for application.ini's "Vendor" field, which also
|
# - MOZ_APP_VENDOR: Used for application.ini's "Vendor" field, which also
|
||||||
|
|
@ -8715,6 +8730,7 @@ AC_SUBST(MOZ_APP_EXTRA_LIBS)
|
||||||
|
|
||||||
AC_SUBST(MOZ_MEDIA)
|
AC_SUBST(MOZ_MEDIA)
|
||||||
AC_SUBST(MOZ_SYDNEYAUDIO)
|
AC_SUBST(MOZ_SYDNEYAUDIO)
|
||||||
|
AC_SUBST(MOZ_SPEEX_RESAMPLER)
|
||||||
AC_SUBST(MOZ_CUBEB)
|
AC_SUBST(MOZ_CUBEB)
|
||||||
AC_SUBST(MOZ_WAVE)
|
AC_SUBST(MOZ_WAVE)
|
||||||
AC_SUBST(MOZ_VORBIS)
|
AC_SUBST(MOZ_VORBIS)
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ nsDOMMultipartFile::GetSize(PRUint64* aLength)
|
||||||
length += l;
|
length += l;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ENSURE_TRUE(length.valid(), NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(length.isValid(), NS_ERROR_FAILURE);
|
||||||
|
|
||||||
mLength = length.value();
|
mLength = length.value();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,8 @@
|
||||||
#define nsDOMBlobBuilder_h
|
#define nsDOMBlobBuilder_h
|
||||||
|
|
||||||
#include "nsDOMFile.h"
|
#include "nsDOMFile.h"
|
||||||
#include "CheckedInt.h"
|
|
||||||
|
|
||||||
#include "mozilla/StandardInteger.h"
|
#include "mozilla/CheckedInt.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
|
|
@ -128,10 +127,10 @@ protected:
|
||||||
|
|
||||||
// Start at 1 or we'll loop forever.
|
// Start at 1 or we'll loop forever.
|
||||||
CheckedUint32 bufferLen = NS_MAX<PRUint32>(mDataBufferLen, 1);
|
CheckedUint32 bufferLen = NS_MAX<PRUint32>(mDataBufferLen, 1);
|
||||||
while (bufferLen.valid() && bufferLen.value() < mDataLen + aSize)
|
while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize)
|
||||||
bufferLen *= 2;
|
bufferLen *= 2;
|
||||||
|
|
||||||
if (!bufferLen.valid())
|
if (!bufferLen.isValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// PR_ memory functions are still fallible
|
// PR_ memory functions are still fallible
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,8 @@
|
||||||
#include "nsIUUIDGenerator.h"
|
#include "nsIUUIDGenerator.h"
|
||||||
#include "nsBlobProtocolHandler.h"
|
#include "nsBlobProtocolHandler.h"
|
||||||
#include "nsStringStream.h"
|
#include "nsStringStream.h"
|
||||||
#include "CheckedInt.h"
|
|
||||||
#include "nsJSUtils.h"
|
#include "nsJSUtils.h"
|
||||||
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
|
||||||
#include "plbase64.h"
|
#include "plbase64.h"
|
||||||
|
|
@ -227,7 +227,7 @@ ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd)
|
||||||
newEndOffset = aSize;
|
newEndOffset = aSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newStartOffset.valid() || !newEndOffset.valid() ||
|
if (!newStartOffset.isValid() || !newEndOffset.isValid() ||
|
||||||
newStartOffset.value() >= newEndOffset.value()) {
|
newStartOffset.value() >= newEndOffset.value()) {
|
||||||
aStart = aEnd = 0;
|
aStart = aEnd = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2133,11 +2133,8 @@ nsGenericElement::SetScrollTop(PRInt32 aScrollTop)
|
||||||
nsIScrollableFrame* sf = GetScrollFrame();
|
nsIScrollableFrame* sf = GetScrollFrame();
|
||||||
if (sf) {
|
if (sf) {
|
||||||
nsPoint pt = sf->GetScrollPosition();
|
nsPoint pt = sf->GetScrollPosition();
|
||||||
pt.y = nsPresContext::CSSPixelsToAppUnits(aScrollTop);
|
sf->ScrollToCSSPixels(nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
|
||||||
nscoord halfPixel = nsPresContext::CSSPixelsToAppUnits(0.5f);
|
aScrollTop));
|
||||||
// Don't allow pt.y + halfPixel since that would round up to the next CSS pixel.
|
|
||||||
nsRect range(pt.x, pt.y - halfPixel, 0, halfPixel*2 - 1);
|
|
||||||
sf->ScrollTo(pt, nsIScrollableFrame::INSTANT, &range);
|
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
@ -2166,11 +2163,8 @@ nsGenericElement::SetScrollLeft(PRInt32 aScrollLeft)
|
||||||
nsIScrollableFrame* sf = GetScrollFrame();
|
nsIScrollableFrame* sf = GetScrollFrame();
|
||||||
if (sf) {
|
if (sf) {
|
||||||
nsPoint pt = sf->GetScrollPosition();
|
nsPoint pt = sf->GetScrollPosition();
|
||||||
pt.x = nsPresContext::CSSPixelsToAppUnits(aScrollLeft);
|
sf->ScrollToCSSPixels(nsIntPoint(aScrollLeft,
|
||||||
nscoord halfPixel = nsPresContext::CSSPixelsToAppUnits(0.5f);
|
nsPresContext::AppUnitsToIntCSSPixels(pt.y)));
|
||||||
// Don't allow pt.x + halfPixel since that would round up to the next CSS pixel.
|
|
||||||
nsRect range(pt.x - halfPixel, pt.y, halfPixel*2 - 1, 0);
|
|
||||||
sf->ScrollTo(pt, nsIScrollableFrame::INSTANT, &range);
|
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- 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 *****
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
*
|
*
|
||||||
|
|
@ -109,6 +110,7 @@
|
||||||
#include "nsIDOMFormData.h"
|
#include "nsIDOMFormData.h"
|
||||||
|
|
||||||
#include "nsWrapperCacheInlines.h"
|
#include "nsWrapperCacheInlines.h"
|
||||||
|
#include "nsStreamListenerWrapper.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
@ -3046,9 +3048,6 @@ nsXMLHttpRequest::Send(JSContext *aCx, nsIVariant* aVariant, const Nullable<Requ
|
||||||
if (mState & XML_HTTP_REQUEST_MULTIPART) {
|
if (mState & XML_HTTP_REQUEST_MULTIPART) {
|
||||||
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 1);
|
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 1);
|
||||||
listener = new nsMultipartProxyListener(listener);
|
listener = new nsMultipartProxyListener(listener);
|
||||||
if (!listener) {
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 0);
|
Telemetry::Accumulate(Telemetry::MULTIPART_XHR_RESPONSE, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -3062,9 +3061,18 @@ nsXMLHttpRequest::Send(JSContext *aCx, nsIVariant* aVariant, const Nullable<Requ
|
||||||
// a same-origin request right now, since it could be redirected.
|
// a same-origin request right now, since it could be redirected.
|
||||||
listener = new nsCORSListenerProxy(listener, mPrincipal, mChannel,
|
listener = new nsCORSListenerProxy(listener, mPrincipal, mChannel,
|
||||||
withCredentials, true, &rv);
|
withCredentials, true, &rv);
|
||||||
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Because of bug 682305, we can't let listener be the XHR object itself
|
||||||
|
// because JS wouldn't be able to use it. So if we haven't otherwise
|
||||||
|
// created a listener around 'this', do so now.
|
||||||
|
|
||||||
|
listener = new nsStreamListenerWrapper(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(listener != this,
|
||||||
|
"Using an object as a listener that can't be exposed to JS");
|
||||||
|
|
||||||
// Bypass the network cache in cases where it makes no sense:
|
// Bypass the network cache in cases where it makes no sense:
|
||||||
// 1) Multipart responses are very large and would likely be doomed by the
|
// 1) Multipart responses are very large and would likely be doomed by the
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ _CHROME_FILES = \
|
||||||
test_bug650784.html \
|
test_bug650784.html \
|
||||||
test_bug752226-3.xul \
|
test_bug752226-3.xul \
|
||||||
test_bug752226-4.xul \
|
test_bug752226-4.xul \
|
||||||
|
test_bug682305.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
libs:: $(_TEST_FILES)
|
libs:: $(_TEST_FILES)
|
||||||
|
|
|
||||||
159
content/base/test/chrome/test_bug682305.html
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=682305
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<title>XMLHttpRequest send and channel implemented in JS</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=682305">Mozilla Bug 682305</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script class="testbody" type="application/javascript;version=1.8">
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register a custom nsIProtocolHandler service
|
||||||
|
* in order to be able to implement *and use* an
|
||||||
|
* nsIChannel component written in Javascript.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Cc = Components.classes;
|
||||||
|
var Ci = Components.interfaces;
|
||||||
|
var Cr = Components.results;
|
||||||
|
var Cu = Components.utils;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
var SimpleURI = Cc["@mozilla.org/network/simple-uri;1"];
|
||||||
|
var ios = Cc["@mozilla.org/network/io-service;1"]
|
||||||
|
.getService(Ci.nsIIOService);
|
||||||
|
|
||||||
|
var PROTOCOL_SCHEME = "jsproto";
|
||||||
|
|
||||||
|
|
||||||
|
function CustomChannel(uri) {
|
||||||
|
this.URI = this.originalURI = uri;
|
||||||
|
}
|
||||||
|
CustomChannel.prototype = {
|
||||||
|
URI: null,
|
||||||
|
originalURI: null,
|
||||||
|
contentCharset: "utf-8",
|
||||||
|
contentLength: 0,
|
||||||
|
contentType: "text/plain",
|
||||||
|
owner: Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal),
|
||||||
|
securityInfo: null,
|
||||||
|
notificationCallbacks: null,
|
||||||
|
loadFlags: 0,
|
||||||
|
loadGroup: null,
|
||||||
|
name: null,
|
||||||
|
status: Cr.NS_OK,
|
||||||
|
asyncOpen: function(listener, context) {
|
||||||
|
let stream = this.open();
|
||||||
|
try {
|
||||||
|
listener.onStartRequest(this, context);
|
||||||
|
} catch(e) {}
|
||||||
|
try {
|
||||||
|
listener.onDataAvailable(this, context, stream, 0, stream.available());
|
||||||
|
} catch(e) {}
|
||||||
|
try {
|
||||||
|
listener.onStopRequest(this, context, Cr.NS_OK);
|
||||||
|
} catch(e) {}
|
||||||
|
},
|
||||||
|
open: function() {
|
||||||
|
let data = "bar";
|
||||||
|
let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
|
||||||
|
stream.setData(data, data.length);
|
||||||
|
return stream;
|
||||||
|
},
|
||||||
|
isPending: function() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
cancel: function() {
|
||||||
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
},
|
||||||
|
suspend: function() {
|
||||||
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
},
|
||||||
|
resume: function() {
|
||||||
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
},
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function CustomProtocol() {}
|
||||||
|
CustomProtocol.prototype = {
|
||||||
|
get scheme() {
|
||||||
|
return PROTOCOL_SCHEME;
|
||||||
|
},
|
||||||
|
get protocolFlags() {
|
||||||
|
return (Ci.nsIProtocolHandler.URI_NORELATIVE |
|
||||||
|
Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE |
|
||||||
|
Ci.nsIProtocolHandler.URI_DANGEROUS_TO_LOAD);
|
||||||
|
},
|
||||||
|
get defaultPort() {
|
||||||
|
return -1;
|
||||||
|
},
|
||||||
|
allowPort: function allowPort() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
newURI: function newURI(spec, charset, baseURI) {
|
||||||
|
var uri = SimpleURI.createInstance(Ci.nsIURI)
|
||||||
|
uri.spec = spec;
|
||||||
|
return uri.QueryInterface(Ci.nsIURI);
|
||||||
|
},
|
||||||
|
newChannel: function newChannel(URI) {
|
||||||
|
return new CustomChannel(URI);
|
||||||
|
},
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||||
|
Ci.nsISupportsWeakReference,
|
||||||
|
Ci.nsIProtocolHandler])
|
||||||
|
};
|
||||||
|
|
||||||
|
var gFactory = {
|
||||||
|
register: function() {
|
||||||
|
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||||
|
|
||||||
|
var classID = Components.ID("{ed064287-1e76-49ba-a28d-dc74394a8334}");
|
||||||
|
var description = PROTOCOL_SCHEME + ": protocol";
|
||||||
|
var contractID = "@mozilla.org/network/protocol;1?name=" + PROTOCOL_SCHEME;
|
||||||
|
var factory = XPCOMUtils._getFactory(CustomProtocol);
|
||||||
|
|
||||||
|
registrar.registerFactory(classID, description, contractID, factory);
|
||||||
|
|
||||||
|
this.unregister = function() {
|
||||||
|
registrar.unregisterFactory(classID, factory);
|
||||||
|
delete this.unregister;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the custom procotol handler
|
||||||
|
gFactory.register();
|
||||||
|
|
||||||
|
// Then, checks if XHR works with it
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", PROTOCOL_SCHEME + ":foo", true);
|
||||||
|
xhr.onload = function () {
|
||||||
|
is(xhr.responseText, "bar", "protocol doesn't work");
|
||||||
|
gFactory.unregister();
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
xhr.send(null);
|
||||||
|
} catch(e) {
|
||||||
|
ok(false, e);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
#include "prtypes.h"
|
#include "prtypes.h"
|
||||||
|
|
||||||
#include "CheckedInt.h"
|
#include "mozilla/CheckedInt.h"
|
||||||
|
|
||||||
class nsHTMLCanvasElement;
|
class nsHTMLCanvasElement;
|
||||||
class nsIPrincipal;
|
class nsIPrincipal;
|
||||||
|
|
@ -63,9 +63,9 @@ inline bool CheckSaneSubrectSize(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h,
|
||||||
CheckedInt32 checked_ymost = CheckedInt32(y) + h;
|
CheckedInt32 checked_ymost = CheckedInt32(y) + h;
|
||||||
|
|
||||||
return w >= 0 && h >= 0 && x >= 0 && y >= 0 &&
|
return w >= 0 && h >= 0 && x >= 0 && y >= 0 &&
|
||||||
checked_xmost.valid() &&
|
checked_xmost.isValid() &&
|
||||||
checked_xmost.value() <= realWidth &&
|
checked_xmost.value() <= realWidth &&
|
||||||
checked_ymost.valid() &&
|
checked_ymost.isValid() &&
|
||||||
checked_ymost.value() <= realHeight;
|
checked_ymost.value() <= realHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsIDOMCanvasRenderingContext2D.h"
|
#include "nsIDOMCanvasRenderingContext2D.h"
|
||||||
#include "CheckedInt.h"
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "nsMathUtils.h"
|
#include "nsMathUtils.h"
|
||||||
#include "CustomQS_Canvas.h"
|
#include "CustomQS_Canvas.h"
|
||||||
|
|
||||||
|
|
@ -169,7 +169,7 @@ CreateImageData(JSContext* cx, JSObject* obj, uint32_t w, uint32_t h, jsval* vp)
|
||||||
h = 1;
|
h = 1;
|
||||||
|
|
||||||
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(w) * h * 4;
|
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(w) * h * 4;
|
||||||
if (!len.valid()) {
|
if (!len.isValid()) {
|
||||||
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -425,7 +425,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||||
// If incrementing the generation would cause overflow,
|
// If incrementing the generation would cause overflow,
|
||||||
// don't allow it. Allowing this would allow us to use
|
// don't allow it. Allowing this would allow us to use
|
||||||
// resource handles created from older context generations.
|
// resource handles created from older context generations.
|
||||||
if (!(mGeneration+1).valid())
|
if (!(mGeneration + 1).isValid())
|
||||||
return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
|
return NS_ERROR_FAILURE; // exit without changing the value of mGeneration
|
||||||
|
|
||||||
gl::ContextFormat format(gl::ContextFormat::BasicRGBA32);
|
gl::ContextFormat format(gl::ContextFormat::BasicRGBA32);
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,9 @@
|
||||||
#include "GLContextProvider.h"
|
#include "GLContextProvider.h"
|
||||||
#include "Layers.h"
|
#include "Layers.h"
|
||||||
|
|
||||||
#include "CheckedInt.h"
|
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
|
|
||||||
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "mozilla/dom/ImageData.h"
|
#include "mozilla/dom/ImageData.h"
|
||||||
|
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
|
|
@ -481,7 +481,7 @@ public:
|
||||||
private:
|
private:
|
||||||
WebGLMonotonicHandle NextMonotonicHandle() {
|
WebGLMonotonicHandle NextMonotonicHandle() {
|
||||||
++mCurrentMonotonicHandle;
|
++mCurrentMonotonicHandle;
|
||||||
if (!mCurrentMonotonicHandle.valid())
|
if (!mCurrentMonotonicHandle.isValid())
|
||||||
NS_RUNTIMEABORT("ran out of monotonic ids!");
|
NS_RUNTIMEABORT("ran out of monotonic ids!");
|
||||||
return mCurrentMonotonicHandle.value();
|
return mCurrentMonotonicHandle.value();
|
||||||
}
|
}
|
||||||
|
|
@ -1748,7 +1748,7 @@ public:
|
||||||
|
|
||||||
bool HasImageInfoAt(size_t level, size_t face) const {
|
bool HasImageInfoAt(size_t level, size_t face) const {
|
||||||
CheckedUint32 checked_index = CheckedUint32(level) * mFacesCount + face;
|
CheckedUint32 checked_index = CheckedUint32(level) * mFacesCount + face;
|
||||||
return checked_index.valid() &&
|
return checked_index.isValid() &&
|
||||||
checked_index.value() < mImageInfos.Length() &&
|
checked_index.value() < mImageInfos.Length() &&
|
||||||
ImageInfoAt(level, face).mIsDefined;
|
ImageInfoAt(level, face).mIsDefined;
|
||||||
}
|
}
|
||||||
|
|
@ -2328,7 +2328,7 @@ public:
|
||||||
|
|
||||||
bool NextGeneration()
|
bool NextGeneration()
|
||||||
{
|
{
|
||||||
if (!(mGeneration+1).valid())
|
if (!(mGeneration + 1).isValid())
|
||||||
return false; // must exit without changing mGeneration
|
return false; // must exit without changing mGeneration
|
||||||
++mGeneration;
|
++mGeneration;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -687,7 +687,7 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||||
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
return ErrorInvalidOperation("BufferData: no buffer bound!");
|
||||||
|
|
||||||
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data->mLength;
|
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data->mLength;
|
||||||
if (!checked_neededByteLength.valid())
|
if (!checked_neededByteLength.isValid())
|
||||||
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
|
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
|
||||||
|
|
||||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
|
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
|
||||||
|
|
@ -726,7 +726,7 @@ WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
|
||||||
return ErrorInvalidOperation("BufferSubData: no buffer bound!");
|
return ErrorInvalidOperation("BufferSubData: no buffer bound!");
|
||||||
|
|
||||||
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.mLength;
|
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.mLength;
|
||||||
if (!checked_neededByteLength.valid())
|
if (!checked_neededByteLength.isValid())
|
||||||
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
|
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
|
||||||
|
|
||||||
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
|
if (checked_neededByteLength.value() > boundBuffer->ByteLength())
|
||||||
|
|
@ -941,7 +941,7 @@ WebGLContext::CopyTexSubImage2D_base(WebGLenum target,
|
||||||
CheckedUint32 checked_neededByteLength =
|
CheckedUint32 checked_neededByteLength =
|
||||||
GetImageSize(height, width, texelSize, mPixelStoreUnpackAlignment);
|
GetImageSize(height, width, texelSize, mPixelStoreUnpackAlignment);
|
||||||
|
|
||||||
if (!checked_neededByteLength.valid())
|
if (!checked_neededByteLength.isValid())
|
||||||
return ErrorInvalidOperation("%s: integer overflow computing the needed buffer size", info);
|
return ErrorInvalidOperation("%s: integer overflow computing the needed buffer size", info);
|
||||||
|
|
||||||
PRUint32 bytesNeeded = checked_neededByteLength.value();
|
PRUint32 bytesNeeded = checked_neededByteLength.value();
|
||||||
|
|
@ -1562,7 +1562,7 @@ WebGLContext::DoFakeVertexAttrib0(WebGLuint vertexCount)
|
||||||
|
|
||||||
CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(WebGLfloat);
|
CheckedUint32 checked_dataSize = CheckedUint32(vertexCount) * 4 * sizeof(WebGLfloat);
|
||||||
|
|
||||||
if (!checked_dataSize.valid()) {
|
if (!checked_dataSize.isValid()) {
|
||||||
ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation "
|
ErrorOutOfMemory("Integer overflow trying to construct a fake vertex attrib 0 array for a draw-operation "
|
||||||
"with %d vertices. Try reducing the number of vertices.", vertexCount);
|
"with %d vertices. Try reducing the number of vertices.", vertexCount);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1779,7 +1779,7 @@ WebGLContext::DrawArrays(GLenum mode, WebGLint first, WebGLsizei count)
|
||||||
|
|
||||||
CheckedInt32 checked_firstPlusCount = CheckedInt32(first) + count;
|
CheckedInt32 checked_firstPlusCount = CheckedInt32(first) + count;
|
||||||
|
|
||||||
if (!checked_firstPlusCount.valid())
|
if (!checked_firstPlusCount.isValid())
|
||||||
return ErrorInvalidOperation("drawArrays: overflow in first+count");
|
return ErrorInvalidOperation("drawArrays: overflow in first+count");
|
||||||
|
|
||||||
if (checked_firstPlusCount.value() > maxAllowedCount)
|
if (checked_firstPlusCount.value() > maxAllowedCount)
|
||||||
|
|
@ -1847,7 +1847,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
|
||||||
return ErrorInvalidEnum("DrawElements: type must be UNSIGNED_SHORT or UNSIGNED_BYTE");
|
return ErrorInvalidEnum("DrawElements: type must be UNSIGNED_SHORT or UNSIGNED_BYTE");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!checked_byteCount.valid())
|
if (!checked_byteCount.isValid())
|
||||||
return ErrorInvalidValue("DrawElements: overflow in byteCount");
|
return ErrorInvalidValue("DrawElements: overflow in byteCount");
|
||||||
|
|
||||||
// If there is no current program, this is silently ignored.
|
// If there is no current program, this is silently ignored.
|
||||||
|
|
@ -1863,7 +1863,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
|
||||||
|
|
||||||
CheckedUint32 checked_neededByteCount = checked_byteCount + byteOffset;
|
CheckedUint32 checked_neededByteCount = checked_byteCount + byteOffset;
|
||||||
|
|
||||||
if (!checked_neededByteCount.valid())
|
if (!checked_neededByteCount.isValid())
|
||||||
return ErrorInvalidOperation("DrawElements: overflow in byteOffset+byteCount");
|
return ErrorInvalidOperation("DrawElements: overflow in byteOffset+byteCount");
|
||||||
|
|
||||||
if (checked_neededByteCount.value() > mBoundElementArrayBuffer->ByteLength())
|
if (checked_neededByteCount.value() > mBoundElementArrayBuffer->ByteLength())
|
||||||
|
|
@ -1880,7 +1880,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
|
||||||
|
|
||||||
CheckedInt32 checked_maxIndexPlusOne = CheckedInt32(maxIndex) + 1;
|
CheckedInt32 checked_maxIndexPlusOne = CheckedInt32(maxIndex) + 1;
|
||||||
|
|
||||||
if (!checked_maxIndexPlusOne.valid() ||
|
if (!checked_maxIndexPlusOne.isValid() ||
|
||||||
checked_maxIndexPlusOne.value() > maxAllowedCount)
|
checked_maxIndexPlusOne.value() > maxAllowedCount)
|
||||||
{
|
{
|
||||||
// the index array contains invalid indices for the current drawing state, but they
|
// the index array contains invalid indices for the current drawing state, but they
|
||||||
|
|
@ -1893,7 +1893,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type,
|
||||||
|
|
||||||
CheckedInt32 checked_maxIndexInSubArrayPlusOne = CheckedInt32(maxIndexInSubArray) + 1;
|
CheckedInt32 checked_maxIndexInSubArrayPlusOne = CheckedInt32(maxIndexInSubArray) + 1;
|
||||||
|
|
||||||
if (!checked_maxIndexInSubArrayPlusOne.valid() ||
|
if (!checked_maxIndexInSubArrayPlusOne.isValid() ||
|
||||||
checked_maxIndexInSubArrayPlusOne.value() > maxAllowedCount)
|
checked_maxIndexInSubArrayPlusOne.value() > maxAllowedCount)
|
||||||
{
|
{
|
||||||
return ErrorInvalidOperation(
|
return ErrorInvalidOperation(
|
||||||
|
|
@ -3883,7 +3883,7 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
|
||||||
CheckedUint32 checked_alignedRowSize =
|
CheckedUint32 checked_alignedRowSize =
|
||||||
RoundedToNextMultipleOf(checked_plainRowSize, mPixelStorePackAlignment);
|
RoundedToNextMultipleOf(checked_plainRowSize, mPixelStorePackAlignment);
|
||||||
|
|
||||||
if (!checked_neededByteLength.valid())
|
if (!checked_neededByteLength.isValid())
|
||||||
return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
|
return ErrorInvalidOperation("ReadPixels: integer overflow computing the needed buffer size");
|
||||||
|
|
||||||
if (checked_neededByteLength.value() > dataByteLen)
|
if (checked_neededByteLength.value() > dataByteLen)
|
||||||
|
|
@ -5601,7 +5601,7 @@ WebGLContext::TexImage2D_base(WebGLenum target, WebGLint level, WebGLenum intern
|
||||||
CheckedUint32 checked_alignedRowSize =
|
CheckedUint32 checked_alignedRowSize =
|
||||||
RoundedToNextMultipleOf(checked_plainRowSize.value(), mPixelStoreUnpackAlignment);
|
RoundedToNextMultipleOf(checked_plainRowSize.value(), mPixelStoreUnpackAlignment);
|
||||||
|
|
||||||
if (!checked_neededByteLength.valid())
|
if (!checked_neededByteLength.isValid())
|
||||||
return ErrorInvalidOperation("texImage2D: integer overflow computing the needed buffer size");
|
return ErrorInvalidOperation("texImage2D: integer overflow computing the needed buffer size");
|
||||||
|
|
||||||
PRUint32 bytesNeeded = checked_neededByteLength.value();
|
PRUint32 bytesNeeded = checked_neededByteLength.value();
|
||||||
|
|
@ -5842,7 +5842,7 @@ WebGLContext::TexSubImage2D_base(WebGLenum target, WebGLint level,
|
||||||
CheckedUint32 checked_alignedRowSize =
|
CheckedUint32 checked_alignedRowSize =
|
||||||
RoundedToNextMultipleOf(checked_plainRowSize.value(), mPixelStoreUnpackAlignment);
|
RoundedToNextMultipleOf(checked_plainRowSize.value(), mPixelStoreUnpackAlignment);
|
||||||
|
|
||||||
if (!checked_neededByteLength.valid())
|
if (!checked_neededByteLength.isValid())
|
||||||
return ErrorInvalidOperation("texSubImage2D: integer overflow computing the needed buffer size");
|
return ErrorInvalidOperation("texSubImage2D: integer overflow computing the needed buffer size");
|
||||||
|
|
||||||
PRUint32 bytesNeeded = checked_neededByteLength.value();
|
PRUint32 bytesNeeded = checked_neededByteLength.value();
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,7 @@
|
||||||
#include "WebGLContext.h"
|
#include "WebGLContext.h"
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "CheckedInt.h"
|
|
||||||
|
|
||||||
#include "jsfriendapi.h"
|
#include "jsfriendapi.h"
|
||||||
|
|
||||||
|
|
@ -143,8 +142,8 @@ WebGLContext::ValidateBuffers(PRInt32 *maxAllowedCount, const char *info)
|
||||||
CheckedInt32 checked_sizeOfLastElement
|
CheckedInt32 checked_sizeOfLastElement
|
||||||
= CheckedInt32(vd.componentSize()) * vd.size;
|
= CheckedInt32(vd.componentSize()) * vd.size;
|
||||||
|
|
||||||
if (!checked_byteLength.valid() ||
|
if (!checked_byteLength.isValid() ||
|
||||||
!checked_sizeOfLastElement.valid())
|
!checked_sizeOfLastElement.isValid())
|
||||||
{
|
{
|
||||||
ErrorInvalidOperation("%s: integer overflow occured while checking vertex attrib %d", info, i);
|
ErrorInvalidOperation("%s: integer overflow occured while checking vertex attrib %d", info, i);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -156,7 +155,7 @@ WebGLContext::ValidateBuffers(PRInt32 *maxAllowedCount, const char *info)
|
||||||
CheckedInt32 checked_maxAllowedCount
|
CheckedInt32 checked_maxAllowedCount
|
||||||
= ((checked_byteLength - checked_sizeOfLastElement) / vd.actualStride()) + 1;
|
= ((checked_byteLength - checked_sizeOfLastElement) / vd.actualStride()) + 1;
|
||||||
|
|
||||||
if (!checked_maxAllowedCount.valid()) {
|
if (!checked_maxAllowedCount.isValid()) {
|
||||||
ErrorInvalidOperation("%s: integer overflow occured while checking vertex attrib %d", info, i);
|
ErrorInvalidOperation("%s: integer overflow occured while checking vertex attrib %d", info, i);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -401,7 +400,7 @@ bool WebGLContext::ValidateCompressedTextureSize(WebGLint level, WebGLenum forma
|
||||||
{
|
{
|
||||||
CheckedUint32 calculated_byteLength = 0;
|
CheckedUint32 calculated_byteLength = 0;
|
||||||
CheckedUint32 checked_byteLength = byteLength;
|
CheckedUint32 checked_byteLength = byteLength;
|
||||||
if (!checked_byteLength.valid()) {
|
if (!checked_byteLength.isValid()) {
|
||||||
ErrorInvalidValue("%s: data length out of bounds", info);
|
ErrorInvalidValue("%s: data length out of bounds", info);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -411,7 +410,7 @@ bool WebGLContext::ValidateCompressedTextureSize(WebGLint level, WebGLenum forma
|
||||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||||
{
|
{
|
||||||
calculated_byteLength = ((CheckedUint32(width) + 3) / 4) * ((CheckedUint32(height) + 3) / 4) * 8;
|
calculated_byteLength = ((CheckedUint32(width) + 3) / 4) * ((CheckedUint32(height) + 3) / 4) * 8;
|
||||||
if (!calculated_byteLength.valid() || !(checked_byteLength == calculated_byteLength)) {
|
if (!calculated_byteLength.isValid() || !(checked_byteLength == calculated_byteLength)) {
|
||||||
ErrorInvalidValue("%s: data size does not match dimensions", info);
|
ErrorInvalidValue("%s: data size does not match dimensions", info);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +420,7 @@ bool WebGLContext::ValidateCompressedTextureSize(WebGLint level, WebGLenum forma
|
||||||
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||||
{
|
{
|
||||||
calculated_byteLength = ((CheckedUint32(width) + 3) / 4) * ((CheckedUint32(height) + 3) / 4) * 16;
|
calculated_byteLength = ((CheckedUint32(width) + 3) / 4) * ((CheckedUint32(height) + 3) / 4) * 16;
|
||||||
if (!calculated_byteLength.valid() || !(checked_byteLength == calculated_byteLength)) {
|
if (!calculated_byteLength.isValid() || !(checked_byteLength == calculated_byteLength)) {
|
||||||
ErrorInvalidValue("%s: data size does not match dimensions", info);
|
ErrorInvalidValue("%s: data size does not match dimensions", info);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,6 @@
|
||||||
#include "nsIMemoryReporter.h"
|
#include "nsIMemoryReporter.h"
|
||||||
#include "nsStyleUtil.h"
|
#include "nsStyleUtil.h"
|
||||||
#include "CanvasImageCache.h"
|
#include "CanvasImageCache.h"
|
||||||
#include "CheckedInt.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
@ -116,6 +115,7 @@
|
||||||
#include "jsfriendapi.h"
|
#include "jsfriendapi.h"
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/dom/ImageData.h"
|
#include "mozilla/dom/ImageData.h"
|
||||||
#include "mozilla/dom/PBrowserParent.h"
|
#include "mozilla/dom/PBrowserParent.h"
|
||||||
|
|
@ -3926,14 +3926,14 @@ nsCanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||||
MOZ_ASSERT(aWidth && aHeight);
|
MOZ_ASSERT(aWidth && aHeight);
|
||||||
|
|
||||||
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
|
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
|
||||||
if (!len.valid()) {
|
if (!len.isValid()) {
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckedInt<int32_t> rightMost = CheckedInt<int32_t>(aX) + aWidth;
|
CheckedInt<int32_t> rightMost = CheckedInt<int32_t>(aX) + aWidth;
|
||||||
CheckedInt<int32_t> bottomMost = CheckedInt<int32_t>(aY) + aHeight;
|
CheckedInt<int32_t> bottomMost = CheckedInt<int32_t>(aY) + aHeight;
|
||||||
|
|
||||||
if (!rightMost.valid() || !bottomMost.valid()) {
|
if (!rightMost.isValid() || !bottomMost.isValid()) {
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4066,7 +4066,7 @@ nsCanvasRenderingContext2D::PutImageData_explicit(PRInt32 x, PRInt32 y, PRUint32
|
||||||
|
|
||||||
CheckedInt32 checkedDirtyX = CheckedInt32(dirtyX) + dirtyWidth;
|
CheckedInt32 checkedDirtyX = CheckedInt32(dirtyX) + dirtyWidth;
|
||||||
|
|
||||||
if (!checkedDirtyX.valid())
|
if (!checkedDirtyX.isValid())
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||||
|
|
||||||
dirtyX = checkedDirtyX.value();
|
dirtyX = checkedDirtyX.value();
|
||||||
|
|
@ -4078,7 +4078,7 @@ nsCanvasRenderingContext2D::PutImageData_explicit(PRInt32 x, PRInt32 y, PRUint32
|
||||||
|
|
||||||
CheckedInt32 checkedDirtyY = CheckedInt32(dirtyY) + dirtyHeight;
|
CheckedInt32 checkedDirtyY = CheckedInt32(dirtyY) + dirtyHeight;
|
||||||
|
|
||||||
if (!checkedDirtyY.valid())
|
if (!checkedDirtyY.isValid())
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||||
|
|
||||||
dirtyY = checkedDirtyY.value();
|
dirtyY = checkedDirtyY.value();
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,6 @@
|
||||||
#include "nsIMemoryReporter.h"
|
#include "nsIMemoryReporter.h"
|
||||||
#include "nsStyleUtil.h"
|
#include "nsStyleUtil.h"
|
||||||
#include "CanvasImageCache.h"
|
#include "CanvasImageCache.h"
|
||||||
#include "CheckedInt.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
@ -112,6 +111,7 @@
|
||||||
#include "jsfriendapi.h"
|
#include "jsfriendapi.h"
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/dom/ImageData.h"
|
#include "mozilla/dom/ImageData.h"
|
||||||
#include "mozilla/dom/PBrowserParent.h"
|
#include "mozilla/dom/PBrowserParent.h"
|
||||||
|
|
@ -4095,14 +4095,14 @@ nsCanvasRenderingContext2DAzure::GetImageDataArray(JSContext* aCx,
|
||||||
MOZ_ASSERT(aWidth && aHeight);
|
MOZ_ASSERT(aWidth && aHeight);
|
||||||
|
|
||||||
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
|
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
|
||||||
if (!len.valid()) {
|
if (!len.isValid()) {
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckedInt<int32_t> rightMost = CheckedInt<int32_t>(aX) + aWidth;
|
CheckedInt<int32_t> rightMost = CheckedInt<int32_t>(aX) + aWidth;
|
||||||
CheckedInt<int32_t> bottomMost = CheckedInt<int32_t>(aY) + aHeight;
|
CheckedInt<int32_t> bottomMost = CheckedInt<int32_t>(aY) + aHeight;
|
||||||
|
|
||||||
if (!rightMost.valid() || !bottomMost.valid()) {
|
if (!rightMost.isValid() || !bottomMost.isValid()) {
|
||||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4233,7 +4233,7 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(PRInt32 x, PRInt32 y, PRU
|
||||||
|
|
||||||
CheckedInt32 checkedDirtyX = CheckedInt32(dirtyX) + dirtyWidth;
|
CheckedInt32 checkedDirtyX = CheckedInt32(dirtyX) + dirtyWidth;
|
||||||
|
|
||||||
if (!checkedDirtyX.valid())
|
if (!checkedDirtyX.isValid())
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||||
|
|
||||||
dirtyX = checkedDirtyX.value();
|
dirtyX = checkedDirtyX.value();
|
||||||
|
|
@ -4245,7 +4245,7 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(PRInt32 x, PRInt32 y, PRU
|
||||||
|
|
||||||
CheckedInt32 checkedDirtyY = CheckedInt32(dirtyY) + dirtyHeight;
|
CheckedInt32 checkedDirtyY = CheckedInt32(dirtyY) + dirtyHeight;
|
||||||
|
|
||||||
if (!checkedDirtyY.valid())
|
if (!checkedDirtyY.isValid())
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||||
|
|
||||||
dirtyY = checkedDirtyY.value();
|
dirtyY = checkedDirtyY.value();
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,10 @@
|
||||||
#include "nsHTMLCanvasElement.h"
|
#include "nsHTMLCanvasElement.h"
|
||||||
|
|
||||||
#include "mozilla/Base64.h"
|
#include "mozilla/Base64.h"
|
||||||
|
#include "mozilla/CheckedInt.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "prmem.h"
|
#include "prmem.h"
|
||||||
#include "nsDOMFile.h"
|
#include "nsDOMFile.h"
|
||||||
#include "CheckedInt.h"
|
|
||||||
|
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsIXPConnect.h"
|
#include "nsIXPConnect.h"
|
||||||
|
|
|
||||||
|
|
@ -3310,17 +3310,15 @@ nsHTMLInputElement::AllowDrop()
|
||||||
void
|
void
|
||||||
nsHTMLInputElement::AddedToRadioGroup()
|
nsHTMLInputElement::AddedToRadioGroup()
|
||||||
{
|
{
|
||||||
// Make sure not to notify if we're still being created by the parser
|
// If the element is neither in a form nor a document, there is no group so we
|
||||||
bool notify = !mParserCreating;
|
// should just stop here.
|
||||||
|
if (!mForm && !IsInDoc()) {
|
||||||
//
|
|
||||||
// If the input element is not in a form and
|
|
||||||
// not in a document, we just need to return.
|
|
||||||
//
|
|
||||||
if (!mForm && !(IsInDoc() && GetParent())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure not to notify if we're still being created by the parser
|
||||||
|
bool notify = !mParserCreating;
|
||||||
|
|
||||||
//
|
//
|
||||||
// If the input element is checked, and we add it to the group, it will
|
// If the input element is checked, and we add it to the group, it will
|
||||||
// deselect whatever is currently selected in that group
|
// deselect whatever is currently selected in that group
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,9 @@
|
||||||
#include "nsDOMMediaStream.h"
|
#include "nsDOMMediaStream.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
|
|
||||||
|
#include "nsCSSParser.h"
|
||||||
|
#include "nsIMediaList.h"
|
||||||
|
|
||||||
#ifdef MOZ_OGG
|
#ifdef MOZ_OGG
|
||||||
#include "nsOggDecoder.h"
|
#include "nsOggDecoder.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -850,6 +853,12 @@ void nsHTMLMediaElement::LoadFromSourceChildren()
|
||||||
"Should delay load event (if in document) during load");
|
"Should delay load event (if in document) during load");
|
||||||
NS_ASSERTION(mIsLoadingFromSourceChildren,
|
NS_ASSERTION(mIsLoadingFromSourceChildren,
|
||||||
"Must remember we're loading from source children");
|
"Must remember we're loading from source children");
|
||||||
|
|
||||||
|
nsIDocument* parentDoc = OwnerDoc()->GetParentDocument();
|
||||||
|
if (parentDoc) {
|
||||||
|
parentDoc->FlushPendingNotifications(Flush_Layout);
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
nsIContent* child = GetNextSource();
|
nsIContent* child = GetNextSource();
|
||||||
if (!child) {
|
if (!child) {
|
||||||
|
|
@ -876,11 +885,25 @@ void nsHTMLMediaElement::LoadFromSourceChildren()
|
||||||
GetCanPlay(type) == CANPLAY_NO) {
|
GetCanPlay(type) == CANPLAY_NO) {
|
||||||
DispatchAsyncSourceError(child);
|
DispatchAsyncSourceError(child);
|
||||||
const PRUnichar* params[] = { type.get(), src.get() };
|
const PRUnichar* params[] = { type.get(), src.get() };
|
||||||
ReportLoadError("MediaLoadUnsupportedType", params, ArrayLength(params));
|
ReportLoadError("MediaLoadUnsupportedTypeAttribute", params, ArrayLength(params));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
LOG(PR_LOG_DEBUG, ("%p Trying load from <source>=%s type=%s", this,
|
nsAutoString media;
|
||||||
NS_ConvertUTF16toUTF8(src).get(), NS_ConvertUTF16toUTF8(type).get()));
|
if (child->GetAttr(kNameSpaceID_None, nsGkAtoms::media, media) && !media.IsEmpty()) {
|
||||||
|
nsCSSParser cssParser;
|
||||||
|
nsRefPtr<nsMediaList> mediaList(new nsMediaList());
|
||||||
|
cssParser.ParseMediaList(media, NULL, 0, mediaList, false);
|
||||||
|
nsIPresShell* presShell = OwnerDoc()->GetShell();
|
||||||
|
if (presShell && !mediaList->Matches(presShell->GetPresContext(), NULL)) {
|
||||||
|
DispatchAsyncSourceError(child);
|
||||||
|
const PRUnichar* params[] = { media.get(), src.get() };
|
||||||
|
ReportLoadError("MediaLoadSourceMediaNotMatched", params, ArrayLength(params));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(PR_LOG_DEBUG, ("%p Trying load from <source>=%s type=%s media=%s", this,
|
||||||
|
NS_ConvertUTF16toUTF8(src).get(), NS_ConvertUTF16toUTF8(type).get(),
|
||||||
|
NS_ConvertUTF16toUTF8(media).get()));
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> uri;
|
nsCOMPtr<nsIURI> uri;
|
||||||
NewURIFromString(src, getter_AddRefs(uri));
|
NewURIFromString(src, getter_AddRefs(uri));
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,7 @@ NS_IMPL_ELEMENT_CLONE(nsHTMLSourceElement)
|
||||||
|
|
||||||
NS_IMPL_URI_ATTR(nsHTMLSourceElement, Src, src)
|
NS_IMPL_URI_ATTR(nsHTMLSourceElement, Src, src)
|
||||||
NS_IMPL_STRING_ATTR(nsHTMLSourceElement, Type, type)
|
NS_IMPL_STRING_ATTR(nsHTMLSourceElement, Type, type)
|
||||||
|
NS_IMPL_STRING_ATTR(nsHTMLSourceElement, Media, media)
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLSourceElement::BindToTree(nsIDocument *aDocument,
|
nsHTMLSourceElement::BindToTree(nsIDocument *aDocument,
|
||||||
|
|
|
||||||
|
|
@ -243,32 +243,88 @@ nsMathMLElement::GetAttributeMappingFunction() const
|
||||||
return &MapMathMLAttributesInto;
|
return &MapMathMLAttributesInto;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================
|
/* static */ bool
|
||||||
// Utilities for parsing and retrieving numeric values
|
nsMathMLElement::ParseNamedSpaceValue(const nsString& aString,
|
||||||
|
nsCSSValue& aCSSValue,
|
||||||
|
PRUint32 aFlags)
|
||||||
|
{
|
||||||
|
PRInt32 i = 0;
|
||||||
|
// See if it is one of the 'namedspace' (ranging -7/18em, -6/18, ... 7/18em)
|
||||||
|
if (aString.EqualsLiteral("veryverythinmathspace")) {
|
||||||
|
i = 1;
|
||||||
|
} else if (aString.EqualsLiteral("verythinmathspace")) {
|
||||||
|
i = 2;
|
||||||
|
} else if (aString.EqualsLiteral("thinmathspace")) {
|
||||||
|
i = 3;
|
||||||
|
} else if (aString.EqualsLiteral("mediummathspace")) {
|
||||||
|
i = 4;
|
||||||
|
} else if (aString.EqualsLiteral("thickmathspace")) {
|
||||||
|
i = 5;
|
||||||
|
} else if (aString.EqualsLiteral("verythickmathspace")) {
|
||||||
|
i = 6;
|
||||||
|
} else if (aString.EqualsLiteral("veryverythickmathspace")) {
|
||||||
|
i = 7;
|
||||||
|
} else if (aFlags & PARSE_ALLOW_NEGATIVE) {
|
||||||
|
if (aString.EqualsLiteral("negativeveryverythinmathspace")) {
|
||||||
|
i = -1;
|
||||||
|
} else if (aString.EqualsLiteral("negativeverythinmathspace")) {
|
||||||
|
i = -2;
|
||||||
|
} else if (aString.EqualsLiteral("negativethinmathspace")) {
|
||||||
|
i = -3;
|
||||||
|
} else if (aString.EqualsLiteral("negativemediummathspace")) {
|
||||||
|
i = -4;
|
||||||
|
} else if (aString.EqualsLiteral("negativethickmathspace")) {
|
||||||
|
i = -5;
|
||||||
|
} else if (aString.EqualsLiteral("negativeverythickmathspace")) {
|
||||||
|
i = -6;
|
||||||
|
} else if (aString.EqualsLiteral("negativeveryverythickmathspace")) {
|
||||||
|
i = -7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0 != i) {
|
||||||
|
aCSSValue.SetFloatValue(float(i)/float(18), eCSSUnit_EM);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
return false;
|
||||||
The REC says:
|
}
|
||||||
An explicit plus sign ('+') is not allowed as part of a numeric value
|
|
||||||
except when it is specifically listed in the syntax (as a quoted '+'
|
|
||||||
or "+"),
|
|
||||||
|
|
||||||
Units allowed
|
|
||||||
ID Description
|
|
||||||
em ems (font-relative unit traditionally used for horizontal lengths)
|
|
||||||
ex exs (font-relative unit traditionally used for vertical lengths)
|
|
||||||
px pixels, or pixel size of a "typical computer display"
|
|
||||||
in inches (1 inch = 2.54 centimeters)
|
|
||||||
cm centimeters
|
|
||||||
mm millimeters
|
|
||||||
pt points (1 point = 1/72 inch)
|
|
||||||
pc picas (1 pica = 12 points)
|
|
||||||
% percentage of default value
|
|
||||||
|
|
||||||
Implementation here:
|
|
||||||
The numeric value is valid only if it is of the form [-] nnn.nnn
|
|
||||||
[h/v-unit]
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
// The REC says:
|
||||||
|
//
|
||||||
|
// "Most presentation elements have attributes that accept values representing
|
||||||
|
// lengths to be used for size, spacing or similar properties. The syntax of a
|
||||||
|
// length is specified as
|
||||||
|
//
|
||||||
|
// number | number unit | namedspace
|
||||||
|
//
|
||||||
|
// There should be no space between the number and the unit of a length."
|
||||||
|
//
|
||||||
|
// "A trailing '%' represents a percent of the default value. The default
|
||||||
|
// value, or how it is obtained, is listed in the table of attributes for each
|
||||||
|
// element. [...] A number without a unit is intepreted as a multiple of the
|
||||||
|
// default value."
|
||||||
|
//
|
||||||
|
// "The possible units in MathML are:
|
||||||
|
//
|
||||||
|
// Unit Description
|
||||||
|
// em an em (font-relative unit traditionally used for horizontal lengths)
|
||||||
|
// ex an ex (font-relative unit traditionally used for vertical lengths)
|
||||||
|
// px pixels, or size of a pixel in the current display
|
||||||
|
// in inches (1 inch = 2.54 centimeters)
|
||||||
|
// cm centimeters
|
||||||
|
// mm millimeters
|
||||||
|
// pt points (1 point = 1/72 inch)
|
||||||
|
// pc picas (1 pica = 12 points)
|
||||||
|
// % percentage of default value"
|
||||||
|
//
|
||||||
|
// The numbers are defined that way:
|
||||||
|
// - unsigned-number: "a string of decimal digits with up to one decimal point
|
||||||
|
// (U+002E), representing a non-negative terminating decimal number (a type of
|
||||||
|
// rational number)"
|
||||||
|
// - number: "an optional prefix of '-' (U+002D), followed by an unsigned
|
||||||
|
// number, representing a terminating decimal number (a type of rational
|
||||||
|
// number)"
|
||||||
|
//
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
nsMathMLElement::ParseNumericValue(const nsString& aString,
|
nsMathMLElement::ParseNumericValue(const nsString& aString,
|
||||||
nsCSSValue& aCSSValue,
|
nsCSSValue& aCSSValue,
|
||||||
|
|
@ -281,6 +337,10 @@ nsMathMLElement::ParseNumericValue(const nsString& aString,
|
||||||
if (!stringLength)
|
if (!stringLength)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (ParseNamedSpaceValue(aString, aCSSValue, aFlags)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
nsAutoString number, unit;
|
nsAutoString number, unit;
|
||||||
|
|
||||||
// see if the negative sign is there
|
// see if the negative sign is there
|
||||||
|
|
@ -289,10 +349,6 @@ nsMathMLElement::ParseNumericValue(const nsString& aString,
|
||||||
if (c == '-') {
|
if (c == '-') {
|
||||||
number.Append(c);
|
number.Append(c);
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
// skip any space after the negative sign
|
|
||||||
if (i < stringLength && nsCRT::IsAsciiSpace(str[i]))
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather up characters that make up the number
|
// Gather up characters that make up the number
|
||||||
|
|
@ -358,6 +414,14 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
|
||||||
nsRuleData* aData)
|
nsRuleData* aData)
|
||||||
{
|
{
|
||||||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
|
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
|
||||||
|
// scriptsizemultiplier
|
||||||
|
//
|
||||||
|
// "Specifies the multiplier to be used to adjust font size due to changes
|
||||||
|
// in scriptlevel.
|
||||||
|
//
|
||||||
|
// values: number
|
||||||
|
// default: 0.71
|
||||||
|
//
|
||||||
const nsAttrValue* value =
|
const nsAttrValue* value =
|
||||||
aAttributes->GetAttr(nsGkAtoms::scriptsizemultiplier_);
|
aAttributes->GetAttr(nsGkAtoms::scriptsizemultiplier_);
|
||||||
nsCSSValue* scriptSizeMultiplier =
|
nsCSSValue* scriptSizeMultiplier =
|
||||||
|
|
@ -377,6 +441,18 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scriptminsize
|
||||||
|
//
|
||||||
|
// "Specifies the minimum font size allowed due to changes in scriptlevel.
|
||||||
|
// Note that this does not limit the font size due to changes to mathsize."
|
||||||
|
//
|
||||||
|
// values: length
|
||||||
|
// default: 8pt
|
||||||
|
//
|
||||||
|
// We don't allow negative values.
|
||||||
|
// XXXfredw Should we allow unitless values? (bug 411227)
|
||||||
|
// XXXfredw Does a relative unit give a multiple of the default value?
|
||||||
|
//
|
||||||
value = aAttributes->GetAttr(nsGkAtoms::scriptminsize_);
|
value = aAttributes->GetAttr(nsGkAtoms::scriptminsize_);
|
||||||
nsCSSValue* scriptMinSize = aData->ValueForScriptMinSize();
|
nsCSSValue* scriptMinSize = aData->ValueForScriptMinSize();
|
||||||
if (value && value->Type() == nsAttrValue::eString &&
|
if (value && value->Type() == nsAttrValue::eString &&
|
||||||
|
|
@ -384,6 +460,17 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
|
||||||
ParseNumericValue(value->GetStringValue(), *scriptMinSize, 0);
|
ParseNumericValue(value->GetStringValue(), *scriptMinSize, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scriptlevel
|
||||||
|
//
|
||||||
|
// "Changes the scriptlevel in effect for the children. When the value is
|
||||||
|
// given without a sign, it sets scriptlevel to the specified value; when a
|
||||||
|
// sign is given, it increments ("+") or decrements ("-") the current
|
||||||
|
// value. (Note that large decrements can result in negative values of
|
||||||
|
// scriptlevel, but these values are considered legal.)"
|
||||||
|
//
|
||||||
|
// values: ( "+" | "-" )? unsigned-integer
|
||||||
|
// default: inherited
|
||||||
|
//
|
||||||
value = aAttributes->GetAttr(nsGkAtoms::scriptlevel_);
|
value = aAttributes->GetAttr(nsGkAtoms::scriptlevel_);
|
||||||
nsCSSValue* scriptLevel = aData->ValueForScriptLevel();
|
nsCSSValue* scriptLevel = aData->ValueForScriptLevel();
|
||||||
if (value && value->Type() == nsAttrValue::eString &&
|
if (value && value->Type() == nsAttrValue::eString &&
|
||||||
|
|
@ -408,6 +495,28 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mathsize
|
||||||
|
//
|
||||||
|
// "Specifies the size to display the token content. The values 'small' and
|
||||||
|
// 'big' choose a size smaller or larger than the current font size, but
|
||||||
|
// leave the exact proportions unspecified; 'normal' is allowed for
|
||||||
|
// completeness, but since it is equivalent to '100%' or '1em', it has no
|
||||||
|
// effect."
|
||||||
|
//
|
||||||
|
// values: "small" | "normal" | "big" | length
|
||||||
|
// default: inherited
|
||||||
|
//
|
||||||
|
// fontsize
|
||||||
|
//
|
||||||
|
// "Specified the size for the token. Deprecated in favor of mathsize."
|
||||||
|
//
|
||||||
|
// values: length
|
||||||
|
// default: inherited
|
||||||
|
//
|
||||||
|
// In both cases, we don't allow negative values.
|
||||||
|
// XXXfredw Should we allow unitless values? (bug 411227)
|
||||||
|
// XXXfredw Does a relative unit give a multiple of the default value?
|
||||||
|
//
|
||||||
bool parseSizeKeywords = true;
|
bool parseSizeKeywords = true;
|
||||||
value = aAttributes->GetAttr(nsGkAtoms::mathsize_);
|
value = aAttributes->GetAttr(nsGkAtoms::mathsize_);
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
|
@ -435,6 +544,14 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fontfamily
|
||||||
|
//
|
||||||
|
// "Should be the name of a font that may be available to a MathML renderer,
|
||||||
|
// or a CSS font specification; See Section 6.5 Using CSS with MathML and
|
||||||
|
// CSS for more information. Deprecated in favor of mathvariant."
|
||||||
|
//
|
||||||
|
// values: string
|
||||||
|
//
|
||||||
value = aAttributes->GetAttr(nsGkAtoms::fontfamily_);
|
value = aAttributes->GetAttr(nsGkAtoms::fontfamily_);
|
||||||
nsCSSValue* fontFamily = aData->ValueForFontFamily();
|
nsCSSValue* fontFamily = aData->ValueForFontFamily();
|
||||||
if (value && value->Type() == nsAttrValue::eString &&
|
if (value && value->Type() == nsAttrValue::eString &&
|
||||||
|
|
@ -443,6 +560,24 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mathbackground
|
||||||
|
//
|
||||||
|
// "Specifies the background color to be used to fill in the bounding box of
|
||||||
|
// the element and its children. The default, 'transparent', lets the
|
||||||
|
// background color, if any, used in the current rendering context to show
|
||||||
|
// through."
|
||||||
|
//
|
||||||
|
// values: color | "transparent"
|
||||||
|
// default: "transparent"
|
||||||
|
//
|
||||||
|
// background
|
||||||
|
//
|
||||||
|
// "Specified the background color to be used to fill in the bounding box of
|
||||||
|
// the element and its children. Deprecated in favor of mathbackground."
|
||||||
|
//
|
||||||
|
// values: color | "transparent"
|
||||||
|
// default: "transparent"
|
||||||
|
//
|
||||||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)) {
|
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Background)) {
|
||||||
const nsAttrValue* value =
|
const nsAttrValue* value =
|
||||||
aAttributes->GetAttr(nsGkAtoms::mathbackground_);
|
aAttributes->GetAttr(nsGkAtoms::mathbackground_);
|
||||||
|
|
@ -458,6 +593,23 @@ nsMathMLElement::MapMathMLAttributesInto(const nsMappedAttributes* aAttributes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mathcolor
|
||||||
|
//
|
||||||
|
// "Specifies the foreground color to use when drawing the components of this
|
||||||
|
// element, such as the content for token elements or any lines, surds, or
|
||||||
|
// other decorations. It also establishes the default mathcolor used for
|
||||||
|
// child elements when used on a layout element."
|
||||||
|
//
|
||||||
|
// values: color
|
||||||
|
// default: inherited
|
||||||
|
//
|
||||||
|
// color
|
||||||
|
//
|
||||||
|
// "Specified the color for the token. Deprecated in favor of mathcolor."
|
||||||
|
//
|
||||||
|
// values: color
|
||||||
|
// default: inherited
|
||||||
|
//
|
||||||
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) {
|
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) {
|
||||||
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::mathcolor_);
|
const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::mathcolor_);
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,10 @@ public:
|
||||||
PARSE_ALLOW_UNITLESS = 0x01, // unitless 0 will be turned into 0px
|
PARSE_ALLOW_UNITLESS = 0x01, // unitless 0 will be turned into 0px
|
||||||
PARSE_ALLOW_NEGATIVE = 0x02
|
PARSE_ALLOW_NEGATIVE = 0x02
|
||||||
};
|
};
|
||||||
|
static bool ParseNamedSpaceValue(const nsString& aString,
|
||||||
|
nsCSSValue& aCSSValue,
|
||||||
|
PRUint32 aFlags);
|
||||||
|
|
||||||
static bool ParseNumericValue(const nsString& aString,
|
static bool ParseNumericValue(const nsString& aString,
|
||||||
nsCSSValue& aCSSValue,
|
nsCSSValue& aCSSValue,
|
||||||
PRUint32 aFlags);
|
PRUint32 aFlags);
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,12 @@
|
||||||
#define VideoUtils_h
|
#define VideoUtils_h
|
||||||
|
|
||||||
#include "mozilla/ReentrantMonitor.h"
|
#include "mozilla/ReentrantMonitor.h"
|
||||||
|
#include "mozilla/CheckedInt.h"
|
||||||
|
|
||||||
#include "nsRect.h"
|
#include "nsRect.h"
|
||||||
#include "nsIThreadManager.h"
|
#include "nsIThreadManager.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
#include "CheckedInt.h"
|
|
||||||
|
|
||||||
using mozilla::CheckedInt64;
|
using mozilla::CheckedInt64;
|
||||||
using mozilla::CheckedUint64;
|
using mozilla::CheckedUint64;
|
||||||
using mozilla::CheckedInt32;
|
using mozilla::CheckedInt32;
|
||||||
|
|
|
||||||
|
|
@ -446,23 +446,18 @@ void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only inform the element of MetadataLoaded if not doing a load() in order
|
|
||||||
// to fulfill a seek, otherwise we'll get multiple metadataloaded events.
|
|
||||||
bool notifyElement = true;
|
|
||||||
{
|
{
|
||||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||||
mDuration = mDecoderStateMachine ? mDecoderStateMachine->GetDuration() : -1;
|
mDuration = mDecoderStateMachine ? mDecoderStateMachine->GetDuration() : -1;
|
||||||
// Duration has changed so we should recompute playback rate
|
// Duration has changed so we should recompute playback rate
|
||||||
UpdatePlaybackRate();
|
UpdatePlaybackRate();
|
||||||
|
|
||||||
notifyElement = mNextState != PLAY_STATE_SEEKING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDuration == -1) {
|
if (mDuration == -1) {
|
||||||
SetInfinite(true);
|
SetInfinite(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mElement && notifyElement) {
|
if (mElement) {
|
||||||
// Make sure the element and the frame (if any) are told about
|
// Make sure the element and the frame (if any) are told about
|
||||||
// our new size.
|
// our new size.
|
||||||
Invalidate();
|
Invalidate();
|
||||||
|
|
@ -482,7 +477,7 @@ void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
|
||||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||||
bool resourceIsLoaded = !mResourceLoaded && mResource &&
|
bool resourceIsLoaded = !mResourceLoaded && mResource &&
|
||||||
mResource->IsDataCachedToEndOfResource(mDecoderPosition);
|
mResource->IsDataCachedToEndOfResource(mDecoderPosition);
|
||||||
if (mElement && notifyElement) {
|
if (mElement) {
|
||||||
mElement->FirstFrameLoaded(resourceIsLoaded);
|
mElement->FirstFrameLoaded(resourceIsLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -567,11 +562,13 @@ void nsBuiltinDecoder::DecodeError()
|
||||||
|
|
||||||
bool nsBuiltinDecoder::IsSeeking() const
|
bool nsBuiltinDecoder::IsSeeking() const
|
||||||
{
|
{
|
||||||
return mPlayState == PLAY_STATE_SEEKING || mNextState == PLAY_STATE_SEEKING;
|
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||||
|
return mPlayState == PLAY_STATE_SEEKING;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsBuiltinDecoder::IsEnded() const
|
bool nsBuiltinDecoder::IsEnded() const
|
||||||
{
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||||
return mPlayState == PLAY_STATE_ENDED || mPlayState == PLAY_STATE_SHUTDOWN;
|
return mPlayState == PLAY_STATE_ENDED || mPlayState == PLAY_STATE_SHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -580,6 +577,7 @@ void nsBuiltinDecoder::PlaybackEnded()
|
||||||
if (mShuttingDown || mPlayState == nsBuiltinDecoder::PLAY_STATE_SEEKING)
|
if (mShuttingDown || mPlayState == nsBuiltinDecoder::PLAY_STATE_SEEKING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
printf("nsBuiltinDecoder::PlaybackEnded mPlayState=%d\n", mPlayState);
|
||||||
PlaybackPositionChanged();
|
PlaybackPositionChanged();
|
||||||
ChangeState(PLAY_STATE_ENDED);
|
ChangeState(PLAY_STATE_ENDED);
|
||||||
|
|
||||||
|
|
@ -794,6 +792,7 @@ void nsBuiltinDecoder::SeekingStopped()
|
||||||
seekWasAborted = true;
|
seekWasAborted = true;
|
||||||
} else {
|
} else {
|
||||||
UnpinForSeek();
|
UnpinForSeek();
|
||||||
|
printf("nsBuiltinDecoder::SeekingStopped, next state=%d\n", mNextState);
|
||||||
ChangeState(mNextState);
|
ChangeState(mNextState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -827,6 +826,7 @@ void nsBuiltinDecoder::SeekingStoppedAtEnd()
|
||||||
seekWasAborted = true;
|
seekWasAborted = true;
|
||||||
} else {
|
} else {
|
||||||
UnpinForSeek();
|
UnpinForSeek();
|
||||||
|
printf("nsBuiltinDecoder::SeekingStoppedAtEnd, next state=PLAY_STATE_ENDED\n");
|
||||||
fireEnded = true;
|
fireEnded = true;
|
||||||
ChangeState(PLAY_STATE_ENDED);
|
ChangeState(PLAY_STATE_ENDED);
|
||||||
}
|
}
|
||||||
|
|
@ -909,6 +909,9 @@ void nsBuiltinDecoder::PlaybackPositionChanged()
|
||||||
// current time after the seek has started but before it has
|
// current time after the seek has started but before it has
|
||||||
// completed.
|
// completed.
|
||||||
mCurrentTime = mDecoderStateMachine->GetCurrentTime();
|
mCurrentTime = mDecoderStateMachine->GetCurrentTime();
|
||||||
|
} else {
|
||||||
|
printf("Suppressed timeupdate during seeking: currentTime=%f, new time=%f\n",
|
||||||
|
mCurrentTime, mDecoderStateMachine->GetCurrentTime());
|
||||||
}
|
}
|
||||||
mDecoderStateMachine->ClearPositionChangeFlag();
|
mDecoderStateMachine->ClearPositionChangeFlag();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -470,8 +470,8 @@ public:
|
||||||
// Call on the main thread only.
|
// Call on the main thread only.
|
||||||
virtual void NetworkError();
|
virtual void NetworkError();
|
||||||
|
|
||||||
// Call from any thread safely. Return true if we are currently
|
// Return true if we are currently seeking in the media resource.
|
||||||
// seeking in the media resource.
|
// Call on the main thread only.
|
||||||
virtual bool IsSeeking() const;
|
virtual bool IsSeeking() const;
|
||||||
|
|
||||||
// Return true if the decoder has reached the end of playback.
|
// Return true if the decoder has reached the end of playback.
|
||||||
|
|
@ -742,16 +742,20 @@ public:
|
||||||
// Data about MediaStreams that are being fed by this decoder.
|
// Data about MediaStreams that are being fed by this decoder.
|
||||||
nsTArray<OutputMediaStream> mOutputStreams;
|
nsTArray<OutputMediaStream> mOutputStreams;
|
||||||
|
|
||||||
// Set to one of the valid play states. It is protected by the
|
// Set to one of the valid play states.
|
||||||
// monitor mReentrantMonitor. This monitor must be acquired when reading or
|
// This can only be changed on the main thread while holding the decoder
|
||||||
// writing the state. Any change to the state on the main thread
|
// monitor. Thus, it can be safely read while holding the decoder monitor
|
||||||
// must call NotifyAll on the monitor so the decode thread can wake up.
|
// OR on the main thread.
|
||||||
|
// Any change to the state on the main thread must call NotifyAll on the
|
||||||
|
// monitor so the decode thread can wake up.
|
||||||
PlayState mPlayState;
|
PlayState mPlayState;
|
||||||
|
|
||||||
// The state to change to after a seek or load operation. It must only
|
// The state to change to after a seek or load operation.
|
||||||
// be changed from the main thread. The decoder monitor must be acquired
|
// This can only be changed on the main thread while holding the decoder
|
||||||
// when writing to the state, or when reading from a non-main thread.
|
// monitor. Thus, it can be safely read while holding the decoder monitor
|
||||||
|
// OR on the main thread.
|
||||||
// Any change to the state must call NotifyAll on the monitor.
|
// Any change to the state must call NotifyAll on the monitor.
|
||||||
|
// This can only be PLAY_STATE_PAUSED or PLAY_STATE_PLAYING.
|
||||||
PlayState mNextState;
|
PlayState mNextState;
|
||||||
|
|
||||||
// True when we have fully loaded the resource and reported that
|
// True when we have fully loaded the resource and reported that
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,8 @@ VideoData* VideoData::Create(nsVideoInfo& aInfo,
|
||||||
// the frame we've been supplied without indexing out of bounds.
|
// the frame we've been supplied without indexing out of bounds.
|
||||||
CheckedUint32 xLimit = aPicture.x + CheckedUint32(aPicture.width);
|
CheckedUint32 xLimit = aPicture.x + CheckedUint32(aPicture.width);
|
||||||
CheckedUint32 yLimit = aPicture.y + CheckedUint32(aPicture.height);
|
CheckedUint32 yLimit = aPicture.y + CheckedUint32(aPicture.height);
|
||||||
if (!xLimit.valid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
|
if (!xLimit.isValid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
|
||||||
!yLimit.valid() || yLimit.value() > aBuffer.mPlanes[0].mHeight)
|
!yLimit.isValid() || yLimit.value() > aBuffer.mPlanes[0].mHeight)
|
||||||
{
|
{
|
||||||
// The specified picture dimensions can't be contained inside the video
|
// The specified picture dimensions can't be contained inside the video
|
||||||
// frame, we'll stomp memory if we try to copy it. Fail.
|
// frame, we'll stomp memory if we try to copy it. Fail.
|
||||||
|
|
@ -346,7 +346,7 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
|
||||||
break;
|
break;
|
||||||
CheckedInt64 startFrame = UsecsToFrames(audio->mTime, mInfo.mAudioRate);
|
CheckedInt64 startFrame = UsecsToFrames(audio->mTime, mInfo.mAudioRate);
|
||||||
CheckedInt64 targetFrame = UsecsToFrames(aTarget, mInfo.mAudioRate);
|
CheckedInt64 targetFrame = UsecsToFrames(aTarget, mInfo.mAudioRate);
|
||||||
if (!startFrame.valid() || !targetFrame.valid()) {
|
if (!startFrame.isValid() || !targetFrame.isValid()) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
if (startFrame.value() + audio->mFrames <= targetFrame.value()) {
|
if (startFrame.value() + audio->mFrames <= targetFrame.value()) {
|
||||||
|
|
@ -390,7 +390,7 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
|
||||||
audio->mAudioData.get() + (framesToPrune * channels),
|
audio->mAudioData.get() + (framesToPrune * channels),
|
||||||
frames * channels * sizeof(AudioDataValue));
|
frames * channels * sizeof(AudioDataValue));
|
||||||
CheckedInt64 duration = FramesToUsecs(frames, mInfo.mAudioRate);
|
CheckedInt64 duration = FramesToUsecs(frames, mInfo.mAudioRate);
|
||||||
if (!duration.valid()) {
|
if (!duration.isValid()) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
nsAutoPtr<AudioData> data(new AudioData(audio->mOffset,
|
nsAutoPtr<AudioData> data(new AudioData(audio->mOffset,
|
||||||
|
|
|
||||||
|
|
@ -547,7 +547,7 @@ void nsBuiltinDecoderStateMachine::SendOutputStreamAudio(AudioData* aAudio,
|
||||||
CheckedInt64 audioWrittenOffset = UsecsToFrames(mInfo.mAudioRate,
|
CheckedInt64 audioWrittenOffset = UsecsToFrames(mInfo.mAudioRate,
|
||||||
aStream->mAudioFramesWrittenBaseTime + mStartTime) + aStream->mAudioFramesWritten;
|
aStream->mAudioFramesWrittenBaseTime + mStartTime) + aStream->mAudioFramesWritten;
|
||||||
CheckedInt64 frameOffset = UsecsToFrames(mInfo.mAudioRate, aAudio->mTime);
|
CheckedInt64 frameOffset = UsecsToFrames(mInfo.mAudioRate, aAudio->mTime);
|
||||||
if (!audioWrittenOffset.valid() || !frameOffset.valid())
|
if (!audioWrittenOffset.isValid() || !frameOffset.isValid())
|
||||||
return;
|
return;
|
||||||
if (audioWrittenOffset.value() < frameOffset.value()) {
|
if (audioWrittenOffset.value() < frameOffset.value()) {
|
||||||
// Write silence to catch up
|
// Write silence to catch up
|
||||||
|
|
@ -1115,7 +1115,7 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
|
||||||
// samples.
|
// samples.
|
||||||
CheckedInt64 sampleTime = UsecsToFrames(s->mTime, rate);
|
CheckedInt64 sampleTime = UsecsToFrames(s->mTime, rate);
|
||||||
CheckedInt64 missingFrames = sampleTime - playedFrames;
|
CheckedInt64 missingFrames = sampleTime - playedFrames;
|
||||||
if (!missingFrames.valid() || !sampleTime.valid()) {
|
if (!missingFrames.isValid() || !sampleTime.isValid()) {
|
||||||
NS_WARNING("Int overflow adding in AudioLoop()");
|
NS_WARNING("Int overflow adding in AudioLoop()");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1139,7 +1139,7 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
|
||||||
{
|
{
|
||||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
CheckedInt64 playedUsecs = FramesToUsecs(audioDuration, rate) + audioStartTime;
|
CheckedInt64 playedUsecs = FramesToUsecs(audioDuration, rate) + audioStartTime;
|
||||||
if (!playedUsecs.valid()) {
|
if (!playedUsecs.isValid()) {
|
||||||
NS_WARNING("Int overflow calculating audio end time");
|
NS_WARNING("Int overflow calculating audio end time");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2198,6 +2198,7 @@ nsresult nsBuiltinDecoderStateMachine::RunStateMachine()
|
||||||
PRInt64 videoTime = HasVideo() ? mVideoFrameEndTime : 0;
|
PRInt64 videoTime = HasVideo() ? mVideoFrameEndTime : 0;
|
||||||
PRInt64 clockTime = NS_MAX(mEndTime, NS_MAX(videoTime, GetAudioClock()));
|
PRInt64 clockTime = NS_MAX(mEndTime, NS_MAX(videoTime, GetAudioClock()));
|
||||||
UpdatePlaybackPosition(clockTime);
|
UpdatePlaybackPosition(clockTime);
|
||||||
|
printf("nsBuiltinDecoderStateMachine::RunStateMachine queuing nsBuiltinDecoder::PlaybackEnded\n");
|
||||||
nsCOMPtr<nsIRunnable> event =
|
nsCOMPtr<nsIRunnable> event =
|
||||||
NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::PlaybackEnded);
|
NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::PlaybackEnded);
|
||||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||||
|
|
|
||||||
|
|
@ -353,10 +353,10 @@ PRInt64 nsTheoraState::Time(th_info* aInfo, PRInt64 aGranulepos)
|
||||||
ogg_int64_t pframe = aGranulepos - (iframe << shift);
|
ogg_int64_t pframe = aGranulepos - (iframe << shift);
|
||||||
PRInt64 frameno = iframe + pframe - TH_VERSION_CHECK(aInfo, 3, 2, 1);
|
PRInt64 frameno = iframe + pframe - TH_VERSION_CHECK(aInfo, 3, 2, 1);
|
||||||
CheckedInt64 t = ((CheckedInt64(frameno) + 1) * USECS_PER_S) * aInfo->fps_denominator;
|
CheckedInt64 t = ((CheckedInt64(frameno) + 1) * USECS_PER_S) * aInfo->fps_denominator;
|
||||||
if (!t.valid())
|
if (!t.isValid())
|
||||||
return -1;
|
return -1;
|
||||||
t /= aInfo->fps_numerator;
|
t /= aInfo->fps_numerator;
|
||||||
return t.valid() ? t.value() : -1;
|
return t.isValid() ? t.value() : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRInt64 nsTheoraState::StartTime(PRInt64 granulepos) {
|
PRInt64 nsTheoraState::StartTime(PRInt64 granulepos) {
|
||||||
|
|
@ -364,7 +364,7 @@ PRInt64 nsTheoraState::StartTime(PRInt64 granulepos) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CheckedInt64 t = (CheckedInt64(th_granule_frame(mCtx, granulepos)) * USECS_PER_S) * mInfo.fps_denominator;
|
CheckedInt64 t = (CheckedInt64(th_granule_frame(mCtx, granulepos)) * USECS_PER_S) * mInfo.fps_denominator;
|
||||||
if (!t.valid())
|
if (!t.isValid())
|
||||||
return -1;
|
return -1;
|
||||||
return t.value() / mInfo.fps_numerator;
|
return t.value() / mInfo.fps_numerator;
|
||||||
}
|
}
|
||||||
|
|
@ -622,7 +622,7 @@ PRInt64 nsVorbisState::Time(vorbis_info* aInfo, PRInt64 aGranulepos)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
CheckedInt64 t = CheckedInt64(aGranulepos) * USECS_PER_S;
|
CheckedInt64 t = CheckedInt64(aGranulepos) * USECS_PER_S;
|
||||||
if (!t.valid())
|
if (!t.isValid())
|
||||||
t = 0;
|
t = 0;
|
||||||
return t.value() / aInfo->rate;
|
return t.value() / aInfo->rate;
|
||||||
}
|
}
|
||||||
|
|
@ -884,7 +884,7 @@ PRInt64 nsOpusState::Time(PRInt64 granulepos)
|
||||||
|
|
||||||
// Ogg Opus always runs at a granule rate of 48 kHz.
|
// Ogg Opus always runs at a granule rate of 48 kHz.
|
||||||
CheckedInt64 t = CheckedInt64(granulepos - mPreSkip) * USECS_PER_S;
|
CheckedInt64 t = CheckedInt64(granulepos - mPreSkip) * USECS_PER_S;
|
||||||
return t.valid() ? t.value() / mRate : -1;
|
return t.isValid() ? t.value() / mRate : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsOpusState::IsHeader(ogg_packet* aPacket)
|
bool nsOpusState::IsHeader(ogg_packet* aPacket)
|
||||||
|
|
@ -1048,7 +1048,7 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
|
||||||
|
|
||||||
// Extract the start time.
|
// Extract the start time.
|
||||||
CheckedInt64 t = CheckedInt64(LEInt64(p + INDEX_FIRST_NUMER_OFFSET)) * USECS_PER_S;
|
CheckedInt64 t = CheckedInt64(LEInt64(p + INDEX_FIRST_NUMER_OFFSET)) * USECS_PER_S;
|
||||||
if (!t.valid()) {
|
if (!t.isValid()) {
|
||||||
return (mActive = false);
|
return (mActive = false);
|
||||||
} else {
|
} else {
|
||||||
startTime = t.value() / timeDenom;
|
startTime = t.value() / timeDenom;
|
||||||
|
|
@ -1056,7 +1056,7 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
|
||||||
|
|
||||||
// Extract the end time.
|
// Extract the end time.
|
||||||
t = LEInt64(p + INDEX_LAST_NUMER_OFFSET) * USECS_PER_S;
|
t = LEInt64(p + INDEX_LAST_NUMER_OFFSET) * USECS_PER_S;
|
||||||
if (!t.valid()) {
|
if (!t.isValid()) {
|
||||||
return (mActive = false);
|
return (mActive = false);
|
||||||
} else {
|
} else {
|
||||||
endTime = t.value() / timeDenom;
|
endTime = t.value() / timeDenom;
|
||||||
|
|
@ -1065,7 +1065,7 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
|
||||||
// Check the numKeyPoints value read, ensure we're not going to run out of
|
// Check the numKeyPoints value read, ensure we're not going to run out of
|
||||||
// memory while trying to decode the index packet.
|
// memory while trying to decode the index packet.
|
||||||
CheckedInt64 minPacketSize = (CheckedInt64(numKeyPoints) * MIN_KEY_POINT_SIZE) + INDEX_KEYPOINT_OFFSET;
|
CheckedInt64 minPacketSize = (CheckedInt64(numKeyPoints) * MIN_KEY_POINT_SIZE) + INDEX_KEYPOINT_OFFSET;
|
||||||
if (!minPacketSize.valid())
|
if (!minPacketSize.isValid())
|
||||||
{
|
{
|
||||||
return (mActive = false);
|
return (mActive = false);
|
||||||
}
|
}
|
||||||
|
|
@ -1103,7 +1103,7 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
|
||||||
p = ReadVariableLengthInt(p, limit, delta);
|
p = ReadVariableLengthInt(p, limit, delta);
|
||||||
offset += delta;
|
offset += delta;
|
||||||
if (p == limit ||
|
if (p == limit ||
|
||||||
!offset.valid() ||
|
!offset.isValid() ||
|
||||||
offset.value() > mLength ||
|
offset.value() > mLength ||
|
||||||
offset.value() < 0)
|
offset.value() < 0)
|
||||||
{
|
{
|
||||||
|
|
@ -1111,14 +1111,14 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
|
||||||
}
|
}
|
||||||
p = ReadVariableLengthInt(p, limit, delta);
|
p = ReadVariableLengthInt(p, limit, delta);
|
||||||
time += delta;
|
time += delta;
|
||||||
if (!time.valid() ||
|
if (!time.isValid() ||
|
||||||
time.value() > endTime ||
|
time.value() > endTime ||
|
||||||
time.value() < startTime)
|
time.value() < startTime)
|
||||||
{
|
{
|
||||||
return (mActive = false);
|
return (mActive = false);
|
||||||
}
|
}
|
||||||
CheckedInt64 timeUsecs = time * USECS_PER_S;
|
CheckedInt64 timeUsecs = time * USECS_PER_S;
|
||||||
if (!timeUsecs.valid())
|
if (!timeUsecs.isValid())
|
||||||
return mActive = false;
|
return mActive = false;
|
||||||
timeUsecs /= timeDenom;
|
timeUsecs /= timeDenom;
|
||||||
keyPoints->Add(offset.value(), timeUsecs.value());
|
keyPoints->Add(offset.value(), timeUsecs.value());
|
||||||
|
|
@ -1228,8 +1228,8 @@ nsresult nsSkeletonState::GetDuration(const nsTArray<PRUint32>& aTracks,
|
||||||
}
|
}
|
||||||
NS_ASSERTION(endTime > startTime, "Duration must be positive");
|
NS_ASSERTION(endTime > startTime, "Duration must be positive");
|
||||||
CheckedInt64 duration = CheckedInt64(endTime) - startTime;
|
CheckedInt64 duration = CheckedInt64(endTime) - startTime;
|
||||||
aDuration = duration.valid() ? duration.value() : 0;
|
aDuration = duration.isValid() ? duration.value() : 0;
|
||||||
return duration.valid() ? NS_OK : NS_ERROR_FAILURE;
|
return duration.isValid() ? NS_OK : NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsSkeletonState::DecodeHeader(ogg_packet* aPacket)
|
bool nsSkeletonState::DecodeHeader(ogg_packet* aPacket)
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo)
|
||||||
|
|
||||||
CheckedUint32 dummy = CheckedUint32(static_cast<PRUint32>(mMetadata.frameWidth)) *
|
CheckedUint32 dummy = CheckedUint32(static_cast<PRUint32>(mMetadata.frameWidth)) *
|
||||||
static_cast<PRUint32>(mMetadata.frameHeight);
|
static_cast<PRUint32>(mMetadata.frameHeight);
|
||||||
NS_ENSURE_TRUE(dummy.valid(), NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(dummy.isValid(), NS_ERROR_FAILURE);
|
||||||
|
|
||||||
if (mMetadata.aspectDenominator == 0 ||
|
if (mMetadata.aspectDenominator == 0 ||
|
||||||
mMetadata.framerateDenominator == 0)
|
mMetadata.framerateDenominator == 0)
|
||||||
|
|
@ -268,7 +268,7 @@ nsresult nsRawReader::Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime,
|
||||||
|
|
||||||
CheckedUint32 offset = CheckedUint32(mCurrentFrame) * mFrameSize;
|
CheckedUint32 offset = CheckedUint32(mCurrentFrame) * mFrameSize;
|
||||||
offset += sizeof(nsRawVideoHeader);
|
offset += sizeof(nsRawVideoHeader);
|
||||||
NS_ENSURE_TRUE(offset.valid(), NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(offset.isValid(), NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsresult rv = resource->Seek(nsISeekableStream::NS_SEEK_SET, offset.value());
|
nsresult rv = resource->Seek(nsISeekableStream::NS_SEEK_SET, offset.value());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,7 @@ _TEST_FILES = \
|
||||||
use_large_cache.js \
|
use_large_cache.js \
|
||||||
test_audiowrite.html \
|
test_audiowrite.html \
|
||||||
test_mozHasAudio.html \
|
test_mozHasAudio.html \
|
||||||
|
test_source_media.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# Don't run in suite
|
# Don't run in suite
|
||||||
|
|
|
||||||
58
content/media/test/test_source_media.html
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Media test: media attribute for the source element.</title>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
<script type="text/javascript" src="manifest.js"></script>
|
||||||
|
<script type="text/javascript" src="../../html/content/test/reflect.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre id="test">
|
||||||
|
<script type="text/javascript">
|
||||||
|
var testCount = 0;
|
||||||
|
function notifyFinished() {
|
||||||
|
testCount++;
|
||||||
|
if (testCount == 2) {
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
reflectString({
|
||||||
|
element: document.createElement("source"),
|
||||||
|
attribute: "media",
|
||||||
|
});
|
||||||
|
|
||||||
|
var media = getPlayableVideo(gSmallTests);
|
||||||
|
|
||||||
|
if (media == null) {
|
||||||
|
todo(false, "No media supported.");
|
||||||
|
SimpleTest.finish();
|
||||||
|
} else {
|
||||||
|
var v = document.createElement('video');
|
||||||
|
v.innerHTML = "<source src=\"" + media.name + "?fail\" media=\"not all\">" +
|
||||||
|
"<source src=\""+ media.name + "?pass\" media=\"all\">";
|
||||||
|
var v2 = document.createElement("video");
|
||||||
|
v2.innerHTML = "<source src=\""+ media.name +"?pass\">" +
|
||||||
|
"<source src=\""+ media.name + "?fail\" media=\"all\">";
|
||||||
|
document.body.appendChild(v);
|
||||||
|
document.body.appendChild(v2);
|
||||||
|
|
||||||
|
v.addEventListener("loadedmetadata", function(e) {
|
||||||
|
ok(/pass/.test(e.target.currentSrc),
|
||||||
|
"The source has been chosen according to the media attribute.");
|
||||||
|
notifyFinished();
|
||||||
|
});
|
||||||
|
v2.addEventListener("loadedmetadata", function(e) {
|
||||||
|
ok(/pass/.test(e.target.currentSrc),
|
||||||
|
"If no media attribute is specified, it defaults to \'all\'.")
|
||||||
|
notifyFinished();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -209,10 +209,8 @@ void nsWebMBufferedParser::Append(const unsigned char* aBuffer, PRUint32 aLength
|
||||||
mCurrentOffset += aLength;
|
mCurrentOffset += aLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered,
|
bool nsWebMBufferedState::CalculateBufferedForRange(PRInt64 aStartOffset, PRInt64 aEndOffset,
|
||||||
PRInt64 aStartOffset, PRInt64 aEndOffset,
|
PRUint64* aStartTime, PRUint64* aEndTime)
|
||||||
PRUint64 aTimecodeScale,
|
|
||||||
PRInt64 aStartTimeOffsetNS)
|
|
||||||
{
|
{
|
||||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||||
|
|
||||||
|
|
@ -220,7 +218,7 @@ void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered,
|
||||||
PRUint32 start;
|
PRUint32 start;
|
||||||
mTimeMapping.GreatestIndexLtEq(aStartOffset, start);
|
mTimeMapping.GreatestIndexLtEq(aStartOffset, start);
|
||||||
if (start == mTimeMapping.Length()) {
|
if (start == mTimeMapping.Length()) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the first nsWebMTimeDataOffset at or before aEndOffset.
|
// Find the first nsWebMTimeDataOffset at or before aEndOffset.
|
||||||
|
|
@ -233,7 +231,7 @@ void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered,
|
||||||
|
|
||||||
// Range is empty.
|
// Range is empty.
|
||||||
if (end <= start) {
|
if (end <= start) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(mTimeMapping[start].mOffset >= aStartOffset &&
|
NS_ASSERTION(mTimeMapping[start].mOffset >= aStartOffset &&
|
||||||
|
|
@ -252,9 +250,9 @@ void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered,
|
||||||
// from the ranges' start and end timestamps, so that those timestamps are
|
// from the ranges' start and end timestamps, so that those timestamps are
|
||||||
// normalized in the range [0,duration].
|
// normalized in the range [0,duration].
|
||||||
|
|
||||||
double startTime = (mTimeMapping[start].mTimecode * aTimecodeScale - aStartTimeOffsetNS) / NS_PER_S;
|
*aStartTime = mTimeMapping[start].mTimecode;
|
||||||
double endTime = (mTimeMapping[end].mTimecode * aTimecodeScale - aStartTimeOffsetNS) / NS_PER_S;
|
*aEndTime = mTimeMapping[end].mTimecode;
|
||||||
aBuffered->Add(startTime, endTime);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsWebMBufferedState::NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset)
|
void nsWebMBufferedState::NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset)
|
||||||
|
|
|
||||||
|
|
@ -225,10 +225,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset);
|
void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRInt64 aOffset);
|
||||||
void CalculateBufferedForRange(nsTimeRanges* aBuffered,
|
bool CalculateBufferedForRange(PRInt64 aStartOffset, PRInt64 aEndOffset,
|
||||||
PRInt64 aStartOffset, PRInt64 aEndOffset,
|
PRUint64* aStartTime, PRUint64* aEndTime);
|
||||||
PRUint64 aTimecodeScale,
|
|
||||||
PRInt64 aStartTimeOffsetNS);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Synchronizes access to the mTimeMapping array.
|
// Synchronizes access to the mTimeMapping array.
|
||||||
|
|
|
||||||
|
|
@ -448,12 +448,12 @@ bool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket, PRInt64 aOffset)
|
||||||
// from after the gap.
|
// from after the gap.
|
||||||
CheckedInt64 tstamp_frames = UsecsToFrames(tstamp_usecs, rate);
|
CheckedInt64 tstamp_frames = UsecsToFrames(tstamp_usecs, rate);
|
||||||
CheckedInt64 decoded_frames = UsecsToFrames(mAudioStartUsec, rate);
|
CheckedInt64 decoded_frames = UsecsToFrames(mAudioStartUsec, rate);
|
||||||
if (!tstamp_frames.valid() || !decoded_frames.valid()) {
|
if (!tstamp_frames.isValid() || !decoded_frames.isValid()) {
|
||||||
NS_WARNING("Int overflow converting WebM times to frames");
|
NS_WARNING("Int overflow converting WebM times to frames");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
decoded_frames += mAudioFrames;
|
decoded_frames += mAudioFrames;
|
||||||
if (!decoded_frames.valid()) {
|
if (!decoded_frames.isValid()) {
|
||||||
NS_WARNING("Int overflow adding decoded_frames");
|
NS_WARNING("Int overflow adding decoded_frames");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -461,7 +461,7 @@ bool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket, PRInt64 aOffset)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
CheckedInt64 usecs = FramesToUsecs(tstamp_frames.value() - decoded_frames.value(), rate);
|
CheckedInt64 usecs = FramesToUsecs(tstamp_frames.value() - decoded_frames.value(), rate);
|
||||||
LOG(PR_LOG_DEBUG, ("WebMReader detected gap of %lld, %lld frames, in audio stream\n",
|
LOG(PR_LOG_DEBUG, ("WebMReader detected gap of %lld, %lld frames, in audio stream\n",
|
||||||
usecs.valid() ? usecs.value(): -1,
|
usecs.isValid() ? usecs.value() : -1,
|
||||||
tstamp_frames.value() - decoded_frames.value()));
|
tstamp_frames.value() - decoded_frames.value()));
|
||||||
#endif
|
#endif
|
||||||
mPacketCount++;
|
mPacketCount++;
|
||||||
|
|
@ -501,18 +501,18 @@ bool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket, PRInt64 aOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckedInt64 duration = FramesToUsecs(frames, rate);
|
CheckedInt64 duration = FramesToUsecs(frames, rate);
|
||||||
if (!duration.valid()) {
|
if (!duration.isValid()) {
|
||||||
NS_WARNING("Int overflow converting WebM audio duration");
|
NS_WARNING("Int overflow converting WebM audio duration");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CheckedInt64 total_duration = FramesToUsecs(total_frames, rate);
|
CheckedInt64 total_duration = FramesToUsecs(total_frames, rate);
|
||||||
if (!total_duration.valid()) {
|
if (!total_duration.isValid()) {
|
||||||
NS_WARNING("Int overflow converting WebM audio total_duration");
|
NS_WARNING("Int overflow converting WebM audio total_duration");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckedInt64 time = total_duration + tstamp_usecs;
|
CheckedInt64 time = total_duration + tstamp_usecs;
|
||||||
if (!time.valid()) {
|
if (!time.isValid()) {
|
||||||
NS_WARNING("Int overflow adding total_duration and tstamp_usecs");
|
NS_WARNING("Int overflow adding total_duration and tstamp_usecs");
|
||||||
nestegg_free_packet(aPacket);
|
nestegg_free_packet(aPacket);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -791,24 +791,45 @@ nsresult nsWebMReader::GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case completely cached files. This also handles local files.
|
// Special case completely cached files. This also handles local files.
|
||||||
if (resource->IsDataCachedToEndOfResource(0)) {
|
bool isFullyCached = resource->IsDataCachedToEndOfResource(0);
|
||||||
|
if (isFullyCached) {
|
||||||
uint64_t duration = 0;
|
uint64_t duration = 0;
|
||||||
if (nestegg_duration(mContext, &duration) == 0) {
|
if (nestegg_duration(mContext, &duration) == 0) {
|
||||||
aBuffered->Add(0, duration / NS_PER_S);
|
aBuffered->Add(0, duration / NS_PER_S);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
PRUint32 bufferedLength = 0;
|
||||||
|
aBuffered->GetLength(&bufferedLength);
|
||||||
|
|
||||||
|
// Either we the file is not fully cached, or we couldn't find a duration in
|
||||||
|
// the WebM bitstream.
|
||||||
|
if (!isFullyCached || !bufferedLength) {
|
||||||
MediaResource* resource = mDecoder->GetResource();
|
MediaResource* resource = mDecoder->GetResource();
|
||||||
nsTArray<MediaByteRange> ranges;
|
nsTArray<MediaByteRange> ranges;
|
||||||
nsresult res = resource->GetCachedRanges(ranges);
|
nsresult res = resource->GetCachedRanges(ranges);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
|
|
||||||
PRInt64 startTimeOffsetNS = aStartTime * NS_PER_USEC;
|
|
||||||
for (PRUint32 index = 0; index < ranges.Length(); index++) {
|
for (PRUint32 index = 0; index < ranges.Length(); index++) {
|
||||||
mBufferedState->CalculateBufferedForRange(aBuffered,
|
PRUint64 start, end;
|
||||||
ranges[index].mStart,
|
bool rv = mBufferedState->CalculateBufferedForRange(ranges[index].mStart,
|
||||||
ranges[index].mEnd,
|
ranges[index].mEnd,
|
||||||
timecodeScale,
|
&start, &end);
|
||||||
startTimeOffsetNS);
|
if (rv) {
|
||||||
|
double startTime = start * timecodeScale / NS_PER_S - aStartTime;
|
||||||
|
double endTime = end * timecodeScale / NS_PER_S - aStartTime;
|
||||||
|
|
||||||
|
// If this range extends to the end of the file, the true end time
|
||||||
|
// is the file's duration.
|
||||||
|
if (resource->IsDataCachedToEndOfResource(ranges[index].mStart)) {
|
||||||
|
uint64_t duration = 0;
|
||||||
|
if (nestegg_duration(mContext, &duration) == 0) {
|
||||||
|
endTime = duration / NS_PER_S;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aBuffered->Add(startTime, endTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,17 +67,17 @@ BrowserElementParent.prototype = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_observeInProcessBrowserFrameShown: function(frameLoader, data) {
|
_observeInProcessBrowserFrameShown: function(frameLoader) {
|
||||||
debug("In-process browser frame shown " + frameLoader);
|
debug("In-process browser frame shown " + frameLoader);
|
||||||
this._setUpMessageManagerListeners(frameLoader, data);
|
this._setUpMessageManagerListeners(frameLoader);
|
||||||
},
|
},
|
||||||
|
|
||||||
_observeRemoteBrowserFrameShown: function(frameLoader, data) {
|
_observeRemoteBrowserFrameShown: function(frameLoader) {
|
||||||
debug("Remote browser frame shown " + frameLoader);
|
debug("Remote browser frame shown " + frameLoader);
|
||||||
this._setUpMessageManagerListeners(frameLoader, data);
|
this._setUpMessageManagerListeners(frameLoader);
|
||||||
},
|
},
|
||||||
|
|
||||||
_setUpMessageManagerListeners: function(frameLoader, data) {
|
_setUpMessageManagerListeners: function(frameLoader) {
|
||||||
let frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
let frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
||||||
if (!frameElement) {
|
if (!frameElement) {
|
||||||
debug("No frame element?");
|
debug("No frame element?");
|
||||||
|
|
@ -150,10 +150,10 @@ BrowserElementParent.prototype = {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'remote-browser-frame-shown':
|
case 'remote-browser-frame-shown':
|
||||||
this._observeRemoteBrowserFrameShown(subject, data);
|
this._observeRemoteBrowserFrameShown(subject);
|
||||||
break;
|
break;
|
||||||
case 'in-process-browser-frame-shown':
|
case 'in-process-browser-frame-shown':
|
||||||
this._observeInProcessBrowserFrameShown(subject, data);
|
this._observeInProcessBrowserFrameShown(subject);
|
||||||
break;
|
break;
|
||||||
case 'content-document-global-created':
|
case 'content-document-global-created':
|
||||||
this._observeContentGlobalCreated(subject);
|
this._observeContentGlobalCreated(subject);
|
||||||
|
|
|
||||||
|
|
@ -5877,7 +5877,7 @@ DefineIDBInterfaceConstants(JSContext *cx, JSObject *obj, const nsIID *aIID)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class nsDOMConstructor : public nsIDOMDOMConstructor
|
class nsDOMConstructor MOZ_FINAL : public nsIDOMDOMConstructor
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
nsDOMConstructor(const PRUnichar* aName,
|
nsDOMConstructor(const PRUnichar* aName,
|
||||||
|
|
|
||||||
|
|
@ -5328,12 +5328,7 @@ nsGlobalWindow::ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll)
|
||||||
if (aYScroll > maxpx) {
|
if (aYScroll > maxpx) {
|
||||||
aYScroll = maxpx;
|
aYScroll = maxpx;
|
||||||
}
|
}
|
||||||
nsPoint pt(nsPresContext::CSSPixelsToAppUnits(aXScroll),
|
sf->ScrollToCSSPixels(nsIntPoint(aXScroll, aYScroll));
|
||||||
nsPresContext::CSSPixelsToAppUnits(aYScroll));
|
|
||||||
nscoord halfPixel = nsPresContext::CSSPixelsToAppUnits(0.5f);
|
|
||||||
// Don't allow pt.x/y + halfPixel since that would round up to the next CSS pixel.
|
|
||||||
nsRect range(pt.x - halfPixel, pt.y - halfPixel, halfPixel*2 - 1, halfPixel*2 - 1);
|
|
||||||
sf->ScrollTo(pt, nsIScrollableFrame::INSTANT, &range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
||||||
|
|
@ -138,18 +138,25 @@ inline bool
|
||||||
IsArrayLike(JSContext* cx, JSObject* obj)
|
IsArrayLike(JSContext* cx, JSObject* obj)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(obj);
|
MOZ_ASSERT(obj);
|
||||||
// For simplicity, check for security wrappers up front
|
// For simplicity, check for security wrappers up front. In case we
|
||||||
|
// have a security wrapper, don't forget to enter the compartment of
|
||||||
|
// the underlying object after unwrapping.
|
||||||
|
JSAutoEnterCompartment ac;
|
||||||
if (js::IsWrapper(obj)) {
|
if (js::IsWrapper(obj)) {
|
||||||
obj = XPCWrapper::Unwrap(cx, obj, false);
|
obj = XPCWrapper::Unwrap(cx, obj, false);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
// Let's say it's not
|
// Let's say it's not
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ac.enter(cx, obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXXbz need to detect platform objects (including listbinding
|
// XXXbz need to detect platform objects (including listbinding
|
||||||
// ones) with indexGetters here!
|
// ones) with indexGetters here!
|
||||||
return JS_IsArrayObject(cx, obj);
|
return JS_IsArrayObject(cx, obj) || JS_IsTypedArrayObject(obj, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
|
|
@ -582,6 +589,84 @@ ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
|
||||||
JSBool
|
JSBool
|
||||||
ThrowingConstructorWorkers(JSContext* cx, unsigned argc, JS::Value* vp);
|
ThrowingConstructorWorkers(JSContext* cx, unsigned argc, JS::Value* vp);
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class NonNull
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NonNull()
|
||||||
|
#ifdef DEBUG
|
||||||
|
: inited(false)
|
||||||
|
#endif
|
||||||
|
{}
|
||||||
|
|
||||||
|
operator T&() {
|
||||||
|
MOZ_ASSERT(inited);
|
||||||
|
MOZ_ASSERT(ptr, "NonNull<T> was set to null");
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(T* t) {
|
||||||
|
ptr = t;
|
||||||
|
MOZ_ASSERT(ptr);
|
||||||
|
#ifdef DEBUG
|
||||||
|
inited = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
T** Slot() {
|
||||||
|
#ifdef DEBUG
|
||||||
|
inited = true;
|
||||||
|
#endif
|
||||||
|
return &ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
T* ptr;
|
||||||
|
#ifdef DEBUG
|
||||||
|
bool inited;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class OwningNonNull
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OwningNonNull()
|
||||||
|
#ifdef DEBUG
|
||||||
|
: inited(false)
|
||||||
|
#endif
|
||||||
|
{}
|
||||||
|
|
||||||
|
operator T&() {
|
||||||
|
MOZ_ASSERT(inited);
|
||||||
|
MOZ_ASSERT(ptr, "OwningNonNull<T> was set to null");
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(T* t) {
|
||||||
|
init(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(const already_AddRefed<T>& t) {
|
||||||
|
init(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
template<typename U>
|
||||||
|
void init(U t) {
|
||||||
|
ptr = t;
|
||||||
|
MOZ_ASSERT(ptr);
|
||||||
|
#ifdef DEBUG
|
||||||
|
inited = true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<T> ptr;
|
||||||
|
#ifdef DEBUG
|
||||||
|
bool inited;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1116,7 +1116,7 @@ class CastableObjectUnwrapper():
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return string.Template(
|
return string.Template(
|
||||||
"""{
|
"""{
|
||||||
nsresult rv = UnwrapObject<${protoID}>(cx, ${source}, &${target});
|
nsresult rv = UnwrapObject<${protoID}>(cx, ${source}, ${target});
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
${codeOnFailure}
|
${codeOnFailure}
|
||||||
}
|
}
|
||||||
|
|
@ -1150,11 +1150,12 @@ class CallbackObjectUnwrapper:
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.descriptor.workers:
|
if self.descriptor.workers:
|
||||||
return string.Template("""
|
return string.Template(
|
||||||
${target} = ${source};""").substitute(self.substitution)
|
"${target} = ${source};"
|
||||||
|
).substitute(self.substitution)
|
||||||
|
|
||||||
return string.Template("""
|
return string.Template(
|
||||||
nsresult rv;
|
"""nsresult rv;
|
||||||
XPCCallContext ccx(JS_CALLER, cx);
|
XPCCallContext ccx(JS_CALLER, cx);
|
||||||
if (!ccx.IsValid()) {
|
if (!ccx.IsValid()) {
|
||||||
rv = NS_ERROR_XPC_BAD_CONVERT_JS;
|
rv = NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||||
|
|
@ -1169,95 +1170,267 @@ class CallbackObjectUnwrapper:
|
||||||
${codeOnFailure}
|
${codeOnFailure}
|
||||||
}
|
}
|
||||||
|
|
||||||
${target} = do_QueryObject(wrappedJS.get());
|
// Use a temp nsCOMPtr for the null-check, because ${target} might be
|
||||||
if (!${target}) {
|
// OwningNonNull, not an nsCOMPtr.
|
||||||
|
nsCOMPtr<${nativeType}> tmp = do_QueryObject(wrappedJS.get());
|
||||||
|
if (!tmp) {
|
||||||
${codeOnFailure}
|
${codeOnFailure}
|
||||||
}""").substitute(self.substitution)
|
|
||||||
|
|
||||||
def getArgumentConversionTemplate(type, descriptor):
|
|
||||||
if type.isSequence() or type.isArray():
|
|
||||||
raise TypeError("Can't handle sequence or array arguments yet")
|
|
||||||
|
|
||||||
if descriptor is not None:
|
|
||||||
assert(type.isInterface())
|
|
||||||
# This is an interface that we implement as a concrete class
|
|
||||||
# or an XPCOM interface.
|
|
||||||
argIsPointer = type.nullable() or type.unroll().inner.isExternal()
|
|
||||||
if argIsPointer:
|
|
||||||
nameSuffix = ""
|
|
||||||
else:
|
|
||||||
nameSuffix = "_ptr"
|
|
||||||
|
|
||||||
# If we're going to QI, we want an nsCOMPtr. But note that XPConnect
|
|
||||||
# unwrapping may or may not QI, and we don't know whether it will. So
|
|
||||||
# we use a raw pointer for the isExternal() case, and if a ref is needed
|
|
||||||
# it'll be handled by the xpc_qsSelfRef we put on the stack later.
|
|
||||||
if descriptor.castable or type.unroll().inner.isExternal() or descriptor.workers:
|
|
||||||
declType = " ${typeName}*"
|
|
||||||
else:
|
|
||||||
declType = " nsCOMPtr<${typeName}>"
|
|
||||||
template = declType + " ${name}%s;\n" % nameSuffix
|
|
||||||
|
|
||||||
# We have to be very careful here to put anything that might need to
|
|
||||||
# hold references across the C++ call in |template| and not
|
|
||||||
# |templateBody|, since things in |templateBody| will go out of scope
|
|
||||||
# before the call happens.
|
|
||||||
templateBody = " if (${argVal}.isObject()) {"
|
|
||||||
if descriptor.castable:
|
|
||||||
templateBody += str(FailureFatalCastableObjectUnwrapper(
|
|
||||||
descriptor,
|
|
||||||
"&${argVal}.toObject()",
|
|
||||||
"${name}"+nameSuffix)).replace("\n", "\n ") + "\n"
|
|
||||||
elif descriptor.interface.isCallback():
|
|
||||||
templateBody += str(CallbackObjectUnwrapper(
|
|
||||||
descriptor,
|
|
||||||
"&${argVal}.toObject()",
|
|
||||||
"${name}"+nameSuffix)) + "\n"
|
|
||||||
elif descriptor.workers:
|
|
||||||
templateBody += """
|
|
||||||
${name}%s = &${argVal}.toObject();
|
|
||||||
MOZ_ASSERT(${name}%s);
|
|
||||||
""" % (nameSuffix, nameSuffix)
|
|
||||||
else:
|
|
||||||
template += " xpc_qsSelfRef tmpRef_${name};\n"
|
|
||||||
template += " jsval tmpVal_${name} = ${argVal};\n"
|
|
||||||
templateBody += """
|
|
||||||
${typeName}* tmp;
|
|
||||||
if (NS_FAILED(xpc_qsUnwrapArg<${typeName}>(cx, ${argVal}, &tmp, &tmpRef_${name}.ptr,
|
|
||||||
&tmpVal_${name}))) {
|
|
||||||
return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
|
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(tmp);
|
${target} = tmp.forget();""").substitute(self.substitution)
|
||||||
${name}%s = tmp;
|
|
||||||
""" % (toStringBool(not descriptor.workers), nameSuffix)
|
|
||||||
|
|
||||||
|
def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
|
||||||
|
isDefinitelyObject=False,
|
||||||
|
isSequenceMember=False):
|
||||||
|
"""
|
||||||
|
Get a template for converting a JS value to a native object based on the
|
||||||
|
given type and descriptor. If failureCode is given, then we're actually
|
||||||
|
testing whether we can convert the argument to the desired type. That
|
||||||
|
means that failures to convert due to the JS value being the wrong type of
|
||||||
|
value need to use failureCode instead of throwing exceptions. Failures to
|
||||||
|
convert that are due to JS exceptions (from toString or valueOf methods) or
|
||||||
|
out of memory conditions need to throw exceptions no matter what
|
||||||
|
failureCode is.
|
||||||
|
|
||||||
|
If isDefinitelyObject is True, that means we know the value
|
||||||
|
isObject() and we have no need to recheck that.
|
||||||
|
|
||||||
|
The return value from this function is a tuple consisting of three things:
|
||||||
|
|
||||||
|
1) A string representing the conversion code. This will have template
|
||||||
|
substitution performed on it as follows:
|
||||||
|
|
||||||
|
${val} replaced by an expression for the JS::Value in question
|
||||||
|
${valPtr} is a pointer to the JS::Value in question
|
||||||
|
${holderName} replaced by the holder's name, if any
|
||||||
|
${declName} replaced by the declaration's name
|
||||||
|
|
||||||
|
2) A CGThing representing the native C++ type we're converting to
|
||||||
|
(declType). This is allowed to be None if the conversion code is
|
||||||
|
supposed to be used as-is.
|
||||||
|
3) A CGThing representing the type of a "holder" (holderType) which will
|
||||||
|
hold a possible reference to the C++ thing whose type we returned in #1,
|
||||||
|
or None if no such holder is needed.
|
||||||
|
|
||||||
|
${declName} must be in scope before the generated code is entered.
|
||||||
|
|
||||||
|
If holderType is not None then ${holderName} must be in scope
|
||||||
|
before the generated code is entered.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# A helper function for wrapping up the template body for
|
||||||
|
# possibly-nullable objecty stuff
|
||||||
|
def wrapObjectTemplate(templateBody, isDefinitelyObject, type,
|
||||||
|
codeToSetNull, isWorker):
|
||||||
|
if not isDefinitelyObject:
|
||||||
|
# Handle the non-object cases by wrapping up the whole
|
||||||
|
# thing in an if cascade.
|
||||||
|
templateBody = (
|
||||||
|
"if (${val}.isObject()) {\n" +
|
||||||
|
CGIndenter(CGGeneric(templateBody)).define() + "\n")
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
templateBody += (
|
templateBody += (
|
||||||
" } else if (${argVal}.isNullOrUndefined()) {\n"
|
"} else if (${val}.isNullOrUndefined()) {\n"
|
||||||
" ${name}%s = NULL;\n" % nameSuffix)
|
" %s;\n" % codeToSetNull)
|
||||||
|
|
||||||
templateBody += (
|
templateBody += (
|
||||||
"} else {\n"
|
"} else {\n"
|
||||||
" return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
|
" return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
|
||||||
" }\n" % toStringBool(not descriptor.workers))
|
"}" % toStringBool(not isWorker))
|
||||||
|
return templateBody
|
||||||
|
|
||||||
template += templateBody
|
if type.isArray():
|
||||||
|
raise TypeError("Can't handle array arguments yet")
|
||||||
|
|
||||||
if not argIsPointer:
|
if type.isSequence():
|
||||||
template += " ${typeName} &${name} = *${name}_ptr;\n"
|
if isSequenceMember:
|
||||||
|
raise TypeError("Can't handle sequences of sequences")
|
||||||
|
if failureCode is not None:
|
||||||
|
raise TypeError("Can't handle sequences when failureCode is not None")
|
||||||
|
nullable = type.nullable();
|
||||||
|
if nullable:
|
||||||
|
type = type.inner;
|
||||||
|
|
||||||
return template
|
elementType = type.inner;
|
||||||
|
# We don't know anything about the object-ness of the things
|
||||||
|
# we wrap, so don't pass through isDefinitelyObject
|
||||||
|
(elementTemplate, elementDeclType,
|
||||||
|
elementHolderType) = getJSToNativeConversionTemplate(
|
||||||
|
elementType, descriptorProvider, isSequenceMember=True)
|
||||||
|
if elementHolderType is not None:
|
||||||
|
raise TypeError("Shouldn't need holders for sequences")
|
||||||
|
|
||||||
|
# Have to make sure to use a fallible array, because it's trivial for
|
||||||
|
# page JS to create things with very large lengths.
|
||||||
|
typeName = CGWrapper(elementDeclType, pre="nsTArray< ", post=" >")
|
||||||
|
if nullable:
|
||||||
|
typeName = CGWrapper(typeName, pre="Nullable< ", post=" >")
|
||||||
|
templateBody = ("""JSObject* seq = &${val}.toObject();\n
|
||||||
|
if (!IsArrayLike(cx, seq)) {
|
||||||
|
return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);
|
||||||
|
}
|
||||||
|
uint32_t length;
|
||||||
|
// JS_GetArrayLength actually works on all objects
|
||||||
|
if (!JS_GetArrayLength(cx, seq, &length)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Jump through a hoop to do a fallible allocation but later end up with
|
||||||
|
// an infallible array.
|
||||||
|
FallibleTArray< %s > arr;
|
||||||
|
if (!arr.SetCapacity(length)) {
|
||||||
|
return Throw<%s>(cx, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
for (uint32_t i = 0; i < length; ++i) {
|
||||||
|
jsval temp;
|
||||||
|
if (!JS_GetElement(cx, seq, i, &temp)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
""" % (toStringBool(descriptorProvider.workers),
|
||||||
|
elementDeclType.define(),
|
||||||
|
toStringBool(descriptorProvider.workers)))
|
||||||
|
|
||||||
|
templateBody += CGIndenter(CGGeneric(
|
||||||
|
string.Template(elementTemplate).substitute(
|
||||||
|
{
|
||||||
|
"val" : "temp",
|
||||||
|
"declName" : "*arr.AppendElement()"
|
||||||
|
}
|
||||||
|
))).define()
|
||||||
|
|
||||||
|
templateBody += """
|
||||||
|
}
|
||||||
|
// And the other half of the hoop-jump"""
|
||||||
|
if nullable:
|
||||||
|
templateBody += """
|
||||||
|
${declName}.SetValue().SwapElements(arr);
|
||||||
|
"""
|
||||||
|
else:
|
||||||
|
templateBody += """
|
||||||
|
${declName}.SwapElements(arr);
|
||||||
|
"""
|
||||||
|
templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
|
||||||
|
type, "${declName}.SetNull()",
|
||||||
|
descriptorProvider.workers)
|
||||||
|
return (templateBody, typeName, None)
|
||||||
|
|
||||||
|
if type.isInterface() and not type.isArrayBuffer():
|
||||||
|
descriptor = descriptorProvider.getDescriptor(
|
||||||
|
type.unroll().inner.identifier.name)
|
||||||
|
# This is an interface that we implement as a concrete class
|
||||||
|
# or an XPCOM interface.
|
||||||
|
|
||||||
|
# Allow null pointers for nullable types and old-binding classes
|
||||||
|
argIsPointer = type.nullable() or type.unroll().inner.isExternal()
|
||||||
|
|
||||||
|
# Sequences and non-worker callbacks have to hold a strong ref to the
|
||||||
|
# thing being passed down.
|
||||||
|
forceOwningType = (descriptor.interface.isCallback() and
|
||||||
|
not descriptor.workers) or isSequenceMember
|
||||||
|
|
||||||
|
typeName = descriptor.nativeType
|
||||||
|
typePtr = typeName + "*"
|
||||||
|
|
||||||
|
# Compute a few things:
|
||||||
|
# - declType is the type we want to return as the first element of our
|
||||||
|
# tuple.
|
||||||
|
# - holderType is the type we want to return as the third element
|
||||||
|
# of our tuple.
|
||||||
|
# - declInit is the initializer expression for our decl, if any.
|
||||||
|
# - target is where a pointer to the object is being stored
|
||||||
|
|
||||||
|
# Set up some sensible defaults for these things insofar as we can.
|
||||||
|
holderType = None
|
||||||
|
if argIsPointer:
|
||||||
|
if forceOwningType:
|
||||||
|
declType = "nsRefPtr<" + typeName + ">"
|
||||||
|
else:
|
||||||
|
declType = typePtr
|
||||||
|
target = "&${declName}"
|
||||||
|
else:
|
||||||
|
if forceOwningType:
|
||||||
|
declType = "OwningNonNull<" + typeName + ">"
|
||||||
|
else:
|
||||||
|
declType = "NonNull<" + typeName + ">"
|
||||||
|
target = "${declName}.Slot()"
|
||||||
|
|
||||||
|
templateBody = ""
|
||||||
|
if descriptor.castable:
|
||||||
|
if failureCode is not None:
|
||||||
|
templateBody += str(CastableObjectUnwrapper(
|
||||||
|
descriptor,
|
||||||
|
"&${val}.toObject()",
|
||||||
|
target,
|
||||||
|
failureCode))
|
||||||
|
else:
|
||||||
|
templateBody += str(FailureFatalCastableObjectUnwrapper(
|
||||||
|
descriptor,
|
||||||
|
"&${val}.toObject()",
|
||||||
|
target))
|
||||||
|
elif descriptor.interface.isCallback():
|
||||||
|
templateBody += str(CallbackObjectUnwrapper(
|
||||||
|
descriptor,
|
||||||
|
"&${val}.toObject()",
|
||||||
|
"${declName}",
|
||||||
|
codeOnFailure=failureCode))
|
||||||
|
elif descriptor.workers:
|
||||||
|
templateBody += "${declName} = &${val}.toObject();"
|
||||||
|
else:
|
||||||
|
# Either external, or new-binding non-castable. We always have a
|
||||||
|
# holder for these, because we don't actually know whether we have
|
||||||
|
# to addref when unwrapping or not. So we just pass an
|
||||||
|
# getter_AddRefs(nsCOMPtr) to XPConnect and if we'll need a release
|
||||||
|
# it'll put a non-null pointer in there.
|
||||||
|
if forceOwningType:
|
||||||
|
# Don't return a holderType in this case; our declName
|
||||||
|
# will just own stuff.
|
||||||
|
templateBody += "nsCOMPtr<" + typeName + "> ${holderName};"
|
||||||
|
else:
|
||||||
|
holderType = "nsCOMPtr<" + typeName + ">"
|
||||||
|
templateBody += (
|
||||||
|
"jsval tmpVal = ${val};\n" +
|
||||||
|
typePtr + " tmp;\n"
|
||||||
|
"if (NS_FAILED(xpc_qsUnwrapArg<" + typeName + ">(cx, ${val}, &tmp, getter_AddRefs(${holderName}), &tmpVal))) {\n")
|
||||||
|
if failureCode is not None:
|
||||||
|
templateBody += " " + failureCode + "\n"
|
||||||
|
else:
|
||||||
|
templateBody += (
|
||||||
|
" return Throw<%s>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
|
||||||
|
% toStringBool(not descriptor.workers))
|
||||||
|
templateBody += ("}\n"
|
||||||
|
"MOZ_ASSERT(tmp);\n")
|
||||||
|
|
||||||
|
if not isDefinitelyObject:
|
||||||
|
# Our tmpVal will go out of scope, so we can't rely on it
|
||||||
|
# for rooting
|
||||||
|
templateBody += (
|
||||||
|
"if (tmpVal != ${val} && !${holderName}) {\n"
|
||||||
|
" // We have to have a strong ref, because we got this off\n"
|
||||||
|
" // some random object that might get GCed\n"
|
||||||
|
" ${holderName} = tmp;\n"
|
||||||
|
"}\n")
|
||||||
|
|
||||||
|
# And store our tmp, before it goes out of scope.
|
||||||
|
templateBody += "${declName} = tmp;"
|
||||||
|
|
||||||
|
templateBody = wrapObjectTemplate(templateBody, isDefinitelyObject,
|
||||||
|
type, "${declName} = NULL",
|
||||||
|
descriptor.workers)
|
||||||
|
|
||||||
|
declType = CGGeneric(declType)
|
||||||
|
if holderType is not None:
|
||||||
|
holderType = CGGeneric(holderType)
|
||||||
|
return (templateBody, declType, holderType)
|
||||||
|
|
||||||
if type.isArrayBuffer():
|
if type.isArrayBuffer():
|
||||||
|
if isSequenceMember:
|
||||||
|
raise TypeError("Can't handle sequences of arraybuffers")
|
||||||
|
declType = "JSObject*"
|
||||||
template = (
|
template = (
|
||||||
" JSObject* ${name};\n"
|
"if (${val}.isObject() && JS_IsArrayBufferObject(&${val}.toObject(), cx)) {\n"
|
||||||
" if (${argVal}.isObject() && JS_IsArrayBufferObject(&${argVal}.toObject(), cx)) {\n"
|
" ${declName} = &${val}.toObject();\n"
|
||||||
" ${name} = &${argVal}.toObject();\n"
|
|
||||||
"}")
|
"}")
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
template += (
|
template += (
|
||||||
" else if (${argVal}.isNullOrUndefined()) {\n"
|
" else if (${val}.isNullOrUndefined()) {\n"
|
||||||
" ${name} = NULL;\n"
|
" ${declName} = NULL;\n"
|
||||||
"}")
|
"}")
|
||||||
|
|
||||||
template += (
|
template += (
|
||||||
|
|
@ -1266,12 +1439,11 @@ def getArgumentConversionTemplate(type, descriptor):
|
||||||
" return Throw<false>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
|
" return Throw<false>(cx, NS_ERROR_XPC_BAD_CONVERT_JS);\n"
|
||||||
"}")
|
"}")
|
||||||
|
|
||||||
return template
|
return (template, CGGeneric(declType), None)
|
||||||
|
|
||||||
if type.isInterface():
|
|
||||||
raise TypeError("Interface type with no descriptor: " + type)
|
|
||||||
|
|
||||||
if type.isString():
|
if type.isString():
|
||||||
|
if isSequenceMember:
|
||||||
|
raise TypeError("Can't handle sequences of strings")
|
||||||
# XXXbz Need to figure out string behavior based on extended args? Also, how to
|
# XXXbz Need to figure out string behavior based on extended args? Also, how to
|
||||||
# detect them?
|
# detect them?
|
||||||
|
|
||||||
|
|
@ -1285,12 +1457,12 @@ def getArgumentConversionTemplate(type, descriptor):
|
||||||
undefinedBehavior = "eStringify"
|
undefinedBehavior = "eStringify"
|
||||||
|
|
||||||
return (
|
return (
|
||||||
" const xpc_qsDOMString ${name}(cx, ${argVal}, ${argPtr},\n"
|
"const xpc_qsDOMString ${declName}(cx, ${val}, ${valPtr},\n"
|
||||||
" xpc_qsDOMString::%s,\n"
|
" xpc_qsDOMString::%s,\n"
|
||||||
" xpc_qsDOMString::%s);\n"
|
" xpc_qsDOMString::%s);\n"
|
||||||
" if (!${name}.IsValid()) {\n"
|
"if (!${declName}.IsValid()) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
" }\n" % (nullBehavior, undefinedBehavior))
|
"}" % (nullBehavior, undefinedBehavior), None, None)
|
||||||
|
|
||||||
if type.isEnum():
|
if type.isEnum():
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
|
|
@ -1298,46 +1470,74 @@ def getArgumentConversionTemplate(type, descriptor):
|
||||||
"yet")
|
"yet")
|
||||||
enum = type.inner.identifier.name
|
enum = type.inner.identifier.name
|
||||||
return (
|
return (
|
||||||
" %(enumtype)s ${name};\n"
|
|
||||||
"{\n"
|
"{\n"
|
||||||
" bool ok;\n"
|
" bool ok;\n"
|
||||||
" ${name} = static_cast<%(enumtype)s>(FindEnumStringIndex(cx, ${argVal}, %(values)s, &ok));\n"
|
" ${declName} = static_cast<%(enumtype)s>(FindEnumStringIndex(cx, ${val}, %(values)s, &ok));\n"
|
||||||
" if (!ok) {\n"
|
" if (!ok) {\n"
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}" % { "enumtype" : enum,
|
"}" % { "enumtype" : enum,
|
||||||
"values" : enum + "Values::strings" })
|
"values" : enum + "Values::strings" },
|
||||||
|
CGGeneric(enum), None)
|
||||||
|
|
||||||
if type.isCallback():
|
if type.isCallback():
|
||||||
|
if isSequenceMember:
|
||||||
|
raise TypeError("Can't handle sequences of callbacks")
|
||||||
# XXXbz we're going to assume that callback types are always
|
# XXXbz we're going to assume that callback types are always
|
||||||
# nullable and always have [TreatNonCallableAsNull] for now.
|
# nullable and always have [TreatNonCallableAsNull] for now.
|
||||||
return (
|
return (
|
||||||
" JSObject* ${name};\n"
|
"if (${val}.isObject() && JS_ObjectIsCallable(cx, &${val}.toObject())) {\n"
|
||||||
" if (${argVal}.isObject() && JS_ObjectIsCallable(cx, &${argVal}.toObject())) {\n"
|
" ${declName} = &${val}.toObject();\n"
|
||||||
" ${name} = &${argVal}.toObject();\n"
|
|
||||||
"} else {\n"
|
"} else {\n"
|
||||||
" ${name} = NULL;\n"
|
" ${declName} = NULL;\n"
|
||||||
" }\n")
|
"}", CGGeneric("JSObject*"), None)
|
||||||
|
|
||||||
if type.isAny():
|
if type.isAny():
|
||||||
return " JS::Value ${name} = ${argVal};\n"
|
if isSequenceMember:
|
||||||
|
raise TypeError("Can't handle sequences of 'any'")
|
||||||
|
return ("${declName} = ${val};", CGGeneric("JS::Value"), None)
|
||||||
|
|
||||||
if not type.isPrimitive():
|
if not type.isPrimitive():
|
||||||
raise TypeError("Need conversion for argument type '%s'" % type)
|
raise TypeError("Need conversion for argument type '%s'" % type)
|
||||||
|
|
||||||
# XXXbz need to add support for [EnforceRange] and [Clamp]
|
# XXXbz need to add support for [EnforceRange] and [Clamp]
|
||||||
|
typeName = builtinNames[type.tag()]
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
return (" Nullable<${typeName}> ${name};\n"
|
return ("if (${val}.isNullOrUndefined()) {\n"
|
||||||
" if (${argVal}.isNullOrUndefined()) {\n"
|
" ${declName}.SetNull();\n"
|
||||||
" ${name}.SetNull();\n"
|
"} else if (!ValueToPrimitive<" + typeName + ">(cx, ${val}, &${declName}.SetValue())) {\n"
|
||||||
" } else if (!ValueToPrimitive<${typeName}>(cx, ${argVal}, &${name}.SetValue())) {\n"
|
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
" }\n")
|
"}", CGGeneric("Nullable<" + typeName + ">"), None)
|
||||||
else:
|
else:
|
||||||
return (" ${typeName} ${name};\n"
|
return ("if (!ValueToPrimitive<" + typeName + ">(cx, ${val}, &${declName})) {\n"
|
||||||
" if (!ValueToPrimitive<${typeName}>(cx, ${argVal}, &${name})) {\n"
|
|
||||||
" return false;\n"
|
" return false;\n"
|
||||||
" }\n")
|
"}", CGGeneric(typeName), None)
|
||||||
|
|
||||||
|
def instantiateJSToNativeConversionTemplate(templateTuple, replacements):
|
||||||
|
"""
|
||||||
|
Take a tuple as returned by getJSToNativeConversionTemplate and a set of
|
||||||
|
replacements as required by the strings in such a tuple, and generate code
|
||||||
|
to convert into stack C++ types.
|
||||||
|
"""
|
||||||
|
(templateBody, declType, holderType) = templateTuple
|
||||||
|
result = CGList([], "\n")
|
||||||
|
if holderType is not None:
|
||||||
|
result.append(
|
||||||
|
CGList([holderType, CGGeneric(" "),
|
||||||
|
CGGeneric(replacements["holderName"]),
|
||||||
|
CGGeneric(";")]))
|
||||||
|
if declType is not None:
|
||||||
|
result.append(
|
||||||
|
CGList([declType, CGGeneric(" "),
|
||||||
|
CGGeneric(replacements["declName"]),
|
||||||
|
CGGeneric(";")]))
|
||||||
|
result.append(CGGeneric(
|
||||||
|
string.Template(templateBody).substitute(replacements)
|
||||||
|
))
|
||||||
|
# Add an empty CGGeneric to get an extra newline after the argument
|
||||||
|
# conversion.
|
||||||
|
result.append(CGGeneric(""))
|
||||||
|
return result;
|
||||||
|
|
||||||
def convertConstIDLValueToJSVal(value):
|
def convertConstIDLValueToJSVal(value):
|
||||||
if isinstance(value, IDLNullValue):
|
if isinstance(value, IDLNullValue):
|
||||||
|
|
@ -1363,7 +1563,6 @@ def convertIDLDefaultValueToJSVal(value):
|
||||||
assert False # Not implemented!
|
assert False # Not implemented!
|
||||||
return convertConstIDLValueToJSVal(value)
|
return convertConstIDLValueToJSVal(value)
|
||||||
|
|
||||||
unindenter = re.compile("^ ", re.MULTILINE)
|
|
||||||
class CGArgumentConverter(CGThing):
|
class CGArgumentConverter(CGThing):
|
||||||
"""
|
"""
|
||||||
A class that takes an IDL argument object, its index in the
|
A class that takes an IDL argument object, its index in the
|
||||||
|
|
@ -1375,44 +1574,38 @@ class CGArgumentConverter(CGThing):
|
||||||
self.argument = argument
|
self.argument = argument
|
||||||
# XXXbz should optional jsval args get JSVAL_VOID? What about
|
# XXXbz should optional jsval args get JSVAL_VOID? What about
|
||||||
# others?
|
# others?
|
||||||
self.replacementVariables = {
|
replacer = {
|
||||||
"index" : index,
|
"index" : index,
|
||||||
"argc" : argc,
|
"argc" : argc,
|
||||||
"argv" : argv,
|
"argv" : argv,
|
||||||
"defaultValue" : "JSVAL_VOID",
|
"defaultValue" : "JSVAL_VOID"
|
||||||
"name" : "arg%d" % index
|
}
|
||||||
|
self.replacementVariables = {
|
||||||
|
"declName" : "arg%d" % index,
|
||||||
|
"holderName" : ("arg%d" % index) + "_holder"
|
||||||
}
|
}
|
||||||
if argument.optional:
|
if argument.optional:
|
||||||
if argument.defaultValue:
|
if argument.defaultValue:
|
||||||
self.replacementVariables["defaultValue"] = convertIDLDefaultValueToJSVal(argument.defaultValue)
|
replacer["defaultValue"] = convertIDLDefaultValueToJSVal(argument.defaultValue)
|
||||||
self.replacementVariables["argVal"] = string.Template(
|
self.replacementVariables["val"] = string.Template(
|
||||||
"(${index} < ${argc} ? ${argv}[${index}] : ${defaultValue})"
|
"(${index} < ${argc} ? ${argv}[${index}] : ${defaultValue})"
|
||||||
).substitute(self.replacementVariables)
|
).substitute(replacer)
|
||||||
self.replacementVariables["argPtr"] = string.Template(
|
self.replacementVariables["valPtr"] = string.Template(
|
||||||
"(${index} < ${argc} ? &${argv}[${index}] : NULL)"
|
"(${index} < ${argc} ? &${argv}[${index}] : NULL)"
|
||||||
).substitute(self.replacementVariables)
|
).substitute(replacer)
|
||||||
else:
|
else:
|
||||||
self.replacementVariables["argVal"] = string.Template(
|
self.replacementVariables["val"] = string.Template(
|
||||||
"${argv}[${index}]"
|
"${argv}[${index}]"
|
||||||
).substitute(self.replacementVariables)
|
).substitute(replacer)
|
||||||
self.replacementVariables["argPtr"] = (
|
self.replacementVariables["valPtr"] = (
|
||||||
"&" + self.replacementVariables["argVal"])
|
"&" + self.replacementVariables["val"])
|
||||||
self.descriptor = None
|
self.descriptorProvider = descriptorProvider
|
||||||
if argument.type.isPrimitive():
|
|
||||||
self.replacementVariables["typeName"] = builtinNames[argument.type.tag()]
|
|
||||||
elif argument.type.isInterface() and not argument.type.isArrayBuffer():
|
|
||||||
descriptor = descriptorProvider.getDescriptor(
|
|
||||||
argument.type.unroll().inner.identifier.name)
|
|
||||||
self.descriptor = descriptor
|
|
||||||
self.replacementVariables["typeName"] = descriptor.nativeType
|
|
||||||
|
|
||||||
def define(self):
|
def define(self):
|
||||||
return string.Template(
|
return instantiateJSToNativeConversionTemplate(
|
||||||
re.sub(unindenter,
|
getJSToNativeConversionTemplate(self.argument.type,
|
||||||
"",
|
self.descriptorProvider),
|
||||||
getArgumentConversionTemplate(self.argument.type,
|
self.replacementVariables).define()
|
||||||
self.descriptor))
|
|
||||||
).substitute(self.replacementVariables)
|
|
||||||
|
|
||||||
def getWrapTemplateForType(type, descriptorProvider, result, successCode):
|
def getWrapTemplateForType(type, descriptorProvider, result, successCode):
|
||||||
"""
|
"""
|
||||||
|
|
@ -1460,8 +1653,45 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode):
|
||||||
if type is None or type.isVoid():
|
if type is None or type.isVoid():
|
||||||
return setValue("JSVAL_VOID")
|
return setValue("JSVAL_VOID")
|
||||||
|
|
||||||
if type.isSequence() or type.isArray():
|
if type.isArray():
|
||||||
raise TypeError("Can't handle sequence or array return values yet")
|
raise TypeError("Can't handle array return values yet")
|
||||||
|
|
||||||
|
if type.isSequence():
|
||||||
|
if type.nullable():
|
||||||
|
# Nullable sequences are Nullable< nsTArray<T> >
|
||||||
|
return """
|
||||||
|
if (%s.IsNull()) {
|
||||||
|
%s
|
||||||
|
}
|
||||||
|
%s""" % (result, CGIndenter(CGGeneric(setValue("JSVAL_NULL"))).define(),
|
||||||
|
getWrapTemplateForType(type.inner, descriptorProvider,
|
||||||
|
"%s.Value()" % result, successCode))
|
||||||
|
|
||||||
|
# Now do non-nullable sequences. We use setting the element
|
||||||
|
# in the array as our succcess code because when we succeed in
|
||||||
|
# wrapping that's what we should do.
|
||||||
|
innerTemplate = wrapForType(
|
||||||
|
type.inner, descriptorProvider,
|
||||||
|
{
|
||||||
|
'result' : "%s[i]" % result,
|
||||||
|
'successCode': ("if (!JS_SetElement(cx, returnArray, i, &tmp)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}"),
|
||||||
|
'jsvalRef': "tmp",
|
||||||
|
'jsvalPtr': "&tmp"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
innerTemplate = CGIndenter(CGGeneric(innerTemplate)).define()
|
||||||
|
return ("""
|
||||||
|
uint32_t length = %s.Length();
|
||||||
|
JSObject *returnArray = JS_NewArrayObject(cx, length, NULL);
|
||||||
|
if (!returnArray) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
jsval tmp;
|
||||||
|
for (uint32_t i = 0; i < length; ++i) {
|
||||||
|
%s
|
||||||
|
}\n""" % (result, innerTemplate)) + setValue("JS::ObjectValue(*returnArray)")
|
||||||
|
|
||||||
if type.isInterface() and not type.isArrayBuffer():
|
if type.isInterface() and not type.isArrayBuffer():
|
||||||
descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
|
descriptor = descriptorProvider.getDescriptor(type.unroll().inner.identifier.name)
|
||||||
|
|
@ -1582,25 +1812,8 @@ def wrapForType(type, descriptorProvider, templateValues):
|
||||||
defaultValues = {'obj': 'obj'}
|
defaultValues = {'obj': 'obj'}
|
||||||
return string.Template(wrap).substitute(defaultValues, **templateValues)
|
return string.Template(wrap).substitute(defaultValues, **templateValues)
|
||||||
|
|
||||||
class CGCallGenerator(CGThing):
|
def getRetvalDeclarationForType(returnType, descriptorProvider,
|
||||||
"""
|
resultAlreadyAddRefed):
|
||||||
A class to generate an actual call to a C++ object. Assumes that the C++
|
|
||||||
object is stored in a variable named "self".
|
|
||||||
"""
|
|
||||||
def __init__(self, errorReport, argCount, argsPre, returnType,
|
|
||||||
resultAlreadyAddRefed, descriptorProvider, nativeMethodName, static):
|
|
||||||
CGThing.__init__(self)
|
|
||||||
|
|
||||||
isFallible = errorReport is not None
|
|
||||||
|
|
||||||
args = CGList([CGGeneric("arg" + str(i)) for i in range(argCount)], ", ")
|
|
||||||
resultOutParam = returnType is not None and returnType.isString()
|
|
||||||
# Return values that go in outparams go here
|
|
||||||
if resultOutParam:
|
|
||||||
args.append(CGGeneric("result"))
|
|
||||||
if isFallible:
|
|
||||||
args.append(CGGeneric("rv"))
|
|
||||||
|
|
||||||
if returnType is None or returnType.isVoid():
|
if returnType is None or returnType.isVoid():
|
||||||
# Nothing to declare
|
# Nothing to declare
|
||||||
result = None
|
result = None
|
||||||
|
|
@ -1627,9 +1840,45 @@ class CGCallGenerator(CGThing):
|
||||||
result = CGGeneric("JSObject*")
|
result = CGGeneric("JSObject*")
|
||||||
elif returnType.tag() is IDLType.Tags.any:
|
elif returnType.tag() is IDLType.Tags.any:
|
||||||
result = CGGeneric("JS::Value")
|
result = CGGeneric("JS::Value")
|
||||||
|
elif returnType.isSequence():
|
||||||
|
nullable = returnType.nullable()
|
||||||
|
if nullable:
|
||||||
|
returnType = returnType.inner
|
||||||
|
# Assume no need to addref for now
|
||||||
|
result = CGWrapper(getRetvalDeclarationForType(returnType.inner,
|
||||||
|
descriptorProvider,
|
||||||
|
False),
|
||||||
|
pre="nsTArray< ", post=" >")
|
||||||
|
if nullable:
|
||||||
|
result = CGWrapper(result, pre="Nullable< ", post=" >")
|
||||||
else:
|
else:
|
||||||
raise TypeError("Don't know how to declare return value for %s" %
|
raise TypeError("Don't know how to declare return value for %s" %
|
||||||
returnType)
|
returnType)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class CGCallGenerator(CGThing):
|
||||||
|
"""
|
||||||
|
A class to generate an actual call to a C++ object. Assumes that the C++
|
||||||
|
object is stored in a variable named "self".
|
||||||
|
"""
|
||||||
|
def __init__(self, errorReport, argCount, argsPre, returnType,
|
||||||
|
resultAlreadyAddRefed, descriptorProvider, nativeMethodName, static):
|
||||||
|
CGThing.__init__(self)
|
||||||
|
|
||||||
|
isFallible = errorReport is not None
|
||||||
|
|
||||||
|
args = CGList([CGGeneric("arg" + str(i)) for i in range(argCount)], ", ")
|
||||||
|
resultOutParam = (returnType is not None and
|
||||||
|
(returnType.isString() or returnType.isSequence()))
|
||||||
|
# Return values that go in outparams go here
|
||||||
|
if resultOutParam:
|
||||||
|
args.append(CGGeneric("result"))
|
||||||
|
if isFallible:
|
||||||
|
args.append(CGGeneric("rv"))
|
||||||
|
|
||||||
|
result = getRetvalDeclarationForType(returnType, descriptorProvider,
|
||||||
|
resultAlreadyAddRefed)
|
||||||
|
|
||||||
# Build up our actual call
|
# Build up our actual call
|
||||||
self.cgRoot = CGList([], "\n")
|
self.cgRoot = CGList([], "\n")
|
||||||
|
|
@ -1958,63 +2207,24 @@ class CGMethodCall(CGThing):
|
||||||
caseBody.append(CGIndenter(CGGeneric("do {")));
|
caseBody.append(CGIndenter(CGGeneric("do {")));
|
||||||
type = sig[1][distinguishingIndex].type
|
type = sig[1][distinguishingIndex].type
|
||||||
|
|
||||||
# XXXbz this duplicates some argument-unwrapping code!
|
testCode = instantiateJSToNativeConversionTemplate(
|
||||||
interfaceDesc = descriptor.getDescriptor(
|
getJSToNativeConversionTemplate(type, descriptor,
|
||||||
type.unroll().inner.identifier.name)
|
failureCode="break;",
|
||||||
argIsPointer = (type.nullable() or
|
isDefinitelyObject=True),
|
||||||
type.unroll().inner.isExternal())
|
|
||||||
if argIsPointer:
|
|
||||||
nameSuffix = ""
|
|
||||||
else:
|
|
||||||
nameSuffix = "_ptr"
|
|
||||||
if (interfaceDesc.castable or
|
|
||||||
type.unroll().inner.isExternal() or
|
|
||||||
interfaceDesc.workers):
|
|
||||||
declType = " ${typeName}*"
|
|
||||||
else:
|
|
||||||
declType = " nsCOMPtr<${typeName}>"
|
|
||||||
template = declType + " ${name}%s;\n" % nameSuffix
|
|
||||||
if interfaceDesc.castable:
|
|
||||||
template += str(CastableObjectUnwrapper(
|
|
||||||
interfaceDesc,
|
|
||||||
"&${argVal}.toObject()",
|
|
||||||
"${name}"+nameSuffix,
|
|
||||||
"break;")) + "\n"
|
|
||||||
elif interfaceDesc.workers:
|
|
||||||
template += """
|
|
||||||
${name}%s = &${argVal}.toObject();
|
|
||||||
MOZ_ASSERT(${name}%s);
|
|
||||||
""" % (nameSuffix, nameSuffix)
|
|
||||||
else:
|
|
||||||
template += " xpc_qsSelfRef tmpRef_${name};\n"
|
|
||||||
template += " jsval tmpVal_${name} = ${argVal};\n"
|
|
||||||
template += """
|
|
||||||
${typeName}* tmp;
|
|
||||||
if (NS_FAILED(xpc_qsUnwrapArg<${typeName}>(cx, ${argVal}, &tmp, &tmpRef_${name}.ptr,
|
|
||||||
&tmpVal_${name}))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(tmp);
|
|
||||||
${name}%s = tmp;
|
|
||||||
""" % nameSuffix
|
|
||||||
|
|
||||||
if not argIsPointer:
|
|
||||||
template += " ${typeName} &${name} = *${name}_ptr;\n"
|
|
||||||
|
|
||||||
testCode = string.Template(template).substitute(
|
|
||||||
{
|
{
|
||||||
"typeName": interfaceDesc.nativeType,
|
"declName" : "arg%d" % distinguishingIndex,
|
||||||
"name" : "arg%d" % distinguishingIndex,
|
"holderName" : ("arg%d" % distinguishingIndex) + "_holder",
|
||||||
"argVal" : distinguishingArg
|
"val" : distinguishingArg
|
||||||
}
|
})
|
||||||
)
|
|
||||||
caseBody.append(CGIndenter(CGGeneric(testCode)));
|
# Indent by 4, since we need to indent further than our "do" statement
|
||||||
|
caseBody.append(CGIndenter(testCode, 4));
|
||||||
# If we got this far, we know we unwrapped to the right
|
# If we got this far, we know we unwrapped to the right
|
||||||
# interface, so just do the call. Start conversion with
|
# interface, so just do the call. Start conversion with
|
||||||
# distinguishingIndex + 1, since we already converted
|
# distinguishingIndex + 1, since we already converted
|
||||||
# distinguishingIndex.
|
# distinguishingIndex.
|
||||||
caseBody.append(CGIndenter(CGIndenter(
|
caseBody.append(CGIndenter(
|
||||||
getPerSignatureCall(sig, distinguishingIndex + 1))))
|
getPerSignatureCall(sig, distinguishingIndex + 1), 4))
|
||||||
caseBody.append(CGIndenter(CGGeneric("} while (0);")))
|
caseBody.append(CGIndenter(CGGeneric("} while (0);")))
|
||||||
|
|
||||||
caseBody.append(CGGeneric("}"))
|
caseBody.append(CGGeneric("}"))
|
||||||
|
|
@ -2022,7 +2232,7 @@ class CGMethodCall(CGThing):
|
||||||
# XXXbz Now we're supposed to check for distinguishingArg being
|
# XXXbz Now we're supposed to check for distinguishingArg being
|
||||||
# an array or a platform object that supports indexed
|
# an array or a platform object that supports indexed
|
||||||
# properties... skip that last for now. It's a bit of a pain.
|
# properties... skip that last for now. It's a bit of a pain.
|
||||||
pickFirstSignature("%s.isObject() && IsArrayLike(cx, &%s.toObject()" %
|
pickFirstSignature("%s.isObject() && IsArrayLike(cx, &%s.toObject())" %
|
||||||
(distinguishingArg, distinguishingArg),
|
(distinguishingArg, distinguishingArg),
|
||||||
lambda s:
|
lambda s:
|
||||||
(s[1][distinguishingIndex].type.isArray() or
|
(s[1][distinguishingIndex].type.isArray() or
|
||||||
|
|
@ -2168,8 +2378,9 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
|
||||||
CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
|
CGAbstractStaticMethod.__init__(self, descriptor, name, "JSBool", args)
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
unwrapThis = CGGeneric(
|
unwrapThis = CGIndenter(CGGeneric(
|
||||||
str(FailureFatalCastableObjectUnwrapper(self.descriptor, "obj", "self")))
|
str(FailureFatalCastableObjectUnwrapper(self.descriptor,
|
||||||
|
"obj", "&self"))))
|
||||||
return CGList([ self.getThis(), unwrapThis,
|
return CGList([ self.getThis(), unwrapThis,
|
||||||
self.generate_code() ], "\n").define()
|
self.generate_code() ], "\n").define()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,10 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsresult mResult;
|
nsresult mResult;
|
||||||
|
|
||||||
|
// Not to be implemented, to make sure people always pass this by
|
||||||
|
// reference, not by value.
|
||||||
|
ErrorResult(const ErrorResult&) MOZ_DELETE;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,11 @@ public:
|
||||||
return mValue;
|
return mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T& Value() {
|
||||||
|
MOZ_ASSERT(!mIsNull);
|
||||||
|
return mValue;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsNull() const {
|
bool IsNull() const {
|
||||||
return mIsNull;
|
return mIsNull;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -814,10 +814,10 @@ class IDLSequenceType(IDLType):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def isPrimitive(self):
|
def isPrimitive(self):
|
||||||
return self.inner.isPrimitive()
|
return False;
|
||||||
|
|
||||||
def isString(self):
|
def isString(self):
|
||||||
return self.inner.isString()
|
return False;
|
||||||
|
|
||||||
def isVoid(self):
|
def isVoid(self):
|
||||||
return False
|
return False
|
||||||
|
|
|
||||||
|
|
@ -104,16 +104,16 @@ class ToggleBtTask : public nsRunnable
|
||||||
}
|
}
|
||||||
|
|
||||||
// return 1 if it's enabled, 0 if it's disabled, and -1 on error
|
// return 1 if it's enabled, 0 if it's disabled, and -1 on error
|
||||||
int isEnabled = sBluedroidFunctions.bt_is_enabled();
|
int isEnabled = IsBluetoothEnabled();
|
||||||
|
|
||||||
if ((isEnabled == 1 && mEnabled) || (isEnabled == 0 && !mEnabled)) {
|
if ((isEnabled == 1 && mEnabled) || (isEnabled == 0 && !mEnabled)) {
|
||||||
result = true;
|
result = true;
|
||||||
} else if (isEnabled < 0) {
|
} else if (isEnabled < 0) {
|
||||||
result = false;
|
result = false;
|
||||||
} else if (mEnabled) {
|
} else if (mEnabled) {
|
||||||
result = (sBluedroidFunctions.bt_enable() == 0) ? true : false;
|
result = (EnableBluetooth() == 0) ? true : false;
|
||||||
} else {
|
} else {
|
||||||
result = (sBluedroidFunctions.bt_disable() == 0) ? true : false;
|
result = (DisableBluetooth() == 0) ? true : false;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
result = true;
|
result = true;
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,21 @@ namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
namespace bluetooth {
|
namespace bluetooth {
|
||||||
|
|
||||||
|
static struct BluedroidFunctions {
|
||||||
|
bool initialized;
|
||||||
|
bool tried_initialization;
|
||||||
|
|
||||||
|
BluedroidFunctions() :
|
||||||
|
initialized(false),
|
||||||
|
tried_initialization(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int (* bt_enable)();
|
||||||
|
int (* bt_disable)();
|
||||||
|
int (* bt_is_enabled)();
|
||||||
|
} sBluedroidFunctions;
|
||||||
|
|
||||||
bool EnsureBluetoothInit() {
|
bool EnsureBluetoothInit() {
|
||||||
if (sBluedroidFunctions.tried_initialization)
|
if (sBluedroidFunctions.tried_initialization)
|
||||||
{
|
{
|
||||||
|
|
@ -49,6 +64,22 @@ bool EnsureBluetoothInit() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int IsBluetoothEnabled()
|
||||||
|
{
|
||||||
|
return sBluedroidFunctions.bt_is_enabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
int EnableBluetooth()
|
||||||
|
{
|
||||||
|
return sBluedroidFunctions.bt_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DisableBluetooth()
|
||||||
|
{
|
||||||
|
return sBluedroidFunctions.bt_disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,22 +11,11 @@ namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
namespace bluetooth {
|
namespace bluetooth {
|
||||||
|
|
||||||
static struct BluedroidFunctions {
|
|
||||||
bool initialized;
|
|
||||||
bool tried_initialization;
|
|
||||||
|
|
||||||
BluedroidFunctions() :
|
|
||||||
initialized(false),
|
|
||||||
tried_initialization(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int (* bt_enable)();
|
|
||||||
int (* bt_disable)();
|
|
||||||
int (* bt_is_enabled)();
|
|
||||||
} sBluedroidFunctions;
|
|
||||||
|
|
||||||
bool EnsureBluetoothInit();
|
bool EnsureBluetoothInit();
|
||||||
|
int IsBluetoothEnabled();
|
||||||
|
int EnableBluetooth();
|
||||||
|
int DisableBluetooth();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ class nsIThread;
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
BEGIN_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
class CheckPermissionsHelper : public nsIRunnable,
|
class CheckPermissionsHelper MOZ_FINAL : public nsIRunnable,
|
||||||
public nsIInterfaceRequestor,
|
public nsIInterfaceRequestor,
|
||||||
public nsIObserver
|
public nsIObserver
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class nsPIDOMWindow;
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
BEGIN_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
class CheckQuotaHelper : public nsIRunnable,
|
class CheckQuotaHelper MOZ_FINAL : public nsIRunnable,
|
||||||
public nsIInterfaceRequestor,
|
public nsIInterfaceRequestor,
|
||||||
public nsIObserver
|
public nsIObserver
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ class ContinueObjectStoreHelper;
|
||||||
class ContinueIndexHelper;
|
class ContinueIndexHelper;
|
||||||
class ContinueIndexObjectHelper;
|
class ContinueIndexObjectHelper;
|
||||||
|
|
||||||
class IDBCursor : public nsIIDBCursorWithValue
|
class IDBCursor MOZ_FINAL : public nsIIDBCursorWithValue
|
||||||
{
|
{
|
||||||
friend class ContinueHelper;
|
friend class ContinueHelper;
|
||||||
friend class ContinueObjectStoreHelper;
|
friend class ContinueObjectStoreHelper;
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ struct DatabaseInfo;
|
||||||
class IDBDatabase;
|
class IDBDatabase;
|
||||||
struct ObjectStoreInfo;
|
struct ObjectStoreInfo;
|
||||||
|
|
||||||
class IDBFactory : public nsIIDBFactory
|
class IDBFactory MOZ_FINAL : public nsIIDBFactory
|
||||||
{
|
{
|
||||||
typedef nsTArray<nsRefPtr<ObjectStoreInfo> > ObjectStoreInfoArray;
|
typedef nsTArray<nsRefPtr<ObjectStoreInfo> > ObjectStoreInfoArray;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class AsyncConnectionHelper;
|
||||||
class IDBObjectStore;
|
class IDBObjectStore;
|
||||||
struct IndexInfo;
|
struct IndexInfo;
|
||||||
|
|
||||||
class IDBIndex : public nsIIDBIndex
|
class IDBIndex MOZ_FINAL : public nsIIDBIndex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ class mozIStorageStatement;
|
||||||
|
|
||||||
BEGIN_INDEXEDDB_NAMESPACE
|
BEGIN_INDEXEDDB_NAMESPACE
|
||||||
|
|
||||||
class IDBKeyRange : public nsIIDBKeyRange
|
class IDBKeyRange MOZ_FINAL : public nsIIDBKeyRange
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ struct IndexUpdateInfo;
|
||||||
struct StructuredCloneReadInfo;
|
struct StructuredCloneReadInfo;
|
||||||
struct StructuredCloneWriteInfo;
|
struct StructuredCloneWriteInfo;
|
||||||
|
|
||||||
class IDBObjectStore : public nsIIDBObjectStore
|
class IDBObjectStore MOZ_FINAL : public nsIIDBObjectStore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ private:
|
||||||
nsTArray<nsRefPtr<FileInfo> > mCreatedFileInfos;
|
nsTArray<nsRefPtr<FileInfo> > mCreatedFileInfos;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CommitHelper : public nsIRunnable
|
class CommitHelper MOZ_FINAL : public nsIRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
@ -263,7 +263,7 @@ private:
|
||||||
bool mAborted;
|
bool mAborted;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UpdateRefcountFunction : public mozIStorageFunction
|
class UpdateRefcountFunction MOZ_FINAL : public mozIStorageFunction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ GetBaseFilename(const nsAString& aFilename,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class QuotaCallback : public mozIStorageQuotaCallback
|
class QuotaCallback MOZ_FINAL : public mozIStorageQuotaCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ class AsyncConnectionHelper;
|
||||||
|
|
||||||
class CheckQuotaHelper;
|
class CheckQuotaHelper;
|
||||||
|
|
||||||
class IndexedDatabaseManager : public nsIIndexedDatabaseManager,
|
class IndexedDatabaseManager MOZ_FINAL : public nsIIndexedDatabaseManager,
|
||||||
public nsIObserver
|
public nsIObserver
|
||||||
{
|
{
|
||||||
friend class IDBDatabase;
|
friend class IDBDatabase;
|
||||||
|
|
@ -243,7 +243,7 @@ private:
|
||||||
// directory that contains them before dispatching itself back to the main
|
// directory that contains them before dispatching itself back to the main
|
||||||
// thread. When back on the main thread the runnable will notify the
|
// thread. When back on the main thread the runnable will notify the
|
||||||
// IndexedDatabaseManager that the job has been completed.
|
// IndexedDatabaseManager that the job has been completed.
|
||||||
class OriginClearRunnable : public nsIRunnable
|
class OriginClearRunnable MOZ_FINAL : public nsIRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
@ -272,7 +272,7 @@ private:
|
||||||
// before dispatching itself back to the main thread. When on the main thread
|
// before dispatching itself back to the main thread. When on the main thread
|
||||||
// the runnable will call the callback and then notify the
|
// the runnable will call the callback and then notify the
|
||||||
// IndexedDatabaseManager that the job has been completed.
|
// IndexedDatabaseManager that the job has been completed.
|
||||||
class AsyncUsageRunnable : public nsIRunnable
|
class AsyncUsageRunnable MOZ_FINAL : public nsIRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
@ -326,7 +326,7 @@ private:
|
||||||
|
|
||||||
// A callback runnable used by the TransactionPool when it's safe to proceed
|
// A callback runnable used by the TransactionPool when it's safe to proceed
|
||||||
// with a SetVersion/DeleteDatabase/etc.
|
// with a SetVersion/DeleteDatabase/etc.
|
||||||
class WaitForTransactionsToFinishRunnable : public nsIRunnable
|
class WaitForTransactionsToFinishRunnable MOZ_FINAL : public nsIRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WaitForTransactionsToFinishRunnable(SynchronizedOp* aOp)
|
WaitForTransactionsToFinishRunnable(SynchronizedOp* aOp)
|
||||||
|
|
@ -345,7 +345,7 @@ private:
|
||||||
SynchronizedOp* mOp;
|
SynchronizedOp* mOp;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AsyncDeleteFileRunnable : public nsIRunnable
|
class AsyncDeleteFileRunnable MOZ_FINAL : public nsIRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
|
||||||
|
|
@ -853,7 +853,7 @@ UpgradeSchemaFrom7To8(mozIStorageConnection* aConnection)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CompressDataBlobsFunction : public mozIStorageFunction
|
class CompressDataBlobsFunction MOZ_FINAL : public mozIStorageFunction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
@ -1095,7 +1095,7 @@ UpgradeSchemaFrom10_0To11_0(mozIStorageConnection* aConnection)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
class EncodeKeysFunction : public mozIStorageFunction
|
class EncodeKeysFunction MOZ_FINAL : public mozIStorageFunction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
|
|
|
||||||