Merge from mozilla-central.
@ -42,6 +42,7 @@
|
||||
#include "Accessible-inl.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsHyperTextAccessible.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "States.h"
|
||||
|
||||
#include "nsArrayUtils.h"
|
||||
@ -217,6 +218,10 @@ nsAccessiblePivot::MoveNext(nsIAccessibleTraversalRule* aRule, bool* aResult)
|
||||
NS_ENSURE_ARG(aResult);
|
||||
NS_ENSURE_ARG(aRule);
|
||||
|
||||
if (mPosition && (mPosition->IsDefunct() ||
|
||||
!mPosition->Document()->IsInDocument(mPosition)))
|
||||
return NS_ERROR_NOT_IN_TREE;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsAccessible* accessible = SearchForward(mPosition, aRule, false, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -234,6 +239,10 @@ nsAccessiblePivot::MovePrevious(nsIAccessibleTraversalRule* aRule, bool* aResult
|
||||
NS_ENSURE_ARG(aResult);
|
||||
NS_ENSURE_ARG(aRule);
|
||||
|
||||
if (mPosition && (mPosition->IsDefunct() ||
|
||||
!mPosition->Document()->IsInDocument(mPosition)))
|
||||
return NS_ERROR_NOT_IN_TREE;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsAccessible* accessible = SearchBackward(mPosition, aRule, false, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -250,6 +259,10 @@ nsAccessiblePivot::MoveFirst(nsIAccessibleTraversalRule* aRule, bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG(aResult);
|
||||
NS_ENSURE_ARG(aRule);
|
||||
|
||||
if (mRoot && mRoot->IsDefunct())
|
||||
return NS_ERROR_NOT_IN_TREE;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsAccessible* accessible = SearchForward(mRoot, aRule, true, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -267,6 +280,9 @@ nsAccessiblePivot::MoveLast(nsIAccessibleTraversalRule* aRule, bool* aResult)
|
||||
NS_ENSURE_ARG(aResult);
|
||||
NS_ENSURE_ARG(aRule);
|
||||
|
||||
if (mRoot && mRoot->IsDefunct())
|
||||
return NS_ERROR_NOT_IN_TREE;
|
||||
|
||||
*aResult = false;
|
||||
nsresult rv = NS_OK;
|
||||
nsAccessible* lastAccessible = mRoot;
|
||||
@ -334,6 +350,9 @@ nsAccessiblePivot::RemoveObserver(nsIAccessiblePivotObserver* aObserver)
|
||||
bool
|
||||
nsAccessiblePivot::IsRootDescendant(nsAccessible* aAccessible)
|
||||
{
|
||||
if (!mRoot || mRoot->IsDefunct())
|
||||
return false;
|
||||
|
||||
nsAccessible* accessible = aAccessible;
|
||||
do {
|
||||
if (accessible == mRoot)
|
||||
|
@ -49,6 +49,10 @@
|
||||
class nsAccessible;
|
||||
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.
|
||||
*/
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "States.h"
|
||||
|
||||
#include "nsBlockFrame.h"
|
||||
#include "nsBulletFrame.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
@ -85,15 +86,15 @@ HTMLLIAccessible::GetBounds(PRInt32* aX, PRInt32* aY,
|
||||
PRInt32* aWidth, PRInt32* aHeight)
|
||||
{
|
||||
nsresult rv = nsAccessibleWrap::GetBounds(aX, aY, aWidth, aHeight);
|
||||
if (NS_FAILED(rv) || !mBullet)
|
||||
if (NS_FAILED(rv) || !mBullet || mBullet->IsInside())
|
||||
return rv;
|
||||
|
||||
PRInt32 bulletX = 0, bulletY = 0, bulletWidth = 0, bulletHeight = 0;
|
||||
rv = mBullet->GetBounds(&bulletX, &bulletY, &bulletWidth, &bulletHeight);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aWidth += *aX - bulletX;
|
||||
*aX = bulletX; // Move x coordinate of list item over to cover bullet as well
|
||||
*aWidth += bulletWidth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -144,6 +145,13 @@ HTMLLIAccessible::CacheChildren()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// HTMLListBulletAccessible: nsAccessNode
|
||||
|
||||
nsIFrame*
|
||||
HTMLListBulletAccessible::GetFrame() const
|
||||
{
|
||||
nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
|
||||
return blockFrame ? blockFrame->GetBullet() : nsnull;
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLListBulletAccessible::IsPrimaryForNode() const
|
||||
{
|
||||
@ -199,3 +207,13 @@ HTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
|
||||
aText.Append(Substring(bulletText, aStartOffset, aLength));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// HTMLListBulletAccessible: public
|
||||
|
||||
bool
|
||||
HTMLListBulletAccessible::IsInside() const
|
||||
{
|
||||
nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
|
||||
return blockFrame ? blockFrame->HasInsideBullet() : false;
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ public:
|
||||
virtual ~HTMLListBulletAccessible() { }
|
||||
|
||||
// nsAccessNode
|
||||
virtual nsIFrame* GetFrame() const;
|
||||
virtual bool IsPrimaryForNode() const;
|
||||
|
||||
// nsAccessible
|
||||
@ -88,6 +89,13 @@ public:
|
||||
virtual PRUint64 NativeState();
|
||||
virtual void AppendTextTo(nsAString& aText, PRUint32 aStartOffset = 0,
|
||||
PRUint32 aLength = PR_UINT32_MAX);
|
||||
|
||||
// HTMLListBulletAccessible
|
||||
|
||||
/**
|
||||
* Return true if the bullet is inside of list item element boundaries.
|
||||
*/
|
||||
bool IsInside() const;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
|
@ -48,14 +48,14 @@ var AccessFu = {
|
||||
} catch (x) {
|
||||
}
|
||||
|
||||
this.processPreferences(accessPref);
|
||||
this._processPreferences(accessPref);
|
||||
},
|
||||
|
||||
/**
|
||||
* Start AccessFu mode, this primarily means controlling the virtual cursor
|
||||
* with arrow keys.
|
||||
*/
|
||||
enable: function enable() {
|
||||
_enable: function _enable() {
|
||||
if (this._enabled)
|
||||
return;
|
||||
this._enabled = true;
|
||||
@ -79,7 +79,7 @@ var AccessFu = {
|
||||
/**
|
||||
* Disable AccessFu and return to default interaction mode.
|
||||
*/
|
||||
disable: function disable() {
|
||||
_disable: function _disable() {
|
||||
if (!this._enabled)
|
||||
return;
|
||||
this._enabled = false;
|
||||
@ -98,7 +98,7 @@ var AccessFu = {
|
||||
this.chromeWin.removeEventListener('TabOpen', this, true);
|
||||
},
|
||||
|
||||
processPreferences: function processPreferences(aPref) {
|
||||
_processPreferences: function _processPreferences(aPref) {
|
||||
if (Services.appinfo.OS == 'Android') {
|
||||
if (aPref == ACCESSFU_AUTO) {
|
||||
if (!this._observingSystemSettings) {
|
||||
@ -118,9 +118,9 @@ var AccessFu = {
|
||||
}
|
||||
|
||||
if (aPref == ACCESSFU_ENABLE)
|
||||
this.enable();
|
||||
this._enable();
|
||||
else
|
||||
this.disable();
|
||||
this._disable();
|
||||
},
|
||||
|
||||
addPresenter: function addPresenter(presenter) {
|
||||
@ -171,19 +171,19 @@ var AccessFu = {
|
||||
switch (aTopic) {
|
||||
case 'Accessibility:Settings':
|
||||
if (JSON.parse(aData).enabled)
|
||||
this.enable();
|
||||
this._enable();
|
||||
else
|
||||
this.disable();
|
||||
this._disable();
|
||||
break;
|
||||
case 'nsPref:changed':
|
||||
if (aData == 'accessfu')
|
||||
this.processPreferences(this.prefsBranch.getIntPref('accessfu'));
|
||||
this._processPreferences(this.prefsBranch.getIntPref('accessfu'));
|
||||
break;
|
||||
case 'accessible-event':
|
||||
let event;
|
||||
try {
|
||||
event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
|
||||
this.handleAccEvent(event);
|
||||
this._handleAccEvent(event);
|
||||
} catch (ex) {
|
||||
dump(ex);
|
||||
return;
|
||||
@ -191,7 +191,7 @@ var AccessFu = {
|
||||
}
|
||||
},
|
||||
|
||||
handleAccEvent: function handleAccEvent(aEvent) {
|
||||
_handleAccEvent: function _handleAccEvent(aEvent) {
|
||||
switch (aEvent.eventType) {
|
||||
case Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED:
|
||||
{
|
||||
@ -251,13 +251,13 @@ var AccessFu = {
|
||||
let state = {};
|
||||
docAcc.getState(state, {});
|
||||
if (state.value & Ci.nsIAccessibleStates.STATE_BUSY &&
|
||||
this.isNotChromeDoc(docAcc))
|
||||
this._isNotChromeDoc(docAcc))
|
||||
this.presenters.forEach(
|
||||
function(p) { p.tabStateChanged(docAcc, 'loading'); }
|
||||
);
|
||||
delete this._pendingDocuments[aEvent.DOMNode];
|
||||
}
|
||||
if (this.isBrowserDoc(docAcc))
|
||||
if (this._isBrowserDoc(docAcc))
|
||||
// A new top-level content document has been attached
|
||||
this.presenters.forEach(
|
||||
function(p) { p.tabStateChanged(docAcc, 'newdoc'); }
|
||||
@ -267,7 +267,7 @@ var AccessFu = {
|
||||
}
|
||||
case Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE:
|
||||
{
|
||||
if (this.isNotChromeDoc(aEvent.accessible)) {
|
||||
if (this._isNotChromeDoc(aEvent.accessible)) {
|
||||
this.presenters.forEach(
|
||||
function(p) {
|
||||
p.tabStateChanged(aEvent.accessible, 'loaded');
|
||||
@ -296,7 +296,7 @@ var AccessFu = {
|
||||
}
|
||||
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.
|
||||
this.presenters.forEach(
|
||||
function(p) { p.tabSelected(aEvent.accessible); });
|
||||
@ -342,7 +342,7 @@ var AccessFu = {
|
||||
* @param {nsIAccessible} aDocAcc the accessible to check.
|
||||
* @return {boolean} true if this is a top-level content document.
|
||||
*/
|
||||
isBrowserDoc: function isBrowserDoc(aDocAcc) {
|
||||
_isBrowserDoc: function _isBrowserDoc(aDocAcc) {
|
||||
let parent = aDocAcc.parent;
|
||||
if (!parent)
|
||||
return false;
|
||||
@ -360,7 +360,7 @@ var AccessFu = {
|
||||
* @param {nsIDOMDocument} aDocument the document to check.
|
||||
* @return {boolean} true if this is not a chrome document.
|
||||
*/
|
||||
isNotChromeDoc: function isNotChromeDoc(aDocument) {
|
||||
_isNotChromeDoc: function _isNotChromeDoc(aDocument) {
|
||||
let location = aDocument.DOMNode.location;
|
||||
if (!location)
|
||||
return false;
|
||||
|
@ -52,7 +52,9 @@ Presenter.prototype = {
|
||||
/**
|
||||
* 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.
|
||||
@ -95,228 +97,236 @@ Presenter.prototype = {
|
||||
|
||||
function VisualPresenter() {}
|
||||
|
||||
VisualPresenter.prototype = new Presenter();
|
||||
VisualPresenter.prototype = {
|
||||
__proto__: Presenter.prototype,
|
||||
|
||||
/**
|
||||
* The padding in pixels between the object and the highlight border.
|
||||
*/
|
||||
VisualPresenter.prototype.BORDER_PADDING = 2;
|
||||
/**
|
||||
* The padding in pixels between the object and the highlight border.
|
||||
*/
|
||||
BORDER_PADDING: 2,
|
||||
|
||||
VisualPresenter.prototype.attach = function(aWindow) {
|
||||
this.chromeWin = aWindow;
|
||||
attach: function VisualPresenter_attach(aWindow) {
|
||||
this.chromeWin = aWindow;
|
||||
|
||||
// Add stylesheet
|
||||
let stylesheetURL = 'chrome://global/content/accessibility/AccessFu.css';
|
||||
this.stylesheet = aWindow.document.createProcessingInstruction(
|
||||
'xml-stylesheet', 'href="' + stylesheetURL + '" type="text/css"');
|
||||
aWindow.document.insertBefore(this.stylesheet, aWindow.document.firstChild);
|
||||
// Add stylesheet
|
||||
let stylesheetURL = 'chrome://global/content/accessibility/AccessFu.css';
|
||||
this.stylesheet = aWindow.document.createProcessingInstruction(
|
||||
'xml-stylesheet', 'href="' + stylesheetURL + '" type="text/css"');
|
||||
aWindow.document.insertBefore(this.stylesheet, aWindow.document.firstChild);
|
||||
|
||||
// Add highlight box
|
||||
this.highlightBox = this.chromeWin.document.
|
||||
createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
||||
this.chromeWin.document.documentElement.appendChild(this.highlightBox);
|
||||
this.highlightBox.id = 'virtual-cursor-box';
|
||||
// Add highlight box
|
||||
this.highlightBox = this.chromeWin.document.
|
||||
createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
||||
this.chromeWin.document.documentElement.appendChild(this.highlightBox);
|
||||
this.highlightBox.id = 'virtual-cursor-box';
|
||||
|
||||
// Add highlight inset for inner shadow
|
||||
let inset = this.chromeWin.document.
|
||||
createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
||||
inset.id = 'virtual-cursor-inset';
|
||||
// Add highlight inset for inner shadow
|
||||
let inset = this.chromeWin.document.
|
||||
createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
||||
inset.id = 'virtual-cursor-inset';
|
||||
|
||||
this.highlightBox.appendChild(inset);
|
||||
};
|
||||
this.highlightBox.appendChild(inset);
|
||||
},
|
||||
|
||||
VisualPresenter.prototype.detach = function() {
|
||||
this.chromeWin.document.removeChild(this.stylesheet);
|
||||
this.highlightBox.parentNode.removeChild(this.highlightBox);
|
||||
this.highlightBox = this.stylesheet = null;
|
||||
};
|
||||
detach: function VisualPresenter_detach() {
|
||||
this.chromeWin.document.removeChild(this.stylesheet);
|
||||
this.highlightBox.parentNode.removeChild(this.highlightBox);
|
||||
this.highlightBox = this.stylesheet = null;
|
||||
},
|
||||
|
||||
VisualPresenter.prototype.viewportChanged = function() {
|
||||
if (this._currentObject)
|
||||
this.highlight(this._currentObject);
|
||||
};
|
||||
viewportChanged: function VisualPresenter_viewportChanged() {
|
||||
if (this._currentObject)
|
||||
this._highlight(this._currentObject);
|
||||
},
|
||||
|
||||
VisualPresenter.prototype.pivotChanged = function(aObject, aNewContext) {
|
||||
this._currentObject = aObject;
|
||||
pivotChanged: function VisualPresenter_pivotChanged(aObject, aNewContext) {
|
||||
this._currentObject = aObject;
|
||||
|
||||
if (!aObject) {
|
||||
this.hide();
|
||||
return;
|
||||
if (!aObject) {
|
||||
this._hide();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
aObject.scrollTo(Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
|
||||
this._highlight(aObject);
|
||||
} catch (e) {
|
||||
dump('Error getting bounds: ' + e);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
tabSelected: function VisualPresenter_tabSelected(aDocObj) {
|
||||
let vcPos = aDocObj ? aDocObj.QueryInterface(Ci.nsIAccessibleCursorable).
|
||||
virtualCursor.position : null;
|
||||
|
||||
this.pivotChanged(vcPos);
|
||||
},
|
||||
|
||||
tabStateChanged: function VisualPresenter_tabStateChanged(aDocObj,
|
||||
aPageState) {
|
||||
if (aPageState == 'newdoc')
|
||||
this.pivotChanged(null);
|
||||
},
|
||||
|
||||
// Internals
|
||||
|
||||
_hide: function _hide() {
|
||||
this.highlightBox.style.display = 'none';
|
||||
},
|
||||
|
||||
_highlight: function _highlight(aObject) {
|
||||
let vp = (Services.appinfo.OS == 'Android') ?
|
||||
this.chromeWin.BrowserApp.selectedTab.getViewport() :
|
||||
{ zoom: 1.0, offsetY: 0 };
|
||||
|
||||
let bounds = this._getBounds(aObject, vp.zoom);
|
||||
|
||||
// First hide it to avoid flickering when changing the style.
|
||||
this.highlightBox.style.display = 'none';
|
||||
this.highlightBox.style.top = bounds.top + 'px';
|
||||
this.highlightBox.style.left = bounds.left + 'px';
|
||||
this.highlightBox.style.width = bounds.width + 'px';
|
||||
this.highlightBox.style.height = bounds.height + 'px';
|
||||
this.highlightBox.style.display = 'block';
|
||||
},
|
||||
|
||||
_getBounds: function _getBounds(aObject, aZoom, aStart, aEnd) {
|
||||
let objX = {}, objY = {}, objW = {}, objH = {};
|
||||
|
||||
if (aEnd >= 0 && aStart >= 0 && aEnd != aStart) {
|
||||
// TODO: Get bounds for text ranges. Leaving this blank until we have
|
||||
// proper text navigation in the virtual cursor.
|
||||
}
|
||||
|
||||
aObject.getBounds(objX, objY, objW, objH);
|
||||
|
||||
// Can't specify relative coords in nsIAccessible.getBounds, so we do it.
|
||||
let docX = {}, docY = {};
|
||||
let docRoot = aObject.rootDocument.QueryInterface(Ci.nsIAccessible);
|
||||
docRoot.getBounds(docX, docY, {}, {});
|
||||
|
||||
let rv = {
|
||||
left: Math.round((objX.value - docX.value - this.BORDER_PADDING) * aZoom),
|
||||
top: Math.round((objY.value - docY.value - this.BORDER_PADDING) * aZoom),
|
||||
width: Math.round((objW.value + (this.BORDER_PADDING * 2)) * aZoom),
|
||||
height: Math.round((objH.value + (this.BORDER_PADDING * 2)) * aZoom)
|
||||
};
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
try {
|
||||
aObject.scrollTo(Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
|
||||
this.highlight(aObject);
|
||||
} catch (e) {
|
||||
dump('Error getting bounds: ' + e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
VisualPresenter.prototype.tabSelected = function(aDocObj) {
|
||||
let vcPos = aDocObj ?
|
||||
aDocObj.QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor.position :
|
||||
null;
|
||||
|
||||
this.pivotChanged(vcPos);
|
||||
};
|
||||
|
||||
VisualPresenter.prototype.tabStateChanged = function(aDocObj, aPageState) {
|
||||
if (aPageState == "newdoc")
|
||||
this.pivotChanged(null);
|
||||
};
|
||||
|
||||
// Internals
|
||||
|
||||
VisualPresenter.prototype.hide = function hide() {
|
||||
this.highlightBox.style.display = 'none';
|
||||
};
|
||||
|
||||
VisualPresenter.prototype.highlight = function(aObject) {
|
||||
let vp = (Services.appinfo.OS == 'Android') ?
|
||||
this.chromeWin.BrowserApp.selectedTab.getViewport() :
|
||||
{ zoom: 1.0, offsetY: 0 };
|
||||
|
||||
let bounds = this.getBounds(aObject, vp.zoom);
|
||||
|
||||
// First hide it to avoid flickering when changing the style.
|
||||
this.highlightBox.style.display = 'none';
|
||||
this.highlightBox.style.top = bounds.top + 'px';
|
||||
this.highlightBox.style.left = bounds.left + 'px';
|
||||
this.highlightBox.style.width = bounds.width + 'px';
|
||||
this.highlightBox.style.height = bounds.height + 'px';
|
||||
this.highlightBox.style.display = 'block';
|
||||
};
|
||||
|
||||
VisualPresenter.prototype.getBounds = function(aObject, aZoom, aStart, aEnd) {
|
||||
let objX = {}, objY = {}, objW = {}, objH = {};
|
||||
|
||||
if (aEnd >= 0 && aStart >= 0 && aEnd != aStart) {
|
||||
// TODO: Get bounds for text ranges. Leaving this blank until we have
|
||||
// proper text navigation in the virtual cursor.
|
||||
}
|
||||
|
||||
aObject.getBounds(objX, objY, objW, objH);
|
||||
|
||||
// Can't specify relative coords in nsIAccessible.getBounds, so we do it.
|
||||
let docX = {}, docY = {};
|
||||
let docRoot = aObject.rootDocument.QueryInterface(Ci.nsIAccessible);
|
||||
docRoot.getBounds(docX, docY, {}, {});
|
||||
|
||||
let rv = {
|
||||
left: Math.round((objX.value - docX.value - this.BORDER_PADDING) * aZoom),
|
||||
top: Math.round((objY.value - docY.value - this.BORDER_PADDING) * aZoom),
|
||||
width: Math.round((objW.value + (this.BORDER_PADDING * 2)) * aZoom),
|
||||
height: Math.round((objH.value + (this.BORDER_PADDING * 2)) * aZoom)
|
||||
};
|
||||
|
||||
return rv;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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() {}
|
||||
|
||||
AndroidPresenter.prototype = new Presenter();
|
||||
AndroidPresenter.prototype = {
|
||||
__proto__: Presenter.prototype,
|
||||
|
||||
// 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 = [];
|
||||
for (let i in aNewContext)
|
||||
output.push.apply(output,
|
||||
UtteranceGenerator.genForObject(aNewContext[i]));
|
||||
|
||||
AndroidPresenter.prototype.pivotChanged = function(aObject, aNewContext) {
|
||||
let output = [];
|
||||
for (let i in aNewContext)
|
||||
output.push.apply(output,
|
||||
UtteranceGenerator.genForObject(aNewContext[i]));
|
||||
UtteranceGenerator.genForObject(aObject, true));
|
||||
|
||||
output.push.apply(output,
|
||||
UtteranceGenerator.genForObject(aObject, true));
|
||||
this.sendMessageToJava({
|
||||
gecko: {
|
||||
type: 'Accessibility:Event',
|
||||
eventType: this.ANDROID_VIEW_FOCUSED,
|
||||
text: output
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
this.sendMessageToJava({
|
||||
gecko: {
|
||||
type: 'Accessibility:Event',
|
||||
eventType: ANDROID_TYPE_VIEW_FOCUSED,
|
||||
text: output
|
||||
actionInvoked: function AndroidPresenter_actionInvoked(aObject, aActionName) {
|
||||
this.sendMessageToJava({
|
||||
gecko: {
|
||||
type: 'Accessibility:Event',
|
||||
eventType: this.ANDROID_VIEW_CLICKED,
|
||||
text: UtteranceGenerator.genForAction(aObject, aActionName)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
tabSelected: function AndroidPresenter_tabSelected(aDocObj) {
|
||||
// Send a pivot change message with the full context utterance for this doc.
|
||||
let vcDoc = aDocObj.QueryInterface(Ci.nsIAccessibleCursorable);
|
||||
let context = [];
|
||||
|
||||
let parent = vcDoc.virtualCursor.position || aDocObj;
|
||||
while ((parent = parent.parent)) {
|
||||
context.push(parent);
|
||||
if (parent == aDocObj)
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
AndroidPresenter.prototype.actionInvoked = function(aObject, aActionName) {
|
||||
this.sendMessageToJava({
|
||||
gecko: {
|
||||
context.reverse();
|
||||
|
||||
this.pivotChanged(vcDoc.virtualCursor.position || aDocObj, context);
|
||||
},
|
||||
|
||||
tabStateChanged: function AndroidPresenter_tabStateChanged(aDocObj,
|
||||
aPageState) {
|
||||
let stateUtterance = UtteranceGenerator.
|
||||
genForTabStateChange(aDocObj, aPageState);
|
||||
|
||||
if (!stateUtterance.length)
|
||||
return;
|
||||
|
||||
this.sendMessageToJava({
|
||||
gecko: {
|
||||
type: 'Accessibility:Event',
|
||||
eventType: this.ANDROID_VIEW_TEXT_CHANGED,
|
||||
text: stateUtterance,
|
||||
addedCount: stateUtterance.join(' ').length,
|
||||
removedCount: 0,
|
||||
fromIndex: 0
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
textChanged: function AndroidPresenter_textChanged(aIsInserted, aStart,
|
||||
aLength, aText,
|
||||
aModifiedText) {
|
||||
let androidEvent = {
|
||||
type: 'Accessibility:Event',
|
||||
eventType: ANDROID_TYPE_VIEW_CLICKED,
|
||||
text: UtteranceGenerator.genForAction(aObject, aActionName)
|
||||
eventType: this.ANDROID_VIEW_TEXT_CHANGED,
|
||||
text: [aText],
|
||||
fromIndex: aStart
|
||||
};
|
||||
|
||||
if (aIsInserted) {
|
||||
androidEvent.addedCount = aLength;
|
||||
androidEvent.beforeText =
|
||||
aText.substring(0, aStart) + aText.substring(aStart + aLength);
|
||||
} else {
|
||||
androidEvent.removedCount = aLength;
|
||||
androidEvent.beforeText =
|
||||
aText.substring(0, aStart) + aModifiedText + aText.substring(aStart);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
AndroidPresenter.prototype.tabSelected = function(aDocObj) {
|
||||
// Send a pivot change message with the full context utterance for this doc.
|
||||
let vcDoc = aDocObj.QueryInterface(Ci.nsIAccessibleCursorable);
|
||||
let context = [];
|
||||
this.sendMessageToJava({gecko: androidEvent});
|
||||
},
|
||||
|
||||
let parent = vcDoc.virtualCursor.position || aDocObj;
|
||||
while ((parent = parent.parent)) {
|
||||
context.push(parent);
|
||||
if (parent == aDocObj)
|
||||
break;
|
||||
sendMessageToJava: function AndroidPresenter_sendMessageTojava(aMessage) {
|
||||
return Cc['@mozilla.org/android/bridge;1'].
|
||||
getService(Ci.nsIAndroidBridge).
|
||||
handleGeckoMessage(JSON.stringify(aMessage));
|
||||
}
|
||||
|
||||
context.reverse();
|
||||
|
||||
this.pivotChanged(vcDoc.virtualCursor.position || aDocObj, context);
|
||||
};
|
||||
|
||||
AndroidPresenter.prototype.tabStateChanged = function(aDocObj, aPageState) {
|
||||
let stateUtterance = UtteranceGenerator.
|
||||
genForTabStateChange(aDocObj, aPageState);
|
||||
|
||||
if (!stateUtterance.length)
|
||||
return;
|
||||
|
||||
this.sendMessageToJava({
|
||||
gecko: {
|
||||
type: 'Accessibility:Event',
|
||||
eventType: ANDROID_TYPE_VIEW_TEXT_CHANGED,
|
||||
text: stateUtterance,
|
||||
addedCount: stateUtterance.join(' ').length,
|
||||
removedCount: 0,
|
||||
fromIndex: 0
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
AndroidPresenter.prototype.textChanged = function(aIsInserted, aStart, aLength, aText, aModifiedText) {
|
||||
let androidEvent = {
|
||||
type: 'Accessibility:Event',
|
||||
eventType: ANDROID_TYPE_VIEW_TEXT_CHANGED,
|
||||
text: [aText],
|
||||
fromIndex: aStart
|
||||
};
|
||||
|
||||
if (aIsInserted) {
|
||||
androidEvent.addedCount = aLength;
|
||||
androidEvent.beforeText =
|
||||
aText.substring(0, aStart) + aText.substring(aStart + aLength);
|
||||
} else {
|
||||
androidEvent.removedCount = aLength;
|
||||
androidEvent.beforeText =
|
||||
aText.substring(0, aStart) + aModifiedText + aText.substring(aStart);
|
||||
}
|
||||
|
||||
this.sendMessageToJava({gecko: androidEvent});
|
||||
};
|
||||
|
||||
AndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
|
||||
return Cc['@mozilla.org/android/bridge;1'].
|
||||
getService(Ci.nsIAndroidBridge).
|
||||
handleGeckoMessage(JSON.stringify(aMessage));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -325,8 +335,10 @@ AndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
|
||||
|
||||
function DummyAndroidPresenter() {}
|
||||
|
||||
DummyAndroidPresenter.prototype = new AndroidPresenter();
|
||||
DummyAndroidPresenter.prototype = {
|
||||
__proto__: AndroidPresenter.prototype,
|
||||
|
||||
DummyAndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
|
||||
dump(JSON.stringify(aMessage, null, 2) + '\n');
|
||||
sendMessageToJava: function DummyAndroidPresenter_sendMessageToJava(aMsg) {
|
||||
dump(JSON.stringify(aMsg, null, 2) + '\n');
|
||||
}
|
||||
};
|
||||
|
@ -65,10 +65,10 @@ var UtteranceGenerator = {
|
||||
* @return {Array} Two string array. The first string describes the 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
|
||||
* is returned as a placeholder. Whether the object's description or it's role
|
||||
* is included is determined by {@link verbosityRoleMap}.
|
||||
* is returned as a placeholder. Whether the object's description or it's
|
||||
* role is included is determined by {@link verbosityRoleMap}.
|
||||
*/
|
||||
genForObject: function(aAccessible, aForceName) {
|
||||
genForObject: function genForObject(aAccessible, aForceName) {
|
||||
let roleString = gAccRetrieval.getStringRole(aAccessible.role);
|
||||
|
||||
let func = this.objectUtteranceFunctions[roleString] ||
|
||||
@ -91,7 +91,7 @@ var UtteranceGenerator = {
|
||||
* {@link gActionMap}.
|
||||
* @return {Array} A one string array with the action.
|
||||
*/
|
||||
genForAction: function(aObject, aActionName) {
|
||||
genForAction: function genForAction(aObject, aActionName) {
|
||||
return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])];
|
||||
},
|
||||
|
||||
@ -103,7 +103,7 @@ var UtteranceGenerator = {
|
||||
* {@link Presenter.tabStateChanged}.
|
||||
* @return {Array} The tab state utterace.
|
||||
*/
|
||||
genForTabStateChange: function (aObject, aTabState) {
|
||||
genForTabStateChange: function genForTabStateChange(aObject, aTabState) {
|
||||
switch (aTabState) {
|
||||
case 'newtab':
|
||||
return [gStringBundle.GetStringFromName('tabNew')];
|
||||
@ -177,7 +177,8 @@ var UtteranceGenerator = {
|
||||
objectUtteranceFunctions: {
|
||||
defaultFunc: function defaultFunc(aAccessible, aRoleStr, aFlags) {
|
||||
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 = [];
|
||||
|
||||
@ -207,7 +208,7 @@ var UtteranceGenerator = {
|
||||
return utterance;
|
||||
},
|
||||
|
||||
heading: function(aAccessible, aRoleStr, aFlags) {
|
||||
heading: function heading(aAccessible, aRoleStr, aFlags) {
|
||||
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
||||
let level = {};
|
||||
aAccessible.groupPosition(level, {}, {});
|
||||
@ -220,7 +221,7 @@ var UtteranceGenerator = {
|
||||
return utterance;
|
||||
},
|
||||
|
||||
listitem: function(aAccessible, aRoleStr, aFlags) {
|
||||
listitem: function listitem(aAccessible, aRoleStr, aFlags) {
|
||||
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
||||
let localizedRole = this._getLocalizedRole(aRoleStr);
|
||||
let itemno = {};
|
||||
|
@ -20,14 +20,15 @@ var gAccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
|
||||
var VirtualCursorController = {
|
||||
attach: function attach(aWindow) {
|
||||
this.chromeWin = aWindow;
|
||||
this.chromeWin.document.addEventListener('keypress', this.onkeypress, true);
|
||||
this.chromeWin.document.addEventListener('keypress', this._onkeypress, true);
|
||||
},
|
||||
|
||||
detach: function detach() {
|
||||
this.chromeWin.document.removeEventListener('keypress', this.onkeypress, true);
|
||||
this.chromeWin.document.removeEventListener('keypress', this._onkeypress,
|
||||
true);
|
||||
},
|
||||
|
||||
getBrowserApp: function getBrowserApp() {
|
||||
_getBrowserApp: function _getBrowserApp() {
|
||||
switch (Services.appinfo.OS) {
|
||||
case 'Android':
|
||||
return this.chromeWin.BrowserApp;
|
||||
@ -36,8 +37,8 @@ var VirtualCursorController = {
|
||||
}
|
||||
},
|
||||
|
||||
onkeypress: function onkeypress(aEvent) {
|
||||
let document = VirtualCursorController.getBrowserApp().
|
||||
_onkeypress: function _onkeypress(aEvent) {
|
||||
let document = VirtualCursorController._getBrowserApp().
|
||||
selectedBrowser.contentDocument;
|
||||
|
||||
dump('keypress ' + aEvent.keyCode + '\n');
|
||||
@ -57,7 +58,7 @@ var VirtualCursorController = {
|
||||
break;
|
||||
case aEvent.DOM_VK_UP:
|
||||
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'].
|
||||
getService(Ci.nsIAndroidBridge).handleGeckoMessage(
|
||||
JSON.stringify({ gecko: { type: 'ToggleChrome:Focus' } }));
|
||||
@ -110,7 +111,7 @@ var VirtualCursorController = {
|
||||
},
|
||||
|
||||
SimpleTraversalRule: {
|
||||
getMatchRoles: function(aRules) {
|
||||
getMatchRoles: function SimpleTraversalRule_getmatchRoles(aRules) {
|
||||
aRules.value = this._matchRoles;
|
||||
return this._matchRoles.length;
|
||||
},
|
||||
@ -118,7 +119,7 @@ var VirtualCursorController = {
|
||||
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
|
||||
|
||||
match: function(aAccessible) {
|
||||
match: function SimpleTraversalRule_match(aAccessible) {
|
||||
switch (aAccessible.role) {
|
||||
case Ci.nsIAccessibleRole.ROLE_COMBOBOX:
|
||||
// We don't want to ignore the subtree because this is often
|
||||
|
@ -46,6 +46,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES =\
|
||||
test_list.html \
|
||||
test_select.html \
|
||||
test_zoom.html \
|
||||
$(NULL)
|
||||
|
81
accessible/tests/mochitest/bounds/test_list.html
Normal file
@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Accessible boundaries when page is zoomed</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../layout.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
// Inside list
|
||||
var li = getAccessible("insidelist_item");
|
||||
testBounds(li);
|
||||
|
||||
var [xLI, yLI, widthLI, heightLI] = getBounds(li);
|
||||
var bullet = li.firstChild;
|
||||
var [x, y, width, height] = getBounds(bullet);
|
||||
is(x, xLI,
|
||||
"Bullet x should match to list item x");
|
||||
ok(y >= yLI,
|
||||
"Bullet y= " + y + " should be not less than list item y=" + yLI);
|
||||
ok(width < widthLI,
|
||||
"Bullet width should be lesser list item width");
|
||||
ok(height <= heightLI,
|
||||
"Bullet height= " + height + " should be not greater than list item height=" + heightLI);
|
||||
|
||||
// Outside list
|
||||
li = getAccessible("outsidelist_item");
|
||||
var [xLIElm, yLIElm, widthLIElm, heightLIElm] = getBoundsForDOMElm(li);
|
||||
[xLI, yLI, widthLI, heightLI] = getBounds(li);
|
||||
|
||||
ok(xLI < xLIElm,
|
||||
"Outside list item x=" + xLI + " should be lesser than list item element x=" + xLIElm);
|
||||
is(yLI, yLIElm,
|
||||
"Outside list item y should match to list item element y");
|
||||
ok(widthLI > widthLIElm,
|
||||
"Outside list item width=" + widthLI + " should be greater than list item element width=" + widthLIElm);
|
||||
is(heightLI, heightLIElm,
|
||||
"Outside list item height should match to list item element height");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=754627"
|
||||
title="GetBounds on bullet return wrong values">
|
||||
Mozilla Bug 754627
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<ul style="list-style-position: inside;">
|
||||
<li id="insidelist_item">item</li>
|
||||
</ul>
|
||||
|
||||
<ul style="list-style-position: outside;">
|
||||
<li id="outsidelist_item">item</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -8,6 +8,8 @@ const FILTER_MATCH = nsIAccessibleTraversalRule.FILTER_MATCH;
|
||||
const FILTER_IGNORE = nsIAccessibleTraversalRule.FILTER_IGNORE;
|
||||
const FILTER_IGNORE_SUBTREE = nsIAccessibleTraversalRule.FILTER_IGNORE_SUBTREE;
|
||||
|
||||
const NS_ERROR_NOT_IN_TREE = 0x80780026;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Traversal rules
|
||||
|
||||
@ -68,13 +70,13 @@ var ObjectTraversalRule =
|
||||
/**
|
||||
* 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.check = function virtualCursorChangedChecker_check(aEvent)
|
||||
this.check = function VCChangedChecker_check(aEvent)
|
||||
{
|
||||
SimpleTest.info("virtualCursorChangedChecker_check");
|
||||
SimpleTest.info("VCChangedChecker_check");
|
||||
|
||||
var event = null;
|
||||
try {
|
||||
@ -100,7 +102,7 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
|
||||
"wrong end offset");
|
||||
}
|
||||
|
||||
var prevPosAndOffset = virtualCursorChangedChecker.
|
||||
var prevPosAndOffset = VCChangedChecker.
|
||||
getPreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||
|
||||
if (prevPosAndOffset) {
|
||||
@ -114,36 +116,36 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
|
||||
};
|
||||
}
|
||||
|
||||
virtualCursorChangedChecker.prevPosAndOffset = {};
|
||||
VCChangedChecker.prevPosAndOffset = {};
|
||||
|
||||
virtualCursorChangedChecker.storePreviousPosAndOffset =
|
||||
VCChangedChecker.storePreviousPosAndOffset =
|
||||
function storePreviousPosAndOffset(aPivot)
|
||||
{
|
||||
virtualCursorChangedChecker.prevPosAndOffset[aPivot] =
|
||||
VCChangedChecker.prevPosAndOffset[aPivot] =
|
||||
{position: aPivot.position,
|
||||
startOffset: aPivot.startOffset,
|
||||
endOffset: aPivot.endOffset};
|
||||
};
|
||||
|
||||
virtualCursorChangedChecker.getPreviousPosAndOffset =
|
||||
VCChangedChecker.getPreviousPosAndOffset =
|
||||
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.
|
||||
*
|
||||
* @param aDocAcc document that manages the virtual cursor
|
||||
* @param aTextAccessible accessible to set to virtual cursor's position
|
||||
* @param aTextOffsets start and end offsets of text range to set in virtual
|
||||
* cursor
|
||||
* @param aDocAcc [in] document that manages the virtual cursor
|
||||
* @param aTextAccessible [in] accessible to set to virtual cursor's position
|
||||
* @param aTextOffsets [in] start and end offsets of text range to set in
|
||||
* virtual cursor.
|
||||
*/
|
||||
function setVirtualCursorRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||
function setVCRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||
{
|
||||
this.invoke = function virtualCursorChangedInvoker_invoke()
|
||||
{
|
||||
virtualCursorChangedChecker.
|
||||
VCChangedChecker.
|
||||
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||
SimpleTest.info(prettyName(aTextAccessible) + " " + aTextOffsets);
|
||||
aDocAcc.virtualCursor.setTextRange(aTextAccessible,
|
||||
@ -151,45 +153,44 @@ function setVirtualCursorRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||
aTextOffsets[1]);
|
||||
};
|
||||
|
||||
this.getID = function setVirtualCursorRangeInvoker_getID()
|
||||
this.getID = function setVCRangeInvoker_getID()
|
||||
{
|
||||
return "Set offset in " + prettyName(aTextAccessible) +
|
||||
" to (" + aTextOffsets[0] + ", " + aTextOffsets[1] + ")";
|
||||
}
|
||||
};
|
||||
|
||||
this.eventSeq = [
|
||||
new virtualCursorChangedChecker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||
new VCChangedChecker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the pivot and wait for virtual cursor change event.
|
||||
*
|
||||
* @param aDocAcc document that manages the virtual cursor
|
||||
* @param aPivotMoveMethod method to test (ie. "moveNext", "moveFirst", etc.)
|
||||
* @param aRule traversal rule object
|
||||
* @param aIdOrNameOrAcc id, accessivle or accessible name to expect virtual
|
||||
* cursor to land on after performing move method.
|
||||
* @param aDocAcc [in] document that manages the virtual cursor
|
||||
* @param aPivotMoveMethod [in] method to test (ie. "moveNext", "moveFirst", etc.)
|
||||
* @param aRule [in] traversal rule object
|
||||
* @param aIdOrNameOrAcc [in] id, accessivle or accessible name to expect
|
||||
* virtual cursor to land on after performing move method.
|
||||
*/
|
||||
function setVirtualCursorPosInvoker(aDocAcc, aPivotMoveMethod, aRule,
|
||||
aIdOrNameOrAcc)
|
||||
function setVCPosInvoker(aDocAcc, aPivotMoveMethod, aRule, aIdOrNameOrAcc)
|
||||
{
|
||||
this.invoke = function virtualCursorChangedInvoker_invoke()
|
||||
{
|
||||
virtualCursorChangedChecker.
|
||||
VCChangedChecker.
|
||||
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||
var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
|
||||
SimpleTest.ok((aIdOrNameOrAcc && moved) || (!aIdOrNameOrAcc && !moved),
|
||||
"moved pivot");
|
||||
};
|
||||
|
||||
this.getID = function setVirtualCursorPosInvoker_getID()
|
||||
this.getID = function setVCPosInvoker_getID()
|
||||
{
|
||||
return "Do " + (aIdOrNameOrAcc ? "" : "no-op ") + aPivotMoveMethod;
|
||||
}
|
||||
};
|
||||
|
||||
if (aIdOrNameOrAcc) {
|
||||
this.eventSeq = [ new virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc) ];
|
||||
this.eventSeq = [ new VCChangedChecker(aDocAcc, aIdOrNameOrAcc) ];
|
||||
} else {
|
||||
this.eventSeq = [];
|
||||
this.unexpectedEventSeq = [
|
||||
@ -202,45 +203,137 @@ function setVirtualCursorPosInvoker(aDocAcc, aPivotMoveMethod, aRule,
|
||||
* 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.
|
||||
*
|
||||
* @param aQueue event queue in which to push invoker sequence.
|
||||
* @param aDocAcc the managing document of the virtual cursor we are testing
|
||||
* @param aRule the traversal rule to use in the invokers
|
||||
* @param aSequence a sequence of accessible names or elemnt ids to expect with
|
||||
* the given rule in the given document
|
||||
* @param aQueue [in] event queue in which to push invoker sequence.
|
||||
* @param aDocAcc [in] the managing document of the virtual cursor we are testing
|
||||
* @param aRule [in] the traversal rule to use in the invokers
|
||||
* @param aSequence [in] a sequence of accessible names or elemnt ids to expect with
|
||||
* the given rule in the given document
|
||||
*/
|
||||
function queueTraversalSequence(aQueue, aDocAcc, aRule, aSequence)
|
||||
{
|
||||
aDocAcc.virtualCursor.position = null;
|
||||
|
||||
for (var i = 0; i < aSequence.length; i++) {
|
||||
var invoker = new setVirtualCursorPosInvoker(aDocAcc, "moveNext",
|
||||
aRule, aSequence[i]);
|
||||
var invoker =
|
||||
new setVCPosInvoker(aDocAcc, "moveNext", aRule, aSequence[i]);
|
||||
aQueue.push(invoker);
|
||||
}
|
||||
|
||||
// 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--) {
|
||||
var invoker = new setVirtualCursorPosInvoker(aDocAcc, "movePrevious",
|
||||
aRule, aSequence[i])
|
||||
var invoker =
|
||||
new setVCPosInvoker(aDocAcc, "movePrevious", aRule, aSequence[i]);
|
||||
aQueue.push(invoker);
|
||||
}
|
||||
|
||||
// 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(
|
||||
aDocAcc, "moveLast", aRule, aSequence[aSequence.length - 1]));
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "moveLast", aRule,
|
||||
aSequence[aSequence.length - 1]));
|
||||
|
||||
// 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(
|
||||
aDocAcc, "moveFirst", aRule, aSequence[0]));
|
||||
aQueue.push(new setVCPosInvoker(aDocAcc, "moveFirst", aRule, aSequence[0]));
|
||||
|
||||
// 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,10 +17,11 @@
|
||||
<iframe
|
||||
src="data:text/html,<html><body>An <i>embedded</i> document.</body></html>">
|
||||
</iframe>
|
||||
<p>
|
||||
<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 3 title">Link 3</a>
|
||||
</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 2 title">Link 2</a>
|
||||
<a href="http://mozilla.org" title="Link 3 title">Link 3</a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -60,15 +60,22 @@
|
||||
'dolor', ' sit amet. Integer vitae urna leo, id ',
|
||||
'semper', ' nulla. ', 'Second Section Title',
|
||||
'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.
|
||||
gQueue.push(
|
||||
new setVirtualCursorRangeInvoker(
|
||||
new setVCRangeInvoker(
|
||||
docAcc,
|
||||
getAccessible(doc.getElementById('paragraph-2'), nsIAccessibleText),
|
||||
[2,6]));
|
||||
|
||||
gQueue.push(new removeVCPositionInvoker(
|
||||
docAcc, doc.getElementById('hide-me')));
|
||||
|
||||
gQueue.push(new removeVCRootInvoker(
|
||||
doc.getElementById('links')));
|
||||
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
||||
|
@ -186,8 +186,6 @@ ifdef MOZ_DEBUG
|
||||
MAC_APP_NAME := $(MAC_APP_NAME)Debug
|
||||
endif
|
||||
|
||||
LOWER_MAC_APP_NAME = $(shell echo $(MAC_APP_NAME) | tr '[A-Z]' '[a-z]')
|
||||
|
||||
AB_CD = $(MOZ_UI_LOCALE)
|
||||
|
||||
AB := $(firstword $(subst -, ,$(AB_CD)))
|
||||
@ -201,6 +199,8 @@ else
|
||||
APPFILES = MacOS
|
||||
endif
|
||||
|
||||
MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/config/buildid)
|
||||
|
||||
libs-preqs = \
|
||||
$(call mkdir_deps,$(dist_dest)/Contents/MacOS) \
|
||||
$(call mkdir_deps,$(dist_dest)/Contents/Resources/$(AB).lproj) \
|
||||
@ -210,7 +210,7 @@ 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/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
|
||||
rsync -a $(DIST)/bin/ $(dist_dest)/Contents/$(APPFILES)
|
||||
ifdef LIBXUL_SDK
|
||||
|
@ -149,7 +149,7 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>firefox</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.mozilla.%LOWER_MAC_APP_NAME%</string>
|
||||
<string>%MOZ_MACBUNDLE_ID%</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
@ -200,7 +200,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>%APP_VERSION%</string>
|
||||
<string>%MAC_BUNDLE_VERSION%</string>
|
||||
<key>NSAppleScriptEnabled</key>
|
||||
<true/>
|
||||
<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;
|
||||
}
|
||||
|
||||
.text-link:-moz-focusring,
|
||||
.bottom-link:-moz-focusring {
|
||||
outline: 1px dotted;
|
||||
}
|
||||
|
||||
#currentChannel {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
@ -308,12 +308,30 @@
|
||||
</menu>
|
||||
#include browser-charsetmenu.inc
|
||||
<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"
|
||||
accesskey="&fullScreenCmd.accesskey;"
|
||||
label="&fullScreenCmd.label;"
|
||||
key="key_fullScreen"
|
||||
type="checkbox"
|
||||
observes="View:FullScreen"/>
|
||||
#endif
|
||||
<menuitem id="menu_showAllTabs"
|
||||
hidden="true"
|
||||
accesskey="&showAllTabsCmd.accesskey;"
|
||||
|
@ -341,7 +341,8 @@
|
||||
<key keycode="VK_F6" command="Browser:FocusNextFrame" modifiers="shift"/>
|
||||
<key id="key_fullScreen" keycode="VK_F11" command="View:FullScreen"/>
|
||||
#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"/>
|
||||
#endif
|
||||
<key key="&reloadCmd.commandkey;" command="Browser:Reload" modifiers="accel" id="key_reload"/>
|
||||
|
@ -3958,6 +3958,12 @@ var FullScreen = {
|
||||
// fullscreen menuitem, menubars, and the appmenu.
|
||||
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
|
||||
// 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
|
||||
|
@ -1126,58 +1126,34 @@
|
||||
|
||||
#ifndef XP_UNIX
|
||||
<svg:svg height="0">
|
||||
<svg:mask id="winstripe-keyhole-forward-mask" maskContentUnits="objectBoundingBox">
|
||||
<svg:rect x="0" y="0" width="1" height="1" fill="white"/>
|
||||
<svg:circle cx="-0.34" cy="0.5" r="0.61"/>
|
||||
</svg:mask>
|
||||
<svg:mask id="winstripe-urlbar-back-button-mask" maskContentUnits="userSpaceOnUse">
|
||||
<svg:rect x="0" y="0" width="10000" height="50" fill="white"/>
|
||||
<svg:circle cx="-11" cy="18" r="15"/>
|
||||
</svg:mask>
|
||||
<svg:clipPath id="winstripe-keyhole-forward-clip-path" clipPathUnits="objectBoundingBox">
|
||||
<svg:path d="M 0,0 C 0.16,0.11 0.28,0.29 0.28,0.5 0.28,0.71 0.16,0.89 0,1 L 1,1 1,0 0,0 z"/>
|
||||
</svg:clipPath>
|
||||
<svg:clipPath id="winstripe-urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
|
||||
<svg:path d="M 0,0 0,7.8 C 2.5,11 4,14 4,18 4,22 2.5,25 0,28 l 0,22 10000,0 0,-50 L 0,0 z"/>
|
||||
</svg:clipPath>
|
||||
</svg:svg>
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
<svg:svg height="0">
|
||||
<svg:mask id="pinstripe-keyhole-forward-mask" maskContentUnits="objectBoundingBox">
|
||||
<svg:rect x="0" y="0" width="1" height="1" fill="white"/>
|
||||
<svg:circle cx="-0.41" cy="0.5" r="0.65"/>
|
||||
</svg:mask>
|
||||
<svg:mask id="pinstripe-urlbar-back-button-mask" maskContentUnits="userSpaceOnUse">
|
||||
<svg:rect x="0" y="-5" width="10000" height="55" fill="white"/>
|
||||
<svg:circle cx="-9" cy="11" r="15"/>
|
||||
</svg:mask>
|
||||
<svg:mask id="pinstripe-tab-ontop-left-curve-mask" maskContentUnits="userSpaceOnUse">
|
||||
<svg:circle cx="9" cy="3" r="3" fill="white"/>
|
||||
<svg:rect x="9" y="0" width="3" height="3" fill="white"/>
|
||||
<svg:rect x="6" y="3" width="6" height="19" fill="white"/>
|
||||
<svg:rect x="1" y="17" width="5" height="5" fill="white"/>
|
||||
<svg:circle cx="1" cy="17" r="5"/>
|
||||
<svg:rect x="0" y="22" width="12" height="1" fill="white"/>
|
||||
</svg:mask>
|
||||
<svg:mask id="pinstripe-tab-ontop-right-curve-mask" maskContentUnits="userSpaceOnUse">
|
||||
<svg:circle cx="3" cy="3" r="3" fill="white"/>
|
||||
<svg:rect x="0" y="0" width="3" height="3" fill="white"/>
|
||||
<svg:rect x="0" y="3" width="6" height="19" fill="white"/>
|
||||
<svg:rect x="6" y="17" width="5" height="5" fill="white"/>
|
||||
<svg:circle cx="11" cy="17" r="5"/>
|
||||
<svg:rect x="0" y="22" width="12" height="1" fill="white"/>
|
||||
</svg:mask>
|
||||
<svg:mask id="pinstripe-tab-onbottom-left-curve-mask" maskContentUnits="userSpaceOnUse">
|
||||
<svg:circle cx="9" cy="20" r="3" fill="white"/>
|
||||
<svg:rect x="9" y="20" width="3" height="3" fill="white"/>
|
||||
<svg:rect x="6" y="1" width="6" height="19" fill="white"/>
|
||||
<svg:rect x="1" y="1" width="5" height="5" fill="white"/>
|
||||
<svg:circle cx="1" cy="6" r="5"/>
|
||||
<svg:rect x="0" y="0" width="12" height="1" fill="white"/>
|
||||
</svg:mask>
|
||||
<svg:mask id="pinstripe-tab-onbottom-right-curve-mask" maskContentUnits="userSpaceOnUse">
|
||||
<svg:circle cx="3" cy="20" r="3" fill="white"/>
|
||||
<svg:rect x="0" y="20" width="3" height="3" fill="white"/>
|
||||
<svg:rect x="0" y="1" width="6" height="19" fill="white"/>
|
||||
<svg:rect x="6" y="1" width="5" height="5" fill="white"/>
|
||||
<svg:circle cx="11" cy="6" r="5"/>
|
||||
<svg:rect x="0" y="0" width="12" height="1" fill="white"/>
|
||||
</svg:mask>
|
||||
<svg:clipPath id="pinstripe-keyhole-forward-clip-path" clipPathUnits="objectBoundingBox">
|
||||
<svg:path d="M 0,0 C 0.15,0.12 0.25,0.3 0.25,0.5 0.25,0.7 0.15,0.88 0,1 L 1,1 1,0 0,0 z"/>
|
||||
</svg:clipPath>
|
||||
<svg:clipPath id="pinstripe-urlbar-back-button-clip-path" clipPathUnits="userSpaceOnUse">
|
||||
<svg:path d="m 0,-5 0,4.03 C 3.6,1.8 6,6.1 6,11 6,16 3.6,20 0,23 l 0,27 10000,0 0,-55 L 0,-5 z"/>
|
||||
</svg:clipPath>
|
||||
<svg:clipPath id="pinstripe-tab-ontop-left-curve-clip-path" clipPathUnits="userSpaceOnUse">
|
||||
<svg:path d="M 9,0 C 7.3,0 6,1.3 6,3 l 0,14 c 0,3 -2.2,5 -5,5 l -1,0 0,1 12,0 0,-1 0,-19 0,-3 -3,0 z"/>
|
||||
</svg:clipPath>
|
||||
<svg:clipPath id="pinstripe-tab-ontop-right-curve-clip-path" clipPathUnits="userSpaceOnUse">
|
||||
<svg:path d="m 0,0 0,3 0,19 0,1 12,0 0,-1 -1,0 C 8.2,22 6,20 6,17 L 6,3 C 6,1.3 4.7,0 3,0 L 0,0 z"/>
|
||||
</svg:clipPath>
|
||||
<svg:clipPath id="pinstripe-tab-onbottom-left-curve-clip-path" clipPathUnits="userSpaceOnUse">
|
||||
<svg:path d="m 0,0 0,1 1,0 c 2.8,0 5,2.2 5,5 l 0,14 c 0,2 1.3,3 3,3 l 3,0 0,-3 L 12,1 12,0 0,0 z"/>
|
||||
</svg:clipPath>
|
||||
<svg:clipPath id="pinstripe-tab-onbottom-right-curve-clip-path" clipPathUnits="userSpaceOnUse">
|
||||
<svg:path d="m 0,0 0,1 0,19 0,3 3,0 c 1.7,0 3,-1 3,-3 L 6,6 C 6,3.2 8.2,1 11,1 L 12,1 12,0 0,0 z"/>
|
||||
</svg:clipPath>
|
||||
</svg:svg>
|
||||
#endif
|
||||
|
||||
|
@ -630,7 +630,7 @@
|
||||
if (topLevel) {
|
||||
// The document loaded correctly, clear the value if we should
|
||||
if (this.mBrowser.userTypedClear > 0 ||
|
||||
(aRequest && !Components.isSuccessCode(aRequest.status)))
|
||||
(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE))
|
||||
this.mBrowser.userTypedValue = null;
|
||||
|
||||
// Clear out the missing plugins list since it's related to the
|
||||
|
@ -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 formhist = Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
|
||||
|
||||
const kUsecPerMin = 60 * 1000000;
|
||||
|
||||
let tempScope = {};
|
||||
Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader)
|
||||
.loadSubScript("chrome://browser/content/sanitize.js", tempScope);
|
||||
let Sanitizer = tempScope.Sanitizer;
|
||||
|
||||
function test() {
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
setupDownloads();
|
||||
setupFormHistory();
|
||||
setupHistory(onHistoryReady);
|
||||
}
|
||||
|
||||
function onHistoryReady() {
|
||||
var hoursSinceMidnight = new Date().getHours();
|
||||
var minutesSinceMidnight = hoursSinceMidnight * 60 + new Date().getMinutes();
|
||||
|
||||
setupHistory();
|
||||
setupFormHistory();
|
||||
setupDownloads();
|
||||
|
||||
// Should test cookies here, but nsICookieManager/nsICookieService
|
||||
// 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");
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
function setupHistory() {
|
||||
bhist.addPageWithDetails(makeURI("http://10minutes.com/"), "10 minutes ago", now_uSec - 10*60*1000000);
|
||||
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);
|
||||
bhist.addPageWithDetails(makeURI("http://2hour.com/"), "Less than 2 hours ago", now_uSec - 90*60*1000000);
|
||||
bhist.addPageWithDetails(makeURI("http://2hour10minutes.com/"), "2 hours 10 minutes ago", now_uSec - 130*60*1000000);
|
||||
bhist.addPageWithDetails(makeURI("http://4hour.com/"), "Less than 4 hours ago", now_uSec - 180*60*1000000);
|
||||
bhist.addPageWithDetails(makeURI("http://4hour10minutes.com/"), "4 hours 10 minutesago", now_uSec - 250*60*1000000);
|
||||
|
||||
function setupHistory(aCallback) {
|
||||
let places = [];
|
||||
|
||||
function addPlace(aURI, aTitle, aVisitDate) {
|
||||
places.push({
|
||||
uri: aURI,
|
||||
title: aTitle,
|
||||
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();
|
||||
today.setHours(0);
|
||||
today.setMinutes(0);
|
||||
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();
|
||||
lastYear.setFullYear(lastYear.getFullYear() - 1);
|
||||
bhist.addPageWithDetails(makeURI("http://before-today.com/"), "Before Today", lastYear.valueOf() * 1000);
|
||||
|
||||
// Confirm everything worked
|
||||
ok(bhist.isVisited(makeURI("http://10minutes.com/")), "Pretend visit to 10minutes.com should exist");
|
||||
ok(bhist.isVisited(makeURI("http://1hour.com")), "Pretend visit to 1hour.com should exist");
|
||||
ok(bhist.isVisited(makeURI("http://1hour10minutes.com/")), "Pretend visit to 1hour10minutes.com should exist");
|
||||
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");
|
||||
addPlace(makeURI("http://before-today.com/"), "Before Today", lastYear.getTime() * 1000);
|
||||
|
||||
PlacesUtils.asyncHistory.updatePlaces(places, {
|
||||
handleError: function () ok(false, "Unexpected error in adding visit."),
|
||||
handleResult: function () { },
|
||||
handleCompletion: function () aCallback()
|
||||
});
|
||||
}
|
||||
|
||||
function setupFormHistory() {
|
||||
@ -321,25 +335,25 @@ function setupFormHistory() {
|
||||
|
||||
// Artifically age the entries to the proper vintage.
|
||||
let db = formhist.DBConnection;
|
||||
let timestamp = now_uSec - 10*60*1000000;
|
||||
let timestamp = now_uSec - 10 * kUsecPerMin;
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = '10minutes'");
|
||||
timestamp = now_uSec - 45*60*1000000;
|
||||
timestamp = now_uSec - 45 * kUsecPerMin;
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = '1hour'");
|
||||
timestamp = now_uSec - 70*60*1000000;
|
||||
timestamp = now_uSec - 70 * kUsecPerMin;
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = '1hour10minutes'");
|
||||
timestamp = now_uSec - 90*60*1000000;
|
||||
timestamp = now_uSec - 90 * kUsecPerMin;
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = '2hour'");
|
||||
timestamp = now_uSec - 130*60*1000000;
|
||||
timestamp = now_uSec - 130 * kUsecPerMin;
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = '2hour10minutes'");
|
||||
timestamp = now_uSec - 180*60*1000000;
|
||||
timestamp = now_uSec - 180 * kUsecPerMin;
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = '4hour'");
|
||||
timestamp = now_uSec - 250*60*1000000;
|
||||
timestamp = now_uSec - 250 * kUsecPerMin;
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = '4hour10minutes'");
|
||||
|
||||
@ -347,13 +361,13 @@ function setupFormHistory() {
|
||||
today.setHours(0);
|
||||
today.setMinutes(0);
|
||||
today.setSeconds(1);
|
||||
timestamp = today.valueOf() * 1000;
|
||||
timestamp = today.getTime() * 1000;
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = 'today'");
|
||||
|
||||
let lastYear = new Date();
|
||||
lastYear.setFullYear(lastYear.getFullYear() - 1);
|
||||
timestamp = lastYear.valueOf() * 1000;
|
||||
timestamp = lastYear.getTime() * 1000;
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = 'b4today'");
|
||||
|
||||
@ -377,8 +391,8 @@ function setupDownloads() {
|
||||
name: "fakefile-10-minutes",
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||
target: "fakefile-10-minutes",
|
||||
startTime: now_uSec - 10*60*1000000, // 10 minutes ago, in uSec
|
||||
endTime: now_uSec - 11*60*1000000, // 1 minute later
|
||||
startTime: now_uSec - 10 * kUsecPerMin, // 10 minutes ago, in uSec
|
||||
endTime: now_uSec - 11 * kUsecPerMin, // 1 minute later
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||
};
|
||||
@ -404,8 +418,8 @@ function setupDownloads() {
|
||||
name: "fakefile-1-hour",
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||
target: "fakefile-1-hour",
|
||||
startTime: now_uSec - 45*60*1000000, // 45 minutes ago, in uSec
|
||||
endTime: now_uSec - 44*60*1000000, // 1 minute later
|
||||
startTime: now_uSec - 45 * kUsecPerMin, // 45 minutes ago, in uSec
|
||||
endTime: now_uSec - 44 * kUsecPerMin, // 1 minute later
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||
};
|
||||
@ -425,8 +439,8 @@ function setupDownloads() {
|
||||
name: "fakefile-1-hour-10-minutes",
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||
target: "fakefile-1-hour-10-minutes",
|
||||
startTime: now_uSec - 70*60*1000000, // 70 minutes ago, in uSec
|
||||
endTime: now_uSec - 71*60*1000000, // 1 minute later
|
||||
startTime: now_uSec - 70 * kUsecPerMin, // 70 minutes ago, in uSec
|
||||
endTime: now_uSec - 71 * kUsecPerMin, // 1 minute later
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||
};
|
||||
@ -446,8 +460,8 @@ function setupDownloads() {
|
||||
name: "fakefile-2-hour",
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||
target: "fakefile-2-hour",
|
||||
startTime: now_uSec - 90*60*1000000, // 90 minutes ago, in uSec
|
||||
endTime: now_uSec - 89*60*1000000, // 1 minute later
|
||||
startTime: now_uSec - 90 * kUsecPerMin, // 90 minutes ago, in uSec
|
||||
endTime: now_uSec - 89 * kUsecPerMin, // 1 minute later
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||
};
|
||||
@ -467,8 +481,8 @@ function setupDownloads() {
|
||||
name: "fakefile-2-hour-10-minutes",
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||
target: "fakefile-2-hour-10-minutes",
|
||||
startTime: now_uSec - 130*60*1000000, // 130 minutes ago, in uSec
|
||||
endTime: now_uSec - 131*60*1000000, // 1 minute later
|
||||
startTime: now_uSec - 130 * kUsecPerMin, // 130 minutes ago, in uSec
|
||||
endTime: now_uSec - 131 * kUsecPerMin, // 1 minute later
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||
};
|
||||
@ -488,8 +502,8 @@ function setupDownloads() {
|
||||
name: "fakefile-4-hour",
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||
target: "fakefile-4-hour",
|
||||
startTime: now_uSec - 180*60*1000000, // 180 minutes ago, in uSec
|
||||
endTime: now_uSec - 179*60*1000000, // 1 minute later
|
||||
startTime: now_uSec - 180 * kUsecPerMin, // 180 minutes ago, in uSec
|
||||
endTime: now_uSec - 179 * kUsecPerMin, // 1 minute later
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||
};
|
||||
@ -509,8 +523,8 @@ function setupDownloads() {
|
||||
name: "fakefile-4-hour-10-minutes",
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||
target: "fakefile-4-hour-10-minutes",
|
||||
startTime: now_uSec - 250*60*1000000, // 250 minutes ago, in uSec
|
||||
endTime: now_uSec - 251*60*1000000, // 1 minute later
|
||||
startTime: now_uSec - 250 * kUsecPerMin, // 250 minutes ago, in uSec
|
||||
endTime: now_uSec - 251 * kUsecPerMin, // 1 minute later
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||
};
|
||||
@ -535,8 +549,8 @@ function setupDownloads() {
|
||||
name: "fakefile-today",
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||
target: "fakefile-today",
|
||||
startTime: today.valueOf() * 1000, // 12:00:30am this morning, in uSec
|
||||
endTime: (today.valueOf() + 1000) * 1000, // 1 second later
|
||||
startTime: today.getTime() * 1000, // 12:00:30am this morning, in uSec
|
||||
endTime: (today.getTime() + 1000) * 1000, // 1 second later
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||
};
|
||||
@ -558,8 +572,8 @@ function setupDownloads() {
|
||||
name: "fakefile-old",
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440",
|
||||
target: "fakefile-old",
|
||||
startTime: lastYear.valueOf() * 1000, // 1 year ago, in uSec
|
||||
endTime: (lastYear.valueOf() + 1000) * 1000, // 1 second later
|
||||
startTime: lastYear.getTime() * 1000, // 1 year ago, in uSec
|
||||
endTime: (lastYear.getTime() + 1000) * 1000, // 1 second later
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
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"].
|
||||
getService(Ci.nsIFormHistory2);
|
||||
|
||||
const kUsecPerMin = 60 * 1000000;
|
||||
|
||||
// Add tests here. Each is a function that's called by doNextTest().
|
||||
var gAllTests = [
|
||||
|
||||
@ -831,8 +833,8 @@ function addDownloadWithMinutesAgo(aMinutesAgo) {
|
||||
name: name,
|
||||
source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169",
|
||||
target: name,
|
||||
startTime: now_uSec - (aMinutesAgo * 60 * 1000000),
|
||||
endTime: now_uSec - ((aMinutesAgo + 1) *60 * 1000000),
|
||||
startTime: now_uSec - (aMinutesAgo * kUsecPerMin),
|
||||
endTime: now_uSec - ((aMinutesAgo + 1) * kUsecPerMin),
|
||||
state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
|
||||
currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
|
||||
};
|
||||
@ -872,7 +874,7 @@ function addFormEntryWithMinutesAgo(aMinutesAgo) {
|
||||
|
||||
// Artifically age the entry to the proper vintage.
|
||||
let db = formhist.DBConnection;
|
||||
let timestamp = now_uSec - (aMinutesAgo * 60 * 1000000);
|
||||
let timestamp = now_uSec - (aMinutesAgo * kUsecPerMin);
|
||||
db.executeSimpleSQL("UPDATE moz_formhistory SET firstUsed = " +
|
||||
timestamp + " WHERE fieldname = '" + name + "'");
|
||||
|
||||
@ -889,10 +891,12 @@ function addFormEntryWithMinutesAgo(aMinutesAgo) {
|
||||
*/
|
||||
function addHistoryWithMinutesAgo(aMinutesAgo) {
|
||||
let pURI = makeURI("http://" + aMinutesAgo + "-minutes-ago.com/");
|
||||
PlacesUtils.bhistory
|
||||
.addPageWithDetails(pURI,
|
||||
aMinutesAgo + " minutes ago",
|
||||
now_uSec - (aMinutesAgo * 60 * 1000 * 1000));
|
||||
PlacesUtils.history.addVisit(pURI,
|
||||
now_uSec - aMinutesAgo * kUsecPerMin,
|
||||
null,
|
||||
Ci.nsINavHistoryService.TRANSITION_LINK,
|
||||
false,
|
||||
0);
|
||||
is(PlacesUtils.bhistory.isVisited(pURI), true,
|
||||
"Sanity check: history visit " + pURI.spec +
|
||||
" should exist after creating it");
|
||||
|
@ -501,10 +501,12 @@ function addFormEntryWithMinutesAgo(aMinutesAgo) {
|
||||
*/
|
||||
function addHistoryWithMinutesAgo(aMinutesAgo) {
|
||||
let pURI = makeURI("http://" + aMinutesAgo + "-minutes-ago.com/");
|
||||
PlacesUtils.bhistory
|
||||
.addPageWithDetails(pURI,
|
||||
aMinutesAgo + " minutes ago",
|
||||
now_uSec - (aMinutesAgo * 60 * 1000 * 1000));
|
||||
PlacesUtils.history.addVisit(pURI,
|
||||
now_uSec - (aMinutesAgo * 60 * 1000 * 1000),
|
||||
null,
|
||||
Ci.nsINavHistoryService.TRANSITION_LINK,
|
||||
false,
|
||||
0);
|
||||
is(PlacesUtils.bhistory.isVisited(pURI), true,
|
||||
"Sanity check: history visit " + pURI.spec +
|
||||
" should exist after creating it");
|
||||
|
@ -17,7 +17,7 @@ let bhist = Cc["@mozilla.org/browser/global-history;2"]
|
||||
|
||||
function runTests() {
|
||||
clearHistory();
|
||||
fillHistory();
|
||||
yield fillHistory();
|
||||
yield addNewTabPageTab();
|
||||
|
||||
is(getCell(0).site.url, URL, "first site is our fake site");
|
||||
@ -29,9 +29,23 @@ function runTests() {
|
||||
}
|
||||
|
||||
function fillHistory() {
|
||||
let uri = makeURI(URL);
|
||||
for (let i = 59; i > 0; i--)
|
||||
bhist.addPageWithDetails(uri, "fake site", NOW - i * 60 * 1000000);
|
||||
let visits = [];
|
||||
for (let i = 59; i > 0; i--) {
|
||||
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() {
|
||||
|
@ -50,13 +50,49 @@ function do_test()
|
||||
const TITLE_2 = "Title 2";
|
||||
|
||||
do_test_pending();
|
||||
waitForClearHistory(function() {
|
||||
PlacesUtils.bhistory.addPageWithDetails(TEST_URI, TITLE_1, Date.now() * 1000);
|
||||
waitForClearHistory(function () {
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
pb.privateBrowsingEnabled = false;
|
||||
@ -73,7 +109,7 @@ function do_test()
|
||||
do_check_eq(PlacesUtils.history.getPageTitle(TEST_URI), TITLE_1);
|
||||
|
||||
waitForClearHistory(do_test_finished);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 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].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
@ -88,9 +90,9 @@ function uri(aURIString)
|
||||
function add_visit(aURI)
|
||||
{
|
||||
check_visited(aURI, false);
|
||||
let bh = Cc["@mozilla.org/browser/global-history;2"].
|
||||
getService(Ci.nsIBrowserHistory);
|
||||
bh.addPageWithDetails(aURI, aURI.spec, Date.now() * 1000);
|
||||
PlacesUtils.history.addVisit(aURI, Date.now() * 1000, null,
|
||||
Ci.nsINavHistoryService.TRANSITION_LINK, false,
|
||||
0);
|
||||
check_visited(aURI, true);
|
||||
}
|
||||
|
||||
@ -104,10 +106,8 @@ function add_visit(aURI)
|
||||
*/
|
||||
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;
|
||||
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);
|
||||
|
||||
// Clear history since we left something there from this test.
|
||||
let bh = Cc["@mozilla.org/browser/global-history;2"].
|
||||
getService(Ci.nsIBrowserHistory);
|
||||
bh.removeAllPages();
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
||||
|
||||
// Cookie Service
|
||||
|
@ -1,181 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const PREF_DISK_CACHE_SSL = "browser.cache.disk_cache_ssl";
|
||||
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
|
||||
let contentWindow;
|
||||
let newTab;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
newTab = gBrowser.addTab();
|
||||
|
||||
HttpRequestObserver.register();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
HttpRequestObserver.unregister();
|
||||
if (gBrowser.tabs[1])
|
||||
gBrowser.removeTab(gBrowser.tabs[1]);
|
||||
hideTabView();
|
||||
|
||||
Services.prefs.clearUserPref(PREF_DISK_CACHE_SSL);
|
||||
pb.privateBrowsingEnabled = false;
|
||||
});
|
||||
|
||||
showTabView(function() {
|
||||
contentWindow = TabView.getContentWindow();
|
||||
test1();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function test1() {
|
||||
// page with cache-control: no-store, should not save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "no-store";
|
||||
|
||||
whenStorageDenied(newTab, function () {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(!contentWindow.StoragePolicy.canStoreThumbnailForTab(newTab),
|
||||
"Should not save the thumbnail for tab");
|
||||
|
||||
whenDeniedToSaveImageData(tabItem, test2);
|
||||
tabItem.saveThumbnail({synchronously: true});
|
||||
HttpRequestObserver.cacheControlValue = null;
|
||||
});
|
||||
|
||||
newTab.linkedBrowser.loadURI("http://www.example.com/browser/browser/components/tabview/test/dummy_page.html");
|
||||
}
|
||||
|
||||
function test2() {
|
||||
// page with cache-control: private, should save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "private";
|
||||
|
||||
newTab.linkedBrowser.loadURI("http://www.example.com/");
|
||||
afterAllTabsLoaded(function() {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(contentWindow.StoragePolicy.canStoreThumbnailForTab(newTab),
|
||||
"Should save the thumbnail for tab");
|
||||
|
||||
whenSavedCachedImageData(tabItem, test3);
|
||||
tabItem.saveThumbnail({synchronously: true});
|
||||
});
|
||||
}
|
||||
|
||||
function test3() {
|
||||
// page with cache-control: private with https caching enabled, should save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "private";
|
||||
|
||||
Services.prefs.setBoolPref(PREF_DISK_CACHE_SSL, true);
|
||||
|
||||
newTab.linkedBrowser.loadURI("https://example.com/browser/browser/components/tabview/test/dummy_page.html");
|
||||
afterAllTabsLoaded(function() {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(contentWindow.StoragePolicy.canStoreThumbnailForTab(newTab),
|
||||
"Should save the thumbnail for tab");
|
||||
|
||||
whenSavedCachedImageData(tabItem, test4);
|
||||
tabItem.saveThumbnail({synchronously: true});
|
||||
});
|
||||
}
|
||||
|
||||
function test4() {
|
||||
// page with cache-control: public with https caching disabled, should save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "public";
|
||||
|
||||
Services.prefs.setBoolPref(PREF_DISK_CACHE_SSL, false);
|
||||
|
||||
newTab.linkedBrowser.loadURI("https://example.com/browser/browser/components/tabview/test/");
|
||||
afterAllTabsLoaded(function() {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(contentWindow.StoragePolicy.canStoreThumbnailForTab(newTab),
|
||||
"Should save the thumbnail for tab");
|
||||
|
||||
whenSavedCachedImageData(tabItem, test5);
|
||||
tabItem.saveThumbnail({synchronously: true});
|
||||
});
|
||||
}
|
||||
|
||||
function test5() {
|
||||
// page with cache-control: private with https caching disabled, should not save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "private";
|
||||
|
||||
whenStorageDenied(newTab, function () {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(!contentWindow.StoragePolicy.canStoreThumbnailForTab(newTab),
|
||||
"Should not save the thumbnail for tab");
|
||||
|
||||
whenDeniedToSaveImageData(tabItem, function () {
|
||||
gBrowser.removeTab(newTab);
|
||||
test6();
|
||||
});
|
||||
|
||||
tabItem.saveThumbnail({synchronously: true});
|
||||
});
|
||||
|
||||
newTab.linkedBrowser.loadURI("https://example.com/");
|
||||
}
|
||||
|
||||
// ensure that no thumbnails are saved while in private browsing mode
|
||||
function test6() {
|
||||
HttpRequestObserver.cacheControlValue = "public";
|
||||
|
||||
togglePrivateBrowsing(function () {
|
||||
let tab = gBrowser.tabs[0];
|
||||
|
||||
ok(!contentWindow.StoragePolicy.canStoreThumbnailForTab(tab),
|
||||
"Should not save the thumbnail for tab");
|
||||
|
||||
togglePrivateBrowsing(finish);
|
||||
});
|
||||
}
|
||||
|
||||
let HttpRequestObserver = {
|
||||
cacheControlValue: null,
|
||||
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic == "http-on-examine-response" && this.cacheControlValue) {
|
||||
let httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
|
||||
httpChannel.setResponseHeader("Cache-Control", this.cacheControlValue, false);
|
||||
}
|
||||
},
|
||||
|
||||
register: function() {
|
||||
Services.obs.addObserver(this, "http-on-examine-response", false);
|
||||
},
|
||||
|
||||
unregister: function() {
|
||||
Services.obs.removeObserver(this, "http-on-examine-response");
|
||||
}
|
||||
};
|
||||
|
||||
function whenSavedCachedImageData(tabItem, callback) {
|
||||
tabItem.addSubscriber("savedCachedImageData", function onSaved() {
|
||||
tabItem.removeSubscriber("savedCachedImageData", onSaved);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
function whenDeniedToSaveImageData(tabItem, callback) {
|
||||
tabItem.addSubscriber("deniedToSaveImageData", function onDenied() {
|
||||
tabItem.removeSubscriber("deniedToSaveImageData", onDenied);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
function whenStorageDenied(tab, callback) {
|
||||
let mm = tab.linkedBrowser.messageManager;
|
||||
|
||||
mm.addMessageListener("Panorama:StoragePolicy:denied", function onDenied() {
|
||||
mm.removeMessageListener("Panorama:StoragePolicy:denied", onDenied);
|
||||
executeSoon(callback);
|
||||
});
|
||||
}
|
@ -245,14 +245,16 @@ let PageThumbs = {
|
||||
};
|
||||
|
||||
let PageThumbsStorage = {
|
||||
getFileForURL: function Storage_getFileForURL(aURL) {
|
||||
getFileForURL: function Storage_getFileForURL(aURL, aOptions) {
|
||||
let hash = this._calculateMD5Hash(aURL);
|
||||
let parts = [THUMBNAIL_DIRECTORY, hash[0], hash[1], hash.slice(2) + ".png"];
|
||||
return FileUtils.getFile("ProfD", parts);
|
||||
let parts = [THUMBNAIL_DIRECTORY, hash[0], hash[1]];
|
||||
let file = FileUtils.getDir("ProfD", parts, aOptions && aOptions.createPath);
|
||||
file.append(hash.slice(2) + ".png");
|
||||
return file;
|
||||
},
|
||||
|
||||
write: function Storage_write(aURL, aDataStream, aCallback) {
|
||||
let file = this.getFileForURL(aURL);
|
||||
let file = this.getFileForURL(aURL, {createPath: true});
|
||||
let fos = FileUtils.openSafeFileOutputStream(file);
|
||||
|
||||
NetUtil.asyncCopy(aDataStream, fos, function (aResult) {
|
||||
|
@ -16,6 +16,7 @@ _BROWSER_FILES = \
|
||||
browser_thumbnails_redirect.js \
|
||||
browser_thumbnails_storage.js \
|
||||
browser_thumbnails_bug726727.js \
|
||||
browser_thumbnails_bug753755.js \
|
||||
head.js \
|
||||
background_red.html \
|
||||
background_red_redirect.sjs \
|
||||
|
@ -0,0 +1,15 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that PageThumbsStorage.getFileForURL(url) doesn't implicitly
|
||||
* create the file's parent path.
|
||||
*/
|
||||
function runTests() {
|
||||
let url = "http://non.existant.url/";
|
||||
let file = PageThumbsStorage.getFileForURL(url);
|
||||
ok(!file.exists() && !file.parent.exists(), "file and path don't exist");
|
||||
|
||||
let file = PageThumbsStorage.getFileForURL(url, {createPath: true});
|
||||
ok(!file.exists() && file.parent.exists(), "path exists, file doesn't");
|
||||
}
|
@ -18,7 +18,7 @@ XPCOMUtils.defineLazyGetter(this, "Sanitizer", function () {
|
||||
* be removed when the user sanitizes their history.
|
||||
*/
|
||||
function runTests() {
|
||||
clearHistory();
|
||||
yield clearHistory();
|
||||
|
||||
// create a thumbnail
|
||||
yield addTab(URL);
|
||||
@ -72,7 +72,7 @@ function clearHistory(aUseRange) {
|
||||
|
||||
executeSoon(function () {
|
||||
if (PageThumbsStorage.getFileForURL(URL).exists())
|
||||
clearHistory(aFile, aUseRange);
|
||||
clearHistory(aUseRange);
|
||||
else
|
||||
next();
|
||||
});
|
||||
|
@ -29,9 +29,12 @@ let TestRunner = {
|
||||
*/
|
||||
run: function () {
|
||||
waitForExplicitFinish();
|
||||
|
||||
this._iter = runTests();
|
||||
this.next();
|
||||
|
||||
if (this._iter)
|
||||
this.next();
|
||||
else
|
||||
finish();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -77,6 +77,12 @@ can reach it easily. -->
|
||||
<!ENTITY pageInfoCmd.label "Page Info">
|
||||
<!ENTITY pageInfoCmd.accesskey "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.accesskey "F">
|
||||
<!ENTITY fullScreenCmd.macCommandKey "f">
|
||||
|
@ -588,10 +588,8 @@ MacNativeApp.prototype = {
|
||||
<string>MOZB</string>\n\
|
||||
<key>CFBundleVersion</key>\n\
|
||||
<string>0</string>\n\
|
||||
#ifdef DEBUG
|
||||
<key>FirefoxBinary</key>\n\
|
||||
<string>org.mozilla.NightlyDebug</string>\n\
|
||||
#endif
|
||||
#expand <string>__MOZ_MACBUNDLE_ID__</string>\n\
|
||||
</dict>\n\
|
||||
</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 |
@ -544,7 +544,7 @@ toolbar[mode="icons"] #forward-button {
|
||||
}
|
||||
|
||||
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button {
|
||||
mask: url(chrome://browser/content/browser.xul#pinstripe-keyhole-forward-mask);
|
||||
clip-path: url(chrome://browser/content/browser.xul#pinstripe-keyhole-forward-clip-path);
|
||||
}
|
||||
|
||||
@conditionalForwardWithUrlbar@ > #forward-button:not(:-moz-lwtheme) {
|
||||
@ -951,7 +951,7 @@ toolbar[mode="icons"] #zoom-in-button {
|
||||
}
|
||||
|
||||
@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container {
|
||||
mask: url("chrome://browser/content/browser.xul#pinstripe-urlbar-back-button-mask");
|
||||
clip-path: url("chrome://browser/content/browser.xul#pinstripe-urlbar-back-button-clip-path");
|
||||
}
|
||||
|
||||
@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container > #urlbar {
|
||||
@ -970,7 +970,7 @@ toolbar[mode="icons"] #zoom-in-button {
|
||||
|
||||
@conditionalForwardWithUrlbar@ + #urlbar-container:-moz-locale-dir(rtl),
|
||||
@conditionalForwardWithUrlbar@ + #urlbar-container > #urlbar:-moz-locale-dir(rtl) {
|
||||
/* let pinstripe-urlbar-back-button-mask clip the urlbar's right side for RTL */
|
||||
/* let pinstripe-urlbar-back-button-clip-path clip the urlbar's right side for RTL */
|
||||
-moz-transform: scaleX(-1);
|
||||
}
|
||||
|
||||
@ -1806,22 +1806,22 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
||||
|
||||
@TABSONTOP_TAB_STACK@ > .tab-background > .tab-background-start:-moz-locale-dir(ltr),
|
||||
@TABSONTOP_TAB_STACK@ > .tab-background > .tab-background-end:-moz-locale-dir(rtl) {
|
||||
mask: url(chrome://browser/content/browser.xul#pinstripe-tab-ontop-left-curve-mask);
|
||||
clip-path: url(chrome://browser/content/browser.xul#pinstripe-tab-ontop-left-curve-clip-path);
|
||||
}
|
||||
|
||||
@TABSONTOP_TAB_STACK@ > .tab-background > .tab-background-end:-moz-locale-dir(ltr),
|
||||
@TABSONTOP_TAB_STACK@ > .tab-background > .tab-background-start:-moz-locale-dir(rtl) {
|
||||
mask: url(chrome://browser/content/browser.xul#pinstripe-tab-ontop-right-curve-mask);
|
||||
clip-path: url(chrome://browser/content/browser.xul#pinstripe-tab-ontop-right-curve-clip-path);
|
||||
}
|
||||
|
||||
@TABSONBOTTOM_TAB_STACK@ > .tab-background > .tab-background-start:-moz-locale-dir(ltr),
|
||||
@TABSONBOTTOM_TAB_STACK@ > .tab-background > .tab-background-end:-moz-locale-dir(rtl) {
|
||||
mask: url(chrome://browser/content/browser.xul#pinstripe-tab-onbottom-left-curve-mask);
|
||||
clip-path: url(chrome://browser/content/browser.xul#pinstripe-tab-onbottom-left-curve-clip-path);
|
||||
}
|
||||
|
||||
@TABSONBOTTOM_TAB_STACK@ > .tab-background > .tab-background-end:-moz-locale-dir(ltr),
|
||||
@TABSONBOTTOM_TAB_STACK@ > .tab-background > .tab-background-start:-moz-locale-dir(rtl) {
|
||||
mask: url(chrome://browser/content/browser.xul#pinstripe-tab-onbottom-right-curve-mask);
|
||||
clip-path: url(chrome://browser/content/browser.xul#pinstripe-tab-onbottom-right-curve-clip-path);
|
||||
}
|
||||
|
||||
.tab-background-start[selected="true"]:not(:-moz-lwtheme),
|
||||
|
Before Width: | Height: | Size: 541 B After Width: | Height: | Size: 520 B |
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 500 B |
@ -817,7 +817,7 @@ toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
border-color: hsla(210,54%,20%,.3) hsla(210,54%,20%,.35) hsla(210,54%,20%,.4);
|
||||
box-shadow: 0 1px 1px hsla(210,54%,20%,.1) inset,
|
||||
0 0 1px hsla(210,54%,20%,.2) inset,
|
||||
/* allows winstripe-keyhole-forward-mask to be used for non-hover as well as hover: */
|
||||
/* allows winstripe-keyhole-forward-clip-path to be used for non-hover as well as hover: */
|
||||
0 1px 0 hsla(210,54%,20%,0),
|
||||
0 0 2px hsla(210,54%,20%,0);
|
||||
text-shadow: none;
|
||||
@ -896,7 +896,7 @@ toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
|
||||
@conditionalForwardWithUrlbar@ > #forward-button > .toolbarbutton-icon {
|
||||
/*mask: url(keyhole-forward-mask.svg#mask); XXX: this regresses twinopen */
|
||||
mask: url(chrome://browser/content/browser.xul#winstripe-keyhole-forward-mask);
|
||||
clip-path: url(chrome://browser/content/browser.xul#winstripe-keyhole-forward-clip-path);
|
||||
-moz-margin-start: -6px !important;
|
||||
border-left-style: none;
|
||||
border-radius: 0;
|
||||
@ -1258,7 +1258,7 @@ toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
}
|
||||
|
||||
@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container {
|
||||
mask: url("chrome://browser/content/browser.xul#winstripe-urlbar-back-button-mask");
|
||||
clip-path: url("chrome://browser/content/browser.xul#winstripe-urlbar-back-button-clip-path");
|
||||
}
|
||||
|
||||
@conditionalForwardWithUrlbar@[forwarddisabled] + #urlbar-container > #urlbar {
|
||||
|
Before Width: | Height: | Size: 900 B After Width: | Height: | Size: 708 B |
Before Width: | Height: | Size: 553 B After Width: | Height: | Size: 672 B |
@ -362,7 +362,7 @@ browser.jar:
|
||||
skin/classic/aero/browser/devtools/layout-background.png (devtools/layout-background.png)
|
||||
skin/classic/aero/browser/devtools/layoutview.css (devtools/layoutview.css)
|
||||
skin/classic/aero/browser/devtools/layout-buttons.png (devtools/layout-buttons.png)
|
||||
skin/classic/aera/browser/devtools/inspector-option-icon.png (devtools/inspector-option-icon.png)
|
||||
skin/classic/aero/browser/devtools/inspector-option-icon.png (devtools/inspector-option-icon.png)
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
skin/classic/aero/browser/sync-throbber.png
|
||||
skin/classic/aero/browser/sync-16.png
|
||||
|
@ -479,7 +479,7 @@ class ShutdownLeakLogger(object):
|
||||
self.currentTest = {"fileName": fileName, "windows": set(), "docShells": set()}
|
||||
elif line.startswith("INFO TEST-END"):
|
||||
# don't track a test if no windows or docShells leaked
|
||||
if self.currentTest["windows"] or self.currentTest["docShells"]:
|
||||
if self.currentTest and (self.currentTest["windows"] or self.currentTest["docShells"]):
|
||||
self.tests.append(self.currentTest)
|
||||
self.currentTest = None
|
||||
elif line.startswith("INFO TEST-START | Shutdown"):
|
||||
|
@ -40,6 +40,7 @@ package com.mozilla.SUTAgentAndroid;
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetAddress;
|
||||
import org.apache.http.conn.util.InetAddressUtils;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.util.Enumeration;
|
||||
@ -665,7 +666,7 @@ public class SUTAgentAndroid extends Activity
|
||||
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
|
||||
{
|
||||
InetAddress inetAddress = enumIpAddr.nextElement();
|
||||
if (!inetAddress.isLoopbackAddress())
|
||||
if (!inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(inetAddress.getHostAddress()))
|
||||
{
|
||||
return inetAddress.getHostAddress().toString();
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ MOZ_APP_UA_NAME = @MOZ_APP_UA_NAME@
|
||||
MOZ_APP_VERSION = @MOZ_APP_VERSION@
|
||||
MOZ_APP_MAXVERSION = @MOZ_APP_MAXVERSION@
|
||||
MOZ_MACBUNDLE_NAME = @MOZ_MACBUNDLE_NAME@
|
||||
MOZ_MACBUNDLE_ID = @MOZ_MACBUNDLE_ID@
|
||||
MOZ_APP_STATIC_INI = @MOZ_APP_STATIC_INI@
|
||||
|
||||
MOZ_PKG_SPECIAL = @MOZ_PKG_SPECIAL@
|
||||
@ -164,6 +165,7 @@ MOZ_ZIPWRITER = @MOZ_ZIPWRITER@
|
||||
MOZ_OGG = @MOZ_OGG@
|
||||
MOZ_RAW = @MOZ_RAW@
|
||||
MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
|
||||
MOZ_SPEEX_RESAMPLER = @MOZ_SPEEX_RESAMPLER@
|
||||
MOZ_CUBEB = @MOZ_CUBEB@
|
||||
MOZ_WAVE = @MOZ_WAVE@
|
||||
MOZ_MEDIA = @MOZ_MEDIA@
|
||||
|
@ -361,25 +361,25 @@ ifndef TARGETS
|
||||
TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
|
||||
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
|
||||
_OBJS = \
|
||||
$(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 = $(COBJS) $(SOBJS) $(CCOBJS) $(CPPOBJS) $(CMOBJS) $(CMMOBJS) $(ASOBJS)
|
||||
OBJS = $(strip $(_OBJS))
|
||||
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
|
||||
_HOST_OBJS = \
|
||||
$(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 = $(HOST_COBJS) $(HOST_CCOBJS) $(HOST_CPPOBJS) $(HOST_CMOBJS) $(HOST_CMMOBJS)
|
||||
HOST_OBJS = $(strip $(_HOST_OBJS))
|
||||
endif
|
||||
|
||||
@ -1090,32 +1090,27 @@ endif # MOZ_AUTO_DEPS
|
||||
$(OBJS) $(HOST_OBJS): $(GLOBAL_DEPS)
|
||||
|
||||
# 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)
|
||||
$(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)
|
||||
$(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)
|
||||
$(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)
|
||||
$(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)
|
||||
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
%:: %.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTOPTION)$@ $(_VPATH_SRCS)
|
||||
|
||||
%.$(OBJ_SUFFIX): %.c
|
||||
$(COBJS): %.$(OBJ_SUFFIX): %.c
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
|
||||
@ -1135,26 +1130,22 @@ qrc_%.cpp: %.qrc
|
||||
ifdef ASFILES
|
||||
# The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
|
||||
# a '-c' flag.
|
||||
%.$(OBJ_SUFFIX): %.$(ASM_SUFFIX)
|
||||
$(ASOBJS): %.$(OBJ_SUFFIX): %.$(ASM_SUFFIX)
|
||||
$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
|
||||
endif
|
||||
|
||||
%.$(OBJ_SUFFIX): %.S
|
||||
$(SOBJS): %.$(OBJ_SUFFIX): %.S
|
||||
$(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.
|
||||
#
|
||||
%.$(OBJ_SUFFIX): %.cc
|
||||
$(CCOBJS): %.$(OBJ_SUFFIX): %.cc
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
%.$(OBJ_SUFFIX): %.cpp
|
||||
$(CPPOBJS): %.$(OBJ_SUFFIX): %.cpp
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
ifdef STRICT_CPLUSPLUS_SUFFIX
|
||||
@ -1165,12 +1156,12 @@ else
|
||||
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
|
||||
endif #STRICT_CPLUSPLUS_SUFFIX
|
||||
|
||||
$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm
|
||||
$(CMMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CXX)
|
||||
$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m
|
||||
$(CMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
|
||||
|
@ -1047,6 +1047,7 @@ vpx/vpx_codec.h
|
||||
vpx/vpx_decoder.h
|
||||
vpx/vp8dx.h
|
||||
sydneyaudio/sydney_audio.h
|
||||
speex/speex_resampler.h
|
||||
vorbis/codec.h
|
||||
theora/theoradec.h
|
||||
tremor/ivorbiscodec.h
|
||||
|
18
configure.in
@ -4548,6 +4548,7 @@ MOZ_AUTH_EXTENSION=1
|
||||
MOZ_OGG=1
|
||||
MOZ_RAW=
|
||||
MOZ_SYDNEYAUDIO=
|
||||
MOZ_SPEEX_RESAMPLER=1
|
||||
MOZ_CUBEB=
|
||||
MOZ_VORBIS=
|
||||
MOZ_TREMOR=
|
||||
@ -5795,6 +5796,10 @@ if test -n "$MOZ_SYDNEYAUDIO"; then
|
||||
AC_DEFINE(MOZ_SYDNEYAUDIO)
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_SPEEX_RESAMPLER"; then
|
||||
AC_DEFINE(MOZ_SPEEX_RESAMPLER)
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_CUBEB"; then
|
||||
case "$target" in
|
||||
*-mingw*)
|
||||
@ -8013,7 +8018,7 @@ dnl ========================================================
|
||||
|
||||
if test -z "$SKIP_PATH_CHECKS"; then
|
||||
if test -z "${GLIB_CFLAGS}" -o -z "${GLIB_LIBS}" ; then
|
||||
if test "$MOZ_ENABLE_GTK2" -o "$MOZ_ENABLE_QT" -o "$USE_ELF_DYNSTR_GC" ; then
|
||||
if test "$MOZ_ENABLE_GTK2" -o "$USE_ELF_DYNSTR_GC" ; then
|
||||
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 1.3.7 gobject-2.0)
|
||||
fi
|
||||
fi
|
||||
@ -8508,6 +8513,16 @@ else
|
||||
fi
|
||||
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
|
||||
# configuration ($BRANDING/configure.sh and $APPLICATION/confvars.sh):
|
||||
# - 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_SYDNEYAUDIO)
|
||||
AC_SUBST(MOZ_SPEEX_RESAMPLER)
|
||||
AC_SUBST(MOZ_CUBEB)
|
||||
AC_SUBST(MOZ_WAVE)
|
||||
AC_SUBST(MOZ_VORBIS)
|
||||
|
@ -107,6 +107,6 @@ load 713417.html
|
||||
load 713417-2.html
|
||||
load 715056.html
|
||||
load 741163-1.html
|
||||
load 752226-1.html
|
||||
load 752226-2.html
|
||||
asserts(0-1) load 752226-1.html
|
||||
asserts(0-1) load 752226-2.html
|
||||
HTTP(..) load xhr_abortinprogress.html
|
||||
|
@ -1669,11 +1669,4 @@ extern const nsIID kThisPtrOffsetsSID;
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID)
|
||||
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
|
||||
nsContentUtils::TraceWrapper(tmp, aCallback, aClosure);
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
|
||||
nsContentUtils::ReleaseWrapper(s, tmp);
|
||||
|
||||
|
||||
#endif /* nsINode_h___ */
|
||||
|
@ -607,16 +607,7 @@ nsDOMMemoryFile::GetInternalStream(nsIInputStream **aStream)
|
||||
|
||||
DOMCI_DATA(FileList, nsDOMFileList)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMFileList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMFileList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMFileList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsDOMFileList)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMFileList)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
|
@ -58,16 +58,7 @@ nsDOMTokenList::nsDOMTokenList(nsGenericElement *aElement, nsIAtom* aAttrAtom)
|
||||
|
||||
nsDOMTokenList::~nsDOMTokenList() { }
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMTokenList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMTokenList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMTokenList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMTokenList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsDOMTokenList)
|
||||
|
||||
DOMCI_DATA(DOMTokenList, nsDOMTokenList)
|
||||
|
||||
|
@ -1717,17 +1717,9 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsChildContentList)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsChildContentList)
|
||||
|
||||
// If nsChildContentList is changed so that any additional fields are
|
||||
// traversed by the cycle collector, then CAN_SKIP must be updated.
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsChildContentList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsChildContentList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsChildContentList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsChildContentList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
// traversed by the cycle collector, then CAN_SKIP must be updated to
|
||||
// check that the additional fields are null.
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(nsChildContentList)
|
||||
|
||||
// nsChildContentList only ever has a single child, its wrapper, so if
|
||||
// the wrapper is black, the list can't be part of a garbage cycle.
|
||||
@ -2141,11 +2133,8 @@ nsGenericElement::SetScrollTop(PRInt32 aScrollTop)
|
||||
nsIScrollableFrame* sf = GetScrollFrame();
|
||||
if (sf) {
|
||||
nsPoint pt = sf->GetScrollPosition();
|
||||
pt.y = nsPresContext::CSSPixelsToAppUnits(aScrollTop);
|
||||
nscoord halfPixel = nsPresContext::CSSPixelsToAppUnits(0.5f);
|
||||
// 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);
|
||||
sf->ScrollToCSSPixels(nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
|
||||
aScrollTop));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2174,11 +2163,8 @@ nsGenericElement::SetScrollLeft(PRInt32 aScrollLeft)
|
||||
nsIScrollableFrame* sf = GetScrollFrame();
|
||||
if (sf) {
|
||||
nsPoint pt = sf->GetScrollPosition();
|
||||
pt.x = nsPresContext::CSSPixelsToAppUnits(aScrollLeft);
|
||||
nscoord halfPixel = nsPresContext::CSSPixelsToAppUnits(0.5f);
|
||||
// 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);
|
||||
sf->ScrollToCSSPixels(nsIntPoint(aScrollLeft,
|
||||
nsPresContext::AppUnitsToIntCSSPixels(pt.y)));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1403,19 +1403,7 @@ NAME_NOT_SUPPORTED(WebGLRenderbuffer)
|
||||
|
||||
// WebGLExtension
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(WebGLExtension)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(WebGLExtension)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WebGLExtension)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WebGLExtension)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLExtension)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLExtension)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
|
@ -84,18 +84,7 @@ nsPaintRequest::GetReason(nsAString& aResult)
|
||||
|
||||
DOMCI_DATA(PaintRequestList, nsPaintRequestList)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsPaintRequestList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsPaintRequestList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsPaintRequestList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsPaintRequestList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsPaintRequestList, mParent)
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsPaintRequestList)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
|
@ -103,18 +103,7 @@ nsClientRect::GetHeight(float* aResult)
|
||||
|
||||
DOMCI_DATA(ClientRectList, nsClientRectList)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsClientRectList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsClientRectList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsClientRectList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsClientRectList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsClientRectList, mParent)
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(nsClientRectList)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
|
@ -3310,17 +3310,15 @@ nsHTMLInputElement::AllowDrop()
|
||||
void
|
||||
nsHTMLInputElement::AddedToRadioGroup()
|
||||
{
|
||||
// Make sure not to notify if we're still being created by the parser
|
||||
bool notify = !mParserCreating;
|
||||
|
||||
//
|
||||
// If the input element is not in a form and
|
||||
// not in a document, we just need to return.
|
||||
//
|
||||
if (!mForm && !(IsInDoc() && GetParent())) {
|
||||
// If the element is neither in a form nor a document, there is no group so we
|
||||
// should just stop here.
|
||||
if (!mForm && !IsInDoc()) {
|
||||
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
|
||||
// deselect whatever is currently selected in that group
|
||||
|
@ -446,23 +446,18 @@ void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
|
||||
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);
|
||||
mDuration = mDecoderStateMachine ? mDecoderStateMachine->GetDuration() : -1;
|
||||
// Duration has changed so we should recompute playback rate
|
||||
UpdatePlaybackRate();
|
||||
|
||||
notifyElement = mNextState != PLAY_STATE_SEEKING;
|
||||
}
|
||||
|
||||
if (mDuration == -1) {
|
||||
SetInfinite(true);
|
||||
}
|
||||
|
||||
if (mElement && notifyElement) {
|
||||
if (mElement) {
|
||||
// Make sure the element and the frame (if any) are told about
|
||||
// our new size.
|
||||
Invalidate();
|
||||
@ -482,7 +477,7 @@ void nsBuiltinDecoder::MetadataLoaded(PRUint32 aChannels,
|
||||
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
|
||||
bool resourceIsLoaded = !mResourceLoaded && mResource &&
|
||||
mResource->IsDataCachedToEndOfResource(mDecoderPosition);
|
||||
if (mElement && notifyElement) {
|
||||
if (mElement) {
|
||||
mElement->FirstFrameLoaded(resourceIsLoaded);
|
||||
}
|
||||
|
||||
@ -567,11 +562,13 @@ void nsBuiltinDecoder::DecodeError()
|
||||
|
||||
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
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
|
||||
return mPlayState == PLAY_STATE_ENDED || mPlayState == PLAY_STATE_SHUTDOWN;
|
||||
}
|
||||
|
||||
@ -580,6 +577,7 @@ void nsBuiltinDecoder::PlaybackEnded()
|
||||
if (mShuttingDown || mPlayState == nsBuiltinDecoder::PLAY_STATE_SEEKING)
|
||||
return;
|
||||
|
||||
printf("nsBuiltinDecoder::PlaybackEnded mPlayState=%d\n", mPlayState);
|
||||
PlaybackPositionChanged();
|
||||
ChangeState(PLAY_STATE_ENDED);
|
||||
|
||||
@ -794,6 +792,7 @@ void nsBuiltinDecoder::SeekingStopped()
|
||||
seekWasAborted = true;
|
||||
} else {
|
||||
UnpinForSeek();
|
||||
printf("nsBuiltinDecoder::SeekingStopped, next state=%d\n", mNextState);
|
||||
ChangeState(mNextState);
|
||||
}
|
||||
}
|
||||
@ -827,6 +826,7 @@ void nsBuiltinDecoder::SeekingStoppedAtEnd()
|
||||
seekWasAborted = true;
|
||||
} else {
|
||||
UnpinForSeek();
|
||||
printf("nsBuiltinDecoder::SeekingStoppedAtEnd, next state=PLAY_STATE_ENDED\n");
|
||||
fireEnded = true;
|
||||
ChangeState(PLAY_STATE_ENDED);
|
||||
}
|
||||
@ -909,6 +909,9 @@ void nsBuiltinDecoder::PlaybackPositionChanged()
|
||||
// current time after the seek has started but before it has
|
||||
// completed.
|
||||
mCurrentTime = mDecoderStateMachine->GetCurrentTime();
|
||||
} else {
|
||||
printf("Suppressed timeupdate during seeking: currentTime=%f, new time=%f\n",
|
||||
mCurrentTime, mDecoderStateMachine->GetCurrentTime());
|
||||
}
|
||||
mDecoderStateMachine->ClearPositionChangeFlag();
|
||||
}
|
||||
|
@ -470,8 +470,8 @@ public:
|
||||
// Call on the main thread only.
|
||||
virtual void NetworkError();
|
||||
|
||||
// Call from any thread safely. Return true if we are currently
|
||||
// seeking in the media resource.
|
||||
// Return true if we are currently seeking in the media resource.
|
||||
// Call on the main thread only.
|
||||
virtual bool IsSeeking() const;
|
||||
|
||||
// Return true if the decoder has reached the end of playback.
|
||||
@ -742,17 +742,21 @@ public:
|
||||
// Data about MediaStreams that are being fed by this decoder.
|
||||
nsTArray<OutputMediaStream> mOutputStreams;
|
||||
|
||||
// Set to one of the valid play states. It is protected by the
|
||||
// monitor mReentrantMonitor. This monitor must be acquired when reading or
|
||||
// writing the state. Any change to the state on the main thread
|
||||
// must call NotifyAll on the monitor so the decode thread can wake up.
|
||||
// Set to one of the valid play states.
|
||||
// This can only be changed on the main thread while holding the decoder
|
||||
// monitor. Thus, it can be safely read while holding the decoder monitor
|
||||
// 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;
|
||||
|
||||
// The state to change to after a seek or load operation. It must only
|
||||
// be changed from the main thread. The decoder monitor must be acquired
|
||||
// when writing to the state, or when reading from a non-main thread.
|
||||
// The state to change to after a seek or load operation.
|
||||
// This can only be changed on the main thread while holding the decoder
|
||||
// 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.
|
||||
PlayState mNextState;
|
||||
// This can only be PLAY_STATE_PAUSED or PLAY_STATE_PLAYING.
|
||||
PlayState mNextState;
|
||||
|
||||
// True when we have fully loaded the resource and reported that
|
||||
// to the element (i.e. reached NETWORK_LOADED state).
|
||||
|
@ -2198,6 +2198,7 @@ nsresult nsBuiltinDecoderStateMachine::RunStateMachine()
|
||||
PRInt64 videoTime = HasVideo() ? mVideoFrameEndTime : 0;
|
||||
PRInt64 clockTime = NS_MAX(mEndTime, NS_MAX(videoTime, GetAudioClock()));
|
||||
UpdatePlaybackPosition(clockTime);
|
||||
printf("nsBuiltinDecoderStateMachine::RunStateMachine queuing nsBuiltinDecoder::PlaybackEnded\n");
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::PlaybackEnded);
|
||||
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
|
@ -5877,7 +5877,7 @@ DefineIDBInterfaceConstants(JSContext *cx, JSObject *obj, const nsIID *aIID)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class nsDOMConstructor : public nsIDOMDOMConstructor
|
||||
class nsDOMConstructor MOZ_FINAL : public nsIDOMDOMConstructor
|
||||
{
|
||||
protected:
|
||||
nsDOMConstructor(const PRUnichar* aName,
|
||||
|
@ -1827,13 +1827,11 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||
nsWindowSH::InvalidateGlobalScopePolluter(cx, currentInner->mJSObject);
|
||||
}
|
||||
|
||||
// The API we're really looking for here is to go clear all of the
|
||||
// Xray wrappers associated with our outer window. However, we
|
||||
// don't expose that API because the implementation would be
|
||||
// identical to that of JS_TransplantObject, so we just call that
|
||||
// instead.
|
||||
// We're reusing the inner window, but this still counts as a navigation,
|
||||
// so all expandos and such defined on the outer window should go away. Force
|
||||
// all Xray wrappers to be recomputed.
|
||||
xpc_UnmarkGrayObject(mJSObject);
|
||||
if (!JS_TransplantObject(cx, mJSObject, mJSObject)) {
|
||||
if (!JS_RefreshCrossCompartmentWrappers(cx, mJSObject)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
@ -5330,12 +5328,7 @@ nsGlobalWindow::ScrollTo(PRInt32 aXScroll, PRInt32 aYScroll)
|
||||
if (aYScroll > maxpx) {
|
||||
aYScroll = maxpx;
|
||||
}
|
||||
nsPoint pt(nsPresContext::CSSPixelsToAppUnits(aXScroll),
|
||||
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);
|
||||
sf->ScrollToCSSPixels(nsIntPoint(aXScroll, aYScroll));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -246,4 +246,40 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperCache, NS_WRAPPERCACHE_IID)
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
|
||||
// Cycle collector macros for wrapper caches.
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
|
||||
nsContentUtils::TraceWrapper(tmp, aCallback, aClosure);
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
|
||||
nsContentUtils::ReleaseWrapper(s, tmp);
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
|
||||
|
||||
#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(_class, _field) \
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(_field) \
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(_field) \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class)
|
||||
|
||||
#endif /* nsWrapperCache_h___ */
|
||||
|
@ -11,7 +11,7 @@ VPATH = \
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
ifeq ($(MOZ_BUILD_APP),b2g)
|
||||
ifeq ($(MOZ_BUILD_APP), $(filter $(MOZ_BUILD_APP),b2g mail))
|
||||
VPATH += $(srcdir)/fallback
|
||||
endif
|
||||
|
||||
@ -24,7 +24,7 @@ EXTRA_COMPONENTS = \
|
||||
ContactManager.manifest \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_BUILD_APP),b2g)
|
||||
ifeq ($(MOZ_BUILD_APP), $(filter $(MOZ_BUILD_APP),b2g mail))
|
||||
EXTRA_JS_MODULES = \
|
||||
ContactService.jsm \
|
||||
ContactDB.jsm \
|
||||
|
@ -52,9 +52,9 @@ class nsIThread;
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class CheckPermissionsHelper : public nsIRunnable,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIObserver
|
||||
class CheckPermissionsHelper MOZ_FINAL : public nsIRunnable,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -55,9 +55,9 @@ class nsPIDOMWindow;
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class CheckQuotaHelper : public nsIRunnable,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIObserver
|
||||
class CheckQuotaHelper MOZ_FINAL : public nsIRunnable,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -63,7 +63,7 @@ class ContinueObjectStoreHelper;
|
||||
class ContinueIndexHelper;
|
||||
class ContinueIndexObjectHelper;
|
||||
|
||||
class IDBCursor : public nsIIDBCursorWithValue
|
||||
class IDBCursor MOZ_FINAL : public nsIIDBCursorWithValue
|
||||
{
|
||||
friend class ContinueHelper;
|
||||
friend class ContinueObjectStoreHelper;
|
||||
|
@ -57,7 +57,7 @@ struct DatabaseInfo;
|
||||
class IDBDatabase;
|
||||
struct ObjectStoreInfo;
|
||||
|
||||
class IDBFactory : public nsIIDBFactory
|
||||
class IDBFactory MOZ_FINAL : public nsIIDBFactory
|
||||
{
|
||||
typedef nsTArray<nsRefPtr<ObjectStoreInfo> > ObjectStoreInfoArray;
|
||||
|
||||
|
@ -55,7 +55,7 @@ class AsyncConnectionHelper;
|
||||
class IDBObjectStore;
|
||||
struct IndexInfo;
|
||||
|
||||
class IDBIndex : public nsIIDBIndex
|
||||
class IDBIndex MOZ_FINAL : public nsIIDBIndex
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
@ -51,7 +51,7 @@ class mozIStorageStatement;
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class IDBKeyRange : public nsIIDBKeyRange
|
||||
class IDBKeyRange MOZ_FINAL : public nsIIDBKeyRange
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
@ -63,7 +63,7 @@ struct IndexUpdateInfo;
|
||||
struct StructuredCloneReadInfo;
|
||||
struct StructuredCloneWriteInfo;
|
||||
|
||||
class IDBObjectStore : public nsIIDBObjectStore
|
||||
class IDBObjectStore MOZ_FINAL : public nsIIDBObjectStore
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
@ -219,7 +219,7 @@ private:
|
||||
nsTArray<nsRefPtr<FileInfo> > mCreatedFileInfos;
|
||||
};
|
||||
|
||||
class CommitHelper : public nsIRunnable
|
||||
class CommitHelper MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -263,7 +263,7 @@ private:
|
||||
bool mAborted;
|
||||
};
|
||||
|
||||
class UpdateRefcountFunction : public mozIStorageFunction
|
||||
class UpdateRefcountFunction MOZ_FINAL : public mozIStorageFunction
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -125,7 +125,7 @@ GetBaseFilename(const nsAString& aFilename,
|
||||
return true;
|
||||
}
|
||||
|
||||
class QuotaCallback : public mozIStorageQuotaCallback
|
||||
class QuotaCallback MOZ_FINAL : public mozIStorageQuotaCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -69,8 +69,8 @@ class AsyncConnectionHelper;
|
||||
|
||||
class CheckQuotaHelper;
|
||||
|
||||
class IndexedDatabaseManager : public nsIIndexedDatabaseManager,
|
||||
public nsIObserver
|
||||
class IndexedDatabaseManager MOZ_FINAL : public nsIIndexedDatabaseManager,
|
||||
public nsIObserver
|
||||
{
|
||||
friend class IDBDatabase;
|
||||
|
||||
@ -243,7 +243,7 @@ private:
|
||||
// directory that contains them before dispatching itself back to the main
|
||||
// thread. When back on the main thread the runnable will notify the
|
||||
// IndexedDatabaseManager that the job has been completed.
|
||||
class OriginClearRunnable : public nsIRunnable
|
||||
class OriginClearRunnable MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -272,7 +272,7 @@ private:
|
||||
// before dispatching itself back to the main thread. When on the main thread
|
||||
// the runnable will call the callback and then notify the
|
||||
// IndexedDatabaseManager that the job has been completed.
|
||||
class AsyncUsageRunnable : public nsIRunnable
|
||||
class AsyncUsageRunnable MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -326,7 +326,7 @@ private:
|
||||
|
||||
// A callback runnable used by the TransactionPool when it's safe to proceed
|
||||
// with a SetVersion/DeleteDatabase/etc.
|
||||
class WaitForTransactionsToFinishRunnable : public nsIRunnable
|
||||
class WaitForTransactionsToFinishRunnable MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
WaitForTransactionsToFinishRunnable(SynchronizedOp* aOp)
|
||||
@ -345,7 +345,7 @@ private:
|
||||
SynchronizedOp* mOp;
|
||||
};
|
||||
|
||||
class AsyncDeleteFileRunnable : public nsIRunnable
|
||||
class AsyncDeleteFileRunnable MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -853,7 +853,7 @@ UpgradeSchemaFrom7To8(mozIStorageConnection* aConnection)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class CompressDataBlobsFunction : public mozIStorageFunction
|
||||
class CompressDataBlobsFunction MOZ_FINAL : public mozIStorageFunction
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -1095,7 +1095,7 @@ UpgradeSchemaFrom10_0To11_0(mozIStorageConnection* aConnection)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class EncodeKeysFunction : public mozIStorageFunction
|
||||
class EncodeKeysFunction MOZ_FINAL : public mozIStorageFunction
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -90,7 +90,7 @@ CheckOverlapAndMergeObjectStores(nsTArray<nsString>& aLockedStores,
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
class FinishTransactionRunnable : public nsIRunnable
|
||||
class FinishTransactionRunnable MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -91,7 +91,7 @@ public:
|
||||
bool HasTransactionsForDatabase(IDBDatabase* aDatabase);
|
||||
|
||||
protected:
|
||||
class TransactionQueue : public nsIRunnable
|
||||
class TransactionQueue MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -154,22 +154,31 @@ static dom::ConstantSpec gLibcProperties[] =
|
||||
INT_CONSTANT(EINVAL),
|
||||
INT_CONSTANT(EIO),
|
||||
INT_CONSTANT(EISDIR),
|
||||
#if defined(ELOOP) // not defined with VC9
|
||||
INT_CONSTANT(ELOOP),
|
||||
#endif // defined(ELOOP)
|
||||
INT_CONSTANT(EMFILE),
|
||||
INT_CONSTANT(ENAMETOOLONG),
|
||||
INT_CONSTANT(ENFILE),
|
||||
INT_CONSTANT(ELOOP),
|
||||
INT_CONSTANT(ENOENT),
|
||||
INT_CONSTANT(ENOMEM),
|
||||
INT_CONSTANT(ENOSPC),
|
||||
INT_CONSTANT(ENOTDIR),
|
||||
INT_CONSTANT(ENXIO),
|
||||
#if defined(EOPNOTSUPP) // not defined with VC 9
|
||||
INT_CONSTANT(EOPNOTSUPP),
|
||||
#endif // defined(EOPNOTSUPP)
|
||||
#if defined(EOVERFLOW) // not defined with VC 9
|
||||
INT_CONSTANT(EOVERFLOW),
|
||||
#endif // defined(EOVERFLOW)
|
||||
INT_CONSTANT(EPERM),
|
||||
INT_CONSTANT(ERANGE),
|
||||
#if defined(ETIMEDOUT) // not defined with VC 9
|
||||
INT_CONSTANT(ETIMEDOUT),
|
||||
#endif // defined(ETIMEDOUT)
|
||||
#if defined(EWOULDBLOCK) // not defined with VC 9
|
||||
INT_CONSTANT(EWOULDBLOCK),
|
||||
#endif // defined(EWOULDBLOCK)
|
||||
INT_CONSTANT(EXDEV),
|
||||
|
||||
PROP_END
|
||||
|
@ -166,6 +166,8 @@ AudioManager::SetPhoneState(PRInt32 aState)
|
||||
if (AudioSystem::setPhoneState(aState)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPhoneState = aState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ const RIL_IPC_MSG_NAMES = [
|
||||
"RIL:DataInfoChanged",
|
||||
"RIL:EnumerateCalls",
|
||||
"RIL:CallStateChanged",
|
||||
"RIL:CallError",
|
||||
];
|
||||
|
||||
const kVoiceChangedTopic = "mobile-connection-voice-changed";
|
||||
@ -231,22 +232,26 @@ RILContentHelper.prototype = {
|
||||
case "RIL:CallStateChanged":
|
||||
this._deliverTelephonyCallback("callStateChanged",
|
||||
[msg.json.callIndex, msg.json.state,
|
||||
msg.json.number]);
|
||||
msg.json.number, msg.json.isActive]);
|
||||
break;
|
||||
case "RIL:CallError":
|
||||
this._deliverTelephonyCallback("notifyError",
|
||||
[msg.json.callIndex,
|
||||
msg.json.error]);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handleEnumerateCalls: function handleEnumerateCalls(message) {
|
||||
debug("handleEnumerateCalls: " + JSON.stringify(message));
|
||||
handleEnumerateCalls: function handleEnumerateCalls(calls) {
|
||||
debug("handleEnumerateCalls: " + JSON.stringify(calls));
|
||||
let callback = this._enumerationTelephonyCallbacks.shift();
|
||||
let calls = message.calls;
|
||||
let activeCallIndex = message.activeCallIndex;
|
||||
for (let i in calls) {
|
||||
let call = calls[i];
|
||||
let keepGoing;
|
||||
try {
|
||||
keepGoing =
|
||||
callback.enumerateCallState(call.callIndex, call.state, call.number,
|
||||
call.callIndex == activeCallIndex);
|
||||
call.isActive);
|
||||
} catch (e) {
|
||||
debug("callback handler for 'enumerateCallState' threw an " +
|
||||
" exception: " + e);
|
||||
|
@ -288,6 +288,9 @@ RadioInterfaceLayer.prototype = {
|
||||
// This one will handle its own notifications.
|
||||
this.handleEnumerateCalls(message.calls);
|
||||
break;
|
||||
case "callError":
|
||||
this.handleCallError(message);
|
||||
break;
|
||||
case "voiceregistrationstatechange":
|
||||
this.updateVoiceConnection(message);
|
||||
break;
|
||||
@ -437,28 +440,29 @@ RadioInterfaceLayer.prototype = {
|
||||
|
||||
/**
|
||||
* Track the active call and update the audio system as its state changes.
|
||||
*
|
||||
* XXX Needs some more work to support hold/resume.
|
||||
*/
|
||||
_activeCall: null,
|
||||
updateCallAudioState: function updateCallAudioState() {
|
||||
if (!this._activeCall) {
|
||||
// Disable audio.
|
||||
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
|
||||
debug("No active call, put audio system into PHONE_STATE_NORMAL.");
|
||||
debug("No active call, put audio system into PHONE_STATE_NORMAL: "
|
||||
+ gAudioManager.phoneState);
|
||||
return;
|
||||
}
|
||||
switch (this._activeCall.state) {
|
||||
case nsIRadioInterfaceLayer.CALL_STATE_INCOMING:
|
||||
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE;
|
||||
debug("Incoming call, put audio system into PHONE_STATE_RINGTONE.");
|
||||
debug("Incoming call, put audio system into PHONE_STATE_RINGTONE: "
|
||||
+ gAudioManager.phoneState);
|
||||
break;
|
||||
case nsIRadioInterfaceLayer.CALL_STATE_DIALING: // Fall through...
|
||||
case nsIRadioInterfaceLayer.CALL_STATE_CONNECTED:
|
||||
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL;
|
||||
gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION,
|
||||
nsIAudioManager.FORCE_NONE);
|
||||
debug("Active call, put audio system into PHONE_STATE_IN_CALL.");
|
||||
debug("Active call, put audio system into PHONE_STATE_IN_CALL: "
|
||||
+ gAudioManager.phoneState);
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -470,11 +474,12 @@ RadioInterfaceLayer.prototype = {
|
||||
handleCallStateChange: function handleCallStateChange(call) {
|
||||
debug("handleCallStateChange: " + JSON.stringify(call));
|
||||
call.state = convertRILCallState(call.state);
|
||||
if (call.state == nsIRadioInterfaceLayer.CALL_STATE_DIALING ||
|
||||
call.state == nsIRadioInterfaceLayer.CALL_STATE_ALERTING ||
|
||||
call.state == nsIRadioInterfaceLayer.CALL_STATE_CONNECTED) {
|
||||
// This is now the active call.
|
||||
if (call.isActive) {
|
||||
this._activeCall = call;
|
||||
} else if (this._activeCall &&
|
||||
this._activeCall.callIndex == call.callIndex) {
|
||||
// Previously active call is not active now.
|
||||
this._activeCall = null;
|
||||
}
|
||||
this.updateCallAudioState();
|
||||
ppmm.sendAsyncMessage("RIL:CallStateChanged", call);
|
||||
@ -485,7 +490,7 @@ RadioInterfaceLayer.prototype = {
|
||||
*/
|
||||
handleCallDisconnected: function handleCallDisconnected(call) {
|
||||
debug("handleCallDisconnected: " + JSON.stringify(call));
|
||||
if (this._activeCall && this._activeCall.callIndex == call.callIndex) {
|
||||
if (call.isActive) {
|
||||
this._activeCall = null;
|
||||
}
|
||||
this.updateCallAudioState();
|
||||
@ -498,12 +503,17 @@ RadioInterfaceLayer.prototype = {
|
||||
*/
|
||||
handleEnumerateCalls: function handleEnumerateCalls(calls) {
|
||||
debug("handleEnumerateCalls: " + JSON.stringify(calls));
|
||||
let activeCallIndex = this._activeCall ? this._activeCall.callIndex : -1;
|
||||
for (let i in calls) {
|
||||
calls[i].state = convertRILCallState(calls[i].state);
|
||||
}
|
||||
ppmm.sendAsyncMessage("RIL:EnumerateCalls",
|
||||
{calls: calls, activeCallIndex: activeCallIndex});
|
||||
ppmm.sendAsyncMessage("RIL:EnumerateCalls", calls);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle call error.
|
||||
*/
|
||||
handleCallError: function handleCallError(message) {
|
||||
ppmm.sendAsyncMessage("RIL:CallError", message);
|
||||
},
|
||||
|
||||
portAddressedSmsApps: null,
|
||||
@ -738,6 +748,10 @@ RadioInterfaceLayer.prototype = {
|
||||
nsIAudioManager.PHONE_STATE_IN_COMMUNICATION :
|
||||
nsIAudioManager.PHONE_STATE_IN_CALL; //XXX why is this needed?
|
||||
gAudioManager.microphoneMuted = value;
|
||||
|
||||
if (!this._activeCall) {
|
||||
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
|
||||
}
|
||||
},
|
||||
|
||||
get speakerEnabled() {
|
||||
@ -752,6 +766,10 @@ RadioInterfaceLayer.prototype = {
|
||||
let force = value ? nsIAudioManager.FORCE_SPEAKER :
|
||||
nsIAudioManager.FORCE_NONE;
|
||||
gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, force);
|
||||
|
||||
if (!this._activeCall) {
|
||||
gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -44,7 +44,7 @@ interface nsIDOMMozMobileConnectionInfo;
|
||||
interface nsIDOMDOMRequest;
|
||||
interface nsIDOMWindow;
|
||||
|
||||
[scriptable, uuid(03eafd60-d138-4f09-81b4-90cd4996b3c7)]
|
||||
[scriptable, uuid(c14c71b8-afba-403b-8320-94593de9380f)]
|
||||
interface nsIRILTelephonyCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -56,10 +56,13 @@ interface nsIRILTelephonyCallback : nsISupports
|
||||
* One of the nsIRadioInterfaceLayer::CALL_STATE_* values.
|
||||
* @param number
|
||||
* Number of the other party.
|
||||
* @param isActive
|
||||
* Indicates whether this call is the currently active one.
|
||||
*/
|
||||
void callStateChanged(in unsigned long callIndex,
|
||||
in unsigned short callState,
|
||||
in AString number);
|
||||
in AString number,
|
||||
in boolean isActive);
|
||||
|
||||
/**
|
||||
* Called when nsIRILContentHelper is asked to enumerate the current
|
||||
@ -81,6 +84,17 @@ interface nsIRILTelephonyCallback : nsISupports
|
||||
in unsigned short callState,
|
||||
in AString number,
|
||||
in boolean isActive);
|
||||
|
||||
/**
|
||||
* Called when RIL error occurs.
|
||||
*
|
||||
* @param callIndex
|
||||
* Call identifier assigned by the RIL. -1 if no connection
|
||||
* @param error
|
||||
* Error from RIL.
|
||||
*/
|
||||
void notifyError(in long callIndex,
|
||||
in AString error);
|
||||
};
|
||||
|
||||
[scriptable, uuid(66a55943-e63b-4731-aece-9c04bfc14019)]
|
||||
|
@ -1352,6 +1352,17 @@ const GECKO_NETWORK_STATE_SUSPENDED = 2;
|
||||
const GECKO_NETWORK_STATE_DISCONNECTING = 3;
|
||||
const GECKO_NETWORK_STATE_DISCONNECTED = 4;
|
||||
|
||||
const CALL_FAIL_UNOBTAINABLE_NUMBER = 1;
|
||||
const CALL_FAIL_NORMAL = 16;
|
||||
const CALL_FAIL_BUSY = 17;
|
||||
const CALL_FAIL_CONGESTION = 34;
|
||||
const CALL_FAIL_ACM_LIMIT_EXCEEDED = 68;
|
||||
const CALL_FAIL_CALL_BARRED = 240;
|
||||
const CALL_FAIL_FDN_BLOCKED = 241;
|
||||
const CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242;
|
||||
const CALL_FAIL_IMEI_NOT_ACCEPTED = 243;
|
||||
const CALL_FAIL_ERROR_UNSPECIFIED = 0xffff;
|
||||
|
||||
// Other Gecko-specific constants
|
||||
const GECKO_RADIOSTATE_UNAVAILABLE = null;
|
||||
const GECKO_RADIOSTATE_OFF = "off";
|
||||
@ -1365,6 +1376,29 @@ const GECKO_CARDSTATE_NETWORK_LOCKED = "network_locked";
|
||||
const GECKO_CARDSTATE_NOT_READY = null;
|
||||
const GECKO_CARDSTATE_READY = "ready";
|
||||
|
||||
const GECKO_CALL_ERROR_BAD_NUMBER = "BadNumberError";
|
||||
const GECKO_CALL_ERROR_NORMAL_CALL_CLEARING = "NormalCallClearingError";
|
||||
const GECKO_CALL_ERROR_BUSY = "BusyError";
|
||||
const GECKO_CALL_ERROR_CONGESTION = "CongestionError";
|
||||
const GECKO_CALL_ERROR_INCOMING_CALL_EXCEEDED = "IncomingCallExceededError";
|
||||
const GECKO_CALL_ERROR_BARRED = "BarredError";
|
||||
const GECKO_CALL_ERROR_FDN_BLOCKED = "FDNBlockedError";
|
||||
const GECKO_CALL_ERROR_SUBSCRIBER_UNKNOWN = "SubscriberUnknownError";
|
||||
const GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED = "DeviceNotAcceptedError";
|
||||
const GECKO_CALL_ERROR_UNSPECIFIED = "UnspecifiedError";
|
||||
|
||||
const RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR = {};
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_UNOBTAINABLE_NUMBER] = GECKO_CALL_ERROR_BAD_NUMBER;
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_NORMAL] = GECKO_CALL_ERROR_NORMAL_CALL_CLEARING;
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_BUSY] = GECKO_CALL_ERROR_BUSY;
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CONGESTION] = GECKO_CALL_ERROR_CONGESTION;
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ACM_LIMIT_EXCEEDED] = GECKO_CALL_ERROR_INCOMING_CALL_EXCEEDED;
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_CALL_BARRED] = GECKO_CALL_ERROR_BARRED;
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_FDN_BLOCKED] = GECKO_CALL_ERROR_FDN_BLOCKED;
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMSI_UNKNOWN_IN_VLR] = GECKO_CALL_ERROR_SUBSCRIBER_UNKNOWN;
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMEI_NOT_ACCEPTED] = GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED;
|
||||
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ERROR_UNSPECIFIED] = GECKO_CALL_ERROR_UNSPECIFIED;
|
||||
|
||||
const GECKO_RADIO_TECH = [
|
||||
null,
|
||||
"gprs",
|
||||
|
@ -299,15 +299,7 @@ let Buf = {
|
||||
// Strings are \0\0 delimited, but that isn't part of the length. And
|
||||
// if the string length is even, the delimiter is two characters wide.
|
||||
// It's insane, I know.
|
||||
let delimiter = this.readUint16();
|
||||
if (!(string_len & 1)) {
|
||||
delimiter |= this.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
this.readStringDelimiter(string_len);
|
||||
return s;
|
||||
},
|
||||
|
||||
@ -319,6 +311,18 @@ let Buf = {
|
||||
}
|
||||
return strings;
|
||||
},
|
||||
|
||||
readStringDelimiter: function readStringDelimiter(length) {
|
||||
let delimiter = this.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= this.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
readParcelSize: function readParcelSize() {
|
||||
return this.readUint8Unchecked() << 24 |
|
||||
@ -363,10 +367,7 @@ let Buf = {
|
||||
// Strings are \0\0 delimited, but that isn't part of the length. And
|
||||
// if the string length is even, the delimiter is two characters wide.
|
||||
// It's insane, I know.
|
||||
this.writeUint16(0);
|
||||
if (!(value.length & 1)) {
|
||||
this.writeUint16(0);
|
||||
}
|
||||
this.writeStringDelimiter(value.length);
|
||||
},
|
||||
|
||||
writeStringList: function writeStringList(strings) {
|
||||
@ -375,6 +376,13 @@ let Buf = {
|
||||
this.writeString(strings[i]);
|
||||
}
|
||||
},
|
||||
|
||||
writeStringDelimiter: function writeStringDelimiter(length) {
|
||||
this.writeUint16(0);
|
||||
if (!(length & 1)) {
|
||||
this.writeUint16(0);
|
||||
}
|
||||
},
|
||||
|
||||
writeParcelSize: function writeParcelSize(value) {
|
||||
/**
|
||||
@ -644,10 +652,15 @@ let RIL = {
|
||||
networkSelectionMode: null,
|
||||
|
||||
/**
|
||||
* Active calls
|
||||
* Valid calls.
|
||||
*/
|
||||
currentCalls: {},
|
||||
|
||||
/**
|
||||
* Current calls length.
|
||||
*/
|
||||
currentCallsLength: null,
|
||||
|
||||
/**
|
||||
* Existing data calls.
|
||||
*/
|
||||
@ -899,15 +912,7 @@ let RIL = {
|
||||
return;
|
||||
}
|
||||
this.iccInfo.MSISDN = GsmPDUHelper.readAddress(len);
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
Buf.readStringDelimiter(length);
|
||||
|
||||
if (DEBUG) debug("MSISDN: " + this.iccInfo.MSISDN);
|
||||
if (this.iccInfo.MSISDN) {
|
||||
@ -938,15 +943,7 @@ let RIL = {
|
||||
// Each octet is encoded into two chars.
|
||||
let len = length / 2;
|
||||
this.iccInfo.AD = GsmPDUHelper.readHexOctetArray(len);
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
Buf.readStringDelimiter(length);
|
||||
|
||||
if (DEBUG) {
|
||||
let str = "";
|
||||
@ -1005,15 +1002,7 @@ let RIL = {
|
||||
// Each octet is encoded into two chars.
|
||||
let len = length / 2;
|
||||
this.iccInfo.UST = GsmPDUHelper.readHexOctetArray(len);
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
Buf.readStringDelimiter(length);
|
||||
|
||||
if (DEBUG) {
|
||||
let str = "";
|
||||
@ -1460,8 +1449,8 @@ let RIL = {
|
||||
/**
|
||||
* Get failure casue code for the most recently failed PDP context.
|
||||
*/
|
||||
getFailCauseCode: function getFailCauseCode() {
|
||||
Buf.simpleRequest(REQUEST_LAST_CALL_FAIL_CAUSE);
|
||||
getFailCauseCode: function getFailCauseCode(options) {
|
||||
Buf.simpleRequest(REQUEST_LAST_CALL_FAIL_CAUSE, options);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1605,15 +1594,7 @@ let RIL = {
|
||||
// Length of a record, data[14]
|
||||
let recordSize = GsmPDUHelper.readHexOctet();
|
||||
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
Buf.readStringDelimiter(length);
|
||||
|
||||
switch (options.type) {
|
||||
case EF_TYPE_LINEAR_FIXED:
|
||||
@ -1749,12 +1730,19 @@ let RIL = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Helpers for processing call state.
|
||||
* Helpers for processing call state and handle the active call.
|
||||
*/
|
||||
_processCalls: function _processCalls(newCalls) {
|
||||
// Go through the calls we currently have on file and see if any of them
|
||||
// changed state. Remove them from the newCalls map as we deal with them
|
||||
// so that only new calls remain in the map after we're done.
|
||||
let lastCallsLength = this.currentCallsLength;
|
||||
if (newCalls) {
|
||||
this.currentCallsLength = newCalls.length;
|
||||
} else {
|
||||
this.currentCallsLength = 0;
|
||||
}
|
||||
|
||||
for each (let currentCall in this.currentCalls) {
|
||||
let newCall;
|
||||
if (newCalls) {
|
||||
@ -1764,9 +1752,12 @@ let RIL = {
|
||||
|
||||
if (newCall) {
|
||||
// Call is still valid.
|
||||
if (newCall.state != currentCall.state) {
|
||||
// State has changed.
|
||||
if (newCall.state != currentCall.state ||
|
||||
this.currentCallsLength != lastCallsLength) {
|
||||
// State has changed. Active call may have changed as valid
|
||||
// calls change.
|
||||
currentCall.state = newCall.state;
|
||||
currentCall.isActive = this._isActiveCall(currentCall.state);
|
||||
this._handleChangedCallState(currentCall);
|
||||
}
|
||||
} else {
|
||||
@ -1788,6 +1779,7 @@ let RIL = {
|
||||
}
|
||||
// Add to our map.
|
||||
this.currentCalls[newCall.callIndex] = newCall;
|
||||
newCall.isActive = this._isActiveCall(newCall.state);
|
||||
this._handleChangedCallState(newCall);
|
||||
}
|
||||
}
|
||||
@ -1809,6 +1801,24 @@ let RIL = {
|
||||
this.sendDOMMessage(message);
|
||||
},
|
||||
|
||||
_isActiveCall: function _isActiveCall(callState) {
|
||||
switch (callState) {
|
||||
case CALL_STATE_INCOMING:
|
||||
case CALL_STATE_DIALING:
|
||||
case CALL_STATE_ALERTING:
|
||||
case CALL_STATE_ACTIVE:
|
||||
return true;
|
||||
case CALL_STATE_HOLDING:
|
||||
return false;
|
||||
case CALL_STATE_WAITING:
|
||||
if (this.currentCallsLength == 1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_processDataCallList: function _processDataCallList(datacalls) {
|
||||
for each (let currentDataCall in this.currentDataCalls) {
|
||||
let updatedDataCall;
|
||||
@ -1882,15 +1892,7 @@ let RIL = {
|
||||
if (DEBUG) debug(message);
|
||||
|
||||
// Read string delimiters. See Buf.readString().
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(messageStringLength & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
Buf.readStringDelimiter(length);
|
||||
|
||||
return message;
|
||||
},
|
||||
@ -2254,11 +2256,21 @@ RIL[REQUEST_GET_CURRENT_CALLS] = function REQUEST_GET_CURRENT_CALLS(length, opti
|
||||
};
|
||||
}
|
||||
|
||||
call.isActive = false;
|
||||
|
||||
calls[call.callIndex] = call;
|
||||
}
|
||||
calls.length = calls_length;
|
||||
this._processCalls(calls);
|
||||
};
|
||||
RIL[REQUEST_DIAL] = null;
|
||||
RIL[REQUEST_DIAL] = function REQUEST_DIAL(length, options) {
|
||||
if (options.rilRequestError) {
|
||||
// The connection is not established yet.
|
||||
options.callIndex = -1;
|
||||
this.getFailCauseCode(options);
|
||||
return;
|
||||
}
|
||||
};
|
||||
RIL[REQUEST_GET_IMSI] = function REQUEST_GET_IMSI(length, options) {
|
||||
if (options.rilRequestError) {
|
||||
return;
|
||||
@ -2306,7 +2318,20 @@ RIL[REQUEST_SWITCH_HOLDING_AND_ACTIVE] = function REQUEST_SWITCH_HOLDING_AND_ACT
|
||||
};
|
||||
RIL[REQUEST_CONFERENCE] = null;
|
||||
RIL[REQUEST_UDUB] = null;
|
||||
RIL[REQUEST_LAST_CALL_FAIL_CAUSE] = null;
|
||||
RIL[REQUEST_LAST_CALL_FAIL_CAUSE] = function REQUEST_LAST_CALL_FAIL_CAUSE(length, options) {
|
||||
let num = 0;
|
||||
if (length) {
|
||||
num = Buf.readUint32();
|
||||
}
|
||||
if (!num) {
|
||||
return;
|
||||
}
|
||||
|
||||
let failCause = Buf.readUint32();
|
||||
options.type = "callError";
|
||||
options.error = RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[failCause];
|
||||
this.sendDOMMessage(options);
|
||||
};
|
||||
RIL[REQUEST_SIGNAL_STRENGTH] = function REQUEST_SIGNAL_STRENGTH(length, options) {
|
||||
if (options.rilRequestError) {
|
||||
return;
|
||||
@ -3004,26 +3029,6 @@ let GsmPDUHelper = {
|
||||
return number;
|
||||
},
|
||||
|
||||
/**
|
||||
* Read a string from Buf and convert it to BCD
|
||||
*
|
||||
* @return the decimal as a number.
|
||||
*/
|
||||
readStringAsBCD: function readStringAsBCD() {
|
||||
let length = Buf.readUint32();
|
||||
let bcd = this.readSwappedNibbleBCD(length / 2);
|
||||
let delimiter = Buf.readUint16();
|
||||
if (!(length & 1)) {
|
||||
delimiter |= Buf.readUint16();
|
||||
}
|
||||
if (DEBUG) {
|
||||
if (delimiter != 0) {
|
||||
debug("Something's wrong, found string delimiter: " + delimiter);
|
||||
}
|
||||
}
|
||||
return bcd;
|
||||
},
|
||||
|
||||
/**
|
||||
* Write numerical data as swapped nibble BCD.
|
||||
*
|
||||
@ -3476,7 +3481,7 @@ let GsmPDUHelper = {
|
||||
encoding = PDU_DCS_MSG_CODING_16BITS_ALPHABET;
|
||||
break;
|
||||
case 0x30:
|
||||
if (!dcs & 0x04) {
|
||||
if (dcs & 0x04) {
|
||||
encoding = PDU_DCS_MSG_CODING_8BITS_ALPHABET;
|
||||
}
|
||||
break;
|
||||
|
@ -404,7 +404,7 @@ NS_IMPL_EVENT_HANDLER(Telephony, callschanged)
|
||||
|
||||
NS_IMETHODIMP
|
||||
Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState,
|
||||
const nsAString& aNumber)
|
||||
const nsAString& aNumber, bool aIsActive)
|
||||
{
|
||||
NS_ASSERTION(aCallIndex != kOutgoingPlaceholderCallIndex,
|
||||
"This should never happen!");
|
||||
@ -445,7 +445,7 @@ Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState,
|
||||
modifiedCall->ChangeState(aCallState);
|
||||
|
||||
// See if this should replace our current active call.
|
||||
if (aCallState == nsIRadioInterfaceLayer::CALL_STATE_CONNECTED) {
|
||||
if (aIsActive) {
|
||||
mActiveCall = modifiedCall;
|
||||
}
|
||||
|
||||
@ -500,6 +500,31 @@ Telephony::EnumerateCallState(PRUint32 aCallIndex, PRUint16 aCallState,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Telephony::NotifyError(PRInt32 aCallIndex,
|
||||
const nsAString& aError)
|
||||
{
|
||||
PRInt32 index = -1;
|
||||
PRInt32 length = mCalls.Length();
|
||||
|
||||
// The connection is not established yet, remove the latest call object
|
||||
if (aCallIndex == -1) {
|
||||
if (length > 0) {
|
||||
index = length - 1;
|
||||
}
|
||||
} else {
|
||||
if (aCallIndex < 0 || aCallIndex >= length) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
index = aCallIndex;
|
||||
}
|
||||
if (index != -1) {
|
||||
mCalls[index]->NotifyError(aError);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewTelephony(nsPIDOMWindow* aWindow, nsIDOMTelephony** aTelephony)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
#include "CallEvent.h"
|
||||
#include "Telephony.h"
|
||||
#include "DOMError.h"
|
||||
|
||||
USING_TELEPHONY_NAMESPACE
|
||||
|
||||
@ -62,6 +63,7 @@ TelephonyCall::Create(Telephony* aTelephony, const nsAString& aNumber,
|
||||
call->mTelephony = aTelephony;
|
||||
call->mNumber = aNumber;
|
||||
call->mCallIndex = aCallIndex;
|
||||
call->mError = nsnull;
|
||||
|
||||
call->ChangeStateInternal(aCallState, false);
|
||||
|
||||
@ -150,6 +152,27 @@ TelephonyCall::ChangeStateInternal(PRUint16 aCallState, bool aFireEvents)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TelephonyCall::NotifyError(const nsAString& aError)
|
||||
{
|
||||
// Set the error string
|
||||
NS_ASSERTION(!mError, "Already have an error?");
|
||||
|
||||
mError = DOMError::CreateWithName(aError);
|
||||
|
||||
// Do the state transitions
|
||||
ChangeStateInternal(nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTED, true);
|
||||
|
||||
// Notify the error event
|
||||
nsRefPtr<CallEvent> event = CallEvent::Create(this);
|
||||
NS_ASSERTION(event, "This should never fail!");
|
||||
|
||||
if (NS_FAILED(event->Dispatch(ToIDOMEventTarget(),
|
||||
NS_LITERAL_STRING("error")))) {
|
||||
NS_WARNING("Failed to dispatch error event!");
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(TelephonyCall)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TelephonyCall,
|
||||
@ -167,6 +190,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TelephonyCall,
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(holding)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(held)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(resuming)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TelephonyCall,
|
||||
@ -183,6 +207,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TelephonyCall,
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(holding)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(held)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(resuming)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TelephonyCall)
|
||||
@ -209,6 +234,13 @@ TelephonyCall::GetState(nsAString& aState)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyCall::GetError(nsIDOMDOMError** aError)
|
||||
{
|
||||
NS_IF_ADDREF(*aError = mError);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelephonyCall::Answer()
|
||||
{
|
||||
@ -289,3 +321,4 @@ NS_IMPL_EVENT_HANDLER(TelephonyCall, disconnected)
|
||||
NS_IMPL_EVENT_HANDLER(TelephonyCall, holding)
|
||||
NS_IMPL_EVENT_HANDLER(TelephonyCall, held)
|
||||
NS_IMPL_EVENT_HANDLER(TelephonyCall, resuming)
|
||||
NS_IMPL_EVENT_HANDLER(TelephonyCall, error)
|
||||
|
@ -63,11 +63,13 @@ class TelephonyCall : public nsDOMEventTargetHelper,
|
||||
NS_DECL_EVENT_HANDLER(holding)
|
||||
NS_DECL_EVENT_HANDLER(held)
|
||||
NS_DECL_EVENT_HANDLER(resuming)
|
||||
NS_DECL_EVENT_HANDLER(error)
|
||||
|
||||
nsRefPtr<Telephony> mTelephony;
|
||||
|
||||
nsString mNumber;
|
||||
nsString mState;
|
||||
nsCOMPtr<nsIDOMDOMError> mError;
|
||||
|
||||
PRUint32 mCallIndex;
|
||||
PRUint16 mCallState;
|
||||
@ -130,6 +132,9 @@ public:
|
||||
return mOutgoing;
|
||||
}
|
||||
|
||||
void
|
||||
NotifyError(const nsAString& aError);
|
||||
|
||||
private:
|
||||
TelephonyCall()
|
||||
: mCallIndex(kOutgoingPlaceholderCallIndex),
|
||||
|
@ -38,16 +38,19 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIDOMEventTarget.idl"
|
||||
#include "nsIDOMDOMError.idl"
|
||||
|
||||
interface nsIDOMEventListener;
|
||||
|
||||
[scriptable, builtinclass, uuid(2fb9502b-2054-4eda-8db7-3726c39144f7)]
|
||||
[scriptable, builtinclass, uuid(d902afb1-2e1d-412e-bfa3-cb6a9453a4db)]
|
||||
interface nsIDOMTelephonyCall : nsIDOMEventTarget
|
||||
{
|
||||
readonly attribute DOMString number;
|
||||
|
||||
readonly attribute DOMString state;
|
||||
|
||||
readonly attribute nsIDOMDOMError error;
|
||||
|
||||
void answer();
|
||||
void hangUp();
|
||||
void hold();
|
||||
@ -65,4 +68,6 @@ interface nsIDOMTelephonyCall : nsIDOMEventTarget
|
||||
attribute nsIDOMEventListener onholding;
|
||||
attribute nsIDOMEventListener onheld;
|
||||
attribute nsIDOMEventListener onresuming;
|
||||
|
||||
attribute nsIDOMEventListener onerror;
|
||||
};
|
||||
|
@ -16,7 +16,7 @@
|
||||
#ifdef MOZ_TABLETS_ONLY
|
||||
<supports-screens android:smallScreens="false"
|
||||
android:normalScreens="false"
|
||||
android:largeScreens="true"
|
||||
android:largeScreens="false"
|
||||
android:xlargeScreens="true" />
|
||||
#endif
|
||||
|
||||
|
@ -88,7 +88,8 @@ struct Rect :
|
||||
{
|
||||
*aOut = IntRect(int32_t(X()), int32_t(Y()),
|
||||
int32_t(Width()), int32_t(Height()));
|
||||
return Rect(aOut->x, aOut->y, aOut->width, aOut->height).IsEqualEdges(*this);
|
||||
return Rect(Float(aOut->x), Float(aOut->y),
|
||||
Float(aOut->width), Float(aOut->height)).IsEqualEdges(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -4031,7 +4031,13 @@ _cairo_image_surface_glyphs (void *abstract_surface,
|
||||
composite_glyphs_info_t glyph_info;
|
||||
cairo_clip_t local_clip;
|
||||
cairo_bool_t have_clip = FALSE;
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
// For performance reasons we don't want to use two passes for overlapping glyphs
|
||||
// on mobile
|
||||
cairo_bool_t overlap = FALSE;
|
||||
#else
|
||||
cairo_bool_t overlap;
|
||||
#endif
|
||||
cairo_status_t status;
|
||||
|
||||
cairo_rectangle_int_t rect;
|
||||
@ -4045,7 +4051,12 @@ _cairo_image_surface_glyphs (void *abstract_surface,
|
||||
scaled_font,
|
||||
glyphs, num_glyphs,
|
||||
clip,
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
NULL);
|
||||
#else
|
||||
&overlap);
|
||||
#endif
|
||||
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
|
@ -185,17 +185,8 @@ CFLAGS += -Wno-missing-field-initializers
|
||||
endif # GNU_CC
|
||||
|
||||
# special rule for pixman-mmx to get the right cflags
|
||||
pixman-mmx.$(OBJ_SUFFIX): pixman-mmx.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(MMX_CFLAGS) $(_VPATH_SRCS)
|
||||
pixman-mmx.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(MMX_CFLAGS)
|
||||
|
||||
pixman-sse2.$(OBJ_SUFFIX): pixman-sse2.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(SSE2_CFLAGS) $(_VPATH_SRCS)
|
||||
pixman-sse2.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(SSE2_CFLAGS)
|
||||
|
||||
pixman-arm-neon.$(OBJ_SUFFIX): pixman-arm-neon.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(ARM_NEON_CFLAGS) $(_VPATH_SRCS)
|
||||
pixman-arm-neon.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(ARM_NEON_CFLAGS)
|
||||
|
@ -101,12 +101,6 @@ CFLAGS += -Wno-missing-field-initializers
|
||||
endif # GNU_CC
|
||||
|
||||
# special rules for transform-sse*.c to get the right cflags. (taken from pixman/src/Makefile.in)
|
||||
transform-sse1.$(OBJ_SUFFIX): transform-sse1.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(SSE1_FLAGS) $(_VPATH_SRCS)
|
||||
transform-sse1.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(SSE1_FLAGS)
|
||||
|
||||
transform-sse2.$(OBJ_SUFFIX): transform-sse2.c $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(SSE2_FLAGS) $(_VPATH_SRCS)
|
||||
transform-sse2.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(SSE2_FLAGS)
|
||||
|
191
gfx/skia/arm-fixes.patch
Normal file
@ -0,0 +1,191 @@
|
||||
diff --git a/gfx/skia/include/core/SkMath.h b/gfx/skia/include/core/SkMath.h
|
||||
--- a/gfx/skia/include/core/SkMath.h
|
||||
+++ b/gfx/skia/include/core/SkMath.h
|
||||
@@ -148,20 +148,17 @@ static inline bool SkIsPow2(int value) {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t.
|
||||
With this requirement, we can generate faster instructions on some
|
||||
architectures.
|
||||
*/
|
||||
-#if defined(__arm__) \
|
||||
- && !defined(__thumb__) \
|
||||
- && !defined(__ARM_ARCH_4T__) \
|
||||
- && !defined(__ARM_ARCH_5T__)
|
||||
+#ifdef SK_ARM_HAS_EDSP
|
||||
static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
|
||||
SkASSERT((int16_t)x == x);
|
||||
SkASSERT((int16_t)y == y);
|
||||
int32_t product;
|
||||
asm("smulbb %0, %1, %2 \n"
|
||||
: "=r"(product)
|
||||
: "r"(x), "r"(y)
|
||||
);
|
||||
diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
|
||||
--- a/gfx/skia/include/core/SkPostConfig.h
|
||||
+++ b/gfx/skia/include/core/SkPostConfig.h
|
||||
@@ -300,8 +300,53 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
|
||||
#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
|
||||
#endif
|
||||
+
|
||||
+//////////////////////////////////////////////////////////////////////
|
||||
+// ARM defines
|
||||
+
|
||||
+#if defined(__GNUC__) && defined(__arm__)
|
||||
+
|
||||
+# define SK_ARM_ARCH 3
|
||||
+
|
||||
+# if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) \
|
||||
+ || defined(_ARM_ARCH_4)
|
||||
+# undef SK_ARM_ARCH
|
||||
+# define SK_ARM_ARCH 4
|
||||
+# endif
|
||||
+
|
||||
+# if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|
||||
+ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|
||||
+ || defined(__ARM_ARCH_5TEJ__) || defined(_ARM_ARCH_5)
|
||||
+# undef SK_ARM_ARCH
|
||||
+# define SK_ARM_ARCH 5
|
||||
+# endif
|
||||
+
|
||||
+# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|
||||
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
|
||||
+ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|
||||
+ || defined(__ARM_ARCH_6M__) || defined(_ARM_ARCH_6)
|
||||
+# undef SK_ARM_ARCH
|
||||
+# define SK_ARM_ARCH 6
|
||||
+# endif
|
||||
+
|
||||
+# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|
||||
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
|
||||
+ || defined(__ARM_ARCH_7EM__) || defined(_ARM_ARCH_7)
|
||||
+# undef SK_ARM_ARCH
|
||||
+# define SK_ARM_ARCH 7
|
||||
+# endif
|
||||
+
|
||||
+# undef SK_ARM_HAS_EDSP
|
||||
+# if defined(__thumb2__) && (SK_ARM_ARCH >= 6) \
|
||||
+ || !defined(__thumb__) \
|
||||
+ && ((SK_ARM_ARCH > 5) || defined(__ARM_ARCH_5E__) \
|
||||
+ || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__))
|
||||
+# define SK_ARM_HAS_EDSP 1
|
||||
+# endif
|
||||
+
|
||||
+#endif
|
||||
diff --git a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
|
||||
--- a/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
|
||||
+++ b/gfx/skia/src/opts/SkBitmapProcState_opts_arm.cpp
|
||||
@@ -6,17 +6,17 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
|
||||
#include "SkBitmapProcState.h"
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkUtils.h"
|
||||
|
||||
-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
+#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
void SI8_D16_nofilter_DX_arm(
|
||||
const SkBitmapProcState& s,
|
||||
const uint32_t* SK_RESTRICT xy,
|
||||
int count,
|
||||
uint16_t* SK_RESTRICT colors) __attribute__((optimize("O1")));
|
||||
|
||||
void SI8_D16_nofilter_DX_arm(const SkBitmapProcState& s,
|
||||
const uint32_t* SK_RESTRICT xy,
|
||||
@@ -177,17 +177,17 @@ void SI8_opaque_D32_nofilter_DX_arm(cons
|
||||
: [xx] "+r" (xx), [count] "+r" (count), [colors] "+r" (colors)
|
||||
: [table] "r" (table), [srcAddr] "r" (srcAddr)
|
||||
: "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11"
|
||||
);
|
||||
}
|
||||
|
||||
s.fBitmap->getColorTable()->unlockColors(false);
|
||||
}
|
||||
-#endif //__ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
+#endif // SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* If we replace a sampleproc, then we null-out the associated shaderproc,
|
||||
otherwise the shader won't even look at the matrix/sampler
|
||||
*/
|
||||
void SkBitmapProcState::platformProcs() {
|
||||
bool doFilter = fDoFilter;
|
||||
@@ -195,17 +195,17 @@ void SkBitmapProcState::platformProcs()
|
||||
bool justDx = false;
|
||||
|
||||
if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
|
||||
justDx = true;
|
||||
}
|
||||
|
||||
switch (fBitmap->config()) {
|
||||
case SkBitmap::kIndex8_Config:
|
||||
-#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
+#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
if (justDx && !doFilter) {
|
||||
#if 0 /* crashing on android device */
|
||||
fSampleProc16 = SI8_D16_nofilter_DX_arm;
|
||||
fShaderProc16 = NULL;
|
||||
#endif
|
||||
if (isOpaque) {
|
||||
// this one is only very slighty faster than the C version
|
||||
fSampleProc32 = SI8_opaque_D32_nofilter_DX_arm;
|
||||
diff --git a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
|
||||
--- a/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
|
||||
+++ b/gfx/skia/src/opts/SkBlitRow_opts_arm.cpp
|
||||
@@ -669,18 +669,23 @@ static void __attribute((noinline,optimi
|
||||
/* Double Loop */
|
||||
"1: \n\t" /* <double loop> */
|
||||
"ldm %[src]!, {r5, r6} \n\t" /* loading src pointers into r5 and r6 */
|
||||
"ldm %[dst], {r7, r8} \n\t" /* loading dst pointers into r7 and r8 */
|
||||
|
||||
/* dst1_scale and dst2_scale*/
|
||||
"lsr r9, r5, #24 \n\t" /* src >> 24 */
|
||||
"lsr r10, r6, #24 \n\t" /* src >> 24 */
|
||||
+#ifdef SK_ARM_HAS_EDSP
|
||||
"smulbb r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */
|
||||
"smulbb r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */
|
||||
+#else
|
||||
+ "mul r9, r9, %[alpha] \n\t" /* r9 = SkMulS16 r9 with src_scale */
|
||||
+ "mul r10, r10, %[alpha] \n\t" /* r10 = SkMulS16 r10 with src_scale */
|
||||
+#endif
|
||||
"lsr r9, r9, #8 \n\t" /* r9 >> 8 */
|
||||
"lsr r10, r10, #8 \n\t" /* r10 >> 8 */
|
||||
"rsb r9, r9, #256 \n\t" /* dst1_scale = r9 = 255 - r9 + 1 */
|
||||
"rsb r10, r10, #256 \n\t" /* dst2_scale = r10 = 255 - r10 + 1 */
|
||||
|
||||
/* ---------------------- */
|
||||
|
||||
/* src1, src1_scale */
|
||||
@@ -739,17 +744,21 @@ static void __attribute((noinline,optimi
|
||||
/* else get into the single loop */
|
||||
/* Single Loop */
|
||||
"2: \n\t" /* <single loop> */
|
||||
"ldr r5, [%[src]], #4 \n\t" /* loading src pointer into r5: r5=src */
|
||||
"ldr r7, [%[dst]] \n\t" /* loading dst pointer into r7: r7=dst */
|
||||
|
||||
"lsr r6, r5, #24 \n\t" /* src >> 24 */
|
||||
"and r8, r12, r5, lsr #8 \n\t" /* ag = r8 = r5 masked by r12 lsr by #8 */
|
||||
+#ifdef SK_ARM_HAS_EDSP
|
||||
"smulbb r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */
|
||||
+#else
|
||||
+ "mul r6, r6, %[alpha] \n\t" /* r6 = SkMulS16 with src_scale */
|
||||
+#endif
|
||||
"and r9, r12, r5 \n\t" /* rb = r9 = r5 masked by r12 */
|
||||
"lsr r6, r6, #8 \n\t" /* r6 >> 8 */
|
||||
"mul r8, r8, %[alpha] \n\t" /* ag = r8 times scale */
|
||||
"rsb r6, r6, #256 \n\t" /* r6 = 255 - r6 + 1 */
|
||||
|
||||
/* src, src_scale */
|
||||
"mul r9, r9, %[alpha] \n\t" /* rb = r9 times scale */
|
||||
"and r8, r8, r12, lsl #8 \n\t" /* ag masked by reverse mask (r12) */
|
@ -153,10 +153,7 @@ static inline bool SkIsPow2(int value) {
|
||||
With this requirement, we can generate faster instructions on some
|
||||
architectures.
|
||||
*/
|
||||
#if defined(__arm__) \
|
||||
&& !defined(__thumb__) \
|
||||
&& !defined(__ARM_ARCH_4T__) \
|
||||
&& !defined(__ARM_ARCH_5T__)
|
||||
#ifdef SK_ARM_HAS_EDSP
|
||||
static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
|
||||
SkASSERT((int16_t)x == x);
|
||||
SkASSERT((int16_t)y == y);
|
||||
|
@ -305,3 +305,48 @@
|
||||
#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
|
||||
#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// ARM defines
|
||||
|
||||
#if defined(__GNUC__) && defined(__arm__)
|
||||
|
||||
# define SK_ARM_ARCH 3
|
||||
|
||||
# if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) \
|
||||
|| defined(_ARM_ARCH_4)
|
||||
# undef SK_ARM_ARCH
|
||||
# define SK_ARM_ARCH 4
|
||||
# endif
|
||||
|
||||
# if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|
||||
|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|
||||
|| defined(__ARM_ARCH_5TEJ__) || defined(_ARM_ARCH_5)
|
||||
# undef SK_ARM_ARCH
|
||||
# define SK_ARM_ARCH 5
|
||||
# endif
|
||||
|
||||
# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|
||||
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
|
||||
|| defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|
||||
|| defined(__ARM_ARCH_6M__) || defined(_ARM_ARCH_6)
|
||||
# undef SK_ARM_ARCH
|
||||
# define SK_ARM_ARCH 6
|
||||
# endif
|
||||
|
||||
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|
||||
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
|
||||
|| defined(__ARM_ARCH_7EM__) || defined(_ARM_ARCH_7)
|
||||
# undef SK_ARM_ARCH
|
||||
# define SK_ARM_ARCH 7
|
||||
# endif
|
||||
|
||||
# undef SK_ARM_HAS_EDSP
|
||||
# if defined(__thumb2__) && (SK_ARM_ARCH >= 6) \
|
||||
|| !defined(__thumb__) \
|
||||
&& ((SK_ARM_ARCH > 5) || defined(__ARM_ARCH_5E__) \
|
||||
|| defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__))
|
||||
# define SK_ARM_HAS_EDSP 1
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "SkColorPriv.h"
|
||||
#include "SkUtils.h"
|
||||
|
||||
#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
void SI8_D16_nofilter_DX_arm(
|
||||
const SkBitmapProcState& s,
|
||||
const uint32_t* SK_RESTRICT xy,
|
||||
@ -182,7 +182,7 @@ void SI8_opaque_D32_nofilter_DX_arm(const SkBitmapProcState& s,
|
||||
|
||||
s.fBitmap->getColorTable()->unlockColors(false);
|
||||
}
|
||||
#endif //__ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
#endif // SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -200,7 +200,7 @@ void SkBitmapProcState::platformProcs() {
|
||||
|
||||
switch (fBitmap->config()) {
|
||||
case SkBitmap::kIndex8_Config:
|
||||
#if __ARM_ARCH__ >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
#if SK_ARM_ARCH >= 6 && !defined(SK_CPU_BENDIAN)
|
||||
if (justDx && !doFilter) {
|
||||
#if 0 /* crashing on android device */
|
||||
fSampleProc16 = SI8_D16_nofilter_DX_arm;
|
||||
|