Merge last green changeset from inbound to mozilla-central

This commit is contained in:
Matt Brubeck 2012-06-12 18:24:45 -07:00
Родитель 1aace33209 0df5f0a3a5
Коммит 99e40fe0fb
266 изменённых файлов: 3575 добавлений и 984 удалений

Просмотреть файл

@ -649,8 +649,7 @@ Accessible::NativeState()
{
PRUint64 state = 0;
DocAccessible* document = Document();
if (!document || !document->IsInDocument(this))
if (!IsInDocument())
state |= states::STALE;
if (mContent->IsElement()) {

Просмотреть файл

@ -689,6 +689,11 @@ public:
*/
bool IsDefunct() const { return mFlags & eIsDefunct; }
/**
* Return true if the accessible is no longer in the document.
*/
bool IsInDocument() const { return !(mFlags & eIsNotInDocument); }
protected:
//////////////////////////////////////////////////////////////////////////////
@ -737,7 +742,8 @@ protected:
* @note keep these flags in sync with ChildrenFlags
*/
enum StateFlags {
eIsDefunct = 1 << 2 // accessible is defunct
eIsDefunct = 1 << 2, // accessible is defunct
eIsNotInDocument = 1 << 3 // accessible is not in document
};
/**
@ -745,22 +751,22 @@ protected:
* @note keep these flags in sync with ChildrenFlags and StateFlags
*/
enum AccessibleTypes {
eApplicationAccessible = 1 << 3,
eAutoCompleteAccessible = 1 << 4,
eAutoCompletePopupAccessible = 1 << 5,
eComboboxAccessible = 1 << 6,
eDocAccessible = 1 << 7,
eHyperTextAccessible = 1 << 8,
eHTMLFileInputAccessible = 1 << 9,
eHTMLListItemAccessible = 1 << 10,
eImageAccessible = 1 << 11,
eImageMapAccessible = 1 << 12,
eListControlAccessible = 1 << 13,
eMenuButtonAccessible = 1 << 14,
eMenuPopupAccessible = 1 << 15,
eRootAccessible = 1 << 16,
eTextLeafAccessible = 1 << 17,
eXULTreeAccessible = 1 << 18
eApplicationAccessible = 1 << 4,
eAutoCompleteAccessible = 1 << 5,
eAutoCompletePopupAccessible = 1 << 6,
eComboboxAccessible = 1 << 7,
eDocAccessible = 1 << 8,
eHyperTextAccessible = 1 << 9,
eHTMLFileInputAccessible = 1 << 10,
eHTMLListItemAccessible = 1 << 11,
eImageAccessible = 1 << 12,
eImageMapAccessible = 1 << 13,
eListControlAccessible = 1 << 14,
eMenuButtonAccessible = 1 << 15,
eMenuPopupAccessible = 1 << 16,
eRootAccessible = 1 << 17,
eTextLeafAccessible = 1 << 18,
eXULTreeAccessible = 1 << 19
};
//////////////////////////////////////////////////////////////////////////////
@ -871,6 +877,7 @@ protected:
eChildrenUninitialized | eMixedChildren | eEmbeddedChildren;
PRUint32 mFlags;
friend class DocAccessible;
nsAutoPtr<EmbeddedObjCollector> mEmbeddedObjCollector;
PRInt32 mIndexOfEmbeddedChild;

Просмотреть файл

@ -2020,6 +2020,8 @@ DocAccessible::CacheChildrenInSubtree(Accessible* aRoot)
void
DocAccessible::UncacheChildrenInSubtree(Accessible* aRoot)
{
aRoot->mFlags |= eIsNotInDocument;
if (aRoot->IsElement())
RemoveDependentIDsFor(aRoot);

Просмотреть файл

@ -242,18 +242,6 @@ public:
bool HasAccessible(nsINode* aNode) const
{ return GetAccessible(aNode); }
/**
* Return true if the given accessible is in document.
*/
bool IsInDocument(Accessible* aAccessible) const
{
Accessible* acc = aAccessible;
while (acc && !acc->IsPrimaryForNode())
acc = acc->Parent();
return acc ? mNodeToAccessibleMap.Get(acc->GetNode()) : false;
}
/**
* Return the cached accessible by the given unique ID within this document.
*

Просмотреть файл

@ -17,6 +17,392 @@ Cu.import('resource://gre/modules/Services.jsm');
var gAccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
getService(Ci.nsIAccessibleRetrieval);
var TraversalRules = {
Simple: {
getMatchRoles: function SimpleTraversalRule_getmatchRoles(aRules) {
aRules.value = this._matchRoles;
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
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
// where the list box hangs out.
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
case Ci.nsIAccessibleRole.ROLE_TEXT_LEAF:
{
// Nameless text leaves are boring, skip them.
let name = aAccessible.name;
if (name && name.trim())
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
else
return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
}
case Ci.nsIAccessibleRole.ROLE_LINK:
// If the link has children we should land on them instead.
// Image map links don't have children so we need to match those.
if (aAccessible.childCount == 0)
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
else
return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
default:
// Ignore the subtree, if there is one. So that we don't land on
// the same content that was already presented by its parent.
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH |
Ci.nsIAccessibleTraversalRule.FILTER_IGNORE_SUBTREE;
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule]),
_matchRoles: [
Ci.nsIAccessibleRole.ROLE_MENUITEM,
Ci.nsIAccessibleRole.ROLE_LINK,
Ci.nsIAccessibleRole.ROLE_PAGETAB,
Ci.nsIAccessibleRole.ROLE_GRAPHIC,
// XXX: Find a better solution for ROLE_STATICTEXT.
// It allows to filter list bullets but at the same time it
// filters CSS generated content too as an unwanted side effect.
// Ci.nsIAccessibleRole.ROLE_STATICTEXT,
Ci.nsIAccessibleRole.ROLE_TEXT_LEAF,
Ci.nsIAccessibleRole.ROLE_PUSHBUTTON,
Ci.nsIAccessibleRole.ROLE_CHECKBUTTON,
Ci.nsIAccessibleRole.ROLE_RADIOBUTTON,
Ci.nsIAccessibleRole.ROLE_COMBOBOX,
Ci.nsIAccessibleRole.ROLE_PROGRESSBAR,
Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWN,
Ci.nsIAccessibleRole.ROLE_BUTTONMENU,
Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM,
Ci.nsIAccessibleRole.ROLE_PASSWORD_TEXT,
Ci.nsIAccessibleRole.ROLE_RADIO_MENU_ITEM,
Ci.nsIAccessibleRole.ROLE_TOGGLE_BUTTON,
Ci.nsIAccessibleRole.ROLE_ENTRY
]
},
Anchor: {
getMatchRoles: function AnchorTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_LINK];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function AnchorTraversalRule_match(aAccessible)
{
// We want to ignore links, only focus named anchors.
let state = {};
let extraState = {};
aAccessible.getState(state, extraState);
if (state.value & Ci.nsIAccessibleStates.STATE_LINKED) {
return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
} else {
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
Button: {
getMatchRoles: function ButtonTraversalRule_getMatchRoles(aRules)
{
aRules.value = this._matchRoles;
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function ButtonTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule]),
_matchRoles: [
Ci.nsIAccessibleRole.ROLE_PUSHBUTTON,
Ci.nsIAccessibleRole.ROLE_SPINBUTTON,
Ci.nsIAccessibleRole.ROLE_TOGGLE_BUTTON,
Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWN,
Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID
]
},
Combobox: {
getMatchRoles: function ComboboxTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_COMBOBOX,
Ci.nsIAccessibleRole.ROLE_LISTBOX];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function ComboboxTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
Entry: {
getMatchRoles: function EntryTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_ENTRY,
Ci.nsIAccessibleRole.ROLE_PASSWORD_TEXT];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function EntryTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
FormElement: {
getMatchRoles: function FormElementTraversalRule_getMatchRoles(aRules)
{
aRules.value = this._matchRoles;
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function FormElementTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule]),
_matchRoles: [
Ci.nsIAccessibleRole.ROLE_PUSHBUTTON,
Ci.nsIAccessibleRole.ROLE_SPINBUTTON,
Ci.nsIAccessibleRole.ROLE_TOGGLE_BUTTON,
Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWN,
Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID,
Ci.nsIAccessibleRole.ROLE_COMBOBOX,
Ci.nsIAccessibleRole.ROLE_LISTBOX,
Ci.nsIAccessibleRole.ROLE_ENTRY,
Ci.nsIAccessibleRole.ROLE_PASSWORD_TEXT,
Ci.nsIAccessibleRole.ROLE_PAGETAB,
Ci.nsIAccessibleRole.ROLE_RADIOBUTTON,
Ci.nsIAccessibleRole.ROLE_RADIO_MENU_ITEM,
Ci.nsIAccessibleRole.ROLE_SLIDER,
Ci.nsIAccessibleRole.ROLE_CHECKBUTTON,
Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM
]
},
Graphic: {
getMatchRoles: function GraphicTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_GRAPHIC];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function GraphicTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
Heading: {
getMatchRoles: function HeadingTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_HEADING];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function HeadingTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
ListItem: {
getMatchRoles: function ListItemTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_LISTITEM,
Ci.nsIAccessibleRole.ROLE_TERM];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function ListItemTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
Link: {
getMatchRoles: function LinkTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_LINK];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function LinkTraversalRule_match(aAccessible)
{
// We want to ignore anchors, only focus real links.
let state = {};
let extraState = {};
aAccessible.getState(state, extraState);
if (state.value & Ci.nsIAccessibleStates.STATE_LINKED) {
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
} else {
return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
List: {
getMatchRoles: function ListTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_LIST,
Ci.nsIAccessibleRole.ROLE_DEFINITION_LIST];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function ListTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
PageTab: {
getMatchRoles: function PageTabTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_PAGETAB];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function PageTabTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
RadioButton: {
getMatchRoles: function RadioButtonTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_RADIOBUTTON,
Ci.nsIAccessibleRole.ROLE_RADIO_MENU_ITEM];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function RadioButtonTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
Separator: {
getMatchRoles: function SeparatorTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_SEPARATOR];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function SeparatorTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
Table: {
getMatchRoles: function TableTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_TABLE];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function TableTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
},
Checkbox: {
getMatchRoles: function CheckboxTraversalRule_getMatchRoles(aRules)
{
aRules.value = [Ci.nsIAccessibleRole.ROLE_CHECKBUTTON,
Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM];
return aRules.value.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
match: function CheckboxTraversalRule_match(aAccessible)
{
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
}
};
var VirtualCursorController = {
NOT_EDITABLE: 0,
SINGLE_LINE_EDITABLE: 1,
@ -45,6 +431,23 @@ var VirtualCursorController = {
let target = aEvent.target;
switch (aEvent.keyCode) {
case 0:
// an alphanumeric key was pressed, handle it separately.
// If it was pressed with either alt or ctrl, just pass through.
// If it was pressed with meta, pass the key on without the meta.
if (this._isEditableText(target) ||
aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey)
return;
let key = String.fromCharCode(aEvent.charCode);
let methodName = '', rule = {};
try {
[methodName, rule] = this.keyMap[key];
} catch (x) {
return;
}
this[methodName](document, false, rule);
break;
case aEvent.DOM_VK_END:
this.moveForward(document, true);
break;
@ -114,30 +517,30 @@ var VirtualCursorController = {
return this.NOT_EDITABLE;
},
moveForward: function moveForward(document, last) {
let virtualCursor = this.getVirtualCursor(document);
if (last) {
virtualCursor.moveLast(this.SimpleTraversalRule);
moveForward: function moveForward(aDocument, aLast, aRule) {
let virtualCursor = this.getVirtualCursor(aDocument);
if (aLast) {
virtualCursor.moveLast(TraversalRules.Simple);
} else {
try {
virtualCursor.moveNext(this.SimpleTraversalRule);
virtualCursor.moveNext(aRule || TraversalRules.Simple);
} catch (x) {
this.moveCursorToObject(
gAccRetrieval.getAccessibleFor(document.activeElement));
gAccRetrieval.getAccessibleFor(aDocument.activeElement), aRule);
}
}
},
moveBackward: function moveBackward(document, first) {
let virtualCursor = this.getVirtualCursor(document);
if (first) {
virtualCursor.moveFirst(this.SimpleTraversalRule);
moveBackward: function moveBackward(aDocument, aFirst, aRule) {
let virtualCursor = this.getVirtualCursor(aDocument);
if (aFirst) {
virtualCursor.moveFirst(TraversalRules.Simple);
} else {
try {
virtualCursor.movePrevious(this.SimpleTraversalRule);
virtualCursor.movePrevious(aRule || TraversalRules.Simple);
} catch (x) {
this.moveCursorToObject(
gAccRetrieval.getAccessibleFor(document.activeElement));
gAccRetrieval.getAccessibleFor(aDocument.activeElement), aRule);
}
}
},
@ -160,8 +563,8 @@ var VirtualCursorController = {
let objX = {}, objY = {}, objW = {}, objH = {};
acc.getBounds(objX, objY, objW, objH);
let x = Math.round((objX.value - docX.value) + objW.value/2);
let y = Math.round((objY.value - docY.value) + objH.value/2);
let x = Math.round((objX.value - docX.value) + objW.value / 2);
let y = Math.round((objY.value - docY.value) + objH.value / 2);
let cwu = this.chromeWin.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
@ -186,74 +589,41 @@ var VirtualCursorController = {
continue;
}
if (vc)
vc.moveNext(aRule || this.SimpleTraversalRule, aAccessible, true);
vc.moveNext(aRule || TraversalRules.Simple, aAccessible, true);
break;
}
},
SimpleTraversalRule: {
getMatchRoles: function SimpleTraversalRule_getmatchRoles(aRules) {
aRules.value = this._matchRoles;
return this._matchRoles.length;
},
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
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
// where the list box hangs out.
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
case Ci.nsIAccessibleRole.ROLE_TEXT_LEAF:
{
// Nameless text leaves are boring, skip them.
let name = aAccessible.name;
if (name && name.trim())
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
else
return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
}
case Ci.nsIAccessibleRole.ROLE_LINK:
// If the link has children we should land on them instead.
// Image map links don't have children so we need to match those.
if (aAccessible.childCount == 0)
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
else
return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
default:
// Ignore the subtree, if there is one. So that we don't land on
// the same content that was already presented by its parent.
return Ci.nsIAccessibleTraversalRule.FILTER_MATCH |
Ci.nsIAccessibleTraversalRule.FILTER_IGNORE_SUBTREE;
}
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule]),
_matchRoles: [
Ci.nsIAccessibleRole.ROLE_MENUITEM,
Ci.nsIAccessibleRole.ROLE_LINK,
Ci.nsIAccessibleRole.ROLE_PAGETAB,
Ci.nsIAccessibleRole.ROLE_GRAPHIC,
// XXX: Find a better solution for ROLE_STATICTEXT.
// It allows to filter list bullets but at the same time it
// filters CSS generated content too as an unwanted side effect.
// Ci.nsIAccessibleRole.ROLE_STATICTEXT,
Ci.nsIAccessibleRole.ROLE_TEXT_LEAF,
Ci.nsIAccessibleRole.ROLE_PUSHBUTTON,
Ci.nsIAccessibleRole.ROLE_CHECKBUTTON,
Ci.nsIAccessibleRole.ROLE_RADIOBUTTON,
Ci.nsIAccessibleRole.ROLE_COMBOBOX,
Ci.nsIAccessibleRole.ROLE_PROGRESSBAR,
Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWN,
Ci.nsIAccessibleRole.ROLE_BUTTONMENU,
Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM,
Ci.nsIAccessibleRole.ROLE_PASSWORD_TEXT,
Ci.nsIAccessibleRole.ROLE_RADIO_MENU_ITEM,
Ci.nsIAccessibleRole.ROLE_TOGGLE_BUTTON,
Ci.nsIAccessibleRole.ROLE_ENTRY
]
keyMap: {
a: ['moveForward', TraversalRules.Anchor],
A: ['moveBackward', TraversalRules.Anchor],
b: ['moveForward', TraversalRules.Button],
B: ['moveBackward', TraversalRules.Button],
c: ['moveForward', TraversalRules.Combobox],
C: ['moveBackward', TraversalRules.Combobox],
e: ['moveForward', TraversalRules.Entry],
E: ['moveBackward', TraversalRules.Entry],
f: ['moveForward', TraversalRules.FormElement],
F: ['moveBackward', TraversalRules.FormElement],
g: ['moveForward', TraversalRules.Graphic],
G: ['moveBackward', TraversalRules.Graphic],
h: ['moveForward', TraversalRules.Heading],
H: ['moveBackward', TraversalRules.Heading],
i: ['moveForward', TraversalRules.ListItem],
I: ['moveBackward', TraversalRules.ListItem],
k: ['moveForward', TraversalRules.Link],
K: ['moveBackward', TraversalRules.Link],
l: ['moveForward', TraversalRules.List],
L: ['moveBackward', TraversalRules.List],
p: ['moveForward', TraversalRules.PageTab],
P: ['moveBackward', TraversalRules.PageTab],
r: ['moveForward', TraversalRules.RadioButton],
R: ['moveBackward', TraversalRules.RadioButton],
s: ['moveForward', TraversalRules.Separator],
S: ['moveBackward', TraversalRules.Separator],
t: ['moveForward', TraversalRules.Table],
T: ['moveBackward', TraversalRules.Table],
x: ['moveForward', TraversalRules.Checkbox],
X: ['moveBackward', TraversalRules.Checkbox]
}
};

Просмотреть файл

@ -162,7 +162,7 @@
key="key_inspect"/>
<menuitem id="appmenu_responsiveUI"
hidden="true"
label="&responsiveUI.label;"
label="&responsiveDesignTool.label;"
type="checkbox"
command="Tools:ResponsiveUI"
key="key_responsiveUI"/>

Просмотреть файл

@ -538,8 +538,8 @@
<menuitem id="menu_responsiveUI"
type="checkbox"
hidden="true"
label="&responsiveUI.label;"
accesskey="&responsiveUI.accesskey;"
label="&responsiveDesignTool.label;"
accesskey="&responsiveDesignTool.accesskey;"
key="key_responsiveUI"
command="Tools:ResponsiveUI"/>
<menuitem id="menu_debugger"

Просмотреть файл

@ -253,7 +253,7 @@
modifiers="accel,shift"
#endif
/>
<key id="key_responsiveUI" key="&responsiveUI.commandkey;" command="Tools:ResponsiveUI"
<key id="key_responsiveUI" key="&responsiveDesignTool.commandkey;" command="Tools:ResponsiveUI"
#ifdef XP_MACOSX
modifiers="accel,alt"
#else

Просмотреть файл

@ -1047,7 +1047,7 @@
hidden="true"
command="Tools:Inspect"/>
<toolbarbutton id="developer-toolbar-responsiveui"
label="&responsiveUI.label;"
label="&responsiveDesignTool.label;"
class="devtools-toolbarbutton"
hidden="true"
command="Tools:ResponsiveUI"/>

Просмотреть файл

@ -44,6 +44,14 @@ ifeq (gtk2, $(MOZ_WIDGET_TOOLKIT))
DEFINES += -DMOZ_GTK2=1
endif
ifdef MOZ_NATIVE_NSPR
DEFINES += -DMOZ_NATIVE_NSPR=1
endif
ifdef MOZ_NATIVE_NSS
DEFINES += -DMOZ_NATIVE_NSS=1
endif
ifdef NSS_DISABLE_DBM
DEFINES += -DNSS_DISABLE_DBM=1
endif

Просмотреть файл

@ -60,9 +60,11 @@
#ifndef MOZ_STATIC_JS
@BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
#endif
#ifndef MOZ_NATIVE_NSPR
@BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
#endif
@BINPATH@/@DLL_PREFIX@xpcom@DLL_SUFFIX@
#ifdef XP_MACOSX
@BINPATH@/XUL
@ -111,7 +113,9 @@
#endif
@BINPATH@/platform.ini
#ifndef XP_OS2
#ifndef MOZ_NATIVE_SQLITE
@BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
#endif
#else
@BINPATH@/mozsqlt3@DLL_SUFFIX@
#endif
@ -585,6 +589,7 @@
; NSS libraries are signed in the staging directory,
; meaning their .chk files are created there directly.
;
#ifndef MOZ_NATIVE_NSS
@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
@ -595,6 +600,7 @@
@BINPATH@/@DLL_PREFIX@smime3@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@softokn3@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@ssl3@DLL_SUFFIX@
#endif
@BINPATH@/chrome/pippki@JAREXT@
@BINPATH@/chrome/pippki.manifest
@BINPATH@/components/pipboot.xpt

Просмотреть файл

@ -214,9 +214,9 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY inspectContextMenu.label "Inspect Element">
<!ENTITY inspectContextMenu.accesskey "Q">
<!ENTITY responsiveUI.label "Responsive Mode">
<!ENTITY responsiveUI.accesskey "R">
<!ENTITY responsiveUI.commandkey "M">
<!ENTITY responsiveDesignTool.label "Responsive Design View">
<!ENTITY responsiveDesignTool.accesskey "R">
<!ENTITY responsiveDesignTool.commandkey "M">
<!-- LOCALIZATION NOTE (scratchpad.label): This menu item label appears
- in the Tools menu. See bug 653093.

Просмотреть файл

@ -8,6 +8,7 @@
#include "nsIProtocolHandler.h"
#include "nsWeakReference.h"
#include "mozilla/Attributes.h"
#define NS_CHROMEPROTOCOLHANDLER_CID \
{ /* 61ba33c0-3031-11d3-8cd0-0060b0fc14a3 */ \
@ -17,7 +18,8 @@
{0x8c, 0xd0, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}
class nsChromeProtocolHandler : public nsIProtocolHandler, public nsSupportsWeakReference
class nsChromeProtocolHandler MOZ_FINAL : public nsIProtocolHandler,
public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS

Просмотреть файл

@ -30,3 +30,19 @@ endif
export:: $(SUBMAKEFILES) $(MAKE_DIRS) $(if $(XPIDLSRCS),$(IDL_DIR))
$(LOOP_OVER_DIRS)
$(LOOP_OVER_TOOL_DIRS)
#
# Rule to create list of libraries for final link
#
# todo: use pre-req deps rather than conditionals
export:: export-gen-final-lib-link-list
export-gen-final-lib-link-list:
ifdef LIBRARY_NAME #{
ifdef EXPORT_LIBRARY #{
ifdef IS_COMPONENT #{
else # !IS_COMPONENT
$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
endif #} IS_COMPONENT
endif #} EXPORT_LIBRARY
endif #} LIBRARY_NAME

Просмотреть файл

@ -16,12 +16,14 @@ MAKEUTILS_UNIT_TEST = 1
include $(topsrcdir)/config/makefiles/makeutils.mk
dir-ts = .deps/test
check-arglist = $(dir-ts)/arglist.ts
check-autotargets = $(dir-ts)/autotargets_mk.ts
check-XinY = $(dir-ts)/check_XinY_mk.ts
check-arglist = $(dir-ts)/arglist.ts
check-autotargets = $(dir-ts)/autotargets_mk.ts
check-export-targets = $(dir-ts)/export-targets-mk.ts
check-XinY = $(dir-ts)/check_XinY_mk.ts
check-tests =\
$(check-arglist) \
$(check-autotargets) \
$(check-export-targets) \
$(check-XinY) \
$(NULL)
@ -101,4 +103,22 @@ $(check-autotargets): $(check-autotargets-preqs)
@$(TOUCH) $@
# </CHECK: autotargets.mk>
###########################################################################
# <CHECK: export-targets.mk>
check-export-targets-preqs=\
$(call mkdir_deps,$(dir-ts)) \
$(topsrcdir)/config/makefiles/makeutils.mk \
$(topsrcdir)/config/makefiles/target_export.mk \
$(srcdir)/check-export-targets.mk \
checkup \
$(NULL)
# include then test
checkup: $(eval include $(srcdir)/check-export-targets.mk)
$(check-export-targets): $(check-export-targets-preqs)
@$(TOUCH) $@
# </CHECK: export-targets.mk>
endif #} findstring check

Просмотреть файл

@ -0,0 +1,33 @@
# -*- makefile -*-
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
ifdef VERBOSE
$(warning loading test)
endif
MOZILLA_DIR ?= $(topsrcdir)
checkup = \
check-final-lib-link-list \
$(NULL)
checkup: $(checkup)
# <CHECK: final-lib-link-list>
LIBRARY_NAME = foo# real_data: xptcmd
EXPORT_LIBRARY = foo# real_data: ../..
undefine IS_COMPONENT
test-data = $(CURDIR)/check-export-targets-test-data
FINAL_LINK_LIBS = $(test-data)
STATIC_LIBRARY_NAME = /dev/null
check-final-lib-link-list: export-gen-final-lib-link-list
@cat $(test-data)
# </CHECK: final-lib-link-list>
include $(topsrcdir)/config/makefiles/target_export.mk

Просмотреть файл

@ -626,19 +626,6 @@ endif
include $(topsrcdir)/config/makefiles/target_export.mk
include $(topsrcdir)/config/makefiles/target_tools.mk
#
# Rule to create list of libraries for final link
#
export::
ifdef LIBRARY_NAME
ifdef EXPORT_LIBRARY
ifdef IS_COMPONENT
else # !IS_COMPONENT
$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
endif # IS_COMPONENT
endif # EXPORT_LIBRARY
endif # LIBRARY_NAME
ifneq (,$(filter-out %.$(LIB_SUFFIX),$(SHARED_LIBRARY_LIBS)))
$(error SHARED_LIBRARY_LIBS must contain .$(LIB_SUFFIX) files only)
endif

Просмотреть файл

@ -3161,42 +3161,6 @@ else
AC_DEFINE(HAVE_LIBXSS)],, $XEXT_LIBS $XLIBS))
LDFLAGS="$_SAVE_LDFLAGS"
dnl ========================================================
dnl = Check for freetype2 and its functionality
dnl ========================================================
PKG_CHECK_MODULES(FT2, freetype2 >= 6.1.0, _HAVE_FREETYPE2=1, _HAVE_FREETYPE2=)
if test "$_HAVE_FREETYPE2"; then
_SAVE_LIBS="$LIBS"
_SAVE_CFLAGS="$CFLAGS"
LIBS="$LIBS $FT2_LIBS"
CFLAGS="$CFLAGS $FT2_CFLAGS"
AC_CACHE_CHECK(for FT_Bitmap_Size.y_ppem,
ac_cv_member_FT_Bitmap_Size_y_ppem,
[AC_TRY_COMPILE([#include <ft2build.h>
#include FT_FREETYPE_H],
[FT_Bitmap_Size s;
if (sizeof s.y_ppem) return 0;
return 1],
ac_cv_member_FT_Bitmap_Size_y_ppem=yes,
ac_cv_member_FT_Bitmap_Size_y_ppem=no)])
if test "$ac_cv_member_FT_Bitmap_Size_y_ppem" = yes; then
HAVE_FT_BITMAP_SIZE_Y_PPEM=1
else
HAVE_FT_BITMAP_SIZE_Y_PPEM=0
fi
AC_DEFINE_UNQUOTED(HAVE_FT_BITMAP_SIZE_Y_PPEM,
$HAVE_FT_BITMAP_SIZE_Y_PPEM,
[FT_Bitmap_Size structure includes y_ppem field])
AC_CHECK_FUNCS(FT_GlyphSlot_Embolden FT_Load_Sfnt_Table FT_Select_Size)
LIBS="$_SAVE_LIBS"
CFLAGS="$_SAVE_CFLAGS"
fi
fi # $no_x
AC_SUBST(XCFLAGS)
@ -7013,7 +6977,7 @@ else
MOZ_GLUE_PROGRAM_LDFLAGS='$(MKSHLIB_FORCE_ALL) $(call EXPAND_LIBNAME_PATH,mozglue,$(LIBXUL_DIST)/lib)'
dnl On other Unix systems, where mozglue is a static library, jemalloc is
dnl separated for the SDK, so we need to add it here.
if test "$MOZ_MEMORY" = 1; then
if test "$MOZ_MEMORY" = 1 -o \( "$LIBXUL_SDK" -a -f "$LIBXUL_SDK/lib/${LIB_PREFIX}memory.${LIB_SUFFIX}" \); then
MOZ_GLUE_PROGRAM_LDFLAGS="$MOZ_GLUE_PROGRAM_LDFLAGS "'$(call EXPAND_LIBNAME_PATH,memory,$(LIBXUL_DIST)/lib)'
fi
MOZ_GLUE_PROGRAM_LDFLAGS="$MOZ_GLUE_PROGRAM_LDFLAGS "'$(MKSHLIB_UNFORCE_ALL)'
@ -7398,6 +7362,17 @@ if test -n "$NS_FUNCTION_TIMER"; then
AC_DEFINE(NS_FUNCTION_TIMER)
fi
dnl ========================================================
dnl = Enable runtime visual profiling logger
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(visual-event-tracer,
[ --enable-visual-event-tracer Enable visual event tracer instrumentation],
MOZ_VISUAL_EVENT_TRACER=1,
MOZ_VISUAL_EVENT_TRACER=)
if test -n "$MOZ_VISUAL_EVENT_TRACER"; then
AC_DEFINE(MOZ_VISUAL_EVENT_TRACER)
fi
dnl ========================================================
dnl Turn on reflow counting
dnl ========================================================
@ -7888,6 +7863,53 @@ MOZ_ARG_ENABLE_BOOL(skia,
MOZ_ENABLE_SKIA=1,
MOZ_ENABLE_SKIA=)
if test "$USE_FC_FREETYPE"; then
if test "$COMPILE_ENVIRONMENT"; then
dnl ========================================================
dnl = Check for freetype2 and its functionality
dnl ========================================================
PKG_CHECK_MODULES(FT2, freetype2 >= 6.1.0, _HAVE_FREETYPE2=1, _HAVE_FREETYPE2=)
if test "$_HAVE_FREETYPE2"; then
_SAVE_LIBS="$LIBS"
_SAVE_CFLAGS="$CFLAGS"
LIBS="$LIBS $FT2_LIBS"
CFLAGS="$CFLAGS $FT2_CFLAGS"
AC_CACHE_CHECK(for FT_Bitmap_Size.y_ppem,
ac_cv_member_FT_Bitmap_Size_y_ppem,
[AC_TRY_COMPILE([#include <ft2build.h>
#include FT_FREETYPE_H],
[FT_Bitmap_Size s;
if (sizeof s.y_ppem) return 0;
return 1],
ac_cv_member_FT_Bitmap_Size_y_ppem=yes,
ac_cv_member_FT_Bitmap_Size_y_ppem=no)])
if test "$ac_cv_member_FT_Bitmap_Size_y_ppem" = yes; then
HAVE_FT_BITMAP_SIZE_Y_PPEM=1
else
HAVE_FT_BITMAP_SIZE_Y_PPEM=0
fi
AC_DEFINE_UNQUOTED(HAVE_FT_BITMAP_SIZE_Y_PPEM,
$HAVE_FT_BITMAP_SIZE_Y_PPEM,
[FT_Bitmap_Size structure includes y_ppem field])
AC_CHECK_FUNCS(FT_GlyphSlot_Embolden FT_Load_Sfnt_Table FT_Select_Size)
LIBS="$_SAVE_LIBS"
CFLAGS="$_SAVE_CFLAGS"
fi
_SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $FT2_CFLAGS $XCFLAGS"
MOZ_CHECK_HEADERS([fontconfig/fcfreetype.h], ,
[AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)], [#include <fontconfig/fontconfig.h>])
CPPFLAGS="$_SAVE_CPPFLAGS"
else
AC_DEFINE(HAVE_FONTCONFIG_FCFREETYPE_H)
fi
fi
dnl ========================================================
dnl Check for pixman and cairo
dnl ========================================================
@ -8672,18 +8694,6 @@ if test "$MOZ_GL_DEFAULT_PROVIDER" = "GLX"; then
fi # MOZ_GL_DEFAULT_PROVIDER=GLX
fi # COMPILE_ENVIRONMENT
if test "$USE_FC_FREETYPE"; then
if test "$COMPILE_ENVIRONMENT"; then
_SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $FT2_CFLAGS $XCFLAGS"
MOZ_CHECK_HEADERS([fontconfig/fcfreetype.h], ,
[AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)], [#include <fontconfig/fontconfig.h>])
CPPFLAGS="$_SAVE_CPPFLAGS"
else
AC_DEFINE(HAVE_FONTCONFIG_FCFREETYPE_H)
fi
fi
dnl Set various defines and substitutions
dnl ========================================================

Просмотреть файл

@ -14,6 +14,11 @@ window.addEventListener('load', parent.testFramesLoaded, false);
<iframe id="deny" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=deny&xfo=deny"></iframe><br>
<iframe id="sameorigin1" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin1&xfo=sameorigin"></iframe><br>
<iframe id="sameorigin2" src="http://example.com/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin2&xfo=sameorigin"></iframe><br>
<iframe id="sameorigin5" src="http://example.com/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin5&xfo=sameorigin2"></iframe><br>
<iframe id="sameorigin6" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin6&xfo=sameorigin2"></iframe><br>
<iframe id="sameorigin7" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin7&xfo=sameorigin3"></iframe><br>
<iframe id="sameorigin8" src="http://example.com/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin8&xfo=sameorigin3"></iframe><br>
<iframe id="mixedpolicy" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=mixedpolicy&xfo=mixedpolicy"></iframe><br>
</body>
</html>

Просмотреть файл

@ -17,6 +17,15 @@ function handleRequest(request, response)
else if (query['xfo'] == "sameorigin") {
response.setHeader("X-Frame-Options", "SAMEORIGIN", false);
}
else if (query['xfo'] == "sameorigin2") {
response.setHeader("X-Frame-Options", "SAMEORIGIN, SAMEORIGIN", false);
}
else if (query['xfo'] == "sameorigin3") {
response.setHeader("X-Frame-Options", "SAMEORIGIN,SAMEORIGIN , SAMEORIGIN", false);
}
else if (query['xfo'] == "mixedpolicy") {
response.setHeader("X-Frame-Options", "DENY,SAMEORIGIN", false);
}
// from the test harness we'll be checking for the presence of this element
// to test if the page loaded

Просмотреть файл

@ -83,6 +83,31 @@ var testFramesLoaded = function() {
var test5 = frame.contentDocument.getElementById("test");
is(test5, null, "test sameorigin2");
// iframe from different origin, X-F-O: SAMEORIGIN, SAMEORIGIN - should not load
frame = harness.contentDocument.getElementById("sameorigin5");
var test6 = frame.contentDocument.getElementById("test");
is(test6, null, "test sameorigin5");
// iframe from same origin, X-F-O: SAMEORIGIN, SAMEORIGIN - should load
frame = harness.contentDocument.getElementById("sameorigin6");
var test7 = frame.contentDocument.getElementById("test").textContent;
is(test7, "sameorigin6", "test sameorigin6");
// iframe from same origin, X-F-O: SAMEORIGIN,SAMEORIGIN, SAMEORIGIN - should load
frame = harness.contentDocument.getElementById("sameorigin7");
var test8 = frame.contentDocument.getElementById("test").textContent;
is(test8, "sameorigin7", "test sameorigin7");
// iframe from same origin, X-F-O: SAMEORIGIN,SAMEORIGIN, SAMEORIGIN - should not load
frame = harness.contentDocument.getElementById("sameorigin8");
var test9 = frame.contentDocument.getElementById("test");
is(test9, null, "test sameorigin8");
// iframe from same origin, X-F-O: DENY,SAMEORIGIN - should not load
frame = harness.contentDocument.getElementById("mixedpolicy");
var test10 = frame.contentDocument.getElementById("test");
is(test10, null, "test mixedpolicy");
// call tests to check principal comparison, e.g. a document can open a window
// to a data: or javascript: document which frames an
// X-Frame-Options: SAMEORIGIN document and the frame should load

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<body onload="document.getElementById('c').getContext('2d').mozCurrentTransformInverse;">
<canvas id="c" width="772" height="76441"></canvas>
</body>
</html>

Просмотреть файл

@ -6,6 +6,7 @@ load 0px-size-font-667225.html
load texImage2D.html
load 729116.html
load 745699-1.html
load 746813-1.html
# this test crashes in a bunch places still
#load 745818-large-source.html
load 743499-negative-size.html

Просмотреть файл

@ -1541,6 +1541,9 @@ NS_IMETHODIMP
nsCanvasRenderingContext2D::GetMozCurrentTransformInverse(JSContext* cx,
jsval* matrix)
{
if (!EnsureSurface())
return NS_ERROR_FAILURE;
gfxMatrix ctm = mThebes->CurrentMatrix();
if (!mThebes->CurrentMatrix().IsSingular()) {

Просмотреть файл

@ -1535,8 +1535,12 @@ nsCanvasRenderingContext2DAzure::Restore()
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::Scale(float x, float y)
{
if (!FloatValidate(x,y))
if (!mTarget) {
return NS_ERROR_FAILURE;
}
if (!FloatValidate(x,y)) {
return NS_OK;
}
TransformWillUpdate();
@ -1548,8 +1552,12 @@ nsCanvasRenderingContext2DAzure::Scale(float x, float y)
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::Rotate(float angle)
{
if (!FloatValidate(angle))
if (!mTarget) {
return NS_ERROR_FAILURE;
}
if (!FloatValidate(angle)) {
return NS_OK;
}
TransformWillUpdate();
@ -1561,6 +1569,9 @@ nsCanvasRenderingContext2DAzure::Rotate(float angle)
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::Translate(float x, float y)
{
if (!mTarget) {
return NS_ERROR_FAILURE;
}
if (!FloatValidate(x,y)) {
return NS_OK;
}
@ -1575,6 +1586,9 @@ nsCanvasRenderingContext2DAzure::Translate(float x, float y)
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::Transform(float m11, float m12, float m21, float m22, float dx, float dy)
{
if (!mTarget) {
return NS_ERROR_FAILURE;
}
if (!FloatValidate(m11,m12,m21,m22,dx,dy)) {
return NS_OK;
}
@ -1589,6 +1603,9 @@ nsCanvasRenderingContext2DAzure::Transform(float m11, float m12, float m21, floa
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::SetTransform(float m11, float m12, float m21, float m22, float dx, float dy)
{
if (!mTarget) {
return NS_ERROR_FAILURE;
}
if (!FloatValidate(m11,m12,m21,m22,dx,dy)) {
return NS_OK;
}
@ -1605,6 +1622,10 @@ NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::SetMozCurrentTransform(JSContext* cx,
const jsval& matrix)
{
if (!mTarget) {
return NS_ERROR_FAILURE;
}
nsresult rv;
Matrix newCTM;
@ -1621,6 +1642,10 @@ NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::GetMozCurrentTransform(JSContext* cx,
jsval* matrix)
{
if (!mTarget) {
return NS_ERROR_FAILURE;
}
return MatrixToJSVal(mTarget->GetTransform(), cx, matrix);
}
@ -1628,6 +1653,10 @@ NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::SetMozCurrentTransformInverse(JSContext* cx,
const jsval& matrix)
{
if (!mTarget) {
return NS_ERROR_FAILURE;
}
nsresult rv;
Matrix newCTMInverse;
@ -1647,6 +1676,10 @@ NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::GetMozCurrentTransformInverse(JSContext* cx,
jsval* matrix)
{
if (!mTarget) {
return NS_ERROR_FAILURE;
}
Matrix ctm = mTarget->GetTransform();
if (!ctm.Invert()) {

Просмотреть файл

@ -4187,7 +4187,8 @@ nsDOMSettableTokenListPropertyDestructor(void *aObject, nsIAtom *aProperty,
{
nsDOMSettableTokenList* list =
static_cast<nsDOMSettableTokenList*>(aPropertyValue);
NS_IF_RELEASE(list);
list->DropReference();
NS_RELEASE(list);
}
nsDOMSettableTokenList*

Просмотреть файл

@ -265,6 +265,7 @@ _TEST_FILES = \
test_bug742549.html \
test_bug745685.html \
test_input_file_picker.html \
test_bug763626.html \
$(NULL)
_BROWSER_TEST_FILES = \

Просмотреть файл

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=763626
-->
<head>
<title>Test for Bug 763626</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
function boom()
{
var r = document.createElement("div").itemRef;
SpecialPowers.DOMWindowUtils.garbageCollect();
is("" + r, "", "ToString should return empty string when element is gone");
SimpleTest.finish();
}
</script>
</head>
<body onload="boom();"></body>
</html>

Просмотреть файл

@ -383,9 +383,10 @@ nsIThread *
nsAudioStream::GetThread()
{
if (!mAudioPlaybackThread) {
NS_NewThread(getter_AddRefs(mAudioPlaybackThread),
nsnull,
MEDIA_THREAD_STACK_SIZE);
NS_NewNamedThread("Audio Stream",
getter_AddRefs(mAudioPlaybackThread),
nsnull,
MEDIA_THREAD_STACK_SIZE);
}
return mAudioPlaybackThread;
}

Просмотреть файл

@ -264,7 +264,7 @@ void StateMachineTracker::EnsureGlobalStateMachine()
ReentrantMonitorAutoEnter mon(mMonitor);
if (mStateMachineCount == 0) {
NS_ASSERTION(!mStateMachineThread, "Should have null state machine thread!");
DebugOnly<nsresult> rv = NS_NewThread(&mStateMachineThread, nsnull);
DebugOnly<nsresult> rv = NS_NewNamedThread("Media State", &mStateMachineThread, nsnull);
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "Can't create media state machine thread");
}
mStateMachineCount++;
@ -1617,9 +1617,10 @@ nsBuiltinDecoderStateMachine::StartDecodeThread()
mRequestedNewDecodeThread = false;
nsresult rv = NS_NewThread(getter_AddRefs(mDecodeThread),
nsnull,
MEDIA_THREAD_STACK_SIZE);
nsresult rv = NS_NewNamedThread("Media Decode",
getter_AddRefs(mDecodeThread),
nsnull,
MEDIA_THREAD_STACK_SIZE);
if (NS_FAILED(rv)) {
// Give up, report error to media element.
nsCOMPtr<nsIRunnable> event =
@ -1644,14 +1645,16 @@ nsBuiltinDecoderStateMachine::StartAudioThread()
mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
mStopAudioThread = false;
if (HasAudio() && !mAudioThread && !mAudioCaptured) {
nsresult rv = NS_NewThread(getter_AddRefs(mAudioThread),
nsnull,
MEDIA_THREAD_STACK_SIZE);
nsresult rv = NS_NewNamedThread("Media Audio",
getter_AddRefs(mAudioThread),
nsnull,
MEDIA_THREAD_STACK_SIZE);
if (NS_FAILED(rv)) {
LOG(PR_LOG_DEBUG, ("%p Changed state to SHUTDOWN because failed to create audio thread", mDecoder.get()));
mState = DECODER_STATE_SHUTDOWN;
return rv;
}
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(this, &nsBuiltinDecoderStateMachine::AudioLoop);
mAudioThread->Dispatch(event, NS_DISPATCH_NORMAL);

Просмотреть файл

@ -15,6 +15,7 @@
#include "nsIHttpChannel.h"
#include "nsIScriptSecurityManager.h"
#include "nsNetError.h"
#include "nsCharSeparatedTokenizer.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
@ -269,29 +270,18 @@ nsDSURIContentListener::SetParentContentListener(nsIURIContentListener*
return NS_OK;
}
// Check if X-Frame-Options permits this document to be loaded as a subdocument.
bool nsDSURIContentListener::CheckFrameOptions(nsIRequest* request)
{
// If X-Frame-Options checking is disabled, return true unconditionally.
if (sIgnoreXFrameOptions) {
bool nsDSURIContentListener::CheckOneFrameOptionsPolicy(nsIRequest *request,
const nsAString& policy) {
// return early if header does not have one of the two values with meaning
if (!policy.LowerCaseEqualsLiteral("deny") &&
!policy.LowerCaseEqualsLiteral("sameorigin"))
return true;
}
nsCAutoString xfoHeaderValue;
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
if (!httpChannel) {
return true;
}
httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-Frame-Options"),
xfoHeaderValue);
// return early if header does not have one of the two values with meaning
if (!xfoHeaderValue.LowerCaseEqualsLiteral("deny") &&
!xfoHeaderValue.LowerCaseEqualsLiteral("sameorigin"))
return true;
if (mDocShell) {
// We need to check the location of this window and the location of the top
// window, if we're not the top. X-F-O: SAMEORIGIN requires that the
@ -321,8 +311,10 @@ bool nsDSURIContentListener::CheckFrameOptions(nsIRequest* request)
nsresult rv;
nsCOMPtr<nsIScriptSecurityManager> ssm =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
if (!ssm)
if (!ssm) {
NS_ASSERTION(ssm, "Failed to get the ScriptSecurityManager.");
return false;
}
// Traverse up the parent chain to the top docshell that doesn't have
// a system principal
@ -333,6 +325,7 @@ bool nsDSURIContentListener::CheckFrameOptions(nsIRequest* request)
if (topDoc) {
if (NS_SUCCEEDED(ssm->IsSystemPrincipal(topDoc->NodePrincipal(),
&system)) && system) {
// Found a system-principled doc: last docshell was top.
break;
}
}
@ -347,34 +340,71 @@ bool nsDSURIContentListener::CheckFrameOptions(nsIRequest* request)
if (curDocShellItem == thisDocShellItem)
return true;
// If the value of the header is DENY, and the previous condition is
// not met (current docshell is not the top docshell), prohibit the
// load.
if (policy.LowerCaseEqualsLiteral("deny")) {
return false;
}
// If the X-Frame-Options value is SAMEORIGIN, then the top frame in the
// parent chain must be from the same origin as this document.
if (xfoHeaderValue.LowerCaseEqualsLiteral("sameorigin")) {
if (policy.LowerCaseEqualsLiteral("sameorigin")) {
nsCOMPtr<nsIURI> uri;
httpChannel->GetURI(getter_AddRefs(uri));
topDoc = do_GetInterface(curDocShellItem);
nsCOMPtr<nsIURI> topUri;
topDoc->NodePrincipal()->GetURI(getter_AddRefs(topUri));
rv = ssm->CheckSameOriginURI(uri, topUri, true);
if (NS_SUCCEEDED(rv))
return true;
if (NS_FAILED(rv))
return false; /* wasn't same-origin */
}
}
return true;
}
// Check if X-Frame-Options permits this document to be loaded as a subdocument.
// This will iterate through and check any number of X-Frame-Options policies
// in the request (comma-separated in a header, multiple headers, etc).
bool nsDSURIContentListener::CheckFrameOptions(nsIRequest *request)
{
// If X-Frame-Options checking is disabled, return true unconditionally.
if (sIgnoreXFrameOptions) {
return true;
}
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request);
if (!httpChannel) {
return true;
}
nsCAutoString xfoHeaderCValue;
httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-Frame-Options"),
xfoHeaderCValue);
NS_ConvertUTF8toUTF16 xfoHeaderValue(xfoHeaderCValue);
// if no header value, there's nothing to do.
if (xfoHeaderValue.IsEmpty())
return true;
// iterate through all the header values (usually there's only one, but can
// be many. If any want to deny the load, deny the load.
nsCharSeparatedTokenizer tokenizer(xfoHeaderValue, ',');
while (tokenizer.hasMoreTokens()) {
const nsSubstring& tok = tokenizer.nextToken();
if (!CheckOneFrameOptionsPolicy(request, tok)) {
// cancel the load and display about:blank
httpChannel->Cancel(NS_BINDING_ABORTED);
if (mDocShell) {
nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(mDocShell));
if (webNav) {
webNav->LoadURI(NS_LITERAL_STRING("about:blank").get(),
0, nsnull, nsnull, nsnull);
}
}
return false;
}
else {
// If the value of the header is DENY, then the document
// should never be permitted to load as a subdocument.
NS_ASSERTION(xfoHeaderValue.LowerCaseEqualsLiteral("deny"),
"How did we get here with some random header value?");
}
// cancel the load and display about:blank
httpChannel->Cancel(NS_BINDING_ABORTED);
nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(mDocShell));
if (webNav) {
webNav->LoadURI(NS_LITERAL_STRING("about:blank").get(),
0, nsnull, nsnull, nsnull);
}
return false;
}
return true;

Просмотреть файл

@ -38,6 +38,8 @@ protected:
// Determine if X-Frame-Options allows content to be framed
// as a subdocument
bool CheckFrameOptions(nsIRequest* request);
bool CheckOneFrameOptionsPolicy(nsIRequest* request,
const nsAString& policy);
protected:
nsDocShell* mDocShell;

Просмотреть файл

@ -338,7 +338,13 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
if (thisv == JSVAL_NULL)
return false;
JSObject* obj = JSVAL_TO_OBJECT(thisv);
// Get the object. It might be a security wrapper, in which case we do a checked
// unwrap.
JSObject* origObj = JSVAL_TO_OBJECT(thisv);
JSObject* obj = js::UnwrapObjectChecked(cx, origObj);
if (!obj)
return false;
JSClass* clasp = js::GetObjectJSClass(obj);
if (!IsDOMClass(clasp) ||
!DOMJSClass::FromJSClass(clasp)->mDOMObjectIsISupports) {
@ -371,9 +377,9 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
return Throw<true>(cx, rv);
}
return WrapObject(cx, obj, ci, &NS_GET_IID(nsIClassInfo), vp);
return WrapObject(cx, origObj, ci, &NS_GET_IID(nsIClassInfo), vp);
}
// Lie, otherwise we need to check classinfo or QI
*vp = thisv;
return true;

Просмотреть файл

@ -571,6 +571,16 @@ WrapNativeParent(JSContext* cx, JSObject* scope, const T& p)
NULL;
}
static inline bool
InternJSString(JSContext* cx, jsid& id, const char* chars)
{
if (JSString *str = ::JS_InternString(cx, chars)) {
id = INTERNED_STRING_TO_JSID(cx, str);
return true;
}
return false;
}
// Spec needs a name property
template <typename Spec>
static bool
@ -583,12 +593,9 @@ InitIds(JSContext* cx, Prefable<Spec>* prefableSpecs, jsid* ids)
// because this is only done once per application runtime.
Spec* spec = prefableSpecs->specs;
do {
JSString *str = ::JS_InternString(cx, spec->name);
if (!str) {
if (!InternJSString(cx, *ids, spec->name)) {
return false;
}
*ids = INTERNED_STRING_TO_JSID(cx, str);
} while (++ids, (++spec)->name);
// We ran out of ids for that pref. Put a JSID_VOID in on the id

Просмотреть файл

@ -313,7 +313,8 @@ class CGHeaders(CGWrapper):
"""
Generates the appropriate include statements.
"""
def __init__(self, descriptors, declareIncludes, defineIncludes, child):
def __init__(self, descriptors, dictionaries, declareIncludes,
defineIncludes, child):
"""
Builds a set of includes to cover |descriptors|.
@ -329,7 +330,7 @@ class CGHeaders(CGWrapper):
ancestors.append(iface.parent)
iface = iface.parent
interfaceDeps.extend(ancestors)
bindingIncludes = set(self.getInterfaceFilename(d) for d in interfaceDeps)
bindingIncludes = set(self.getDeclarationFilename(d) for d in interfaceDeps)
# Grab all the implementation declaration files we need.
implementationIncludes = set(d.headerFile for d in descriptors)
@ -359,22 +360,30 @@ class CGHeaders(CGWrapper):
typeDesc = d.getDescriptor(t.unroll().inner.identifier.name)
if typeDesc is not None:
implementationIncludes.add(typeDesc.headerFile)
bindingHeaders.add(self.getInterfaceFilename(typeDesc.interface))
bindingHeaders.add(self.getDeclarationFilename(typeDesc.interface))
elif t.unroll().isDictionary():
bindingHeaders.add(self.getDeclarationFilename(t.unroll().inner))
declareIncludes = set(declareIncludes)
for d in dictionaries:
if d.parent:
declareIncludes.add(self.getDeclarationFilename(d.parent))
bindingHeaders.add(self.getDeclarationFilename(d))
# Let the machinery do its thing.
def _includeString(includes):
return ''.join(['#include "%s"\n' % i for i in includes]) + '\n'
CGWrapper.__init__(self, child,
declarePre=_includeString(declareIncludes),
declarePre=_includeString(sorted(declareIncludes)),
definePre=_includeString(sorted(set(defineIncludes) |
bindingIncludes |
bindingHeaders |
implementationIncludes)))
@staticmethod
def getInterfaceFilename(interface):
def getDeclarationFilename(decl):
# Use our local version of the header, not the exported one, so that
# test bindings, which don't export, will work correctly.
basename = os.path.basename(interface.filename())
basename = os.path.basename(decl.filename())
return basename.replace('.webidl', 'Binding.h')
class Argument():
@ -1300,7 +1309,7 @@ ${target} = tmp.forget();""").substitute(self.substitution)
def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
isDefinitelyObject=False,
isSequenceMember=False,
isMember=False,
isOptional=False):
"""
Get a template for converting a JS value to a native object based on the
@ -1315,7 +1324,9 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
If isDefinitelyObject is True, that means we know the value
isObject() and we have no need to recheck that.
if isSequenceMember is True, we're being converted as part of a sequence.
if isMember is True, we're being converted from a property of some
JS object, not from an actual method argument, so we can't rely on
our jsval being rooted or outliving us in any way.
If isOptional is true, then we are doing conversion of an optional
argument with no default value.
@ -1380,8 +1391,14 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
raise TypeError("Can't handle array arguments yet")
if type.isSequence():
if isSequenceMember:
raise TypeError("Can't handle sequences of sequences")
if isMember:
# XXXbz we probably _could_ handle this; we just have to be careful
# with reallocation behavior for arrays. In particular, if we have
# a return value that's a sequence of dictionaries of sequences,
# that will cause us to have an nsTArray containing objects with
# nsAutoTArray members, which is a recipe for badness as the
# outermost array is resized.
raise TypeError("Can't handle unrooted sequences")
if failureCode is not None:
raise TypeError("Can't handle sequences when failureCode is not None")
nullable = type.nullable();
@ -1394,7 +1411,7 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
# we wrap, so don't pass through isDefinitelyObject
(elementTemplate, elementDeclType,
elementHolderType, dealWithOptional) = getJSToNativeConversionTemplate(
elementType, descriptorProvider, isSequenceMember=True)
elementType, descriptorProvider, isMember=True)
if dealWithOptional:
raise TypeError("Shouldn't have optional things in sequences")
if elementHolderType is not None:
@ -1439,6 +1456,7 @@ for (uint32_t i = 0; i < length; ++i) {
string.Template(elementTemplate).substitute(
{
"val" : "temp",
"valPtr": "&temp",
"declName" : "(*arr.AppendElement())"
}
))).define()
@ -1462,7 +1480,7 @@ for (uint32_t i = 0; i < length; ++i) {
# Sequences and non-worker callbacks have to hold a strong ref to the
# thing being passed down.
forceOwningType = (descriptor.interface.isCallback() and
not descriptor.workers) or isSequenceMember
not descriptor.workers) or isMember
typeName = descriptor.nativeType
typePtr = typeName + "*"
@ -1551,8 +1569,8 @@ for (uint32_t i = 0; i < length; ++i) {
return (templateBody, declType, holderType, isOptional)
if type.isSpiderMonkeyInterface():
if isSequenceMember:
raise TypeError("Can't handle sequences of arraybuffers or "
if isMember:
raise TypeError("Can't handle member arraybuffers or "
"arraybuffer views because making sure all the "
"objects are properly rooted is hard")
name = type.name
@ -1612,8 +1630,6 @@ for (uint32_t i = 0; i < length; ++i) {
return (template, CGGeneric(declType), holderType, False)
if type.isString():
if isSequenceMember:
raise TypeError("Can't handle sequences of strings")
# XXXbz Need to figure out string behavior based on extended args? Also, how to
# detect them?
@ -1626,6 +1642,22 @@ for (uint32_t i = 0; i < length; ++i) {
nullBehavior = "eStringify"
undefinedBehavior = "eStringify"
if isMember:
# We have to make a copy, because our jsval may well not
# live as long as our string needs to.
declType = CGGeneric("nsString")
return (
"{\n"
" nsDependentString str;\n"
" if (!ConvertJSValueToString(cx, ${val}, ${valPtr}, %s, %s, str)) {\n"
" return false;\n"
" }\n"
" ${declName} = str;\n"
"}\n" %
(nullBehavior, undefinedBehavior),
declType, None,
isOptional)
if isOptional:
declType = "Optional<nsAString>"
else:
@ -1657,8 +1689,9 @@ for (uint32_t i = 0; i < length; ++i) {
CGGeneric(enum), None, isOptional)
if type.isCallback():
if isSequenceMember:
raise TypeError("Can't handle sequences of callbacks")
if isMember:
raise TypeError("Can't handle member callbacks; need to sort out "
"rooting issues")
# XXXbz we're going to assume that callback types are always
# nullable and always have [TreatNonCallableAsNull] for now.
return (
@ -1669,13 +1702,15 @@ for (uint32_t i = 0; i < length; ++i) {
"}", CGGeneric("JSObject*"), None, isOptional)
if type.isAny():
if isSequenceMember:
raise TypeError("Can't handle sequences of 'any'")
if isMember:
raise TypeError("Can't handle member 'any'; need to sort out "
"rooting issues")
return ("${declName} = ${val};", CGGeneric("JS::Value"), None, isOptional)
if type.isObject():
if isSequenceMember:
raise TypeError("Can't handle sequences of 'object'")
if isMember:
raise TypeError("Can't handle member 'object'; need to sort out "
"rooting issues")
template = wrapObjectTemplate("${declName} = &${val}.toObject();",
isDefinitelyObject, type,
"${declName} = NULL",
@ -1686,6 +1721,35 @@ for (uint32_t i = 0; i < length; ++i) {
declType = CGGeneric("NonNull<JSObject>")
return (template, declType, None, isOptional)
if type.isDictionary():
if failureCode is not None:
raise TypeError("Can't handle dictionaries when failureCode is not None")
if type.nullable():
typeName = type.inner.inner.identifier.name
declType = CGGeneric("Nullable<%s>" % typeName)
selfRef = "${declName}.Value()"
else:
typeName = type.inner.identifier.name
declType = CGGeneric(typeName)
selfRef = "${declName}"
# If we're optional or a member of something else, the const
# will come from the Optional or our container.
mutableTypeName = declType
if not isOptional and not isMember:
declType = CGWrapper(declType, pre="const ")
selfRef = "const_cast<%s&>(%s)" % (typeName, selfRef)
template = wrapObjectTemplate("if (!%s.Init(cx, &${val}.toObject())) {\n"
" return false;\n"
"}" % selfRef,
isDefinitelyObject, type,
("const_cast<%s&>(${declName}).SetNull()" %
mutableTypeName.define()),
descriptorProvider.workers, None)
return (template, declType, None, isOptional)
if not type.isPrimitive():
raise TypeError("Need conversion for argument type '%s'" % type)
@ -3367,6 +3431,179 @@ class CGNamespacedEnum(CGThing):
def define(self):
assert False # Only for headers.
class CGDictionary(CGThing):
def __init__(self, dictionary, workers):
self.dictionary = dictionary;
self.workers = workers
# Fake a descriptorProvider
# XXXbz this will fail for interface types!
for member in dictionary.members:
if member.type.unroll().isInterface():
raise TypeError("No support for interface members of dictionaries: %s.%s" %
(dictionary.identifier.name, member.identifier.name))
self.memberInfo = [
(member,
getJSToNativeConversionTemplate(member.type,
{ "workers": workers },
isMember=True,
isOptional=(not member.defaultValue)))
for member in dictionary.members ]
def declare(self):
d = self.dictionary
if d.parent:
inheritance = ": public %s " % self.makeClassName(d.parent)
else:
inheritance = ""
memberDecls = [" %s %s;" %
(self.getMemberType(m), m[0].identifier.name)
for m in self.memberInfo]
return (string.Template(
"struct ${selfName} ${inheritance}{\n"
" ${selfName}() {}\n"
" bool Init(JSContext* cx, JSObject* obj);\n"
"\n" +
"\n".join(memberDecls) + "\n"
"private:\n"
" // Disallow copy-construction\n"
" ${selfName}(const ${selfName}&) MOZ_DELETE;\n"
" static bool InitIds(JSContext* cx);\n"
" static bool initedIds;\n" +
"\n".join(" static jsid " +
self.makeIdName(m.identifier.name) + ";" for
m in d.members) + "\n"
"};").substitute( { "selfName": self.makeClassName(d),
"inheritance": inheritance }))
def define(self):
d = self.dictionary
if d.parent:
initParent = ("// Per spec, we init the parent's members first\n"
"if (!%s::Init(cx, obj)) {\n"
" return false;\n"
"}\n" % self.makeClassName(d.parent))
else:
initParent = ""
memberInits = [CGIndenter(self.getMemberConversion(m)).define()
for m in self.memberInfo]
idinit = [CGGeneric('!InternJSString(cx, %s, "%s")' %
(m.identifier.name + "_id", m.identifier.name))
for m in d.members]
idinit = CGList(idinit, " ||\n")
idinit = CGWrapper(idinit, pre="if (",
post=(") {\n"
" return false;\n"
"}"),
reindent=True)
return string.Template(
"bool ${selfName}::initedIds = false;\n" +
"\n".join("jsid ${selfName}::%s = JSID_VOID;" %
self.makeIdName(m.identifier.name)
for m in d.members) + "\n"
"\n"
"bool\n"
"${selfName}::InitIds(JSContext* cx)\n"
"{\n"
" MOZ_ASSERT(!initedIds);\n"
"${idInit}\n"
" initedIds = true;\n"
" return true;\n"
"}\n"
"\n"
"bool\n"
"${selfName}::Init(JSContext* cx, JSObject* obj)\n"
"{\n"
" if (!initedIds && !InitIds(cx)) {\n"
" return false;\n"
" }\n"
"${initParent}"
" JSBool found;\n"
" JS::Value temp;\n"
"\n"
"${initMembers}\n"
" return true;\n"
"}").substitute({
"selfName": self.makeClassName(d),
"initParent": CGIndenter(CGGeneric(initParent)).define(),
"initMembers": "\n\n".join(memberInits),
"idInit": CGIndenter(idinit).define()
})
def makeClassName(self, dictionary):
suffix = "Workers" if self.workers else ""
return dictionary.identifier.name + suffix
def getMemberType(self, memberInfo):
(member, (templateBody, declType,
holderType, dealWithOptional)) = memberInfo
# We can't handle having a holderType here
assert holderType is None
if dealWithOptional:
declType = CGWrapper(declType, pre="Optional< ", post=" >")
return declType.define()
def getMemberConversion(self, memberInfo):
# Fake a descriptorProvider
(member, (templateBody, declType,
holderType, dealWithOptional)) = memberInfo
replacements = { "val": "temp",
"valPtr": "&temp",
# Use this->%s to refer to members, because we don't
# control the member names and want to make sure we're
# talking about the member, not some local that
# shadows the member. Another option would be to move
# the guts of init to a static method which is passed
# an explicit reference to our dictionary object, so
# we couldn't screw this up even if we wanted to....
"declName": ("(this->%s)" % member.identifier.name) }
# We can't handle having a holderType here
assert holderType is None
if dealWithOptional:
replacements["declName"] = "(" + replacements["declName"] + ".Value())"
conversionReplacements = {
"propId" : self.makeIdName(member.identifier.name),
"prop": "(this->%s)" % member.identifier.name,
"convert": string.Template(templateBody).substitute(replacements)
}
conversion = ("if (!JS_HasPropertyById(cx, obj, ${propId}, &found)) {\n"
" return false;\n"
"}\n")
if member.defaultValue:
conversion += (
"if (found) {\n"
" if (!JS_GetPropertyById(cx, obj, ${propId}, &temp)) {\n"
" return false;\n"
" }\n"
"} else {\n"
" temp = ${defaultVal};\n"
"}\n"
"${convert}")
conversionReplacements["defaultVal"] = (
convertIDLDefaultValueToJSVal(member.defaultValue))
else:
conversion += (
"if (found) {\n"
" ${prop}.Construct();\n"
" if (!JS_GetPropertyById(cx, obj, ${propId}, &temp)) {\n"
" return false;\n"
" }\n"
"${convert}\n"
"}")
conversionReplacements["convert"] = CGIndenter(
CGGeneric(conversionReplacements["convert"])).define()
return CGGeneric(
string.Template(conversion).substitute(conversionReplacements)
)
@staticmethod
def makeIdName(name):
return name + "_id"
class CGRegisterProtos(CGAbstractMethod):
def __init__(self, config):
CGAbstractMethod.__init__(self, None, 'Register', 'void',
@ -3397,6 +3634,7 @@ class CGBindingRoot(CGThing):
def __init__(self, config, prefix, webIDLFile):
descriptors = config.getDescriptors(webIDLFile=webIDLFile,
hasInterfaceOrInterfacePrototypeObject=True)
dictionaries = config.getDictionaries(webIDLFile)
forwardDeclares = [CGClassForwardDeclare('XPCWrappedNativeScope')]
@ -3434,7 +3672,7 @@ class CGBindingRoot(CGThing):
else:
traitsClasses = None
# Do codegen for all the descriptors and enums.
# Do codegen for all the enums
def makeEnum(e):
return CGNamespace.build([e.identifier.name + "Values"],
CGEnum(e))
@ -3443,8 +3681,30 @@ class CGBindingRoot(CGThing):
(e.identifier.name, e.identifier.name)))
cgthings = [ fun(e) for e in config.getEnums(webIDLFile)
for fun in [makeEnum, makeEnumTypedef] ]
# Do codegen for all the dictionaries. We have to be a bit careful
# here, because we have to generate these in order from least derived to
# most derived so that class inheritance works out.
#
# XXXbz this will fail if we have two webidl files A and B such that A
# declares a dictionary which inherits from a dictionary in B and B
# declares a dictionary (possibly a different one!) that inherits from a
# dictionary in A. The good news is that I expect this to never happen.
reSortedDictionaries = []
while len(dictionaries) != 0:
toMove = [d for d in dictionaries if d.parent not in dictionaries]
dictionaries = [d for d in dictionaries if d.parent in dictionaries]
reSortedDictionaries.extend(toMove)
dictionaries = reSortedDictionaries
cgthings.extend([CGDictionary(d, workers=True) for d in dictionaries])
cgthings.extend([CGDictionary(d, workers=False) for d in dictionaries])
# Do codegen for all the descriptors
cgthings.extend([CGDescriptor(x) for x in descriptors])
curr = CGList(cgthings, "\n")
# And make sure we have the right number of newlines at the end
curr = CGWrapper(CGList(cgthings, "\n\n"), post="\n\n")
# Wrap all of that in our namespaces.
curr = CGNamespace.build(['mozilla', 'dom'],
@ -3458,6 +3718,7 @@ class CGBindingRoot(CGThing):
# Add header includes.
curr = CGHeaders(descriptors,
dictionaries,
['mozilla/dom/BindingUtils.h',
'mozilla/dom/DOMJSClass.h'],
['mozilla/dom/Nullable.h',
@ -3560,12 +3821,12 @@ struct PrototypeIDMap;
curr = CGWrapper(curr, post='\n')
# Add the includes
defineIncludes = [CGHeaders.getInterfaceFilename(desc.interface)
defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
for desc in config.getDescriptors(hasInterfaceObject=True,
workers=False,
register=True)]
defineIncludes.append('nsScriptNameSpaceManager.h')
curr = CGHeaders([], [], defineIncludes, curr)
curr = CGHeaders([], [], [], defineIncludes, curr)
# Add include guards.
curr = CGIncludeGuard('RegisterBindings', curr)

Просмотреть файл

@ -42,6 +42,7 @@ class Configuration:
descriptor.uniqueImplementation = len(otherDescriptors) == 1
self.enums = [e for e in parseData if e.isEnum()]
self.dictionaries = [d for d in parseData if d.isDictionary()]
# Keep the descriptor list sorted for determinism.
self.descriptors.sort(lambda x,y: cmp(x.name, y.name))
@ -72,6 +73,8 @@ class Configuration:
return curr
def getEnums(self, webIDLFile):
return filter(lambda e: e.filename() == webIDLFile, self.enums)
def getDictionaries(self, webIDLFile):
return filter(lambda d: d.filename() == webIDLFile, self.dictionaries)
class Descriptor:
"""

Просмотреть файл

@ -146,3 +146,9 @@ GARBAGE += \
webidlyacc.py \
parser.out \
$(NULL)
# Make sure all binding header files are created during the export stage, so we
# don't have issues with .cpp files being compiled before we've generated the
# headers they depend on. This is really only needed for the test files, since
# the non-test headers are all exported above anyway.
export:: $(binding_header_files)

Просмотреть файл

@ -150,6 +150,9 @@ class IDLObject(object):
def isType(self):
return False
def isDictionary(self):
return False;
def getUserData(self, key, default):
return self.userData.get(key, default)
@ -317,7 +320,7 @@ class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope):
IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier)
IDLScope.__init__(self, location, parentScope, self.identifier)
class IDLInterfacePlaceholder(IDLObjectWithIdentifier):
class IDLIdentifierPlaceholder(IDLObjectWithIdentifier):
def __init__(self, location, identifier):
assert isinstance(identifier, IDLUnresolvedIdentifier)
IDLObjectWithIdentifier.__init__(self, location, None, identifier)
@ -328,8 +331,8 @@ class IDLInterfacePlaceholder(IDLObjectWithIdentifier):
except:
raise WebIDLError("Unresolved type '%s'." % self.identifier, self.location)
iface = self.identifier.resolve(scope, None)
return scope.lookupIdentifier(iface)
obj = self.identifier.resolve(scope, None)
return scope.lookupIdentifier(obj)
class IDLExternalInterface(IDLObjectWithIdentifier):
def __init__(self, location, parentScope, identifier):
@ -358,7 +361,7 @@ class IDLInterface(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members):
assert isinstance(parentScope, IDLScope)
assert isinstance(name, IDLUnresolvedIdentifier)
assert not parent or isinstance(parent, IDLInterfacePlaceholder)
assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
self.parent = parent
self._callback = False
@ -403,7 +406,7 @@ class IDLInterface(IDLObjectWithScope):
self._finished = True
assert not self.parent or isinstance(self.parent, IDLInterfacePlaceholder)
assert not self.parent or isinstance(self.parent, IDLIdentifierPlaceholder)
parent = self.parent.finish(scope) if self.parent else None
assert not parent or isinstance(parent, IDLInterface)
@ -588,6 +591,73 @@ class IDLInterface(IDLObjectWithScope):
return consequentialInterfaces | temp
class IDLDictionary(IDLObjectWithScope):
def __init__(self, location, parentScope, name, parent, members):
assert isinstance(parentScope, IDLScope)
assert isinstance(name, IDLUnresolvedIdentifier)
assert not parent or isinstance(parent, IDLIdentifierPlaceholder)
self.parent = parent
self._finished = False
self.members = list(members)
IDLObjectWithScope.__init__(self, location, parentScope, name)
def __str__(self):
return "Dictionary '%s'" % self.identifier.name
def isDictionary(self):
return True;
def finish(self, scope):
if self._finished:
return
self._finished = True
if self.parent:
assert isinstance(self.parent, IDLIdentifierPlaceholder)
oldParent = self.parent
self.parent = self.parent.finish(scope)
if not isinstance(self.parent, IDLDictionary):
raise WebIDLError("Dictionary %s has parent that is not a dictionary" %
self.identifier.name,
oldParent.location,
extraLocation=self.parent.location)
# Make sure the parent resolves all its members before we start
# looking at them.
self.parent.finish(scope)
for member in self.members:
member.resolve(self)
# Members of a dictionary are sorted in lexicographic order
self.members.sort(cmp=cmp, key=lambda x: x.identifier.name)
inheritedMembers = []
ancestor = self.parent
while ancestor:
if ancestor == self:
raise WebIDLError("Dictionary %s has itself as an ancestor" %
self.identifier.name,
self.identifier.location)
inheritedMembers.extend(ancestor.members)
ancestor = ancestor.parent
# Catch name duplication
for inheritedMember in inheritedMembers:
for member in self.members:
if member.identifier.name == inheritedMember.identifier.name:
raise WebIDLError("Dictionary %s has two members with name %s" %
(self.identifier.name, member.identifier.name),
member.location,
extraLocation=inheritedMember.location)
def addExtendedAttributes(self, attrs):
assert len(attrs) == 0
class IDLEnum(IDLObjectWithIdentifier):
def __init__(self, location, parentScope, name, values):
assert isinstance(parentScope, IDLScope)
@ -1093,7 +1163,7 @@ class IDLWrapperType(IDLType):
return False
def isDictionary(self):
return False
return isinstance(self.inner, IDLDictionary)
def isInterface(self):
return isinstance(self.inner, IDLInterface) or \
@ -1114,6 +1184,8 @@ class IDLWrapperType(IDLType):
return IDLType.Tags.interface
elif self.isEnum():
return IDLType.Tags.enum
elif self.isDictionary():
return IDLType.Tags.dictionary
else:
assert False
@ -1481,6 +1553,9 @@ class IDLConst(IDLInterfaceMember):
IDLInterfaceMember.Tags.Const)
assert isinstance(type, IDLType)
if type.isDictionary():
raise WebIDLError("A constant cannot be of a dictionary type",
self.location)
self.type = type
# The value might not match the type
@ -1518,6 +1593,9 @@ class IDLAttribute(IDLInterfaceMember):
assert not isinstance(t, IDLUnresolvedType)
assert not isinstance(t.name, IDLUnresolvedIdentifier)
if t.isDictionary():
raise WebIDLError("An attribute cannot be of a dictionary type",
self.location)
self.type = t
def handleExtendedAttribute(self, name, list):
@ -1804,8 +1882,8 @@ class IDLImplementsStatement(IDLObject):
self.implementee = implementee
def finish(self, scope):
assert(isinstance(self.implementor, IDLInterfacePlaceholder))
assert(isinstance(self.implementee, IDLInterfacePlaceholder))
assert(isinstance(self.implementor, IDLIdentifierPlaceholder))
assert(isinstance(self.implementee, IDLIdentifierPlaceholder))
implementor = self.implementor.finish(scope)
implementee = self.implementee.finish(scope)
implementor.addImplementedInterface(implementee)
@ -2041,7 +2119,7 @@ class Parser(Tokenizer):
"""
Inheritance : COLON ScopedName
"""
p[0] = IDLInterfacePlaceholder(self.getLocation(p, 2), p[2])
p[0] = IDLIdentifierPlaceholder(self.getLocation(p, 2), p[2])
def p_InheritanceEmpty(self, p):
"""
@ -2077,20 +2155,37 @@ class Parser(Tokenizer):
"""
Dictionary : DICTIONARY IDENTIFIER Inheritance LBRACE DictionaryMembers RBRACE SEMICOLON
"""
pass
location = self.getLocation(p, 1)
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
members = p[5]
p[0] = IDLDictionary(location, self.globalScope(), identifier, p[3], members)
def p_DictionaryMembers(self, p):
"""
DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers
|
"""
pass
if len(p) == 1:
# We're at the end of the list
p[0] = []
return
# Add our extended attributes
p[2].addExtendedAttributes(p[1])
p[0] = [p[2]]
p[0].extend(p[3])
def p_DictionaryMember(self, p):
"""
DictionaryMember : Type IDENTIFIER DefaultValue SEMICOLON
"""
pass
# These quack a lot like optional arguments, so just treat them that way.
t = p[1]
assert isinstance(t, IDLType)
identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2])
defaultValue = p[3]
p[0] = IDLArgument(self.getLocation(p, 2), identifier, t, optional=True,
defaultValue=defaultValue, variadic=False)
def p_DefaultValue(self, p):
"""
@ -2167,8 +2262,8 @@ class Parser(Tokenizer):
ImplementsStatement : ScopedName IMPLEMENTS ScopedName SEMICOLON
"""
assert(p[2] == "implements")
implementor = IDLInterfacePlaceholder(self.getLocation(p, 1), p[1])
implementee = IDLInterfacePlaceholder(self.getLocation(p, 3), p[3])
implementor = IDLIdentifierPlaceholder(self.getLocation(p, 1), p[1])
implementee = IDLIdentifierPlaceholder(self.getLocation(p, 3), p[3])
p[0] = IDLImplementsStatement(self.getLocation(p, 1), implementor,
implementee)

Просмотреть файл

@ -62,8 +62,8 @@ def run_tests(tests, verbose):
harness.start()
try:
_test.WebIDLTest.__call__(WebIDL.Parser(), harness)
except:
print "TEST-UNEXPECTED-FAIL | Unhandled exception in test %s" % testpath
except Exception, ex:
print "TEST-UNEXPECTED-FAIL | Unhandled exception in test %s: %s" % (testpath, ex)
traceback.print_exc()
finally:
harness.finish()

Просмотреть файл

@ -0,0 +1,97 @@
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
dictionary Dict2 : Dict1 {
long child = 5;
Dict1 aaandAnother;
};
dictionary Dict1 {
long parent;
double otherParent;
};
""")
results = parser.finish()
dict1 = results[1];
dict2 = results[0];
harness.check(len(dict1.members), 2, "Dict1 has two members")
harness.check(len(dict2.members), 2, "Dict2 has four members")
harness.check(dict1.members[0].identifier.name, "otherParent",
"'o' comes before 'p'")
harness.check(dict1.members[1].identifier.name, "parent",
"'o' really comes before 'p'")
harness.check(dict2.members[0].identifier.name, "aaandAnother",
"'a' comes before 'c'")
harness.check(dict2.members[1].identifier.name, "child",
"'a' really comes before 'c'")
# Now reset our parser
parser = WebIDL.Parser()
threw = False
try:
parser.parse("""
dictionary Dict {
long prop = 5;
long prop;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow name duplication in a dictionary")
# Now reset our parser again
parser = WebIDL.Parser()
threw = False
try:
parser.parse("""
dictionary Dict1 : Dict2 {
long prop = 5;
};
dictionary Dict2 : Dict3 {
long prop2;
};
dictionary Dict3 {
double prop;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow name duplication in a dictionary and "
"its ancestor")
# More reset
parser = WebIDL.Parser()
threw = False
try:
parser.parse("""
interface Iface {};
dictionary Dict : Iface {
long prop;
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow non-dictionary parents for dictionaries")
# Even more reset
parser = WebIDL.Parser()
threw = False
try:
parser.parse("""
dictionary A : B {};
dictionary B : A {};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw, "Should not allow cycles in dictionary inheritance chains")

Просмотреть файл

@ -12,15 +12,7 @@ def WebIDLTest(parser, harness):
attribute ArrayBuffer? b;
};
/* Not implemented */
/*dictionary TestNullableEquivalency3Dict {
long foo = 42;
};
interface TestNullableEquivalency3 {
attribute Test3Dict a;
attribute Test3Dict? b;
};*/
/* Can't have dictionary-valued attributes, so can't test that here */
enum TestNullableEquivalency4Enum {
"Foo",

Просмотреть файл

@ -233,6 +233,9 @@ public:
void PassOptionalObjectSequence(const Optional<Sequence<OwningNonNull<TestInterface> > >&,
ErrorResult&);
void ReceiveStringSequence(nsTArray<nsString>&, ErrorResult&);
void PassStringSequence(const Sequence<nsString>&, ErrorResult&);
// Typed array types
void PassArrayBuffer(ArrayBuffer&, ErrorResult&);
void PassNullableArrayBuffer(ArrayBuffer*, ErrorResult&);
@ -294,6 +297,14 @@ public:
int8_t GetAttributeRenamedTo(ErrorResult&);
void SetAttributeRenamedTo(int8_t, ErrorResult&);
// Dictionary tests
void PassDictionary(const Dict&, ErrorResult&);
void PassOptionalDictionary(const Optional<Dict>&, ErrorResult&);
void PassNullableDictionary(const Nullable<Dict>&, ErrorResult&);
void PassOptionalNullableDictionary(const Optional<Nullable<Dict> >&, ErrorResult&);
void PassOtherDictionary(const GrandparentDict&, ErrorResult&);
void PassSequenceOfDictionaries(const Sequence<Dict>&, ErrorResult&);
// Methods and properties imported via "implements"
bool GetImplementedProperty(ErrorResult&);
void SetImplementedProperty(bool, ErrorResult&);

Просмотреть файл

@ -163,6 +163,9 @@ interface TestInterface {
void passOptionalNullableSequenceWithDefaultValue(optional sequence<long>? arg = null);
void passOptionalObjectSequence(optional sequence<TestInterface> arg);
sequence<DOMString> receiveStringSequence();
void passStringSequence(sequence<DOMString> arg);
// Typed array types
void passArrayBuffer(ArrayBuffer arg);
void passNullableArrayBuffer(ArrayBuffer? arg);
@ -224,6 +227,13 @@ interface TestInterface {
void methodRenamedFrom(byte argument);
readonly attribute byte attributeGetterRenamedFrom;
attribute byte attributeRenamedFrom;
void passDictionary(Dict x);
void passOptionalDictionary(optional Dict x);
void passNullableDictionary(Dict? x);
void passOptionalNullableDictionary(optional Dict? x);
void passOtherDictionary(GrandparentDict x);
void passSequenceOfDictionaries(sequence<Dict> x);
};
interface ImplementedInterfaceParent {
@ -266,3 +276,15 @@ TestInterface implements DiamondBranch2A;
TestInterface implements DiamondBranch2B;
DiamondBranch1A implements DiamondImplements;
DiamondBranch1B implements DiamondImplements;
dictionary Dict : ParentDict {
long x;
long a;
long b = 8;
long z = 9;
DOMString str;
};
dictionary ParentDict : GrandparentDict {
long c = 5;
};

Просмотреть файл

@ -0,0 +1,9 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
dictionary GrandparentDict {
double someNum;
};

Просмотреть файл

@ -210,7 +210,7 @@ BluetoothManager::SetEnabled(bool aEnabled, nsIDOMDOMRequest** aDomRequest)
NS_ENSURE_SUCCESS(rv, rv);
if (!mToggleBtThread) {
mToggleBtThread = new LazyIdleThread(15000);
mToggleBtThread = new LazyIdleThread(15000, NS_LITERAL_CSTRING("Bluetooth"));
}
nsCOMPtr<nsIRunnable> r = new ToggleBtTask(aEnabled, request, this);

Просмотреть файл

@ -19,14 +19,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id={674720}
<pre id="test">
<script class="testbody" type="text/javascript">
"use strict"
"use strict";
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager)
.add(SpecialPowers.getDocumentURIObject(window.document),
"webcontacts-manage",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
SpecialPowers.addPermission("webcontacts-manage", true, document);
// For Sorting
var c1 = {
@ -526,12 +521,6 @@ var steps = [
req.onsuccess = onUnwantedSuccess;
req.onerror = function() { ok(true, "Successfully declined updating old contact!"); next(); };
},
function() {
ok(true, "Saving old contact, should abort!");
req = mozContacts.save(findResult1)
req.onsuccess = onUnwantedSuccess;
req.onerror = function() { ok(true, "Successfully declined updating old contact!"); next(); };
},
function () {
ok(true, "Retrieving a specific contact by ID");
var options = {filterBy: ["id"],

Просмотреть файл

@ -226,7 +226,8 @@ IndexedDatabaseManager::GetOrCreate()
// Make a lazy thread for any IO we need (like clearing or enumerating the
// contents of indexedDB database directories).
instance->mIOThread = new LazyIdleThread(DEFAULT_THREAD_TIMEOUT_MS,
LazyIdleThread::ManualShutdown);
NS_LITERAL_CSTRING("IndexedDB I/O"),
LazyIdleThread::ManualShutdown);
// We need one quota callback object to hand to SQLite.
instance->mQuotaCallbackSingleton = new QuotaCallback();

Просмотреть файл

@ -137,6 +137,9 @@ TransactionThreadPool::Init()
mThreadPool = do_CreateInstance(NS_THREADPOOL_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = mThreadPool->SetName(NS_LITERAL_CSTRING("IndexedDB Trans"));
NS_ENSURE_SUCCESS(rv, rv);
rv = mThreadPool->SetThreadLimit(kThreadLimit);
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -117,6 +117,8 @@ public:
NS_IMETHODIMP
AudioRunnable::Run()
{
PR_SetCurrentThreadName("Android Audio");
JNIEnv* jenv = GetJNIForThread();
if (!jenv)
return NS_ERROR_FAILURE;

Просмотреть файл

@ -19,19 +19,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id={678695}
<pre id="test">
<script class="testbody" type="text/javascript">
"use strict"
"use strict";
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager)
.add(SpecialPowers.getDocumentURIObject(window.document),
"websettings-read",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager)
.add(SpecialPowers.getDocumentURIObject(window.document),
"websettings-readwrite",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
SpecialPowers.addPermission("websettings-read", true, document);
SpecialPowers.addPermission("websettings-readwrite", true, document);
function onUnwantedSuccess() {
ok(false, "onUnwantedSuccess: shouldn't get here");

Просмотреть файл

@ -15,7 +15,10 @@ webidl_files = \
$(NULL)
ifdef ENABLE_TESTS
test_webidl_files := TestCodeGen.webidl
test_webidl_files := \
TestCodeGen.webidl \
TestDictionary.webidl \
$(NULL)
else
test_webidl_files := $(NULL)
endif

Просмотреть файл

@ -781,8 +781,9 @@ RuntimeService::ScheduleWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
}
if (!thread) {
if (NS_FAILED(NS_NewThread(getter_AddRefs(thread), nsnull,
WORKER_STACK_SIZE))) {
if (NS_FAILED(NS_NewNamedThread("DOM Worker",
getter_AddRefs(thread), nsnull,
WORKER_STACK_SIZE))) {
UnregisterWorker(aCx, aWorkerPrivate);
JS_ReportError(aCx, "Could not create new thread!");
return false;

Просмотреть файл

@ -436,16 +436,17 @@ public:
#else
virtual bool
RenewSurface() {
ReleaseSurface();
EGLConfig config;
sEGLLibrary.fMakeCurrent(EGL_DISPLAY(), EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
if (!mSurface) {
#ifdef MOZ_JAVA_COMPOSITOR
mSurface = mozilla::AndroidBridge::Bridge()->ProvideEGLSurface();
mSurface = mozilla::AndroidBridge::Bridge()->ProvideEGLSurface();
#else
CreateConfig(&config);
mSurface = CreateSurfaceForWindow(NULL, config);
EGLConfig config;
CreateConfig(&config);
mSurface = CreateSurfaceForWindow(NULL, config);
#endif
}
return sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
mSurface, mSurface,
mContext);

Просмотреть файл

@ -143,6 +143,8 @@ CompositorParent::ResumeComposition()
static_cast<LayerManagerOGL*>(mLayerManager.get())->gl()->RenewSurface();
#endif
Composite();
// if anyone's waiting to make sure that composition really got resumed, tell them
lock.NotifyAll();
}

Просмотреть файл

@ -8,6 +8,7 @@
#include "nsICollation.h"
#include "nsCollation.h"
#include "mozilla/Attributes.h"
#include <Carbon/Carbon.h>
// Maximum number of characters for a buffer to remember
@ -17,7 +18,7 @@ const PRUint32 kCacheSize = 128;
// at least 5 * textLength, but 6* would be safer.
const PRUint32 kCollationValueSizeFactor = 6;
class nsCollationMacUC : public nsICollation {
class nsCollationMacUC MOZ_FINAL : public nsICollation {
public:
nsCollationMacUC();

Просмотреть файл

@ -11,11 +11,12 @@
#include "nsICollation.h"
#include "nsICharsetConverterManager.h"
#include "nsCOMPtr.h"
#include "mozilla/Attributes.h"
// Create a collation interface for an input locale.
//
class nsCollationFactory: public nsICollationFactory {
class nsCollationFactory MOZ_FINAL : public nsICollationFactory {
public:
NS_DECL_ISUPPORTS

Просмотреть файл

@ -10,11 +10,12 @@
#include "nsCRT.h"
#include "nsInterfaceHashtable.h"
#include "nsIAtom.h"
#include "mozilla/Attributes.h"
#define NS_LANGUAGEATOMSERVICE_CID \
{0xB7C65853, 0x2996, 0x435E, {0x96, 0x54, 0xDC, 0xC1, 0x78, 0xAA, 0xB4, 0x8C}}
class nsLanguageAtomService : public nsILanguageAtomService
class nsLanguageAtomService MOZ_FINAL : public nsILanguageAtomService
{
public:
NS_DECL_ISUPPORTS

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsIOutputStream.h"
#include "nsIConverterOutputStream.h"
#include "nsCOMPtr.h"
#include "mozilla/Attributes.h"
class nsIUnicodeEncoder;
class nsIOutputStream;
@ -18,7 +19,7 @@ class nsIOutputStream;
{ 0xff8780a5, 0xbbb1, 0x4bc5, \
{ 0x8e, 0xe7, 0x05, 0x7e, 0x7b, 0xc5, 0xc9, 0x25 } }
class nsConverterOutputStream : public nsIConverterOutputStream {
class nsConverterOutputStream MOZ_FINAL : public nsIConverterOutputStream {
public:
nsConverterOutputStream() {}

Просмотреть файл

@ -6,6 +6,8 @@
#ifndef nsUnicodeToUTF8_h___
#define nsUnicodeToUTF8_h___
#include "mozilla/Attributes.h"
// Class ID for our UnicodeToUTF8 charset converter
// {7C657D18-EC5E-11d2-8AAC-00600811A836}
#define NS_UNICODETOUTF8_CID \
@ -25,7 +27,7 @@
* @created 05/Apr/1999
* @author Catalin Rotaru [CATA]
*/
class nsUnicodeToUTF8 : public nsIUnicodeEncoder
class nsUnicodeToUTF8 MOZ_FINAL : public nsIUnicodeEncoder
{
NS_DECL_ISUPPORTS

Просмотреть файл

@ -284,7 +284,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
RegExpStatics *res = cx->regExpStatics();
RegExpObject *reobj = builder.build(escapedSourceStr, RegExpFlag(flags | res->getFlags()));
if (!reobj)
return NULL;
return false;
args.rval() = ObjectValue(*reobj);
return true;

Просмотреть файл

@ -30,3 +30,19 @@ endif
export:: $(SUBMAKEFILES) $(MAKE_DIRS) $(if $(XPIDLSRCS),$(IDL_DIR))
$(LOOP_OVER_DIRS)
$(LOOP_OVER_TOOL_DIRS)
#
# Rule to create list of libraries for final link
#
# todo: use pre-req deps rather than conditionals
export:: export-gen-final-lib-link-list
export-gen-final-lib-link-list:
ifdef LIBRARY_NAME #{
ifdef EXPORT_LIBRARY #{
ifdef IS_COMPONENT #{
else # !IS_COMPONENT
$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
endif #} IS_COMPONENT
endif #} EXPORT_LIBRARY
endif #} LIBRARY_NAME

Просмотреть файл

@ -626,19 +626,6 @@ endif
include $(topsrcdir)/config/makefiles/target_export.mk
include $(topsrcdir)/config/makefiles/target_tools.mk
#
# Rule to create list of libraries for final link
#
export::
ifdef LIBRARY_NAME
ifdef EXPORT_LIBRARY
ifdef IS_COMPONENT
else # !IS_COMPONENT
$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
endif # IS_COMPONENT
endif # EXPORT_LIBRARY
endif # LIBRARY_NAME
ifneq (,$(filter-out %.$(LIB_SUFFIX),$(SHARED_LIBRARY_LIBS)))
$(error SHARED_LIBRARY_LIBS must contain .$(LIB_SUFFIX) files only)
endif

Просмотреть файл

@ -274,7 +274,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun,
TreeContext funtc(&parser, &funsc);
if (!funtc.init())
return NULL;
return false;
BytecodeEmitter funbce(&parser, &funsc, lineno,
/* noScriptRval = */ false, /* needsScriptGlobal = */ false);

Просмотреть файл

@ -5606,7 +5606,10 @@ EmitSyntheticStatements(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrd
JS_ASSERT(pn->isArity(PN_LIST));
StmtInfo stmtInfo(cx);
PushStatement(bce->sc, &stmtInfo, STMT_SEQ, top);
for (ParseNode *pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
ParseNode *pn2 = pn->pn_head;
if (pn->pn_xflags & PNX_DESTRUCT)
pn2 = pn2->pn_next;
for (; pn2; pn2 = pn2->pn_next) {
if (!EmitTree(cx, bce, pn2))
return false;
}

Просмотреть файл

@ -0,0 +1,6 @@
// See bug 763313
function f([a]) a
var i = 0;
var o = {get 0() { i++; return 42; }};
assertEq(f(o), 42);
assertEq(i, 1);

Просмотреть файл

@ -0,0 +1,21 @@
function getter() { return 1; }
function setter() { }
function getDescriptor(name) {
if (name != 'prop')
throw "Unknown property: " + name;
return { configurable: true, enumerable: true, get: getter, set: setter };
}
function getNames() { return ['prop']; }
var handler = {
getOwnPropertyDescriptor: getDescriptor,
getPropertyDescriptor: getDescriptor,
getOwnPropertyNames: getNames,
getPropertyNames: getNames,
defineProperty: function() {},
delete: function() {}
};
// Make sure that __lookup{Getter,Setter}__ works on proxies.
var proxy = Proxy.create(handler);
assertEq(Object.prototype.__lookupGetter__.call(proxy, 'prop'), getter);
assertEq(Object.prototype.__lookupSetter__.call(proxy, 'prop'), setter);

Просмотреть файл

@ -489,7 +489,7 @@ class AutoEnterCompartmentAndPushPrincipal : public JSAutoEnterCompartment
if (cb->pushContextPrincipal)
return cb->pushContextPrincipal(cx, target->principals(cx));
return true;
};
}
~AutoEnterCompartmentAndPushPrincipal() {
// Pop the principal if necessary.
@ -499,7 +499,7 @@ class AutoEnterCompartmentAndPushPrincipal : public JSAutoEnterCompartment
if (cb->popContextPrincipal)
cb->popContextPrincipal(ac->context);
}
};
}
};

Просмотреть файл

@ -1441,13 +1441,17 @@ class AutoLockGC
class AutoUnlockGC {
private:
#ifdef JS_THREADSAFE
JSRuntime *rt;
#endif
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
public:
explicit AutoUnlockGC(JSRuntime *rt
JS_GUARD_OBJECT_NOTIFIER_PARAM)
#ifdef JS_THREADSAFE
: rt(rt)
#endif
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
JS_UNLOCK_GC(rt);

Просмотреть файл

@ -2691,6 +2691,7 @@ GCHelperThread::finish()
void
GCHelperThread::threadMain(void *arg)
{
PR_SetCurrentThreadName("JS GC Helper");
static_cast<GCHelperThread *>(arg)->threadLoop();
}

Просмотреть файл

@ -285,7 +285,7 @@ Snapshot(JSContext *cx, JSObject *obj_, unsigned flags, AutoIdVector *props)
{
IdSet ht(cx);
if (!ht.init(32))
return NULL;
return false;
RootedObject obj(cx, obj_), pobj(cx);
pobj = obj;

Просмотреть файл

@ -156,7 +156,7 @@ obj_setProto(JSContext *cx, HandleObject obj, HandleId id, JSBool strict, Value
static bool
MarkSharpObjects(JSContext *cx, HandleObject obj, JSIdArray **idap, JSSharpInfo *value)
{
JS_CHECK_RECURSION(cx, return NULL);
JS_CHECK_RECURSION(cx, return false);
JSIdArray *ida;
@ -1436,6 +1436,17 @@ obj_lookupGetter(JSContext *cx, unsigned argc, Value *vp)
RootedObject obj(cx, ToObject(cx, &vp[1]));
if (!obj)
return JS_FALSE;
if (obj->isProxy()) {
// The vanilla getter lookup code below requires that the object is
// native. Handle proxies separately.
vp->setUndefined();
PropertyDescriptor desc;
if (!Proxy::getPropertyDescriptor(cx, obj, id, false, &desc))
return JS_FALSE;
if ((desc.attrs & JSPROP_GETTER) && desc.getter)
*vp = CastAsObjectJsval(desc.getter);
return JS_TRUE;
}
JSObject *pobj;
JSProperty *prop;
if (!obj->lookupGeneric(cx, id, &pobj, &prop))
@ -1460,6 +1471,17 @@ obj_lookupSetter(JSContext *cx, unsigned argc, Value *vp)
RootedObject obj(cx, ToObject(cx, &vp[1]));
if (!obj)
return JS_FALSE;
if (obj->isProxy()) {
// The vanilla setter lookup code below requires that the object is
// native. Handle proxies separately.
vp->setUndefined();
PropertyDescriptor desc;
if (!Proxy::getPropertyDescriptor(cx, obj, id, false, &desc))
return JS_FALSE;
if ((desc.attrs & JSPROP_SETTER) && desc.setter)
*vp = CastAsObjectJsval(desc.setter);
return JS_TRUE;
}
JSObject *pobj;
JSProperty *prop;
if (!obj->lookupGeneric(cx, id, &pobj, &prop))
@ -2533,7 +2555,7 @@ JSObject::sealOrFreeze(JSContext *cx, ImmutabilityType it)
last = cx->propertyTree().getChild(cx, last, self->numFixedSlots(), child);
if (!last)
return NULL;
return false;
}
JS_ASSERT(self->lastProperty()->slotSpan() == last->slotSpan());

Просмотреть файл

@ -1851,14 +1851,14 @@ IsVarSlot(JSPrinter *jp, jsbytecode *pc, JSAtom **varAtom, int *localSlot)
{
if (JOF_OPTYPE(*pc) == JOF_SCOPECOORD) {
*varAtom = ScopeCoordinateName(jp->sprinter.context->runtime, jp->script, pc);
LOCAL_ASSERT_RV(*varAtom, NULL);
LOCAL_ASSERT_RV(*varAtom, false);
return true;
}
unsigned slot = GET_SLOTNO(pc);
if (slot < jp->script->nfixed) {
*varAtom = GetArgOrVarAtom(jp, jp->fun->nargs + slot);
LOCAL_ASSERT_RV(*varAtom, NULL);
LOCAL_ASSERT_RV(*varAtom, false);
return true;
}

Просмотреть файл

@ -1192,7 +1192,7 @@ Proxy::fun_toString(JSContext *cx, JSObject *proxy, unsigned indent)
bool
Proxy::regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g)
{
JS_CHECK_RECURSION(cx, return NULL);
JS_CHECK_RECURSION(cx, return false);
AutoPendingProxyOperation pending(cx, proxy);
return GetProxyHandler(proxy)->regexp_toShared(cx, proxy, g);
}
@ -1200,7 +1200,7 @@ Proxy::regexp_toShared(JSContext *cx, JSObject *proxy, RegExpGuard *g)
bool
Proxy::defaultValue(JSContext *cx, JSObject *proxy, JSType hint, Value *vp)
{
JS_CHECK_RECURSION(cx, return NULL);
JS_CHECK_RECURSION(cx, return false);
AutoPendingProxyOperation pending(cx, proxy);
return GetProxyHandler(proxy)->defaultValue(cx, proxy, hint, vp);
}
@ -1208,7 +1208,7 @@ Proxy::defaultValue(JSContext *cx, JSObject *proxy, JSType hint, Value *vp)
bool
Proxy::iteratorNext(JSContext *cx, JSObject *proxy, Value *vp)
{
JS_CHECK_RECURSION(cx, return NULL);
JS_CHECK_RECURSION(cx, return false);
AutoPendingProxyOperation pending(cx, proxy);
return GetProxyHandler(proxy)->iteratorNext(cx, proxy, vp);
}

Просмотреть файл

@ -129,7 +129,7 @@ Bindings::add(JSContext *cx, HandleAtom name, BindingKind kind)
UnownedBaseShape *nbase = BaseShape::getUnowned(cx, base);
if (!nbase)
return NULL;
return false;
StackShape child(nbase, id, slot, 0, attrs, Shape::HAS_SHORTID, *indexp);

Просмотреть файл

@ -2023,7 +2023,7 @@ BuildDollarReplacement(JSContext *cx, JSString *textstrArg, JSLinearString *reps
{
Rooted<JSLinearString*> textstr(cx, textstrArg->ensureLinear(cx));
if (!textstr)
return NULL;
return false;
JS_ASSERT(repstr->chars() <= firstDollar && firstDollar < repstr->chars() + repstr->length());
size_t matchStart = fm.match();

Просмотреть файл

@ -611,10 +611,10 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::MIPSRegiste
pc, pinlined, fd); \
}
STUB_CALL_TYPE(JSObjStub);
STUB_CALL_TYPE(VoidPtrStubUInt32);
STUB_CALL_TYPE(VoidStubUInt32);
STUB_CALL_TYPE(VoidStub);
STUB_CALL_TYPE(JSObjStub)
STUB_CALL_TYPE(VoidPtrStubUInt32)
STUB_CALL_TYPE(VoidStubUInt32)
STUB_CALL_TYPE(VoidStub)
#undef STUB_CALL_TYPE

Просмотреть файл

@ -5124,7 +5124,7 @@ mjit::Compiler::testSingletonPropertyTypes(FrameEntry *top, HandleId id, bool *t
RootedObject proto(cx);
if (!js_GetClassPrototype(cx, globalObj, key, proto.address(), NULL))
return NULL;
return false;
return testSingletonProperty(proto, id);
}

Просмотреть файл

@ -202,10 +202,11 @@ ReportException(JSContext *cx)
}
}
class ToStringHelper {
class ToStringHelper
{
public:
ToStringHelper(JSContext *aCx, jsval v, bool aThrow = false)
: cx(aCx), mThrow(aThrow)
: cx(aCx)
{
mStr = JS_ValueToString(cx, v);
if (!aThrow && !mStr)
@ -225,7 +226,6 @@ class ToStringHelper {
private:
JSContext *cx;
JSString *mStr;
bool mThrow;
JSAutoByteString mBytes;
};
@ -2927,6 +2927,8 @@ KillWatchdog()
static void
WatchdogMain(void *arg)
{
PR_SetCurrentThreadName("JS Watchdog");
JSRuntime *rt = (JSRuntime *) arg;
PR_Lock(gWatchdogLock);

Просмотреть файл

@ -486,7 +486,7 @@ ReferenceFinder::addReferrer(jsval referrer_, Path *path)
Rooted<jsval> referrer(context, referrer_);
if (!context->compartment->wrap(context, referrer.address()))
return NULL;
return false;
char *pathName = path->computeName(context);
if (!pathName)

Просмотреть файл

@ -434,6 +434,7 @@ class ThreadPool
static JSClass jsClass;
static void start(void* arg) {
PR_SetCurrentThreadName("JS Worker");
((WorkerQueue *) arg)->work();
}

Просмотреть файл

@ -119,8 +119,8 @@ ValueToIdentifier(JSContext *cx, const Value &v, jsid *idp)
* Debugger::removeDebuggeeGlobal to make sure only current debuggers have Frame
* objects with .live === true.
*/
class Debugger::FrameRange {
JSContext *cx;
class Debugger::FrameRange
{
StackFrame *fp;
/* The debuggers in |fp|'s compartment, or NULL if there are none. */
@ -150,8 +150,9 @@ class Debugger::FrameRange {
* Similarly, if stack frames are added to or removed from frontDebugger(),
* then the range's front is invalid until popFront is called.
*/
FrameRange(JSContext *cx, StackFrame *fp, GlobalObject *global = NULL)
: cx(cx), fp(fp) {
FrameRange(StackFrame *fp, GlobalObject *global = NULL)
: fp(fp)
{
nextDebugger = 0;
/* Find our global, if we were not given one. */
@ -510,7 +511,7 @@ Debugger::slowPathOnLeaveFrame(JSContext *cx, bool frameOk)
/* Build a list of the recipients. */
AutoObjectVector frames(cx);
for (FrameRange r(cx, fp, global); !r.empty(); r.popFront()) {
for (FrameRange r(fp, global); !r.empty(); r.popFront()) {
if (!frames.append(r.frontFrame())) {
cx->clearPendingException();
return false;
@ -565,7 +566,7 @@ Debugger::slowPathOnLeaveFrame(JSContext *cx, bool frameOk)
* debugger's onPop handler could have caused another debugger to create its
* own Debugger.Frame instance.
*/
for (FrameRange r(cx, fp, global); !r.empty(); r.popFront()) {
for (FrameRange r(fp, global); !r.empty(); r.popFront()) {
JSObject *frameobj = r.frontFrame();
Debugger *dbg = r.frontDebugger();
JS_ASSERT(dbg == Debugger::fromChildJSObject(frameobj));
@ -1174,7 +1175,7 @@ Debugger::onSingleStep(JSContext *cx, Value *vp)
* onStep handlers.
*/
AutoObjectVector frames(cx);
for (FrameRange r(cx, fp); !r.empty(); r.popFront()) {
for (FrameRange r(fp); !r.empty(); r.popFront()) {
JSObject *frame = r.frontFrame();
if (!frame->getReservedSlot(JSSLOT_DEBUGFRAME_ONSTEP_HANDLER).isUndefined() &&
!frames.append(frame))

Просмотреть файл

@ -950,7 +950,7 @@ ContextStack::pushExecuteFrame(JSContext *cx, JSScript *script, const Value &thi
unsigned nvars = 2 /* callee, this */ + VALUES_PER_STACK_FRAME + script->nslots;
Value *firstUnused = ensureOnTop(cx, REPORT_ERROR, nvars, extend, &efg->pushedSeg_);
if (!firstUnused)
return NULL;
return false;
StackFrame *prev = evalInFrame ? evalInFrame : maybefp();
StackFrame *fp = reinterpret_cast<StackFrame *>(firstUnused + 2);

Просмотреть файл

@ -585,6 +585,7 @@ class JSShortString : public JSInlineString
offsetof(JSShortString, d.inlineStorage)) / sizeof(jschar));
}
protected: /* to fool clang into not warning this is unused */
jschar inlineStorageExtension[INLINE_EXTENSION_CHARS];
public:

Просмотреть файл

@ -885,6 +885,8 @@ class AutoLockWatchdog {
void
XPCJSRuntime::WatchdogMain(void *arg)
{
PR_SetCurrentThreadName("JS Watchdog");
XPCJSRuntime* self = static_cast<XPCJSRuntime*>(arg);
// Lock lasts until we return

Просмотреть файл

@ -63,6 +63,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=500931
is(win.XPathResult.NUMBER_TYPE, 1, "can access constants on constructors");
is(typeof win.IDBKeyRange.bound, "function", "can access crazy IDBKeyRange static functions");
// Test getter/setter lookup on Xray wrappers.
ok(Object.prototype.__lookupGetter__.call(win.document, 'title'), 'found getter on document');
ok(Object.prototype.__lookupGetter__.call(win.document, 'title'), 'found getter on document');
// Test QI on new dom bindings.
var contentXHR = XPCNativeWrapper(win.wrappedJSObject.xhr);
try {
var QIed = contentXHR.QueryInterface(Components.interfaces.nsIClassInfo);
ok(QIed, "Successfully QI-ed on wrapper");
} catch(e) {
ok(false, "Threw while QI-ing on wrapper");
}
}
SimpleTest.waitForExplicitFinish();

Просмотреть файл

@ -3,20 +3,17 @@
<script>
function check_wrapper(ok, wrapper, expected, note) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
var utils = SpecialPowers.DOMWindowUtils;
ok(utils.getClassName(wrapper) === expected, note);
}
function check_parent(ok, obj, expected, note) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
var utils = SpecialPowers.DOMWindowUtils;
ok(utils.getParent(obj) === expected, note);
}
function run_test(ok, xpcnw, sjow) {
// both wrappers should point to our window: XOW
check_wrapper(ok, ok, "Proxy", "functions are wrapped properly")
check_parent(ok, ok, window, "ok is parented correctly");
check_wrapper(ok, xpcnw, "Proxy", "XPCNWs are transformed correctly");
check_wrapper(ok, sjow, "Proxy", "SJOWs are transformed correctly");
@ -29,6 +26,8 @@
// defprop2 = {}; disabled because the test doesn't work
}
window.xhr = new XMLHttpRequest();
</script>
</head>
<body>

Просмотреть файл

@ -0,0 +1,13 @@
<html>
<head>
</head>
<body style="background-color: lime;">
<svg width="300" height="300"
style="border-radius: 200px; overflow: hidden; background-color: red; position: absolute;">
<rect width="300" height="300" fill="red"/>
</svg>
<svg width="300" height="300" style="position: absolute;">
<circle cx="150" cy="150" r="155" fill="lime"/>
</svg>
</body>
</html>

Просмотреть файл

@ -23,6 +23,7 @@ include moz-only/reftest.list
include svg-integration/reftest.list
== altGlyph-01.svg altGlyph-01-ref.svg
== border-radius-01.html pass.svg
== cssComment-in-attribute-01.svg cssComment-in-attribute-01-ref.svg
== clip-01.svg pass.svg
== clip-02a.svg clip-02-ref.svg

Просмотреть файл

@ -626,8 +626,15 @@ nsSVGOuterSVGFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
NS_ENSURE_SUCCESS(rv, rv);
return aLists.Content()->AppendNewToTop(
nsDisplayList replacedContent;
rv = replacedContent.AppendNewToTop(
new (aBuilder) nsDisplaySVG(aBuilder, this));
NS_ENSURE_SUCCESS(rv, rv);
WrapReplacedContentForBorderRadius(aBuilder, &replacedContent, aLists);
return NS_OK;
}
void

Просмотреть файл

@ -6,13 +6,13 @@
#filter substitution
package @ANDROID_PACKAGE_NAME@;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.BrowserApp;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.R;
import android.view.MenuItem;
public class App extends GeckoApp {
public class App extends BrowserApp {
public String getPackageName() {
return "@ANDROID_PACKAGE_NAME@";
}

Просмотреть файл

@ -75,9 +75,6 @@ public class AwesomeBar extends GeckoActivity implements GeckoEventListener {
private SuggestClient mSuggestClient;
private AsyncTask<String, Void, ArrayList<String>> mSuggestTask;
private static String sSuggestEngine;
private static String sSuggestTemplate;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -230,45 +227,17 @@ public class AwesomeBar extends GeckoActivity implements GeckoEventListener {
registerForContextMenu(mAwesomeTabs.findViewById(R.id.bookmarks_list));
registerForContextMenu(mAwesomeTabs.findViewById(R.id.history_list));
if (sSuggestTemplate == null) {
loadSuggestClientFromPrefs();
} else {
loadSuggestClient();
}
GeckoAppShell.registerGeckoEventListener("SearchEngines:Data", this);
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SearchEngines:Get", null));
}
private void loadSuggestClientFromPrefs() {
GeckoAppShell.getHandler().post(new Runnable() {
public void run() {
SharedPreferences prefs = getSearchPreferences();
sSuggestEngine = prefs.getString("suggestEngine", null);
sSuggestTemplate = prefs.getString("suggestTemplate", null);
if (sSuggestTemplate != null) {
loadSuggestClient();
mAwesomeTabs.setSuggestEngine(sSuggestEngine, null);
}
}
});
}
private void loadSuggestClient() {
mSuggestClient = new SuggestClient(GeckoApp.mAppContext, sSuggestTemplate, SUGGESTION_TIMEOUT, SUGGESTION_MAX);
}
public void handleMessage(String event, JSONObject message) {
try {
if (event.equals("SearchEngines:Data")) {
final String suggestEngine = message.optString("suggestEngine");
final String suggestTemplate = message.optString("suggestTemplate");
if (!TextUtils.equals(suggestTemplate, sSuggestTemplate)) {
saveSuggestEngineData(suggestEngine, suggestTemplate);
sSuggestEngine = suggestEngine;
sSuggestTemplate = suggestTemplate;
loadSuggestClient();
}
final String suggestEngine = message.isNull("suggestEngine") ? null : message.getString("suggestEngine");
final String suggestTemplate = message.isNull("suggestTemplate") ? null : message.getString("suggestTemplate");
if (suggestTemplate != null)
mSuggestClient = new SuggestClient(GeckoApp.mAppContext, suggestTemplate, SUGGESTION_TIMEOUT, SUGGESTION_MAX);
mAwesomeTabs.setSearchEngines(suggestEngine, message.getJSONArray("searchEngines"));
}
} catch (Exception e) {
@ -277,18 +246,6 @@ public class AwesomeBar extends GeckoActivity implements GeckoEventListener {
}
}
private void saveSuggestEngineData(final String suggestEngine, final String suggestTemplate) {
GeckoAppShell.getHandler().post(new Runnable() {
public void run() {
SharedPreferences prefs = getSearchPreferences();
SharedPreferences.Editor editor = prefs.edit();
editor.putString("suggestEngine", suggestEngine);
editor.putString("suggestTemplate", suggestTemplate);
editor.commit();
}
});
}
@Override
public void onConfigurationChanged(Configuration newConfiguration) {
super.onConfigurationChanged(newConfiguration);
@ -671,9 +628,13 @@ public class AwesomeBar extends GeckoActivity implements GeckoEventListener {
@Override
public void onPostExecute(Void result) {
int messageId = R.string.bookmark_removed;
if (mInReadingList)
if (mInReadingList) {
messageId = R.string.reading_list_removed;
GeckoEvent e = GeckoEvent.createBroadcastEvent("Reader:Remove", url);
GeckoAppShell.sendEventToGecko(e);
}
Toast.makeText(AwesomeBar.this, messageId, Toast.LENGTH_SHORT).show();
}
}).execute();
@ -762,8 +723,4 @@ public class AwesomeBar extends GeckoActivity implements GeckoEventListener {
mOnKeyPreImeListener = listener;
}
}
private SharedPreferences getSearchPreferences() {
return getSharedPreferences("search.prefs", MODE_PRIVATE);
}
}

Просмотреть файл

@ -1166,10 +1166,6 @@ public class AwesomeBarTabs extends TabHost {
public Drawable icon;
public ArrayList<String> suggestions;
public SearchEngine(String name) {
this(name, null);
}
public SearchEngine(String name, Drawable icon) {
this.name = name;
this.icon = icon;
@ -1177,28 +1173,6 @@ public class AwesomeBarTabs extends TabHost {
}
};
/**
* Sets the suggest engine, which will show suggestions for user-entered queries.
* If the suggest engine has already been set, it will be replaced, and its
* suggestions will be copied to the new suggest engine.
*/
public void setSuggestEngine(String name, Drawable icon) {
// We currently save the suggest engine in shared preferences, so this
// method is called immediately when the AwesomeBar is created. It's
// called again in setSuggestions(), when the list of search engines is
// received from Gecko (in case the suggestion engine has changed).
final SearchEngine suggestEngine = new SearchEngine(name, icon);
if (mSuggestEngine != null)
suggestEngine.suggestions = mSuggestEngine.suggestions;
GeckoAppShell.getMainHandler().post(new Runnable() {
public void run() {
mSuggestEngine = suggestEngine;
mAllPagesCursorAdapter.notifyDataSetChanged();
}
});
}
/**
* Sets suggestions associated with the current suggest engine.
* If there is no suggest engine, this does nothing.
@ -1217,16 +1191,17 @@ public class AwesomeBarTabs extends TabHost {
/**
* Sets search engines to be shown for user-entered queries.
*/
public void setSearchEngines(String suggestEngine, JSONArray engines) {
public void setSearchEngines(String suggestEngineName, JSONArray engines) {
final ArrayList<SearchEngine> searchEngines = new ArrayList<SearchEngine>();
SearchEngine suggestEngine = null;
for (int i = 0; i < engines.length(); i++) {
try {
JSONObject engineJSON = engines.getJSONObject(i);
String name = engineJSON.getString("name");
String iconURI = engineJSON.getString("iconURI");
Drawable icon = getDrawableFromDataURI(iconURI);
if (name.equals(suggestEngine)) {
setSuggestEngine(name, icon);
if (name.equals(suggestEngineName)) {
suggestEngine = new SearchEngine(name, icon);
} else {
searchEngines.add(new SearchEngine(name, icon));
}
@ -1236,8 +1211,10 @@ public class AwesomeBarTabs extends TabHost {
}
}
final SearchEngine suggestEngineArg = suggestEngine;
GeckoAppShell.getMainHandler().post(new Runnable() {
public void run() {
mSuggestEngine = suggestEngineArg;
mSearchEngines = searchEngines;
mAllPagesCursorAdapter.notifyDataSetChanged();
}

Просмотреть файл

@ -0,0 +1,478 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.BufferedCairoImage;
import org.mozilla.gecko.gfx.FloatSize;
import org.mozilla.gecko.gfx.GeckoLayerClient;
import org.mozilla.gecko.gfx.IntSize;
import org.mozilla.gecko.gfx.Layer;
import org.mozilla.gecko.gfx.LayerController;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.gfx.PluginLayer;
import org.mozilla.gecko.gfx.RectUtils;
import org.mozilla.gecko.gfx.SurfaceTextureLayer;
import org.mozilla.gecko.gfx.ViewportMetrics;
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
import java.io.*;
import java.util.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.zip.*;
import java.net.URL;
import java.nio.*;
import java.nio.channels.FileChannel;
import java.util.concurrent.*;
import java.lang.reflect.*;
import java.net.*;
import org.json.*;
import android.os.*;
import android.app.*;
import android.text.*;
import android.text.format.Time;
import android.view.*;
import android.view.inputmethod.*;
import android.view.ViewGroup.LayoutParams;
import android.content.*;
import android.content.res.*;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.BitmapDrawable;
import android.widget.*;
import android.hardware.*;
import android.location.*;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityEvent;
import android.util.*;
import android.net.*;
import android.database.*;
import android.database.sqlite.*;
import android.provider.*;
import android.content.pm.*;
import android.content.pm.PackageManager.*;
import dalvik.system.*;
abstract public class BrowserApp extends GeckoApp {
private static final String LOGTAG = "GeckoBrowserApp";
public static BrowserToolbar mBrowserToolbar;
private AboutHomeContent mAboutHomeContent;
@Override
public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
switch(msg) {
case LOCATION_CHANGE:
if (Tabs.getInstance().isSelectedTab(tab)) {
String url = tab.getURL();
if (url.equals("about:home"))
showAboutHome();
else
hideAboutHome();
maybeCancelFaviconLoad(tab);
}
break;
case START:
if (Tabs.getInstance().isSelectedTab(tab)) {
invalidateOptionsMenu();
}
case STOP:
if (Tabs.getInstance().isSelectedTab(tab)) {
invalidateOptionsMenu();
}
break;
case SELECTED:
if ("about:home".equals(tab.getURL()))
showAboutHome();
else
hideAboutHome();
break;
}
super.onTabChanged(tab, msg, data);
}
@Override
void handlePageShow(final int tabId) {
super.handlePageShow(tabId);
final Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null)
return;
mMainHandler.post(new Runnable() {
public void run() {
loadFavicon(tab);
}
});
}
@Override
void handleLinkAdded(final int tabId, String rel, final String href, int size) {
super.handleLinkAdded(tabId, rel, href, size);
if (rel.indexOf("[icon]") == -1)
return;
final Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null)
return;
// If tab is not loading and the favicon is updated, we
// want to load the image straight away. If tab is still
// loading, we only load the favicon once the page's content
// is fully loaded (see handleContentLoaded()).
if (tab.getState() != Tab.STATE_LOADING) {
mMainHandler.post(new Runnable() {
public void run() {
loadFavicon(tab);
}
});
}
}
@Override
void handleClearHistory() {
updateAboutHomeTopSites();
super.handleClearHistory();
}
@Override
void handleSecurityChange(final int tabId, final JSONObject identityData) {
super.handleSecurityChange(tabId, identityData);
final Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null)
return;
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab))
mBrowserToolbar.setSecurityMode(tab.getSecurityMode());
}
});
}
void handleReaderEnabled(final int tabId) {
super.handleReaderEnabled(tabId);
final Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null)
return;
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab))
mBrowserToolbar.setReaderVisibility(tab.getReaderEnabled());
}
});
}
@Override
void onStatePurged() {
mMainHandler.post(new Runnable() {
public void run() {
if (mAboutHomeContent != null)
mAboutHomeContent.setLastTabsVisibility(false);
}
});
super.onStatePurged();
}
@Override
protected void loadRequest(String url, AwesomeBar.Target target, String searchEngine, boolean userEntered) {
mBrowserToolbar.setTitle(url);
super.loadRequest(url, target, searchEngine, userEntered);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout actionBar = (LinearLayout) findViewById(R.id.browser_toolbar);
mBrowserToolbar = new BrowserToolbar(mAppContext);
mBrowserToolbar.from(actionBar);
if (savedInstanceState != null) {
mBrowserToolbar.setTitle(savedInstanceState.getString(SAVED_STATE_TITLE));
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mAboutHomeContent != null)
mAboutHomeContent.onDestroy();
}
@Override
public void onContentChanged() {
super.onContentChanged();
if (mAboutHomeContent != null)
mAboutHomeContent.onActivityContentChanged(this);
}
@Override
protected void finishProfileMigration() {
// Update about:home with the new information.
updateAboutHomeTopSites();
super.finishProfileMigration();
}
@Override void initializeChrome(String uri, Boolean isExternalURL) {
super.initializeChrome(uri, isExternalURL);
mBrowserToolbar.updateBackButton(false);
mBrowserToolbar.updateForwardButton(false);
Intent intent = getIntent();
String action = intent.getAction();
String args = intent.getStringExtra("args");
if (args != null && args.contains("-profile")) {
Pattern p = Pattern.compile("(?:-profile\\s*)(\\w*)(\\s*)");
Matcher m = p.matcher(args);
if (m.find()) {
mBrowserToolbar.setTitle(null);
}
}
if (uri != null && uri.length() > 0) {
mBrowserToolbar.setTitle(uri);
}
if (!isExternalURL) {
// show about:home if we aren't restoring previous session
if (mRestoreMode == GeckoAppShell.RESTORE_NONE) {
mBrowserToolbar.updateTabCount(1);
showAboutHome();
}
} else {
mBrowserToolbar.updateTabCount(1);
}
mBrowserToolbar.setProgressVisibility(isExternalURL || (mRestoreMode != GeckoAppShell.RESTORE_NONE));
}
void toggleChrome(final boolean aShow) {
mMainHandler.post(new Runnable() {
public void run() {
if (aShow) {
mBrowserToolbar.show();
} else {
mBrowserToolbar.hide();
}
}
});
super.toggleChrome(aShow);
}
@Override
void focusChrome() {
mMainHandler.post(new Runnable() {
public void run() {
mBrowserToolbar.setVisibility(View.VISIBLE);
mBrowserToolbar.requestFocusFromTouch();
}
});
}
@Override
public void refreshChrome() {
if (Build.VERSION.SDK_INT >= 11) {
mBrowserToolbar.requestLayout();
mBrowserToolbar.refresh();
invalidateOptionsMenu();
mTabsPanel.refresh();
}
}
void addTab() {
showAwesomebar(AwesomeBar.Target.NEW_TAB);
}
public void showLocalTabs() {
showTabs(TabsPanel.Panel.LOCAL_TABS);
}
public void showRemoteTabs() {
showTabs(TabsPanel.Panel.REMOTE_TABS);
}
private void showTabs(TabsPanel.Panel panel) {
if (!sIsGeckoReady)
return;
mTabsPanel.show(panel);
mBrowserToolbar.updateTabs(true);
}
public void hideTabs() {
mTabsPanel.hide();
mBrowserToolbar.updateTabs(false);
}
public boolean areTabsShown() {
return mTabsPanel.isShown();
}
/* Doorhanger notification methods */
@Override
void updatePopups(final Tab tab) {
mDoorHangerPopup.updatePopup(mBrowserToolbar.mFavicon);
}
@Override
void addDoorHanger(String message, String value, JSONArray buttons, Tab tab, JSONObject options) {
mDoorHangerPopup.addDoorHanger(message, value, buttons, tab, options, mBrowserToolbar.mFavicon);
}
/* Favicon methods */
private void loadFavicon(final Tab tab) {
maybeCancelFaviconLoad(tab);
long id = mFavicons.loadFavicon(tab.getURL(), tab.getFaviconURL(),
new Favicons.OnFaviconLoadedListener() {
public void onFaviconLoaded(String pageUrl, Drawable favicon) {
// Leave favicon UI untouched if we failed to load the image
// for some reason.
if (favicon == null)
return;
Log.i(LOGTAG, "Favicon successfully loaded for URL = " + pageUrl);
// The tab might be pointing to another URL by the time the
// favicon is finally loaded, in which case we simply ignore it.
if (!tab.getURL().equals(pageUrl))
return;
Log.i(LOGTAG, "Favicon is for current URL = " + pageUrl);
tab.updateFavicon(favicon);
tab.setFaviconLoadId(Favicons.NOT_LOADING);
if (Tabs.getInstance().isSelectedTab(tab))
mBrowserToolbar.setFavicon(tab.getFavicon());
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.FAVICON);
}
});
tab.setFaviconLoadId(id);
}
private void maybeCancelFaviconLoad(Tab tab) {
long faviconLoadId = tab.getFaviconLoadId();
if (faviconLoadId == Favicons.NOT_LOADING)
return;
// Cancel pending favicon load task
mFavicons.cancelFaviconLoad(faviconLoadId);
// Reset favicon load state
tab.setFaviconLoadId(Favicons.NOT_LOADING);
}
/* About:home UI */
void updateAboutHomeTopSites() {
if (mAboutHomeContent == null)
return;
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
public void run() {
mAboutHomeContent.update(GeckoApp.mAppContext,
EnumSet.of(AboutHomeContent.UpdateFlags.TOP_SITES));
}
});
}
public void showAboutHome() {
Runnable r = new AboutHomeRunnable(true);
mMainHandler.postAtFrontOfQueue(r);
}
public void hideAboutHome() {
Runnable r = new AboutHomeRunnable(false);
mMainHandler.postAtFrontOfQueue(r);
}
public class AboutHomeRunnable implements Runnable {
boolean mShow;
AboutHomeRunnable(boolean show) {
mShow = show;
}
public void run() {
mFormAssistPopup.hide();
if (mShow) {
if (mAboutHomeContent == null) {
mAboutHomeContent = (AboutHomeContent) findViewById(R.id.abouthome_content);
mAboutHomeContent.init();
mAboutHomeContent.update(GeckoApp.mAppContext, AboutHomeContent.UpdateFlags.ALL);
mAboutHomeContent.setUriLoadCallback(new AboutHomeContent.UriLoadCallback() {
public void callback(String url) {
mBrowserToolbar.setProgressVisibility(true);
loadUrl(url, AwesomeBar.Target.CURRENT_TAB);
}
});
} else {
mAboutHomeContent.update(GeckoApp.mAppContext,
EnumSet.of(AboutHomeContent.UpdateFlags.TOP_SITES,
AboutHomeContent.UpdateFlags.REMOTE_TABS));
}
mAboutHomeContent.setVisibility(View.VISIBLE);
} else {
findViewById(R.id.abouthome_content).setVisibility(View.GONE);
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
sMenu = menu;
// Inform the menu about the action-items bar.
if (menu instanceof GeckoMenu && isTablet())
((GeckoMenu) menu).setActionItemBarPresenter(mBrowserToolbar);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.gecko_menu, sMenu);
return true;
}
@Override
public void openOptionsMenu() {
// Scroll custom menu to the top
if (mMenuPanel != null)
mMenuPanel.scrollTo(0, 0);
if (!mBrowserToolbar.openOptionsMenu())
super.openOptionsMenu();
}
@Override
public void closeOptionsMenu() {
if (!mBrowserToolbar.closeOptionsMenu())
super.closeOptionsMenu();
}
@Override
public void setFullScreen(final boolean fullscreen) {
super.setFullScreen(fullscreen);
if (fullscreen)
mBrowserToolbar.hide();
else
mBrowserToolbar.show();
}
}

Просмотреть файл

@ -46,6 +46,7 @@ import android.widget.Toast;
import android.widget.ViewSwitcher;
public class BrowserToolbar implements ViewSwitcher.ViewFactory,
Tabs.OnTabsChangedListener,
GeckoMenu.ActionItemBarPresenter {
private static final String LOGTAG = "GeckoToolbar";
private LinearLayout mLayout;
@ -93,6 +94,7 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
mInflater = LayoutInflater.from(context);
sActionItems = new ArrayList<View>();
Tabs.getInstance().registerOnTabsChangedListener(this);
}
public void from(LinearLayout layout) {
@ -180,7 +182,7 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
// Calculate the left margin for the arrow based on the position of the lock icon.
int leftMargin = lockLocation[0] - lockLayoutParams.rightMargin;
SiteIdentityPopup.getInstance().show(leftMargin);
SiteIdentityPopup.getInstance().show(mSiteSecurity, leftMargin);
}
});
@ -266,6 +268,49 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
mLayout.invalidate();
}
public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
switch(msg) {
case TITLE:
// if (sameDocument)
if (Tabs.getInstance().isSelectedTab(tab)) {
setTitle(tab.getDisplayTitle());
}
break;
case START:
if (Tabs.getInstance().isSelectedTab(tab)) {
setSecurityMode(tab.getSecurityMode());
setReaderVisibility(tab.getReaderEnabled());
updateBackButton(tab.canDoBack());
updateForwardButton(tab.canDoForward());
Boolean showProgress = (Boolean)data;
if (showProgress && tab.getState() == Tab.STATE_LOADING)
setProgressVisibility(true);
}
break;
case STOP:
if (Tabs.getInstance().isSelectedTab(tab)) {
updateBackButton(tab.canDoBack());
updateForwardButton(tab.canDoForward());
setProgressVisibility(false);
}
break;
case RESTORED:
case SELECTED:
case LOCATION_CHANGE:
case LOAD_ERROR:
if (Tabs.getInstance().isSelectedTab(tab)) {
refresh();
}
break;
case CLOSED:
case ADDED:
updateTabCountAndAnimate(Tabs.getInstance().getCount());
updateBackButton(false);
updateForwardButton(false);
break;
}
}
@Override
public View makeView() {
// This returns a TextView for the TextSwitcher.
@ -571,9 +616,6 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
selectedTab.addToReadingList();
}
Toast.makeText(GeckoApp.mAppContext,
R.string.reading_list_added, Toast.LENGTH_SHORT).show();
dismiss();
}
});

Просмотреть файл

@ -90,7 +90,7 @@ public class DoorHanger extends LinearLayout implements Button.OnClickListener {
// This will hide the doorhanger (and hide the popup if there are no
// more doorhangers to show)
GeckoApp.mDoorHangerPopup.updatePopup();
((GeckoApp)mContext).updatePopups(mTab);
}
public void show() {

Просмотреть файл

@ -10,8 +10,10 @@ import java.util.HashMap;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.View;
import android.widget.PopupWindow;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
@ -48,7 +50,7 @@ public class DoorHangerPopup extends PopupWindow {
}
public void addDoorHanger(String message, String value, JSONArray buttons,
Tab tab, JSONObject options) {
Tab tab, JSONObject options, View v) {
Log.i(LOGTAG, "Adding a DoorHanger to Tab: " + tab.getId());
if (!mInflated)
@ -81,11 +83,15 @@ public class DoorHangerPopup extends PopupWindow {
// Only update the popup if we're adding a notifcation to the selected tab
if (tab.equals(Tabs.getInstance().getSelectedTab()))
updatePopup();
updatePopup(v);
}
// Updates popup contents to show doorhangers for the selected tab
public void updatePopup() {
updatePopup(null);
}
public void updatePopup(View v) {
Tab tab = Tabs.getInstance().getSelectedTab();
if (tab == null) {
hidePopup();
@ -115,24 +121,25 @@ public class DoorHangerPopup extends PopupWindow {
dh.show();
}
showPopup();
if (v == null)
showAtLocation(((GeckoApp)mContext).getView(), Gravity.TOP, 0, 0);
else
showPopup(v);
}
public void hidePopup() {
if (isShowing()) {
Log.i(LOGTAG, "Hiding the DoorHangerPopup");
dismiss();
}
}
public void showPopup() {
Log.i(LOGTAG, "Showing the DoorHangerPopup");
public void showPopup(View v) {
fixBackgroundForFirst();
if (isShowing())
update();
else
showAsDropDown(GeckoApp.mBrowserToolbar.mFavicon);
showAsDropDown(v);
}
private void fixBackgroundForFirst() {

Просмотреть файл

@ -65,7 +65,9 @@ abstract public class GeckoApp
extends GeckoActivity
implements GeckoEventListener, SensorEventListener, LocationListener,
GeckoApplication.ApplicationLifecycleCallbacks,
TabsPanel.TabsLayoutChangeListener {
Tabs.OnTabsChangedListener,
TabsPanel.TabsLayoutChangeListener
{
private static final String LOGTAG = "GeckoApp";
public static enum StartupMode {
@ -87,10 +89,11 @@ abstract public class GeckoApp
StartupMode mStartupMode = null;
private LinearLayout mMainLayout;
private RelativeLayout mGeckoLayout;
public View getView() { return mGeckoLayout; }
public static SurfaceView cameraView;
public static GeckoApp mAppContext;
public static boolean mDOMFullScreen = false;
private MenuPanel mMenuPanel;
protected MenuPanel mMenuPanel;
public static Menu sMenu;
private static GeckoThread sGeckoThread = null;
public Handler mMainHandler;
@ -101,7 +104,6 @@ abstract public class GeckoApp
private GeckoConnectivityReceiver mConnectivityReceiver;
private GeckoBatteryManager mBatteryReceiver;
public static BrowserToolbar mBrowserToolbar;
public static DoorHangerPopup mDoorHangerPopup;
public static FormAssistPopup mFormAssistPopup;
public TabsPanel mTabsPanel;
@ -109,7 +111,6 @@ abstract public class GeckoApp
private static LayerController mLayerController;
private static GeckoLayerClient mLayerClient;
private AboutHomeContent mAboutHomeContent;
private static AbsoluteLayout mPluginContainer;
private static FindInPageBar mFindInPageBar;
@ -120,7 +121,7 @@ abstract public class GeckoApp
private HashMap<String, PowerManager.WakeLock> mWakeLocks = new HashMap<String, PowerManager.WakeLock>();
private int mRestoreMode = GeckoAppShell.RESTORE_NONE;
protected int mRestoreMode = GeckoAppShell.RESTORE_NONE;
private boolean mInitialized = false;
static Vector<MenuItem> sAddonMenuItems = new Vector<MenuItem>();
@ -158,6 +159,42 @@ abstract public class GeckoApp
}
}
void toggleChrome(final Boolean aShow) { }
void focusChrome() { }
public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) {
switch(msg) {
case LOCATION_CHANGE:
if (Tabs.getInstance().isSelectedTab(tab)) {
hidePlugins(tab);
updatePopups(tab);
invalidateOptionsMenu();
}
break;
case LOAD_ERROR:
case START:
case STOP:
if (Tabs.getInstance().isSelectedTab(tab)) {
invalidateOptionsMenu();
}
break;
case UNSELECTED:
case CLOSED:
invalidateOptionsMenu();
updatePopups(tab);
hidePlugins(tab);
break;
case ADDED:
case SELECTED:
invalidateOptionsMenu();
updatePopups(tab);
break;
}
}
public void refreshChrome() { }
public static final String PLUGIN_ACTION = "android.webkit.PLUGIN";
/**
@ -449,10 +486,6 @@ abstract public class GeckoApp
{
sMenu = menu;
// Inform the menu about the action-items bar.
if (menu instanceof GeckoMenu && isTablet())
((GeckoMenu) menu).setActionItemBarPresenter(mBrowserToolbar);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.gecko_menu, sMenu);
return true;
@ -512,22 +545,6 @@ abstract public class GeckoApp
return true;
}
@Override
public void openOptionsMenu() {
// Scroll custom menu to the top
if (mMenuPanel != null)
mMenuPanel.scrollTo(0, 0);
if (!mBrowserToolbar.openOptionsMenu())
super.openOptionsMenu();
}
@Override
public void closeOptionsMenu() {
if (!mBrowserToolbar.closeOptionsMenu())
super.closeOptionsMenu();
}
@Override
public MenuInflater getMenuInflater() {
if (Build.VERSION.SDK_INT >= 11)
@ -772,51 +789,12 @@ abstract public class GeckoApp
}
}
private void maybeCancelFaviconLoad(Tab tab) {
long faviconLoadId = tab.getFaviconLoadId();
if (faviconLoadId == Favicons.NOT_LOADING)
return;
// Cancel pending favicon load task
mFavicons.cancelFaviconLoad(faviconLoadId);
// Reset favicon load state
tab.setFaviconLoadId(Favicons.NOT_LOADING);
void updatePopups(final Tab tab) {
mDoorHangerPopup.updatePopup();
}
private void loadFavicon(final Tab tab) {
maybeCancelFaviconLoad(tab);
long id = mFavicons.loadFavicon(tab.getURL(), tab.getFaviconURL(),
new Favicons.OnFaviconLoadedListener() {
public void onFaviconLoaded(String pageUrl, Drawable favicon) {
// Leave favicon UI untouched if we failed to load the image
// for some reason.
if (favicon == null)
return;
Log.i(LOGTAG, "Favicon successfully loaded for URL = " + pageUrl);
// The tab might be pointing to another URL by the time the
// favicon is finally loaded, in which case we simply ignore it.
if (!tab.getURL().equals(pageUrl))
return;
Log.i(LOGTAG, "Favicon is for current URL = " + pageUrl);
tab.updateFavicon(favicon);
tab.setFaviconLoadId(Favicons.NOT_LOADING);
if (Tabs.getInstance().isSelectedTab(tab))
mBrowserToolbar.setFavicon(tab.getFavicon());
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.FAVICON);
}
});
tab.setFaviconLoadId(id);
void addDoorHanger(String message, String value, JSONArray buttons, Tab tab, JSONObject options) {
mDoorHangerPopup.addDoorHanger(message, value, buttons, tab, options, null);
}
void handleLocationChange(final int tabId, final String uri,
@ -826,27 +804,9 @@ abstract public class GeckoApp
if (tab == null)
return;
if (Tabs.getInstance().isSelectedTab(tab)) {
if (uri.equals("about:home"))
showAboutHome();
else
hideAboutHome();
}
tab.updateURL(uri);
tab.setDocumentURI(documentURI);
if (sameDocument) {
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab)) {
mBrowserToolbar.setTitle(uri);
}
}
});
return;
}
tab.setContentType(contentType);
tab.clearFavicon();
tab.updateIdentityData(null);
@ -859,18 +819,9 @@ abstract public class GeckoApp
tab.setHasTouchListeners(false);
tab.setCheckerboardColor(Color.WHITE);
maybeCancelFaviconLoad(tab);
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab)) {
mBrowserToolbar.refresh();
invalidateOptionsMenu();
mDoorHangerPopup.updatePopup();
if (tab != null)
hidePlugins(tab);
}
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.LOCATION_CHANGE);
}
});
}
@ -881,13 +832,6 @@ abstract public class GeckoApp
return;
tab.updateIdentityData(identityData);
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab))
mBrowserToolbar.setSecurityMode(tab.getSecurityMode());
}
});
}
void handleReaderEnabled(final int tabId) {
@ -896,58 +840,28 @@ abstract public class GeckoApp
return;
tab.setReaderEnabled(true);
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab))
mBrowserToolbar.setReaderVisibility(tab.getReaderEnabled());
}
});
}
void handleLoadError(final int tabId, final String uri, final String title) {
final Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null)
return;
// When a load error occurs, the URLBar can get corrupt so we reset it
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab)) {
mBrowserToolbar.refresh();
invalidateOptionsMenu();
}
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.LOAD_ERROR);
}
});
}
void handlePageShow(final int tabId) {
final Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null)
return;
mMainHandler.post(new Runnable() {
public void run() {
loadFavicon(tab);
}
});
void handlePageShow(final int tabId) { }
private String getDefaultProfileName() {
return "default";
}
void updateAboutHomeTopSites() {
if (mAboutHomeContent == null)
return;
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
public void run() {
mAboutHomeContent.update(GeckoApp.mAppContext,
EnumSet.of(AboutHomeContent.UpdateFlags.TOP_SITES));
}
});
}
void handleClearHistory() {
updateAboutHomeTopSites();
}
void handleClearHistory() { }
public StartupMode getStartupMode() {
// This function might touch the disk and should not
@ -962,7 +876,10 @@ abstract public class GeckoApp
// This key should be profile-dependent. For now, we're simply hardcoding
// the "default" profile here.
String keyName = packageName + ".default.startup_version";
String profileName = getDefaultProfileName();
if (profileName == null)
profileName = "default";
String keyName = packageName + "." + profileName + ".startup_version";
String appVersion = null;
try {
@ -994,34 +911,17 @@ abstract public class GeckoApp
}
}
void addTab() {
showAwesomebar(AwesomeBar.Target.NEW_TAB);
}
void addTab() { }
public void showLocalTabs() {
showTabs(TabsPanel.Panel.LOCAL_TABS);
}
public void showLocalTabs() { }
public void showRemoteTabs() {
showTabs(TabsPanel.Panel.REMOTE_TABS);
}
public void showRemoteTabs() { }
private void showTabs(TabsPanel.Panel panel) {
if (!sIsGeckoReady)
return;
private void showTabs(TabsPanel.Panel panel) { }
mTabsPanel.show(panel);
mBrowserToolbar.updateTabs(true);
}
public void hideTabs() { }
public void hideTabs() {
mTabsPanel.hide();
mBrowserToolbar.updateTabs(false);
}
public boolean areTabsShown() {
return mTabsPanel.isShown();
}
public boolean areTabsShown() { return false; }
@Override
public void onTabsLayoutChange(int width, int height) {
@ -1164,24 +1064,11 @@ abstract public class GeckoApp
GeckoAppShell.sendPendingEventsToGecko();
connectGeckoLayerClient();
} else if (event.equals("ToggleChrome:Hide")) {
mMainHandler.post(new Runnable() {
public void run() {
mBrowserToolbar.hide();
}
});
toggleChrome(false);
} else if (event.equals("ToggleChrome:Show")) {
mMainHandler.post(new Runnable() {
public void run() {
mBrowserToolbar.show();
}
});
toggleChrome(true);
} else if (event.equals("ToggleChrome:Focus")) {
mMainHandler.post(new Runnable() {
public void run() {
mBrowserToolbar.setVisibility(View.VISIBLE);
mBrowserToolbar.requestFocusFromTouch();
}
});
focusChrome();
} else if (event.equals("DOMFullScreen:Start")) {
mDOMFullScreen = true;
} else if (event.equals("DOMFullScreen:Stop")) {
@ -1262,12 +1149,7 @@ abstract public class GeckoApp
}
});
} else if (event.equals("Session:StatePurged")) {
mMainHandler.post(new Runnable() {
public void run() {
if (mAboutHomeContent != null)
mAboutHomeContent.setLastTabsVisibility(false);
}
});
onStatePurged();
} else if (event.equals("Bookmark:Insert")) {
final String url = message.getString("url");
final String title = message.getString("title");
@ -1336,47 +1218,7 @@ abstract public class GeckoApp
}
}
public void showAboutHome() {
Runnable r = new AboutHomeRunnable(true);
mMainHandler.postAtFrontOfQueue(r);
}
public void hideAboutHome() {
Runnable r = new AboutHomeRunnable(false);
mMainHandler.postAtFrontOfQueue(r);
}
public class AboutHomeRunnable implements Runnable {
boolean mShow;
AboutHomeRunnable(boolean show) {
mShow = show;
}
public void run() {
mFormAssistPopup.hide();
if (mShow) {
if (mAboutHomeContent == null) {
mAboutHomeContent = (AboutHomeContent) findViewById(R.id.abouthome_content);
mAboutHomeContent.init();
mAboutHomeContent.update(GeckoApp.mAppContext, AboutHomeContent.UpdateFlags.ALL);
mAboutHomeContent.setUriLoadCallback(new AboutHomeContent.UriLoadCallback() {
public void callback(String url) {
mBrowserToolbar.setProgressVisibility(true);
loadUrl(url, AwesomeBar.Target.CURRENT_TAB);
}
});
} else {
mAboutHomeContent.update(GeckoApp.mAppContext,
EnumSet.of(AboutHomeContent.UpdateFlags.TOP_SITES,
AboutHomeContent.UpdateFlags.REMOTE_TABS));
}
mAboutHomeContent.setVisibility(View.VISIBLE);
} else {
findViewById(R.id.abouthome_content).setVisibility(View.GONE);
}
}
}
void onStatePurged() { }
/**
* @param aPermissions
@ -1458,7 +1300,7 @@ abstract public class GeckoApp
public void run() {
Tab tab = Tabs.getInstance().getTab(tabId);
if (tab != null)
mDoorHangerPopup.addDoorHanger(message, value, buttons, tab, options);
addDoorHanger(message, value, buttons, tab, options);
}
});
}
@ -1475,7 +1317,7 @@ abstract public class GeckoApp
if (tab == null)
return;
tab.removeDoorHanger(value);
mDoorHangerPopup.updatePopup();
updatePopups(tab);
}
});
}
@ -1492,16 +1334,7 @@ abstract public class GeckoApp
getLayerController().getView().getRenderer().resetCheckerboard();
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab)) {
mBrowserToolbar.setSecurityMode(tab.getSecurityMode());
mBrowserToolbar.setReaderVisibility(tab.getReaderEnabled());
mBrowserToolbar.updateBackButton(tab.canDoBack());
mBrowserToolbar.updateForwardButton(tab.canDoForward());
invalidateOptionsMenu();
if (showProgress && tab.getState() == Tab.STATE_LOADING)
mBrowserToolbar.setProgressVisibility(true);
}
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.START);
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.START, showProgress);
}
});
}
@ -1515,12 +1348,6 @@ abstract public class GeckoApp
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab)) {
mBrowserToolbar.updateBackButton(tab.canDoBack());
mBrowserToolbar.updateForwardButton(tab.canDoForward());
invalidateOptionsMenu();
mBrowserToolbar.setProgressVisibility(false);
}
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.STOP);
}
});
@ -1570,14 +1397,6 @@ abstract public class GeckoApp
return;
tab.updateTitle(title);
mMainHandler.post(new Runnable() {
public void run() {
if (Tabs.getInstance().isSelectedTab(tab))
mBrowserToolbar.setTitle(tab.getDisplayTitle());
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.TITLE);
}
});
}
void handleLinkAdded(final int tabId, String rel, final String href, int size) {
@ -1589,18 +1408,6 @@ abstract public class GeckoApp
return;
tab.updateFaviconURL(href, size);
// If tab is not loading and the favicon is updated, we
// want to load the image straight away. If tab is still
// loading, we only load the favicon once the page's content
// is fully loaded (see handleContentLoaded()).
if (tab.getState() != Tab.STATE_LOADING) {
mMainHandler.post(new Runnable() {
public void run() {
loadFavicon(tab);
}
});
}
}
void handleWindowClose(final int tabId) {
@ -1853,16 +1660,6 @@ abstract public class GeckoApp
return false;
}
// The ActionBar needs to be refreshed on rotation as different orientation uses different resources
public void refreshActionBar() {
if (Build.VERSION.SDK_INT >= 11) {
mBrowserToolbar.requestLayout();
mBrowserToolbar.refresh();
invalidateOptionsMenu();
mTabsPanel.refresh();
}
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
@ -1901,32 +1698,27 @@ abstract public class GeckoApp
setContentView(R.layout.gecko_app);
LinearLayout actionBar = (LinearLayout) findViewById(R.id.browser_toolbar);
mBrowserToolbar = new BrowserToolbar(mAppContext);
mBrowserToolbar.from(actionBar);
// setup gecko layout
mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
mMainLayout = (LinearLayout) findViewById(R.id.main_layout);
// setup tabs panel
mTabsPanel = (TabsPanel) findViewById(R.id.tabs_panel);
mTabsPanel.setTabsLayoutChangeListener(this);
if (mTabsPanel != null)
mTabsPanel.setTabsLayoutChangeListener(this);
if (savedInstanceState != null) {
mBrowserToolbar.setTitle(savedInstanceState.getString(SAVED_STATE_TITLE));
mRestoreMode = GeckoAppShell.RESTORE_OOM;
}
((GeckoApplication) getApplication()).addApplicationLifecycleCallbacks(this);
}
void initializeChrome(String uri, Boolean isExternalURL) { }
private void initialize() {
mInitialized = true;
mBrowserToolbar.updateBackButton(false);
mBrowserToolbar.updateForwardButton(false);
invalidateOptionsMenu();
Intent intent = getIntent();
@ -1937,7 +1729,6 @@ abstract public class GeckoApp
Matcher m = p.matcher(args);
if (m.find()) {
mProfile = GeckoProfile.get(this, m.group(1));
mBrowserToolbar.setTitle(null);
}
}
@ -1950,24 +1741,13 @@ abstract public class GeckoApp
String uri = getURIFromIntent(intent);
if (uri != null && uri.length() > 0) {
passedUri = uri;
mBrowserToolbar.setTitle(uri);
}
if (mRestoreMode == GeckoAppShell.RESTORE_NONE && getProfile().shouldRestoreSession())
mRestoreMode = GeckoAppShell.RESTORE_CRASH;
boolean isExternalURL = passedUri != null && !passedUri.equals("about:home");
if (!isExternalURL) {
// show about:home if we aren't restoring previous session
if (mRestoreMode == GeckoAppShell.RESTORE_NONE) {
mBrowserToolbar.updateTabCount(1);
showAboutHome();
}
} else {
mBrowserToolbar.updateTabCount(1);
}
mBrowserToolbar.setProgressVisibility(isExternalURL || (mRestoreMode != GeckoAppShell.RESTORE_NONE));
initializeChrome(uri, isExternalURL);
// Start migrating as early as possible, can do this in
// parallel with Gecko load.
@ -2005,7 +1785,8 @@ abstract public class GeckoApp
mFavicons = new Favicons(this);
Tabs.getInstance().setContentResolver(getContentResolver());
Tabs.getInstance().setContentResolver(getContentResolver());
Tabs.getInstance().registerOnTabsChangedListener(this);
if (cameraView == null) {
cameraView = new SurfaceView(this);
@ -2326,7 +2107,7 @@ abstract public class GeckoApp
if (mOrientation != newOrientation) {
mOrientation = newOrientation;
refreshActionBar();
refreshChrome();
}
}
@ -2428,17 +2209,12 @@ abstract public class GeckoApp
if (mBatteryReceiver != null)
mBatteryReceiver.unregisterFor(mAppContext);
if (mAboutHomeContent != null)
mAboutHomeContent.onDestroy();
((GeckoApplication) getApplication()).removeApplicationLifecycleCallbacks(this);
}
@Override
public void onContentChanged() {
super.onContentChanged();
if (mAboutHomeContent != null)
mAboutHomeContent.onActivityContentChanged(this);
}
@ -2454,7 +2230,7 @@ abstract public class GeckoApp
if (mFormAssistPopup != null)
mFormAssistPopup.hide();
SiteIdentityPopup.getInstance().dismiss();
refreshActionBar();
refreshChrome();
}
}
@ -2658,14 +2434,16 @@ abstract public class GeckoApp
long timeDiff = SystemClock.uptimeMillis() - currentTime;
Log.i(LOGTAG, "Profile migration took " + timeDiff + " ms");
// Update about:home with the new information.
updateAboutHomeTopSites();
finishProfileMigration();
}
}}
);
}
}
protected void finishProfileMigration() {
}
private void checkMigrateSync() {
final File profileDir = getProfile().getDir();
if (profileDir != null) {
@ -2907,7 +2685,7 @@ abstract public class GeckoApp
@Override
public void onBackPressed() {
if (mTabsPanel.isShown()) {
if (mTabsPanel != null && mTabsPanel.isShown()) {
mTabsPanel.hide();
return;
}
@ -3110,8 +2888,7 @@ abstract public class GeckoApp
// If searchEngine is provided, url will be used as the search query.
// Otherwise, the url is loaded.
private void loadRequest(String url, AwesomeBar.Target target, String searchEngine, boolean userEntered) {
mBrowserToolbar.setTitle(url);
protected void loadRequest(String url, AwesomeBar.Target target, String searchEngine, boolean userEntered) {
Log.d(LOGTAG, target.name());
JSONObject args = new JSONObject();
try {

Просмотреть файл

@ -26,6 +26,7 @@ FENNEC_JAVA_FILES = \
AlertNotification.java \
AwesomeBar.java \
AwesomeBarTabs.java \
BrowserApp.java \
BrowserToolbar.java \
ConfirmPreference.java \
SyncPreference.java \
@ -602,6 +603,7 @@ RES_DRAWABLE_LAND_MDPI_V14 = \
res/drawable-land-mdpi-v14/tabs_normal.png \
res/drawable-land-mdpi-v14/tabs_pressed.png \
res/drawable-land-mdpi-v14/urlbar_stop.png \
res/drawable-land-mdpi-v14/reader.png \
res/drawable-land-mdpi-v14/site_security_identified.png \
res/drawable-land-mdpi-v14/site_security_verified.png \
$(NULL)
@ -616,6 +618,7 @@ RES_DRAWABLE_LAND_HDPI_V14 = \
res/drawable-land-hdpi-v14/tabs_normal.png \
res/drawable-land-hdpi-v14/tabs_pressed.png \
res/drawable-land-hdpi-v14/urlbar_stop.png \
res/drawable-land-hdpi-v14/reader.png \
res/drawable-land-hdpi-v14/site_security_identified.png \
res/drawable-land-hdpi-v14/site_security_verified.png \
$(NULL)
@ -630,6 +633,7 @@ RES_DRAWABLE_LAND_XHDPI_V14 = \
res/drawable-land-xhdpi-v14/tabs_normal.png \
res/drawable-land-xhdpi-v14/tabs_pressed.png \
res/drawable-land-xhdpi-v14/urlbar_stop.png \
res/drawable-land-xhdpi-v14/reader.png \
res/drawable-land-xhdpi-v14/site_security_identified.png \
res/drawable-land-xhdpi-v14/site_security_verified.png \
$(NULL)
@ -642,6 +646,8 @@ RES_DRAWABLE_XLARGE_MDPI = \
res/drawable-xlarge-mdpi/address_bar_url_default.9.png \
res/drawable-xlarge-mdpi/address_bar_url_pressed.9.png \
res/drawable-xlarge-mdpi/menu.png \
res/drawable-xlarge-mdpi/ic_awesomebar_go.png \
res/drawable-xlarge-mdpi/ic_awesomebar_search.png \
res/drawable-xlarge-mdpi/ic_menu_bookmark_add.png \
res/drawable-xlarge-mdpi/ic_menu_bookmark_remove.png \
res/drawable-xlarge-mdpi/ic_menu_reload.png \
@ -650,6 +656,9 @@ RES_DRAWABLE_XLARGE_MDPI = \
res/drawable-xlarge-mdpi/tabs_normal.png \
res/drawable-xlarge-mdpi/tabs_pressed.png \
res/drawable-xlarge-mdpi/urlbar_stop.png \
res/drawable-xlarge-mdpi/reader.png \
res/drawable-xlarge-mdpi/site_security_identified.png \
res/drawable-xlarge-mdpi/site_security_verified.png \
$(NULL)
RES_DRAWABLE_XLARGE_HDPI = \
@ -659,6 +668,8 @@ RES_DRAWABLE_XLARGE_HDPI = \
res/drawable-xlarge-hdpi/address_bar_url_default.9.png \
res/drawable-xlarge-hdpi/address_bar_url_pressed.9.png \
res/drawable-xlarge-hdpi/menu.png \
res/drawable-xlarge-hdpi/ic_awesomebar_go.png \
res/drawable-xlarge-hdpi/ic_awesomebar_search.png \
res/drawable-xlarge-hdpi/ic_menu_bookmark_add.png \
res/drawable-xlarge-hdpi/ic_menu_bookmark_remove.png \
res/drawable-xlarge-hdpi/ic_menu_reload.png \
@ -667,6 +678,9 @@ RES_DRAWABLE_XLARGE_HDPI = \
res/drawable-xlarge-hdpi/tabs_normal.png \
res/drawable-xlarge-hdpi/tabs_pressed.png \
res/drawable-xlarge-hdpi/urlbar_stop.png \
res/drawable-xlarge-hdpi/reader.png \
res/drawable-xlarge-hdpi/site_security_identified.png \
res/drawable-xlarge-hdpi/site_security_verified.png \
$(NULL)
RES_DRAWABLE_XLARGE_XHDPI = \
@ -676,6 +690,8 @@ RES_DRAWABLE_XLARGE_XHDPI = \
res/drawable-xlarge-xhdpi/address_bar_url_default.9.png \
res/drawable-xlarge-xhdpi/address_bar_url_pressed.9.png \
res/drawable-xlarge-xhdpi/menu.png \
res/drawable-xlarge-xhdpi/ic_awesomebar_go.png \
res/drawable-xlarge-xhdpi/ic_awesomebar_search.png \
res/drawable-xlarge-xhdpi/ic_menu_bookmark_add.png \
res/drawable-xlarge-xhdpi/ic_menu_bookmark_remove.png \
res/drawable-xlarge-xhdpi/ic_menu_reload.png \
@ -684,6 +700,9 @@ RES_DRAWABLE_XLARGE_XHDPI = \
res/drawable-xlarge-xhdpi/tabs_normal.png \
res/drawable-xlarge-xhdpi/tabs_pressed.png \
res/drawable-xlarge-xhdpi/urlbar_stop.png \
res/drawable-xlarge-xhdpi/reader.png \
res/drawable-xlarge-xhdpi/site_security_identified.png \
res/drawable-xlarge-xhdpi/site_security_verified.png \
$(NULL)
RES_DRAWABLE_SW600DP_MDPI = \
@ -694,6 +713,8 @@ RES_DRAWABLE_SW600DP_MDPI = \
res/drawable-sw600dp-mdpi/address_bar_url_default.9.png \
res/drawable-sw600dp-mdpi/address_bar_url_pressed.9.png \
res/drawable-sw600dp-mdpi/menu.png \
res/drawable-sw600dp-mdpi/ic_awesomebar_go.png \
res/drawable-sw600dp-mdpi/ic_awesomebar_search.png \
res/drawable-sw600dp-mdpi/ic_menu_bookmark_add.png \
res/drawable-sw600dp-mdpi/ic_menu_bookmark_remove.png \
res/drawable-sw600dp-mdpi/ic_menu_reload.png \
@ -702,6 +723,9 @@ RES_DRAWABLE_SW600DP_MDPI = \
res/drawable-sw600dp-mdpi/tabs_normal.png \
res/drawable-sw600dp-mdpi/tabs_pressed.png \
res/drawable-sw600dp-mdpi/urlbar_stop.png \
res/drawable-sw600dp-mdpi/reader.png \
res/drawable-sw600dp-mdpi/site_security_identified.png \
res/drawable-sw600dp-mdpi/site_security_verified.png \
$(NULL)
RES_DRAWABLE_SW600DP_HDPI = \
@ -711,6 +735,8 @@ RES_DRAWABLE_SW600DP_HDPI = \
res/drawable-sw600dp-hdpi/address_bar_url_default.9.png \
res/drawable-sw600dp-hdpi/address_bar_url_pressed.9.png \
res/drawable-sw600dp-hdpi/menu.png \
res/drawable-sw600dp-hdpi/ic_awesomebar_go.png \
res/drawable-sw600dp-hdpi/ic_awesomebar_search.png \
res/drawable-sw600dp-hdpi/ic_menu_bookmark_add.png \
res/drawable-sw600dp-hdpi/ic_menu_bookmark_remove.png \
res/drawable-sw600dp-hdpi/ic_menu_reload.png \
@ -719,6 +745,9 @@ RES_DRAWABLE_SW600DP_HDPI = \
res/drawable-sw600dp-hdpi/tabs_normal.png \
res/drawable-sw600dp-hdpi/tabs_pressed.png \
res/drawable-sw600dp-hdpi/urlbar_stop.png \
res/drawable-sw600dp-hdpi/reader.png \
res/drawable-sw600dp-hdpi/site_security_identified.png \
res/drawable-sw600dp-hdpi/site_security_verified.png \
$(NULL)
RES_DRAWABLE_SW600DP_XHDPI = \
@ -728,6 +757,8 @@ RES_DRAWABLE_SW600DP_XHDPI = \
res/drawable-sw600dp-xhdpi/address_bar_url_default.9.png \
res/drawable-sw600dp-xhdpi/address_bar_url_pressed.9.png \
res/drawable-sw600dp-xhdpi/menu.png \
res/drawable-sw600dp-xhdpi/ic_awesomebar_go.png \
res/drawable-sw600dp-xhdpi/ic_awesomebar_search.png \
res/drawable-sw600dp-xhdpi/ic_menu_bookmark_add.png \
res/drawable-sw600dp-xhdpi/ic_menu_bookmark_remove.png \
res/drawable-sw600dp-xhdpi/ic_menu_reload.png \
@ -736,6 +767,9 @@ RES_DRAWABLE_SW600DP_XHDPI = \
res/drawable-sw600dp-xhdpi/tabs_normal.png \
res/drawable-sw600dp-xhdpi/tabs_pressed.png \
res/drawable-sw600dp-xhdpi/urlbar_stop.png \
res/drawable-sw600dp-xhdpi/reader.png \
res/drawable-sw600dp-xhdpi/site_security_identified.png \
res/drawable-sw600dp-xhdpi/site_security_verified.png \
$(NULL)
RES_COLOR = \

Просмотреть файл

@ -79,7 +79,7 @@ public class SiteIdentityPopup extends PopupWindow {
mInflated = true;
}
public void show(int leftMargin) {
public void show(View v, int leftMargin) {
Tab selectedTab = Tabs.getInstance().getSelectedTab();
if (selectedTab == null) {
Log.e(LOGTAG, "Selected tab is null");
@ -154,6 +154,6 @@ public class SiteIdentityPopup extends PopupWindow {
mArrow.setLayoutParams(newLayoutParams);
// This will place the popup at the correct vertical position
showAsDropDown(GeckoApp.mBrowserToolbar.mSiteSecurity);
showAsDropDown(v);
}
}

Просмотреть файл

@ -243,6 +243,13 @@ public final class Tab {
Log.i(LOGTAG, "Updated title: " + mTitle + " for tab with id: " + mId);
updateHistory(mUrl, mTitle);
final Tab tab = this;
GeckoAppShell.getMainHandler().post(new Runnable() {
public void run() {
Tabs.getInstance().notifyListeners(tab, Tabs.TabEvents.TITLE);
}
});
}
private void updateHistory(final String uri, final String title) {
@ -386,15 +393,8 @@ public final class Tab {
if (!mReaderEnabled)
return;
GeckoAppShell.getHandler().post(new Runnable() {
public void run() {
String url = getURL();
if (url == null)
return;
BrowserDB.addReadingListItem(mContentResolver, getTitle(), url);
}
});
GeckoEvent e = GeckoEvent.createBroadcastEvent("Reader:Add", String.valueOf(getId()));
GeckoAppShell.sendEventToGecko(e);
}
public void readerMode() {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше