mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge last PGO green inbound changeset to m-c
This commit is contained in:
commit
11389729fe
@ -551,8 +551,6 @@ nsHTMLComboboxAccessible::Shutdown()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
PRUint64
|
||||
nsHTMLComboboxAccessible::NativeState()
|
||||
{
|
||||
@ -561,8 +559,7 @@ nsHTMLComboboxAccessible::NativeState()
|
||||
// Get focus status from base class
|
||||
PRUint64 state = nsAccessible::NativeState();
|
||||
|
||||
nsIFrame *frame = GetBoundsFrame();
|
||||
nsIComboboxControlFrame *comboFrame = do_QueryFrame(frame);
|
||||
nsIComboboxControlFrame* comboFrame = do_QueryFrame(GetFrame());
|
||||
if (comboFrame && comboFrame->IsDroppedDown())
|
||||
state |= states::EXPANDED;
|
||||
else
|
||||
@ -750,8 +747,7 @@ nsHTMLComboboxListAccessible::NativeState()
|
||||
// Get focus status from base class
|
||||
PRUint64 state = nsAccessible::NativeState();
|
||||
|
||||
nsIFrame *boundsFrame = GetBoundsFrame();
|
||||
nsIComboboxControlFrame* comboFrame = do_QueryFrame(boundsFrame);
|
||||
nsIComboboxControlFrame* comboFrame = do_QueryFrame(mParent->GetFrame());
|
||||
if (comboFrame && comboFrame->IsDroppedDown())
|
||||
state |= states::FLOATING;
|
||||
else
|
||||
|
@ -53,9 +53,8 @@ var AccessFu = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Start the special AccessFu mode, this primarily means controlling the virtual
|
||||
* cursor with arrow keys. Currently, on platforms other than Android this needs
|
||||
* to be called explicitly.
|
||||
* Start AccessFu mode, this primarily means controlling the virtual cursor
|
||||
* with arrow keys.
|
||||
*/
|
||||
enable: function enable() {
|
||||
dump('AccessFu enable');
|
||||
@ -72,8 +71,6 @@ var AccessFu = {
|
||||
this.chromeWin.addEventListener('resize', this, true);
|
||||
this.chromeWin.addEventListener('scroll', this, true);
|
||||
this.chromeWin.addEventListener('TabOpen', this, true);
|
||||
this.chromeWin.addEventListener('TabSelect', this, true);
|
||||
this.chromeWin.addEventListener('TabClosed', this, true);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -87,13 +84,11 @@ var AccessFu = {
|
||||
|
||||
VirtualCursorController.detach();
|
||||
|
||||
Services.obs.addObserver(this, 'accessible-event', false);
|
||||
this.chromeWin.removeEventListener('DOMActivate', this);
|
||||
this.chromeWin.removeEventListener('resize', this);
|
||||
this.chromeWin.removeEventListener('scroll', this);
|
||||
this.chromeWin.removeEventListener('TabOpen', this);
|
||||
this.chromeWin.removeEventListener('TabSelect', this);
|
||||
this.chromeWin.removeEventListener('TabClose', this);
|
||||
Services.obs.removeObserver(this, 'accessible-event');
|
||||
this.chromeWin.removeEventListener('DOMActivate', this, true);
|
||||
this.chromeWin.removeEventListener('resize', this, true);
|
||||
this.chromeWin.removeEventListener('scroll', this, true);
|
||||
this.chromeWin.removeEventListener('TabOpen', this, true);
|
||||
},
|
||||
|
||||
amINeeded: function(aPref) {
|
||||
@ -125,12 +120,15 @@ var AccessFu = {
|
||||
|
||||
handleEvent: function handleEvent(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case 'TabSelect':
|
||||
case 'TabOpen':
|
||||
{
|
||||
this.getDocAccessible(
|
||||
function(docAcc) {
|
||||
this.presenters.forEach(function(p) {p.tabSelected(docAcc);});
|
||||
});
|
||||
let browser = aEvent.target.linkedBrowser || aEvent.target;
|
||||
// Store the new browser node. We will need to check later when a new
|
||||
// content document is attached if it has been attached to this new tab.
|
||||
// If it has, than we will need to send a 'loading' message along with
|
||||
// the usual 'newdoc' to presenters.
|
||||
this._pendingDocuments[browser] = true;
|
||||
this.presenters.forEach(function(p) { p.tabStateChanged(null, 'newtab'); });
|
||||
break;
|
||||
}
|
||||
case 'DOMActivate':
|
||||
@ -159,19 +157,6 @@ var AccessFu = {
|
||||
}
|
||||
},
|
||||
|
||||
getDocAccessible: function getDocAccessible(aCallback) {
|
||||
let browserApp = (Services.appinfo.OS == 'Android') ?
|
||||
this.chromeWin.BrowserApp : this.chromeWin.gBrowser;
|
||||
|
||||
let docAcc = getAccessible(browserApp.selectedBrowser.contentDocument);
|
||||
if (!docAcc) {
|
||||
// Wait for a reorder event fired by the parent of the new doc.
|
||||
this._pendingDocuments[browserApp.selectedBrowser] = aCallback;
|
||||
} else {
|
||||
aCallback.apply(this, [docAcc]);
|
||||
}
|
||||
},
|
||||
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case 'nsPref:changed':
|
||||
@ -223,16 +208,86 @@ var AccessFu = {
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (event.state == Ci.nsIAccessibleStates.STATE_BUSY &&
|
||||
!(event.isExtraState()) && event.isEnabled()) {
|
||||
let role = event.accessible.role;
|
||||
if ((role == Ci.nsIAccessibleRole.ROLE_DOCUMENT ||
|
||||
role == Ci.nsIAccessibleRole.ROLE_APPLICATION)) {
|
||||
// An existing document has changed to state "busy", this means
|
||||
// something is loading. Send a 'loading' message to presenters.
|
||||
this.presenters.forEach(
|
||||
function(p) {
|
||||
p.tabStateChanged(event.accessible, 'loading');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Ci.nsIAccessibleEvent.EVENT_REORDER:
|
||||
{
|
||||
let node = aEvent.accessible.DOMNode;
|
||||
let callback = this._pendingDocuments[node];
|
||||
if (callback && aEvent.accessible.childCount) {
|
||||
// We have a callback associated with a document.
|
||||
callback.apply(this, [aEvent.accessible.getChildAt(0)]);
|
||||
delete this._pendingDocuments[node];
|
||||
let acc = aEvent.accessible;
|
||||
if (acc.childCount) {
|
||||
let docAcc = acc.getChildAt(0);
|
||||
if (this._pendingDocuments[aEvent.DOMNode]) {
|
||||
// This is a document in a new tab. Check if it is
|
||||
// in a BUSY state (i.e. loading), and inform presenters.
|
||||
// We need to do this because a state change event will not be
|
||||
// fired when an object is created with the BUSY state.
|
||||
// If this is not a new tab, don't bother because we sent 'loading'
|
||||
// when the previous doc changed its state to BUSY.
|
||||
let state = {};
|
||||
docAcc.getState(state, {});
|
||||
if (state.value & Ci.nsIAccessibleStates.STATE_BUSY &&
|
||||
this.isNotChromeDoc(docAcc))
|
||||
this.presenters.forEach(
|
||||
function(p) { p.tabStateChanged(docAcc, 'loading'); }
|
||||
);
|
||||
delete this._pendingDocuments[aEvent.DOMNode];
|
||||
}
|
||||
if (this.isBrowserDoc(docAcc))
|
||||
// A new top-level content document has been attached
|
||||
this.presenters.forEach(
|
||||
function(p) { p.tabStateChanged(docAcc, 'newdoc'); }
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE:
|
||||
{
|
||||
if (this.isNotChromeDoc(aEvent.accessible)) {
|
||||
this.presenters.forEach(
|
||||
function(p) {
|
||||
p.tabStateChanged(aEvent.accessible, 'loaded');
|
||||
}
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_STOPPED:
|
||||
{
|
||||
this.presenters.forEach(
|
||||
function(p) {
|
||||
p.tabStateChanged(aEvent.accessible, 'loadstopped');
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
case Ci.nsIAccessibleEvent.EVENT_DOCUMENT_RELOAD:
|
||||
{
|
||||
this.presenters.forEach(
|
||||
function(p) {
|
||||
p.tabStateChanged(aEvent.accessible, 'reload');
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
case Ci.nsIAccessibleEvent.EVENT_FOCUS:
|
||||
{
|
||||
if (this.isBrowserDoc(aEvent.accessible)) {
|
||||
// The document recieved focus, call tabSelected to present current tab.
|
||||
this.presenters.forEach(
|
||||
function(p) { p.tabSelected(aEvent.accessible); });
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -269,6 +324,38 @@ var AccessFu = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if accessible is a top-level content document (i.e. a child of a XUL
|
||||
* browser node).
|
||||
* @param {nsIAccessible} aDocAcc the accessible to check.
|
||||
* @return {boolean} true if this is a top-level content document.
|
||||
*/
|
||||
isBrowserDoc: function isBrowserDoc(aDocAcc) {
|
||||
let parent = aDocAcc.parent;
|
||||
if (!parent)
|
||||
return false;
|
||||
|
||||
let domNode = parent.DOMNode;
|
||||
if (!domNode)
|
||||
return false;
|
||||
|
||||
const ns = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
|
||||
return (domNode.localName == 'browser' && domNode.namespaceURI == ns);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if document is not a local "chrome" document, like about:home.
|
||||
* @param {nsIDOMDocument} aDocument the document to check.
|
||||
* @return {boolean} true if this is not a chrome document.
|
||||
*/
|
||||
isNotChromeDoc: function isNotChromeDoc(aDocument) {
|
||||
let location = aDocument.DOMNode.location;
|
||||
if (!location)
|
||||
return false;
|
||||
|
||||
return location.protocol != "about:";
|
||||
},
|
||||
|
||||
getNewContext: function getNewContext(aOldObject, aNewObject) {
|
||||
let newLineage = [];
|
||||
let oldLineage = [];
|
||||
|
@ -66,15 +66,21 @@ Presenter.prototype = {
|
||||
selectionChanged: function selectionChanged(aObject) {},
|
||||
|
||||
/**
|
||||
* The page state has changed, loading, stopped loading, etc. TODO.
|
||||
* The tab, or the tab's document state has changed.
|
||||
* @param {nsIAccessible} aDocObj the tab document accessible that has had its
|
||||
* state changed, or null if the tab has no associated document yet.
|
||||
* @param {string} aPageState the state name for the tab, valid states are:
|
||||
* 'newtab', 'loading', 'newdoc', 'loaded', 'stopped', and 'reload'.
|
||||
*/
|
||||
pageStateChanged: function pageStateChanged() {},
|
||||
tabStateChanged: function tabStateChanged(aDocObj, aPageState) {},
|
||||
|
||||
/**
|
||||
* The tab has changed.
|
||||
* @param {nsIAccessible} aObject the document contained in the tab.
|
||||
* The current tab has changed.
|
||||
* @param {nsIAccessible} aObject the document contained by the tab
|
||||
* accessible, or null if it is a new tab with no attached
|
||||
* document yet.
|
||||
*/
|
||||
tabSelected: function tabSelected(aObject) {},
|
||||
tabSelected: function tabSelected(aDocObj) {},
|
||||
|
||||
/**
|
||||
* The viewport has changed, either a scroll, pan, zoom, or
|
||||
@ -147,9 +153,17 @@ VisualPresenter.prototype.pivotChanged = function(aObject, aNewContext) {
|
||||
}
|
||||
};
|
||||
|
||||
VisualPresenter.prototype.tabSelected = function(aObject) {
|
||||
let vcDoc = aObject.QueryInterface(Ci.nsIAccessibleCursorable);
|
||||
this.pivotChanged(vcDoc.virtualCursor.position);
|
||||
VisualPresenter.prototype.tabSelected = function(aDocObj) {
|
||||
let vcPos = aDocObj ?
|
||||
aDocObj.QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor.position :
|
||||
null;
|
||||
|
||||
this.pivotChanged(vcPos);
|
||||
};
|
||||
|
||||
VisualPresenter.prototype.tabStateChanged = function(aDocObj, aPageState) {
|
||||
if (aPageState == "newdoc")
|
||||
this.pivotChanged(null);
|
||||
};
|
||||
|
||||
// Internals
|
||||
@ -242,16 +256,40 @@ AndroidPresenter.prototype.actionInvoked = function(aObject, aActionName) {
|
||||
});
|
||||
};
|
||||
|
||||
AndroidPresenter.prototype.tabSelected = function(aObject) {
|
||||
let vcDoc = aObject.QueryInterface(Ci.nsIAccessibleCursorable);
|
||||
AndroidPresenter.prototype.tabSelected = function(aDocObj) {
|
||||
// Send a pivot change message with the full context utterance for this doc.
|
||||
let vcDoc = aDocObj.QueryInterface(Ci.nsIAccessibleCursorable);
|
||||
let context = [];
|
||||
|
||||
let parent = vcDoc.virtualCursor.position || aObject;
|
||||
while ((parent = parent.parent))
|
||||
let parent = vcDoc.virtualCursor.position || aDocObj;
|
||||
while ((parent = parent.parent)) {
|
||||
context.push(parent);
|
||||
if (parent == aDocObj)
|
||||
break;
|
||||
}
|
||||
|
||||
context.reverse();
|
||||
|
||||
this.pivotChanged(vcDoc.virtualCursor.position || aObject, context);
|
||||
this.pivotChanged(vcDoc.virtualCursor.position || aDocObj, context);
|
||||
};
|
||||
|
||||
AndroidPresenter.prototype.tabStateChanged = function(aDocObj, aPageState) {
|
||||
let stateUtterance = UtteranceGenerator.
|
||||
genForTabStateChange(aDocObj, aPageState);
|
||||
|
||||
if (!stateUtterance.length)
|
||||
return;
|
||||
|
||||
this.sendMessageToJava({
|
||||
gecko: {
|
||||
type: 'Accessibility:Event',
|
||||
eventType: ANDROID_TYPE_VIEW_TEXT_CHANGED,
|
||||
text: stateUtterance,
|
||||
addedCount: stateUtterance.join(' ').length,
|
||||
removedCount: 0,
|
||||
fromIndex: 0
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
AndroidPresenter.prototype.textChanged = function(aIsInserted, aStart, aLength, aText, aModifiedText) {
|
||||
|
@ -22,6 +22,22 @@ var gAccRetrieval = Cc['@mozilla.org/accessibleRetrieval;1'].
|
||||
|
||||
var EXPORTED_SYMBOLS = ['UtteranceGenerator'];
|
||||
|
||||
/**
|
||||
* Generates speech utterances from objects, actions and state changes.
|
||||
* An utterance is an array of strings.
|
||||
*
|
||||
* It should not be assumed that flattening an utterance array would create a
|
||||
* gramatically correct sentence. For example, {@link genForObject} might
|
||||
* return: ['graphic', 'Welcome to my home page'].
|
||||
* Each string element in an utterance should be gramatically correct in itself.
|
||||
* Another example from {@link genForObject}: ['list item 2 of 5', 'Alabama'].
|
||||
*
|
||||
* An utterance is ordered from the least to the most important. Speaking the
|
||||
* last string usually makes sense, but speaking the first often won't.
|
||||
* For example {@link genForAction} might return ['button', 'clicked'] for a
|
||||
* clicked event. Speaking only 'clicked' makes sense. Speaking 'button' does
|
||||
* not.
|
||||
*/
|
||||
var UtteranceGenerator = {
|
||||
gActionMap: {
|
||||
jump: 'jumpAction',
|
||||
@ -39,6 +55,19 @@ var UtteranceGenerator = {
|
||||
cycle: 'cycleAction'
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Generates an utterance for an object.
|
||||
* @param {nsIAccessible} aAccessible accessible object to generate utterance
|
||||
* for.
|
||||
* @param {boolean} aForceName include the object's name in the utterance
|
||||
* even if this object type does not usually have it's name uttered.
|
||||
* @return {Array} Two string array. The first string describes the object
|
||||
* and its states. The second string is the object's name. Some object
|
||||
* types may have the description or name omitted, instead an empty string
|
||||
* is returned as a placeholder. Whether the object's description or it's role
|
||||
* is included is determined by {@link verbosityRoleMap}.
|
||||
*/
|
||||
genForObject: function(aAccessible, aForceName) {
|
||||
let roleString = gAccRetrieval.getStringRole(aAccessible.role);
|
||||
|
||||
@ -53,10 +82,45 @@ var UtteranceGenerator = {
|
||||
return func.apply(this, [aAccessible, roleString, flags]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates an utterance for an action performed.
|
||||
* TODO: May become more verbose in the future.
|
||||
* @param {nsIAccessible} aAccessible accessible object that the action was
|
||||
* invoked in.
|
||||
* @param {string} aActionName the name of the action, one of the keys in
|
||||
* {@link gActionMap}.
|
||||
* @return {Array} A one string array with the action.
|
||||
*/
|
||||
genForAction: function(aObject, aActionName) {
|
||||
return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])];
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates an utterance for a tab state change.
|
||||
* @param {nsIAccessible} aAccessible accessible object of the tab's attached
|
||||
* document.
|
||||
* @param {string} aTabState the tab state name, see
|
||||
* {@link Presenter.tabStateChanged}.
|
||||
* @return {Array} The tab state utterace.
|
||||
*/
|
||||
genForTabStateChange: function (aObject, aTabState) {
|
||||
switch (aTabState) {
|
||||
case 'newtab':
|
||||
return [gStringBundle.GetStringFromName('tabNew')];
|
||||
case 'loading':
|
||||
return [gStringBundle.GetStringFromName('tabLoading')];
|
||||
case 'loaded':
|
||||
return [aObject.name || '',
|
||||
gStringBundle.GetStringFromName('tabLoaded')];
|
||||
case 'loadstopped':
|
||||
return [gStringBundle.GetStringFromName('tabLoadStopped')];
|
||||
case 'reload':
|
||||
return [gStringBundle.GetStringFromName('tabReload')];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
verbosityRoleMap: {
|
||||
'menubar': INCLUDE_ROLE,
|
||||
'scrollbar': INCLUDE_ROLE,
|
||||
@ -115,9 +179,9 @@ var UtteranceGenerator = {
|
||||
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
||||
let desc = (aFlags & INCLUDE_ROLE) ? this._getLocalizedRole(aRoleStr) : '';
|
||||
|
||||
if (!name && !desc)
|
||||
return [];
|
||||
let utterance = [];
|
||||
|
||||
if (desc) {
|
||||
let state = {};
|
||||
let extState = {};
|
||||
aAccessible.getState(state, extState);
|
||||
@ -134,16 +198,26 @@ var UtteranceGenerator = {
|
||||
desc = gStringBundle.formatStringFromName(stateStr, [desc], 1);
|
||||
}
|
||||
|
||||
return [desc, name];
|
||||
utterance.push(desc);
|
||||
}
|
||||
|
||||
if (name)
|
||||
utterance.push(name);
|
||||
|
||||
return utterance;
|
||||
},
|
||||
|
||||
heading: function(aAccessible, aRoleStr, aFlags) {
|
||||
let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
|
||||
let level = {};
|
||||
aAccessible.groupPosition(level, {}, {});
|
||||
let desc = gStringBundle.formatStringFromName('headingLevel',
|
||||
[level.value], 1);
|
||||
return [desc, name];
|
||||
let utterance =
|
||||
[gStringBundle.formatStringFromName('headingLevel', [level.value], 1)];
|
||||
|
||||
if (name)
|
||||
utterance.push(name);
|
||||
|
||||
return utterance;
|
||||
},
|
||||
|
||||
listitem: function(aAccessible, aRoleStr, aFlags) {
|
||||
@ -152,10 +226,14 @@ var UtteranceGenerator = {
|
||||
let itemno = {};
|
||||
let itemof = {};
|
||||
aAccessible.groupPosition({}, itemof, itemno);
|
||||
let desc = gStringBundle.formatStringFromName(
|
||||
'objItemOf', [localizedRole, itemno.value, itemof.value], 3);
|
||||
let utterance =
|
||||
[gStringBundle.formatStringFromName(
|
||||
'objItemOf', [localizedRole, itemno.value, itemof.value], 3)];
|
||||
|
||||
return [desc, name];
|
||||
if (name)
|
||||
utterance.push(name);
|
||||
|
||||
return utterance;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -24,7 +24,7 @@ var VirtualCursorController = {
|
||||
},
|
||||
|
||||
detach: function detach() {
|
||||
this.chromeWin.document.removeEventListener('keypress', this.onkeypress);
|
||||
this.chromeWin.document.removeEventListener('keypress', this.onkeypress, true);
|
||||
},
|
||||
|
||||
getBrowserApp: function getBrowserApp() {
|
||||
@ -114,38 +114,67 @@ var VirtualCursorController = {
|
||||
|
||||
SimpleTraversalRule: {
|
||||
getMatchRoles: function(aRules) {
|
||||
aRules.value = [];
|
||||
return 0;
|
||||
aRules.value = this._matchRoles;
|
||||
return this._matchRoles.length;
|
||||
},
|
||||
|
||||
preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
|
||||
Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
|
||||
|
||||
match: function(aAccessible) {
|
||||
if (aAccessible.childCount)
|
||||
// Non-leafs do not interest us.
|
||||
return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
|
||||
|
||||
// XXX: Find a better solution for ROLE_STATICTEXT.
|
||||
// It allows to filter list bullets but the same time it
|
||||
// filters CSS generated content too as unwanted side effect.
|
||||
let ignoreRoles = [Ci.nsIAccessibleRole.ROLE_WHITESPACE,
|
||||
Ci.nsIAccessibleRole.ROLE_STATICTEXT];
|
||||
|
||||
if (ignoreRoles.indexOf(aAccessible.role) < 0) {
|
||||
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;
|
||||
}
|
||||
|
||||
let state = {};
|
||||
aAccessible.getState(state, {});
|
||||
if (state.value & Ci.nsIAccessibleStates.STATE_FOCUSABLE)
|
||||
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])
|
||||
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
|
||||
]
|
||||
}
|
||||
};
|
||||
|
@ -17,6 +17,7 @@ const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
|
||||
const STATE_DEFAULT = nsIAccessibleStates.STATE_DEFAULT;
|
||||
const STATE_EXPANDED = nsIAccessibleStates.STATE_EXPANDED;
|
||||
const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE;
|
||||
const STATE_FLOATING = nsIAccessibleStates.STATE_FLOATING;
|
||||
const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE;
|
||||
const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED;
|
||||
const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
|
||||
|
@ -7,14 +7,53 @@
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function openComboboxNCheckStates(aID)
|
||||
{
|
||||
this.combobox = getAccessible(aID);
|
||||
this.comboboxList = this.combobox.firstChild;
|
||||
this.comboboxOption = this.comboboxList.firstChild;
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, this.comboboxOption)
|
||||
];
|
||||
|
||||
this.invoke = function openComboboxNCheckStates_invoke()
|
||||
{
|
||||
getNode(aID).focus();
|
||||
synthesizeKey("VK_DOWN", { altKey: true });
|
||||
}
|
||||
|
||||
this.finalCheck = function openComboboxNCheckStates_invoke()
|
||||
{
|
||||
// Expanded state on combobox.
|
||||
testStates(this.combobox, STATE_EXPANDED);
|
||||
|
||||
// Floating state on combobox list.
|
||||
testStates(this.comboboxList, STATE_FLOATING);
|
||||
}
|
||||
|
||||
this.getID = function openComboboxNCheckStates_getID()
|
||||
{
|
||||
return "open combobox and test states";
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
// combobox
|
||||
@ -24,7 +63,7 @@
|
||||
STATE_FOCUSED, 0);
|
||||
|
||||
var comboboxList = combobox.firstChild;
|
||||
testStates(comboboxList, 0, 0, STATE_FOCUSABLE, 0);
|
||||
testStates(comboboxList, STATE_INVISIBLE, 0, STATE_FOCUSABLE, 0);
|
||||
|
||||
var opt1 = comboboxList.firstChild;
|
||||
testStates(opt1, STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE,
|
||||
@ -46,7 +85,10 @@
|
||||
STATE_SELECTED | STATE_FOCUSED | STATE_FOCUSED,
|
||||
0, 0, EXT_STATE_ACTIVE);
|
||||
|
||||
SimpleTest.finish();
|
||||
// open combobox
|
||||
gQueue = new eventQueue();
|
||||
gQueue.push(new openComboboxNCheckStates("combobox"));
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -1069,6 +1069,7 @@ toolbar[iconsize="small"] #feed-button {
|
||||
padding: 1px;
|
||||
margin: -1px;
|
||||
-moz-margin-end: 0;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
#identity-box:-moz-locale-dir(ltr) {
|
||||
@ -1093,9 +1094,19 @@ toolbar[iconsize="small"] #feed-button {
|
||||
|
||||
#identity-box.verifiedIdentity {
|
||||
background-color: #fff;
|
||||
color: hsl(92,81%,16%);
|
||||
-moz-border-end: 1px solid hsla(92,81%,16%,.2);
|
||||
color: hsl(92,100%,30%);
|
||||
-moz-margin-end: 4px;
|
||||
background-image: -moz-linear-gradient(hsla(92,81%,16%,0),
|
||||
hsla(92,81%,16%,.2) 25%,
|
||||
hsla(92,81%,16%,.2) 75%,
|
||||
hsla(92,81%,16%,0));
|
||||
background-position: right;
|
||||
background-size: 1px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#identity-box.verifiedIdentity:-moz-locale-dir(rtl) {
|
||||
background-position: left;
|
||||
}
|
||||
|
||||
/* Identity popup icons */
|
||||
|
@ -980,6 +980,7 @@ toolbar[mode="icons"] #zoom-in-button {
|
||||
padding-bottom: 1px;
|
||||
-moz-padding-start: 4px;
|
||||
-moz-padding-end: 0;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
#identity-box:-moz-locale-dir(ltr) {
|
||||
@ -1025,9 +1026,19 @@ toolbar[mode="icons"] #zoom-in-button {
|
||||
}
|
||||
|
||||
#identity-box.verifiedIdentity {
|
||||
color: hsl(92,100%,20%);
|
||||
-moz-border-end: 1px solid hsla(92,81%,16%,.2);
|
||||
color: hsl(92,100%,30%);
|
||||
-moz-padding-end: 4px;
|
||||
background-image: -moz-linear-gradient(hsla(92,81%,16%,0),
|
||||
hsla(92,81%,16%,.2) 25%,
|
||||
hsla(92,81%,16%,.2) 75%,
|
||||
hsla(92,81%,16%,0));
|
||||
background-position: right;
|
||||
background-size: 1px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#identity-box.verifiedIdentity:-moz-locale-dir(rtl) {
|
||||
background-position: left;
|
||||
}
|
||||
|
||||
#identity-box:-moz-focusring {
|
||||
|
@ -1359,6 +1359,7 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
|
||||
|
||||
#identity-box {
|
||||
padding: 2px;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
#identity-box:-moz-locale-dir(ltr) {
|
||||
@ -1406,9 +1407,19 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
|
||||
}
|
||||
|
||||
#identity-box.verifiedIdentity {
|
||||
color: hsl(92,100%,20%);
|
||||
-moz-border-end: 1px solid hsla(92,81%,16%,.2);
|
||||
color: hsl(92,100%,30%);
|
||||
-moz-margin-end: 4px;
|
||||
background-image: -moz-linear-gradient(hsla(92,81%,16%,0),
|
||||
hsla(92,81%,16%,.2) 25%,
|
||||
hsla(92,81%,16%,.2) 75%,
|
||||
hsla(92,81%,16%,0));
|
||||
background-position: right;
|
||||
background-size: 1px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#identity-box.verifiedIdentity:-moz-locale-dir(rtl) {
|
||||
background-position: left;
|
||||
}
|
||||
|
||||
#identity-box.verifiedIdentity:not(:-moz-lwtheme) {
|
||||
|
@ -169,7 +169,7 @@ class Preprocessor:
|
||||
args = [sys.stdin]
|
||||
includes.extend(args)
|
||||
for f in includes:
|
||||
self.do_include(f)
|
||||
self.do_include(f, False)
|
||||
pass
|
||||
|
||||
def getCommandLineParser(self, unescapeDefines = False):
|
||||
@ -414,7 +414,7 @@ class Preprocessor:
|
||||
def filter_attemptSubstitution(self, aLine):
|
||||
return self.filter_substitution(aLine, fatal=False)
|
||||
# File ops
|
||||
def do_include(self, args):
|
||||
def do_include(self, args, filters=True):
|
||||
"""
|
||||
Preprocess a given file.
|
||||
args can either be a file name, or a file-like object.
|
||||
@ -427,10 +427,13 @@ class Preprocessor:
|
||||
if isName:
|
||||
try:
|
||||
args = str(args)
|
||||
if filters:
|
||||
args = self.applyFilters(args)
|
||||
if not os.path.isabs(args):
|
||||
args = os.path.join(self.context['DIRECTORY'], args)
|
||||
args = open(args, 'rU')
|
||||
except Preprocessor.Error:
|
||||
raise
|
||||
except:
|
||||
raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args))
|
||||
self.checkLineNumbers = bool(re.search('\.(js|java)(?:\.in)?$', args.name))
|
||||
@ -476,7 +479,7 @@ def preprocess(includes=[sys.stdin], defines={},
|
||||
pp.setMarker(marker)
|
||||
pp.out = output
|
||||
for f in includes:
|
||||
pp.do_include(f)
|
||||
pp.do_include(f, False)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -1,3 +1,4 @@
|
||||
from __future__ import with_statement
|
||||
import unittest
|
||||
|
||||
from StringIO import StringIO
|
||||
@ -13,6 +14,33 @@ class NamedIO(StringIO):
|
||||
self.name = name
|
||||
StringIO.__init__(self, content)
|
||||
|
||||
class MockedOpen(object):
|
||||
"""
|
||||
Context manager diverting the open builtin such that opening files
|
||||
can open NamedIO instances given when creating a MockedOpen.
|
||||
|
||||
with MockedOpen(NamedIO('foo', 'foo'), NamedIO('bar', 'bar')):
|
||||
f = open('foo', 'r')
|
||||
|
||||
will thus assign the NamedIO instance for the file 'foo' to f.
|
||||
"""
|
||||
def __init__(self, *files):
|
||||
self.files = {}
|
||||
for f in files:
|
||||
self.files[os.path.abspath(f.name)] = f
|
||||
def __call__(self, name, args):
|
||||
absname = os.path.abspath(name)
|
||||
if absname in self.files:
|
||||
return self.files[absname]
|
||||
return self.open(name, args)
|
||||
def __enter__(self):
|
||||
import __builtin__
|
||||
self.open = __builtin__.open
|
||||
__builtin__.open = self
|
||||
def __exit__(self, type, value, traceback):
|
||||
import __builtin__
|
||||
__builtin__.open = self.open
|
||||
|
||||
class TestPreprocessor(unittest.TestCase):
|
||||
"""
|
||||
Unit tests for the Context class
|
||||
@ -499,5 +527,69 @@ octal value is not equal
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), "octal value is not equal\n")
|
||||
|
||||
def test_undefined_variable(self):
|
||||
f = NamedIO("undefined_variable.in", """#filter substitution
|
||||
@foo@
|
||||
""")
|
||||
try:
|
||||
self.pp.do_include(f)
|
||||
except Preprocessor.Error, exception:
|
||||
self.assertEqual(exception.key, 'UNDEFINED_VAR')
|
||||
else:
|
||||
self.fail("Expected a Preprocessor.Error")
|
||||
|
||||
def test_include(self):
|
||||
with MockedOpen(NamedIO("foo/test", """#define foo foobarbaz
|
||||
#include @inc@
|
||||
@bar@
|
||||
"""),
|
||||
NamedIO("bar", """#define bar barfoobaz
|
||||
@foo@
|
||||
""")):
|
||||
f = NamedIO("include.in", """#filter substitution
|
||||
#define inc ../bar
|
||||
#include foo/test""")
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), """foobarbaz
|
||||
barfoobaz
|
||||
""")
|
||||
|
||||
def test_include_missing_file(self):
|
||||
f = NamedIO("include_missing_file.in", "#include foo")
|
||||
try:
|
||||
self.pp.do_include(f)
|
||||
except Preprocessor.Error, exception:
|
||||
self.assertEqual(exception.key, 'FILE_NOT_FOUND')
|
||||
else:
|
||||
self.fail("Expected a Preprocessor.Error")
|
||||
|
||||
def test_include_undefined_variable(self):
|
||||
f = NamedIO("include_undefined_variable.in", """#filter substitution
|
||||
#include @foo@
|
||||
""")
|
||||
try:
|
||||
self.pp.do_include(f)
|
||||
except Preprocessor.Error, exception:
|
||||
self.assertEqual(exception.key, 'UNDEFINED_VAR')
|
||||
else:
|
||||
self.fail("Expected a Preprocessor.Error")
|
||||
|
||||
def test_include_literal_at(self):
|
||||
with MockedOpen(NamedIO("@foo@", "#define foo foobarbaz")):
|
||||
f = NamedIO("include_literal_at.in", """#include @foo@
|
||||
#filter substitution
|
||||
@foo@
|
||||
""")
|
||||
self.pp.do_include(f)
|
||||
self.assertEqual(self.pp.out.getvalue(), """foobarbaz
|
||||
""")
|
||||
|
||||
def test_command_line_literal_at(self):
|
||||
with MockedOpen(NamedIO("@foo@.in", """@foo@
|
||||
""")):
|
||||
self.pp.handleCommandLine(['-Fsubstitution', '-Dfoo=foobarbaz', '@foo@.in'])
|
||||
self.assertEqual(self.pp.out.getvalue(), """foobarbaz
|
||||
""")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
19
configure.in
19
configure.in
@ -1724,6 +1724,19 @@ if test "$GNU_CC"; then
|
||||
DSO_CFLAGS=''
|
||||
DSO_PIC_CFLAGS='-fPIC'
|
||||
ASFLAGS="$ASFLAGS -fPIC"
|
||||
AC_MSG_CHECKING([for --noexecstack option to as])
|
||||
_SAVE_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS -Wa,--noexecstack"
|
||||
AC_TRY_COMPILE(,,AC_MSG_RESULT([yes])
|
||||
[ASFLAGS="$ASFLAGS -Wa,--noexecstack"],
|
||||
AC_MSG_RESULT([no]))
|
||||
CFLAGS=$_SAVE_CFLAGS
|
||||
AC_MSG_CHECKING([for -z noexecstack option to ld])
|
||||
_SAVE_LDFLAGS=$LDFLAGS
|
||||
LDFLAGS="$LDFLAGS -Wl,-z,noexecstack"
|
||||
AC_TRY_LINK(,,AC_MSG_RESULT([yes]),
|
||||
AC_MSG_RESULT([no])
|
||||
LDFLAGS=$_SAVE_LDFLAGS)
|
||||
_MOZ_RTTI_FLAGS_ON=-frtti
|
||||
_MOZ_RTTI_FLAGS_OFF=-fno-rtti
|
||||
|
||||
@ -3586,15 +3599,15 @@ dnl check for clock_gettime(), the CLOCK_MONOTONIC clock
|
||||
AC_CACHE_CHECK(for clock_gettime(CLOCK_MONOTONIC),
|
||||
ac_cv_clock_monotonic,
|
||||
[for libs in "" -lrt; do
|
||||
_SAVE_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $libs"
|
||||
_SAVE_LIBS="$LIBS"
|
||||
LIBS="$LIBS $libs"
|
||||
AC_TRY_LINK([#include <time.h>],
|
||||
[ struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts); ],
|
||||
ac_cv_clock_monotonic=$libs
|
||||
break,
|
||||
ac_cv_clock_monotonic=no)
|
||||
LDFLAGS="$_SAVE_LDFLAGS"
|
||||
LIBS="$_SAVE_LIBS"
|
||||
done])
|
||||
if test "$ac_cv_clock_monotonic" != "no"; then
|
||||
HAVE_CLOCK_MONOTONIC=1
|
||||
|
@ -1021,6 +1021,9 @@ nsHTMLInputElement::SetValue(const nsAString& aValue)
|
||||
}
|
||||
else {
|
||||
SetValueInternal(aValue, false, true);
|
||||
if (IsSingleLineTextControl(false)) {
|
||||
GetValueInternal(mFocusedValue);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1330,6 +1333,24 @@ nsHTMLInputElement::AfterSetFiles(bool aSetValueChanged)
|
||||
UpdateAllValidityStates(true);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLInputElement::FireChangeEventIfNeeded()
|
||||
{
|
||||
nsString value;
|
||||
GetValueInternal(value);
|
||||
|
||||
if (!IsSingleLineTextControl(false) || mFocusedValue.Equals(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dispatch the change event.
|
||||
mFocusedValue = value;
|
||||
nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
|
||||
static_cast<nsIContent*>(this),
|
||||
NS_LITERAL_STRING("change"), true,
|
||||
false);
|
||||
}
|
||||
|
||||
const nsCOMArray<nsIDOMFile>&
|
||||
nsHTMLInputElement::GetFiles() const
|
||||
{
|
||||
@ -1908,13 +1929,7 @@ nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
|
||||
// Fire onchange (if necessary), before we do the blur, bug 357684.
|
||||
if (aVisitor.mEvent->message == NS_BLUR_CONTENT) {
|
||||
nsIFrame* primaryFrame = GetPrimaryFrame();
|
||||
if (primaryFrame) {
|
||||
nsITextControlFrame* textFrame = do_QueryFrame(primaryFrame);
|
||||
if (textFrame) {
|
||||
textFrame->CheckFireOnChange();
|
||||
}
|
||||
}
|
||||
FireChangeEventIfNeeded();
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::PreHandleEvent(aVisitor);
|
||||
@ -1947,6 +1962,10 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
|
||||
if (aVisitor.mEvent->message == NS_FOCUS_CONTENT ||
|
||||
aVisitor.mEvent->message == NS_BLUR_CONTENT) {
|
||||
if (aVisitor.mEvent->message == NS_FOCUS_CONTENT &&
|
||||
IsSingleLineTextControl(false)) {
|
||||
GetValueInternal(mFocusedValue);
|
||||
}
|
||||
|
||||
UpdateValidityUIBits(aVisitor.mEvent->message == NS_FOCUS_CONTENT);
|
||||
|
||||
@ -2195,16 +2214,7 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
(keyEvent->keyCode == NS_VK_RETURN ||
|
||||
keyEvent->keyCode == NS_VK_ENTER) &&
|
||||
IsSingleLineTextControl(false, mType)) {
|
||||
nsIFrame* primaryFrame = GetPrimaryFrame();
|
||||
if (primaryFrame) {
|
||||
nsITextControlFrame* textFrame = do_QueryFrame(primaryFrame);
|
||||
|
||||
// Fire onChange (if necessary)
|
||||
if (textFrame) {
|
||||
textFrame->CheckFireOnChange();
|
||||
}
|
||||
}
|
||||
|
||||
FireChangeEventIfNeeded();
|
||||
rv = MaybeSubmitForm(aVisitor.mPresContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -2441,6 +2451,14 @@ nsHTMLInputElement::HandleTypeChange(PRUint8 aNewType)
|
||||
// There is no value sanitizing algorithm for elements in this mode.
|
||||
break;
|
||||
}
|
||||
|
||||
//Updating mFocusedValue in consequence.
|
||||
if (isNewTypeSingleLine && !isCurrentTypeSingleLine) {
|
||||
GetValueInternal(mFocusedValue);
|
||||
}
|
||||
else if (!isNewTypeSingleLine && isCurrentTypeSingleLine) {
|
||||
mFocusedValue.Truncate();
|
||||
}
|
||||
}
|
||||
|
||||
// Do not notify, it will be done after if needed.
|
||||
|
@ -303,6 +303,11 @@ public:
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::checked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires change event if mFocusedValue and current value held are unequal.
|
||||
*/
|
||||
void FireChangeEventIfNeeded();
|
||||
|
||||
protected:
|
||||
// Pull IsSingleLineTextControl into our scope, otherwise it'd be hidden
|
||||
// by the nsITextControlElement version.
|
||||
@ -586,6 +591,15 @@ protected:
|
||||
|
||||
nsString mStaticDocFileList;
|
||||
|
||||
/**
|
||||
* The value of the input element when first initialized and it is updated
|
||||
* when the element is either changed through a script, focused or dispatches
|
||||
* a change event. This is to ensure correct future change event firing.
|
||||
* NB: This is ONLY applicable where the element is a text control. ie,
|
||||
* where type= "text", "email", "search", "tel", "url" or "password".
|
||||
*/
|
||||
nsString mFocusedValue;
|
||||
|
||||
/**
|
||||
* The type of this input (<input type=...>) as an integer.
|
||||
* @see nsIFormControl.h (specifically NS_FORM_INPUT_*)
|
||||
|
@ -260,6 +260,10 @@ protected:
|
||||
/** Whether we should make :-moz-ui-valid apply on the element. **/
|
||||
bool mCanShowValidUI;
|
||||
|
||||
void FireChangeEventIfNeeded();
|
||||
|
||||
nsString mFocusedValue;
|
||||
|
||||
/** The state of the text editor (selection controller and the editor) **/
|
||||
nsTextEditorState mState;
|
||||
|
||||
@ -589,7 +593,9 @@ nsHTMLTextAreaElement::SetValueInternal(const nsAString& aValue,
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTextAreaElement::SetValue(const nsAString& aValue)
|
||||
{
|
||||
return SetValueInternal(aValue, false);
|
||||
SetValueInternal(aValue, false);
|
||||
GetValueInternal(mFocusedValue, true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -733,18 +739,30 @@ nsHTMLTextAreaElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
|
||||
// Fire onchange (if necessary), before we do the blur, bug 370521.
|
||||
if (aVisitor.mEvent->message == NS_BLUR_CONTENT) {
|
||||
nsIFrame* primaryFrame = GetPrimaryFrame();
|
||||
if (primaryFrame) {
|
||||
nsITextControlFrame* textFrame = do_QueryFrame(primaryFrame);
|
||||
if (textFrame) {
|
||||
textFrame->CheckFireOnChange();
|
||||
}
|
||||
}
|
||||
FireChangeEventIfNeeded();
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLTextAreaElement::FireChangeEventIfNeeded()
|
||||
{
|
||||
nsString value;
|
||||
GetValueInternal(value, true);
|
||||
|
||||
if (mFocusedValue.Equals(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dispatch the change event.
|
||||
mFocusedValue = value;
|
||||
nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
|
||||
static_cast<nsIContent*>(this),
|
||||
NS_LITERAL_STRING("change"), true,
|
||||
false);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLTextAreaElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
@ -757,6 +775,7 @@ nsHTMLTextAreaElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
if (aVisitor.mEvent->message == NS_FOCUS_CONTENT) {
|
||||
// If the invalid UI is shown, we should show it while focusing (and
|
||||
// update). Otherwise, we should not.
|
||||
GetValueInternal(mFocusedValue, true);
|
||||
mCanShowInvalidUI = !IsValid() && ShouldShowValidityUI();
|
||||
|
||||
// If neither invalid UI nor valid UI is shown, we shouldn't show the valid
|
||||
|
@ -1743,11 +1743,6 @@ nsTextEditorState::SetValue(const nsAString& aValue, bool aUserInput)
|
||||
// PrepareEditor cannot be called prematurely.
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
bool fireChangeEvent = mBoundFrame->GetFireChangeEventState();
|
||||
if (aUserInput) {
|
||||
mBoundFrame->SetFireChangeEventState(true);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (IsSingleLineTextControl()) {
|
||||
NS_ASSERTION(mEditorInitialized || mInitializing,
|
||||
@ -1774,8 +1769,7 @@ nsTextEditorState::SetValue(const nsAString& aValue, bool aUserInput)
|
||||
// this is necessary to avoid infinite recursion
|
||||
if (!currentValue.Equals(aValue))
|
||||
{
|
||||
nsTextControlFrame::ValueSetter valueSetter(mBoundFrame, mEditor,
|
||||
mBoundFrame->mFocusedValue.Equals(currentValue));
|
||||
nsTextControlFrame::ValueSetter valueSetter(mBoundFrame, mEditor);
|
||||
|
||||
// \r is an illegal character in the dom, but people use them,
|
||||
// so convert windows and mac platform linebreaks to \n:
|
||||
@ -1894,9 +1888,6 @@ nsTextEditorState::SetValue(const nsAString& aValue, bool aUserInput)
|
||||
scrollableFrame->ScrollTo(nsPoint(0, 0), nsIScrollableFrame::INSTANT);
|
||||
}
|
||||
|
||||
if (aUserInput) {
|
||||
mBoundFrame->SetFireChangeEventState(fireChangeEvent);
|
||||
}
|
||||
} else {
|
||||
if (!mValue) {
|
||||
mValue = new nsCString;
|
||||
|
@ -46,6 +46,7 @@ include $(topsrcdir)/config/rules.mk
|
||||
_TEST_FILES = \
|
||||
save_restore_radio_groups.sjs \
|
||||
test_save_restore_radio_groups.html \
|
||||
test_change_event.html \
|
||||
test_mozistextfield.html \
|
||||
test_input_attributes_reflection.html \
|
||||
test_input_list_attribute.html \
|
||||
|
148
content/html/content/test/forms/test_change_event.html
Normal file
148
content/html/content/test/forms/test_change_event.html
Normal file
@ -0,0 +1,148 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=722599
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 722599</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=722599">Mozilla Bug 722599</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<input type="file" id="fileInput"></input>
|
||||
<textarea id="textarea" onchange="++textareaChange;"></textarea>
|
||||
<input type="text" id="input_text" onchange="++textInputChange[0];"></input>
|
||||
<input type="email" id="input_email" onchange="++textInputChange[1];"></input>
|
||||
<input type="search" id="input_search" onchange="++textInputChange[2];"></input>
|
||||
<input type="tel" id="input_telephone" onchange="++textInputChange[3];"></input>
|
||||
<input type="url" id="input_url" onchange="++textInputChange[4];"></input>
|
||||
<input type="password" id="input_password" onchange="++textInputChange[5];"></input>
|
||||
|
||||
<!-- "Non-text" inputs-->
|
||||
<input type="button" id="input_button" onchange="++NonTextInputChange[0];"></input>
|
||||
<input type="submit" id="input_submit" onchange="++NonTextInputChange[1];"></input>
|
||||
<input type="image" id="input_image" onchange="++NonTextInputChange[2];"></input>
|
||||
<input type="reset" id="input_reset" onchange="++NonTextInputChange[3];"></input>
|
||||
<input type="radio" id="input_radio" onchange="++NonTextInputChange[4];"></input>
|
||||
<input type="checkbox" id="input_checkbox" onchange="++NonTextInputChange[5];"></input>
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 722599 **/
|
||||
var textareaChange = 0;
|
||||
var fileInputChange = 0;
|
||||
|
||||
var textInputTypes = ["text", "email", "search", "telephone", "url", "password"];
|
||||
var textInputChange = [0, 0, 0, 0, 0, 0];
|
||||
|
||||
var NonTextInputTypes = ["button", "submit", "image", "reset", "radio", "checkbox"];
|
||||
var NonTextInputChange = [0, 0, 0, 0, 0, 0];
|
||||
|
||||
var blurTestCalled = false; //Sentinel to prevent infinite loop.
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var MockFilePicker = SpecialPowers.MockFilePicker;
|
||||
MockFilePicker.init();
|
||||
|
||||
function fileInputBlurTest() {
|
||||
var btn = document.getElementById('fileInput');
|
||||
btn.focus()
|
||||
btn.blur();
|
||||
is(fileInputChange, 1, "change event shouldn't be dispatched on blur for file input element(1)");
|
||||
}
|
||||
|
||||
function testUserInput() {
|
||||
//Simulating an OK click and with a file name return.
|
||||
MockFilePicker.useAnyFile();
|
||||
MockFilePicker.returnValue = MockFilePicker.returnOK;
|
||||
var input = document.getElementById('fileInput');
|
||||
input.focus();
|
||||
|
||||
input.addEventListener("change", function (aEvent) {
|
||||
++fileInputChange;
|
||||
if (!blurTestCalled) {
|
||||
is(fileInputChange, 1, "change event should have been dispatched on file input.");
|
||||
blurTestCalled = true;
|
||||
fileInputBlurTest();
|
||||
}
|
||||
else {
|
||||
is(fileInputChange, 1, "change event shouldn't be dispatched on blur for file input element (2)");
|
||||
}
|
||||
}, false);
|
||||
|
||||
input.click();
|
||||
|
||||
//text, email, search, telephone, url & password input tests
|
||||
for (var i = 0; i < textInputTypes.length; ++i) {
|
||||
input = document.getElementById("input_" + textInputTypes[i]);
|
||||
input.focus();
|
||||
synthesizeKey("VK_ENTER", {});
|
||||
is(textInputChange[i], 0, "Change event shouldn't be dispatched on " + textInputTypes[i] + " input element");
|
||||
|
||||
synthesizeKey("m", {});
|
||||
synthesizeKey("VK_RETURN", {});
|
||||
is(textInputChange[i], 1, textInputTypes[i] + " input element should have dispatched change event.");
|
||||
}
|
||||
|
||||
//focus and blur text input
|
||||
input = document.getElementById("input_text");
|
||||
input.focus();
|
||||
synthesizeKey("f", {});
|
||||
input.blur();
|
||||
is(textInputChange[0], 2, "text input element should have dispatched change event (2).");
|
||||
|
||||
//focus and blur textarea
|
||||
var textarea = document.getElementById("textarea");
|
||||
textarea.focus();
|
||||
synthesizeKey("f", {});
|
||||
textarea.blur();
|
||||
is(textareaChange, 1, "Textarea element should have dispatched change event.");
|
||||
|
||||
//Non-text input tests:
|
||||
for (var i = 0; i < NonTextInputTypes.length; ++i) {
|
||||
//button, submit, image and reset input type tests.
|
||||
if (i < 4) {
|
||||
input = document.getElementById("input_" + NonTextInputTypes[i]);
|
||||
input.focus();
|
||||
input.click();
|
||||
is(NonTextInputChange[i], 0, "Change event shouldn't be dispatched on " + NonTextInputTypes[i] + " input element");
|
||||
input.blur();
|
||||
is(NonTextInputChange[i], 0, "Change event shouldn't be dispatched on " + NonTextInputTypes[i] + " input element(2)");
|
||||
}
|
||||
//for radio and and checkboxes, we require that change event should ONLY be dispatched on setting the value.
|
||||
else {
|
||||
input = document.getElementById("input_" + NonTextInputTypes[i]);
|
||||
input.focus();
|
||||
input.click();
|
||||
is(NonTextInputChange[i], 1, NonTextInputTypes[i] + " input element should have dispatched change event.");
|
||||
input.blur();
|
||||
is(NonTextInputChange[i], 1, "Change event shouldn't be dispatched on " + NonTextInputTypes[i] + " input element");
|
||||
}
|
||||
}
|
||||
|
||||
//Input type change test.
|
||||
input = document.getElementById("input_checkbox");
|
||||
input.type = "text";
|
||||
input.focus();
|
||||
input.click();
|
||||
input.blur();
|
||||
is(NonTextInputChange[5], 1, "Change event shouldn't be dispatched for checkbox ---> text input type change");
|
||||
|
||||
MockFilePicker.cleanup;
|
||||
SimpleTest.finish();
|
||||
|
||||
}
|
||||
|
||||
addLoadEvent(testUserInput);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
@ -92,3 +92,10 @@ collapseAction = collapsed
|
||||
expandAction = expanded
|
||||
activateAction = activated
|
||||
cycleAction = cycled
|
||||
|
||||
# Tab states
|
||||
tabLoading = loading
|
||||
tabLoaded = loaded
|
||||
tabNew = new tab
|
||||
tabLoadStopped = loading stopped
|
||||
tabReload = reloading
|
||||
|
@ -8,16 +8,29 @@
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
ok(window.performance);
|
||||
ok(typeof window.performance.now == 'function');
|
||||
var n = window.performance.now();
|
||||
ok(n >= 0);
|
||||
ok(window.performance.now() >= n);
|
||||
ok(window.performance, "Performance object should exist.");
|
||||
ok(typeof window.performance.now == 'function', "Performance object should have a 'now' method.");
|
||||
var n = window.performance.now(), d = Date.now();
|
||||
ok(n >= 0, "The value of now() should be equal to or greater than 0.");
|
||||
ok(window.performance.now() >= n, "The value of now() should monotonically increase.");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setTimeout(function() {
|
||||
ok(window.performance.now() > n);
|
||||
|
||||
var checks = 0;
|
||||
function checkAfterTimeout() {
|
||||
checks++;
|
||||
var d2 = Date.now();
|
||||
// Timeouts aren't extremely reliable and especially on Windows we are prone to fallback to
|
||||
// millisecond timers, in which case this test might occasionally fail. This is a workaround:
|
||||
if (navigator.platform.indexOf("Win") == 0 &&
|
||||
window.performance.now() == n && d == d2 &&
|
||||
checks < 5) {
|
||||
setTimeout(checkAfterTimeout, 20);
|
||||
return;
|
||||
}
|
||||
ok(window.performance.now() > n, "After a timeout, the value of now() should be strictly greater than before.");
|
||||
SimpleTest.finish();
|
||||
}, 20);
|
||||
};
|
||||
setTimeout(checkAfterTimeout, 20);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -236,7 +236,13 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
->Paint(aContext, nsnull);
|
||||
}
|
||||
|
||||
BasicManager()->PaintedTiledLayerBuffer(BasicManager()->Hold(this), &mTiledBuffer);
|
||||
// Create a heap copy owned and released by the compositor. This is needed
|
||||
// since we're sending this over an async message and content needs to be
|
||||
// be able to modify the tiled buffer in the next transaction.
|
||||
// TODO: Remove me once Bug 747811 lands.
|
||||
BasicTiledLayerBuffer *heapCopy = new BasicTiledLayerBuffer(mTiledBuffer);
|
||||
|
||||
BasicManager()->PaintedTiledLayerBuffer(BasicManager()->Hold(this), heapCopy);
|
||||
}
|
||||
|
||||
} // mozilla
|
||||
|
@ -244,6 +244,10 @@ parent:
|
||||
sync Update(Edit[] cset, bool isFirstPaint)
|
||||
returns (EditReply[] reply);
|
||||
|
||||
// We don't need to send a sync transaction if
|
||||
// no transaction operate require a swap.
|
||||
async UpdateNoSwap(Edit[] cset, bool isFirstPaint);
|
||||
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
|
@ -66,7 +66,10 @@ typedef std::set<ShadowableLayer*> ShadowableLayerSet;
|
||||
class Transaction
|
||||
{
|
||||
public:
|
||||
Transaction() : mOpen(false) {}
|
||||
Transaction()
|
||||
: mOpen(false)
|
||||
, mSwapRequired(false)
|
||||
{}
|
||||
|
||||
void Begin() { mOpen = true; }
|
||||
|
||||
@ -76,6 +79,11 @@ public:
|
||||
mCset.push_back(aEdit);
|
||||
}
|
||||
void AddPaint(const Edit& aPaint)
|
||||
{
|
||||
AddNoSwapPaint(aPaint);
|
||||
mSwapRequired = true;
|
||||
}
|
||||
void AddNoSwapPaint(const Edit& aPaint)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!Finished(), "forgot BeginTransaction?");
|
||||
mPaints.push_back(aPaint);
|
||||
@ -102,6 +110,7 @@ public:
|
||||
mDyingBuffers.Clear();
|
||||
mMutants.clear();
|
||||
mOpen = false;
|
||||
mSwapRequired = false;
|
||||
}
|
||||
|
||||
bool Empty() const {
|
||||
@ -113,6 +122,7 @@ public:
|
||||
EditVector mPaints;
|
||||
BufferArray mDyingBuffers;
|
||||
ShadowableLayerSet mMutants;
|
||||
bool mSwapRequired;
|
||||
|
||||
private:
|
||||
bool mOpen;
|
||||
@ -247,7 +257,7 @@ ShadowLayerForwarder::PaintedTiledLayerBuffer(ShadowableLayer* aLayer,
|
||||
{
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default)
|
||||
NS_RUNTIMEABORT("PaintedTiledLayerBuffer must be made IPC safe (not share pointers)");
|
||||
mTxn->AddPaint(OpPaintTiledLayerBuffer(NULL, Shadow(aLayer),
|
||||
mTxn->AddNoSwapPaint(OpPaintTiledLayerBuffer(NULL, Shadow(aLayer),
|
||||
uintptr_t(aTiledLayerBuffer)));
|
||||
}
|
||||
|
||||
@ -341,12 +351,23 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] syncing before send..."));
|
||||
PlatformSyncBeforeUpdate();
|
||||
|
||||
if (mTxn->mSwapRequired) {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] sending transaction..."));
|
||||
RenderTraceScope rendertrace3("Foward Transaction", "000093");
|
||||
RenderTraceScope rendertrace3("Forward Transaction", "000093");
|
||||
if (!mShadowManager->SendUpdate(cset, mIsFirstPaint, aReplies)) {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// If we don't require a swap we can call SendUpdateNoSwap which
|
||||
// assumes that aReplies is empty (DEBUG assertion)
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] sending no swap transaction..."));
|
||||
RenderTraceScope rendertrace3("Forward NoSwap Transaction", "000093");
|
||||
if (!mShadowManager->SendUpdateNoSwap(cset, mIsFirstPaint)) {
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mIsFirstPaint = false;
|
||||
MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
|
||||
|
@ -147,6 +147,17 @@ ShadowLayersParent::Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
bool
|
||||
ShadowLayersParent::RecvUpdateNoSwap(const InfallibleTArray<Edit>& cset,
|
||||
const bool& isFirstPaint)
|
||||
{
|
||||
InfallibleTArray<EditReply> noReplies;
|
||||
bool success = RecvUpdate(cset, isFirstPaint, &noReplies);
|
||||
NS_ABORT_IF_FALSE(noReplies.Length() == 0, "RecvUpdateNoSwap requires a sync Update to carry Edits");
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
||||
const bool& isFirstPaint,
|
||||
|
@ -81,6 +81,9 @@ protected:
|
||||
const bool& isFirstPaint,
|
||||
EditReplyArray* reply);
|
||||
|
||||
NS_OVERRIDE virtual bool RecvUpdateNoSwap(const EditArray& cset,
|
||||
const bool& isFirstPaint);
|
||||
|
||||
NS_OVERRIDE virtual PLayerParent* AllocPLayer();
|
||||
NS_OVERRIDE virtual bool DeallocPLayer(PLayerParent* actor);
|
||||
|
||||
|
@ -132,6 +132,8 @@ void
|
||||
TiledThebesLayerOGL::PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* mTiledBuffer)
|
||||
{
|
||||
mMainMemoryTiledBuffer = *mTiledBuffer;
|
||||
// TODO: Remove me once Bug 747811 lands.
|
||||
delete mTiledBuffer;
|
||||
mRegionToUpload.Or(mRegionToUpload, mMainMemoryTiledBuffer.GetLastPaintRegion());
|
||||
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ class Preprocessor:
|
||||
args = [sys.stdin]
|
||||
includes.extend(args)
|
||||
for f in includes:
|
||||
self.do_include(f)
|
||||
self.do_include(f, False)
|
||||
pass
|
||||
|
||||
def getCommandLineParser(self, unescapeDefines = False):
|
||||
@ -414,7 +414,7 @@ class Preprocessor:
|
||||
def filter_attemptSubstitution(self, aLine):
|
||||
return self.filter_substitution(aLine, fatal=False)
|
||||
# File ops
|
||||
def do_include(self, args):
|
||||
def do_include(self, args, filters=True):
|
||||
"""
|
||||
Preprocess a given file.
|
||||
args can either be a file name, or a file-like object.
|
||||
@ -427,10 +427,13 @@ class Preprocessor:
|
||||
if isName:
|
||||
try:
|
||||
args = str(args)
|
||||
if filters:
|
||||
args = self.applyFilters(args)
|
||||
if not os.path.isabs(args):
|
||||
args = os.path.join(self.context['DIRECTORY'], args)
|
||||
args = open(args, 'rU')
|
||||
except Preprocessor.Error:
|
||||
raise
|
||||
except:
|
||||
raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args))
|
||||
self.checkLineNumbers = bool(re.search('\.(js|java)(?:\.in)?$', args.name))
|
||||
@ -476,7 +479,7 @@ def preprocess(includes=[sys.stdin], defines={},
|
||||
pp.setMarker(marker)
|
||||
pp.out = output
|
||||
for f in includes:
|
||||
pp.do_include(f)
|
||||
pp.do_include(f, False)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
12
js/src/jit-test/tests/basic/bug747926.js
Normal file
12
js/src/jit-test/tests/basic/bug747926.js
Normal file
@ -0,0 +1,12 @@
|
||||
a = 'a';
|
||||
b = [,];
|
||||
exhaustiveSliceTest("exhaustive slice test 1", a);
|
||||
print('---');
|
||||
exhaustiveSliceTest("exhaustive slice test 2", b);
|
||||
function exhaustiveSliceTest(testname, a){
|
||||
x = 0
|
||||
var y = 0;
|
||||
countHeap();
|
||||
for (y=a.length; y + a.length; y--) { print(y);
|
||||
var b = a.slice(x,y); }
|
||||
}
|
11
js/src/jit-test/tests/basic/bug749039.js
Normal file
11
js/src/jit-test/tests/basic/bug749039.js
Normal file
@ -0,0 +1,11 @@
|
||||
// |jit-test| error: ReferenceError;
|
||||
gczeal(4);
|
||||
try { jsTestDriverEnd(); } catch(exc1) {}
|
||||
evaluate("\
|
||||
schedulegc(10);\
|
||||
for(var i=0; i<3; i++) {\
|
||||
var obj = { first: 'first', second: 'second' };\
|
||||
for (var elem in obj) {}\
|
||||
x.push(count);\
|
||||
}\
|
||||
");
|
@ -1742,35 +1742,20 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
|
||||
|
||||
#define CLASP(name) (&name##Class)
|
||||
#define TYPED_ARRAY_CLASP(type) (&TypedArray::classes[TypedArray::type])
|
||||
#define EAGER_ATOM(name) NAME_OFFSET(name), NULL
|
||||
#define EAGER_CLASS_ATOM(name) CLASS_NAME_OFFSET(name), NULL
|
||||
#define EAGER_ATOM(name) NAME_OFFSET(name)
|
||||
#define EAGER_CLASS_ATOM(name) CLASS_NAME_OFFSET(name)
|
||||
#define EAGER_ATOM_AND_CLASP(name) EAGER_CLASS_ATOM(name), CLASP(name)
|
||||
#define LAZY_ATOM(name) NAME_OFFSET(lazy.name), js_##name##_str
|
||||
|
||||
typedef struct JSStdName {
|
||||
JSObjectOp init;
|
||||
size_t atomOffset; /* offset of atom pointer in JSAtomState */
|
||||
const char *name; /* null if atom is pre-pinned, else name */
|
||||
Class *clasp;
|
||||
} JSStdName;
|
||||
|
||||
static PropertyName *
|
||||
StdNameToPropertyName(JSContext *cx, JSStdName *stdn)
|
||||
{
|
||||
size_t offset;
|
||||
PropertyName *atom;
|
||||
const char *name;
|
||||
|
||||
offset = stdn->atomOffset;
|
||||
atom = OFFSET_TO_NAME(cx->runtime, offset);
|
||||
if (!atom) {
|
||||
name = stdn->name;
|
||||
if (name) {
|
||||
atom = js_Atomize(cx, name, strlen(name), InternAtom)->asPropertyName();
|
||||
OFFSET_TO_NAME(cx->runtime, offset) = atom;
|
||||
}
|
||||
}
|
||||
return atom;
|
||||
return OFFSET_TO_NAME(cx->runtime, stdn->atomOffset);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1801,7 +1786,7 @@ static JSStdName standard_class_atoms[] = {
|
||||
{js_InitWeakMapClass, EAGER_CLASS_ATOM(WeakMap), &js::WeakMapClass},
|
||||
{js_InitMapClass, EAGER_CLASS_ATOM(Map), &js::MapObject::class_},
|
||||
{js_InitSetClass, EAGER_CLASS_ATOM(Set), &js::SetObject::class_},
|
||||
{NULL, 0, NULL, NULL}
|
||||
{NULL, 0, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1815,20 +1800,20 @@ static JSStdName standard_class_names[] = {
|
||||
/* Global properties and functions defined by the Number class. */
|
||||
{js_InitNumberClass, EAGER_ATOM(NaN), CLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(Infinity), CLASP(Number)},
|
||||
{js_InitNumberClass, LAZY_ATOM(isNaN), CLASP(Number)},
|
||||
{js_InitNumberClass, LAZY_ATOM(isFinite), CLASP(Number)},
|
||||
{js_InitNumberClass, LAZY_ATOM(parseFloat), CLASP(Number)},
|
||||
{js_InitNumberClass, LAZY_ATOM(parseInt), CLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(isNaN), CLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(isFinite), CLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(parseFloat), CLASP(Number)},
|
||||
{js_InitNumberClass, EAGER_ATOM(parseInt), CLASP(Number)},
|
||||
|
||||
/* String global functions. */
|
||||
{js_InitStringClass, LAZY_ATOM(escape), CLASP(String)},
|
||||
{js_InitStringClass, LAZY_ATOM(unescape), CLASP(String)},
|
||||
{js_InitStringClass, LAZY_ATOM(decodeURI), CLASP(String)},
|
||||
{js_InitStringClass, LAZY_ATOM(encodeURI), CLASP(String)},
|
||||
{js_InitStringClass, LAZY_ATOM(decodeURIComponent), CLASP(String)},
|
||||
{js_InitStringClass, LAZY_ATOM(encodeURIComponent), CLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(escape), CLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(unescape), CLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(decodeURI), CLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(encodeURI), CLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(decodeURIComponent), CLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(encodeURIComponent), CLASP(String)},
|
||||
#if JS_HAS_UNEVAL
|
||||
{js_InitStringClass, LAZY_ATOM(uneval), CLASP(String)},
|
||||
{js_InitStringClass, EAGER_ATOM(uneval), CLASP(String)},
|
||||
#endif
|
||||
|
||||
/* Exception constructors. */
|
||||
@ -1842,8 +1827,8 @@ static JSStdName standard_class_names[] = {
|
||||
{js_InitExceptionClasses, EAGER_CLASS_ATOM(URIError), CLASP(Error)},
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
{js_InitXMLClass, LAZY_ATOM(XMLList), CLASP(XML)},
|
||||
{js_InitXMLClass, LAZY_ATOM(isXMLName), CLASP(XML)},
|
||||
{js_InitXMLClass, EAGER_ATOM(XMLList), CLASP(XML)},
|
||||
{js_InitXMLClass, EAGER_ATOM(isXMLName), CLASP(XML)},
|
||||
#endif
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
@ -1867,7 +1852,7 @@ static JSStdName standard_class_names[] = {
|
||||
{js_InitWeakMapClass, EAGER_ATOM_AND_CLASP(WeakMap)},
|
||||
{js_InitProxyClass, EAGER_ATOM_AND_CLASP(Proxy)},
|
||||
|
||||
{NULL, 0, NULL, NULL}
|
||||
{NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static JSStdName object_prototype_names[] = {
|
||||
@ -1880,20 +1865,20 @@ static JSStdName object_prototype_names[] = {
|
||||
{js_InitObjectClass, EAGER_ATOM(toLocaleString), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(valueOf), CLASP(Object)},
|
||||
#if JS_HAS_OBJ_WATCHPOINT
|
||||
{js_InitObjectClass, LAZY_ATOM(watch), CLASP(Object)},
|
||||
{js_InitObjectClass, LAZY_ATOM(unwatch), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(watch), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(unwatch), CLASP(Object)},
|
||||
#endif
|
||||
{js_InitObjectClass, LAZY_ATOM(hasOwnProperty), CLASP(Object)},
|
||||
{js_InitObjectClass, LAZY_ATOM(isPrototypeOf), CLASP(Object)},
|
||||
{js_InitObjectClass, LAZY_ATOM(propertyIsEnumerable), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(hasOwnProperty), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(isPrototypeOf), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(propertyIsEnumerable), CLASP(Object)},
|
||||
#if OLD_GETTER_SETTER_METHODS
|
||||
{js_InitObjectClass, LAZY_ATOM(defineGetter), CLASP(Object)},
|
||||
{js_InitObjectClass, LAZY_ATOM(defineSetter), CLASP(Object)},
|
||||
{js_InitObjectClass, LAZY_ATOM(lookupGetter), CLASP(Object)},
|
||||
{js_InitObjectClass, LAZY_ATOM(lookupSetter), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(defineGetter), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(defineSetter), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(lookupGetter), CLASP(Object)},
|
||||
{js_InitObjectClass, EAGER_ATOM(lookupSetter), CLASP(Object)},
|
||||
#endif
|
||||
|
||||
{NULL, 0, NULL, NULL}
|
||||
{NULL, 0, NULL}
|
||||
};
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
@ -2149,7 +2134,6 @@ JS_EnumerateResolvedStandardClasses(JSContext *cx, JSObject *obj, JSIdArray *ida
|
||||
#undef EAGER_ATOM
|
||||
#undef EAGER_CLASS_ATOM
|
||||
#undef EAGER_ATOM_CLASP
|
||||
#undef LAZY_ATOM
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject **objp)
|
||||
|
@ -75,7 +75,6 @@ using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
const size_t JSAtomState::commonAtomsOffset = offsetof(JSAtomState, emptyAtom);
|
||||
const size_t JSAtomState::lazyAtomsOffset = offsetof(JSAtomState, lazy);
|
||||
|
||||
/*
|
||||
* ATOM_HASH assumes that JSHashNumber is 32-bit even on 64-bit systems.
|
||||
@ -151,9 +150,6 @@ JSAtomState::checkStaticInvariants()
|
||||
offsetof(JSAtomState, booleanAtoms) - commonAtomsOffset);
|
||||
JS_STATIC_ASSERT((1 + 2) * sizeof(JSAtom *) ==
|
||||
offsetof(JSAtomState, typeAtoms) - commonAtomsOffset);
|
||||
|
||||
JS_STATIC_ASSERT(JS_ARRAY_LENGTH(js_common_atom_names) * sizeof(JSAtom *) ==
|
||||
lazyAtomsOffset - commonAtomsOffset);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -236,7 +232,6 @@ js::InitCommonAtoms(JSContext *cx)
|
||||
*atoms = atom->asPropertyName();
|
||||
}
|
||||
|
||||
state->clearLazyAtoms();
|
||||
cx->runtime->emptyString = state->emptyAtom;
|
||||
return true;
|
||||
}
|
||||
|
@ -308,38 +308,7 @@ struct JSAtomState
|
||||
#undef DEFINE_PROTOTYPE_ATOM
|
||||
#undef DEFINE_KEYWORD_ATOM
|
||||
|
||||
/* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */
|
||||
struct {
|
||||
js::PropertyName *XMLListAtom;
|
||||
js::PropertyName *decodeURIAtom;
|
||||
js::PropertyName *decodeURIComponentAtom;
|
||||
js::PropertyName *defineGetterAtom;
|
||||
js::PropertyName *defineSetterAtom;
|
||||
js::PropertyName *encodeURIAtom;
|
||||
js::PropertyName *encodeURIComponentAtom;
|
||||
js::PropertyName *escapeAtom;
|
||||
js::PropertyName *hasOwnPropertyAtom;
|
||||
js::PropertyName *isFiniteAtom;
|
||||
js::PropertyName *isNaNAtom;
|
||||
js::PropertyName *isPrototypeOfAtom;
|
||||
js::PropertyName *isXMLNameAtom;
|
||||
js::PropertyName *lookupGetterAtom;
|
||||
js::PropertyName *lookupSetterAtom;
|
||||
js::PropertyName *parseFloatAtom;
|
||||
js::PropertyName *parseIntAtom;
|
||||
js::PropertyName *propertyIsEnumerableAtom;
|
||||
js::PropertyName *unescapeAtom;
|
||||
js::PropertyName *unevalAtom;
|
||||
js::PropertyName *unwatchAtom;
|
||||
js::PropertyName *watchAtom;
|
||||
} lazy;
|
||||
|
||||
static const size_t commonAtomsOffset;
|
||||
static const size_t lazyAtomsOffset;
|
||||
|
||||
void clearLazyAtoms() {
|
||||
memset(&lazy, 0, sizeof(lazy));
|
||||
}
|
||||
|
||||
void junkAtoms() {
|
||||
#ifdef DEBUG
|
||||
|
@ -123,3 +123,26 @@ DEFINE_KEYWORD_ATOM(return)
|
||||
DEFINE_KEYWORD_ATOM(throw)
|
||||
DEFINE_ATOM(url, "url")
|
||||
DEFINE_ATOM(innermost, "innermost")
|
||||
|
||||
DEFINE_ATOM(XMLList, "XMLList")
|
||||
DEFINE_ATOM(decodeURI, "decodeURI")
|
||||
DEFINE_ATOM(decodeURIComponent, "decodeURIComponent")
|
||||
DEFINE_ATOM(defineGetter, "__defineGetter__")
|
||||
DEFINE_ATOM(defineSetter, "__defineSetter__")
|
||||
DEFINE_ATOM(encodeURI, "encodeURI")
|
||||
DEFINE_ATOM(encodeURIComponent, "encodeURIComponent")
|
||||
DEFINE_ATOM(escape, "escape")
|
||||
DEFINE_ATOM(hasOwnProperty, "hasOwnProperty")
|
||||
DEFINE_ATOM(isFinite, "isFinite")
|
||||
DEFINE_ATOM(isNaN, "isNaN")
|
||||
DEFINE_ATOM(isPrototypeOf, "isPrototypeOf")
|
||||
DEFINE_ATOM(isXMLName, "isXMLName")
|
||||
DEFINE_ATOM(lookupGetter, "__lookupGetter__")
|
||||
DEFINE_ATOM(lookupSetter, "__lookupSetter__")
|
||||
DEFINE_ATOM(parseFloat, "parseFloat")
|
||||
DEFINE_ATOM(parseInt, "parseInt")
|
||||
DEFINE_ATOM(propertyIsEnumerable, "propertyIsEnumerable")
|
||||
DEFINE_ATOM(unescape, "unescape")
|
||||
DEFINE_ATOM(uneval, "uneval")
|
||||
DEFINE_ATOM(unwatch, "unwatch")
|
||||
DEFINE_ATOM(watch, "watch")
|
||||
|
@ -4289,12 +4289,6 @@ oom:
|
||||
js_free(trc);
|
||||
}
|
||||
|
||||
static void
|
||||
MarkFromAutorooter(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
static_cast<Cell *>(*thingp)->markIfUnmarked();
|
||||
}
|
||||
|
||||
static bool
|
||||
IsMarkedOrAllocated(Cell *cell)
|
||||
{
|
||||
@ -4327,21 +4321,6 @@ CheckEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Anything that is reachable now should have been reachable before, or else
|
||||
* it should be marked.
|
||||
*/
|
||||
NodeMap::Ptr p = trc->nodemap.lookup(*thingp);
|
||||
JS_ASSERT_IF(!p, IsMarkedOrAllocated(static_cast<Cell *>(*thingp)));
|
||||
}
|
||||
|
||||
static void
|
||||
CheckReachable(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
||||
{
|
||||
VerifyTracer *trc = (VerifyTracer *)jstrc;
|
||||
NodeMap::Ptr p = trc->nodemap.lookup(*thingp);
|
||||
JS_ASSERT_IF(!p, IsMarkedOrAllocated(static_cast<Cell *>(*thingp)));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4387,18 +4366,7 @@ EndVerifyBarriers(JSRuntime *rt)
|
||||
rt->gcVerifyData = NULL;
|
||||
rt->gcIncrementalState = NO_INCREMENTAL;
|
||||
|
||||
JS_TracerInit(trc, rt, MarkFromAutorooter);
|
||||
|
||||
AutoGCRooter::traceAll(trc);
|
||||
|
||||
if (!compartmentCreated && IsIncrementalGCSafe(rt)) {
|
||||
/*
|
||||
* Verify that all the current roots were reachable previously, or else
|
||||
* are marked.
|
||||
*/
|
||||
JS_TracerInit(trc, rt, CheckReachable);
|
||||
MarkRuntime(trc, true);
|
||||
|
||||
JS_TracerInit(trc, rt, CheckEdge);
|
||||
|
||||
/* Start after the roots. */
|
||||
|
@ -107,10 +107,7 @@ class Type
|
||||
return data > JSVAL_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
TypeObjectKey *objectKey() const {
|
||||
JS_ASSERT(isObject());
|
||||
return (TypeObjectKey *) data;
|
||||
}
|
||||
inline TypeObjectKey *objectKey() const;
|
||||
|
||||
/* Accessors for JSObject types */
|
||||
|
||||
@ -118,10 +115,7 @@ class Type
|
||||
return isObject() && !!(data & 1);
|
||||
}
|
||||
|
||||
JSObject *singleObject() const {
|
||||
JS_ASSERT(isSingleObject());
|
||||
return (JSObject *) (data ^ 1);
|
||||
}
|
||||
inline JSObject *singleObject() const;
|
||||
|
||||
/* Accessors for TypeObject types */
|
||||
|
||||
@ -129,10 +123,7 @@ class Type
|
||||
return isObject() && !(data & 1);
|
||||
}
|
||||
|
||||
TypeObject *typeObject() const {
|
||||
JS_ASSERT(isTypeObject());
|
||||
return (TypeObject *) data;
|
||||
}
|
||||
inline TypeObject *typeObject() const;
|
||||
|
||||
bool operator == (Type o) const { return data == o.data; }
|
||||
bool operator != (Type o) const { return data != o.data; }
|
||||
|
@ -1014,6 +1014,33 @@ HashSetLookup(U **values, unsigned count, T key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline TypeObjectKey *
|
||||
Type::objectKey() const
|
||||
{
|
||||
JS_ASSERT(isObject());
|
||||
if (isTypeObject())
|
||||
TypeObject::readBarrier((TypeObject *) data);
|
||||
else
|
||||
JSObject::readBarrier((JSObject *) (data ^ 1));
|
||||
return (TypeObjectKey *) data;
|
||||
}
|
||||
|
||||
inline JSObject *
|
||||
Type::singleObject() const
|
||||
{
|
||||
JS_ASSERT(isSingleObject());
|
||||
JSObject::readBarrier((JSObject *) (data ^ 1));
|
||||
return (JSObject *) (data ^ 1);
|
||||
}
|
||||
|
||||
inline TypeObject *
|
||||
Type::typeObject() const
|
||||
{
|
||||
JS_ASSERT(isTypeObject());
|
||||
TypeObject::readBarrier((TypeObject *) data);
|
||||
return (TypeObject *) data;
|
||||
}
|
||||
|
||||
inline bool
|
||||
TypeSet::hasType(Type type)
|
||||
{
|
||||
|
@ -4249,9 +4249,7 @@ END_CASE(JSOP_ARRAYPUSH)
|
||||
|
||||
forced_return:
|
||||
UnwindScope(cx, 0);
|
||||
regs.sp = regs.fp()->base();
|
||||
regs.pc = script->code + script->length - JSOP_STOP_LENGTH;
|
||||
JS_ASSERT(*regs.pc == JSOP_STOP);
|
||||
regs.setToEndOfScript();
|
||||
|
||||
if (entryFrame != regs.fp())
|
||||
goto inline_return;
|
||||
|
@ -455,11 +455,6 @@ js::num_parseInt(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
const char js_isNaN_str[] = "isNaN";
|
||||
const char js_isFinite_str[] = "isFinite";
|
||||
const char js_parseFloat_str[] = "parseFloat";
|
||||
const char js_parseInt_str[] = "parseInt";
|
||||
|
||||
static JSFunctionSpec number_functions[] = {
|
||||
JS_FN(js_isNaN_str, num_isNaN, 1,0),
|
||||
JS_FN(js_isFinite_str, num_isFinite, 1,0),
|
||||
|
@ -1392,11 +1392,6 @@ js_PropertyIsEnumerable(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
||||
|
||||
#if OLD_GETTER_SETTER_METHODS
|
||||
|
||||
const char js_defineGetter_str[] = "__defineGetter__";
|
||||
const char js_defineSetter_str[] = "__defineSetter__";
|
||||
const char js_lookupGetter_str[] = "__lookupGetter__";
|
||||
const char js_lookupSetter_str[] = "__lookupSetter__";
|
||||
|
||||
enum DefineType { Getter, Setter };
|
||||
|
||||
template<DefineType Type>
|
||||
@ -2674,14 +2669,6 @@ obj_isSealed(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
#if JS_HAS_OBJ_WATCHPOINT
|
||||
const char js_watch_str[] = "watch";
|
||||
const char js_unwatch_str[] = "unwatch";
|
||||
#endif
|
||||
const char js_hasOwnProperty_str[] = "hasOwnProperty";
|
||||
const char js_isPrototypeOf_str[] = "isPrototypeOf";
|
||||
const char js_propertyIsEnumerable_str[] = "propertyIsEnumerable";
|
||||
|
||||
JSFunctionSpec object_methods[] = {
|
||||
#if JS_HAS_TOSOURCE
|
||||
JS_FN(js_toSource_str, obj_toSource, 0,0),
|
||||
|
@ -372,16 +372,6 @@ str_uneval(JSContext *cx, unsigned argc, Value *vp)
|
||||
}
|
||||
#endif
|
||||
|
||||
const char js_escape_str[] = "escape";
|
||||
const char js_unescape_str[] = "unescape";
|
||||
#if JS_HAS_UNEVAL
|
||||
const char js_uneval_str[] = "uneval";
|
||||
#endif
|
||||
const char js_decodeURI_str[] = "decodeURI";
|
||||
const char js_encodeURI_str[] = "encodeURI";
|
||||
const char js_decodeURIComponent_str[] = "decodeURIComponent";
|
||||
const char js_encodeURIComponent_str[] = "encodeURIComponent";
|
||||
|
||||
static JSFunctionSpec string_functions[] = {
|
||||
JS_FN(js_escape_str, str_escape, 1,0),
|
||||
JS_FN(js_unescape_str, str_unescape, 1,0),
|
||||
|
@ -139,8 +139,6 @@ js_LeaveLocalRootScopeWithResult(JSContext *cx, void *rval)
|
||||
* Random utilities and global functions.
|
||||
*/
|
||||
const char js_AttributeName_str[] = "AttributeName";
|
||||
const char js_isXMLName_str[] = "isXMLName";
|
||||
const char js_XMLList_str[] = "XMLList";
|
||||
const char js_localName_str[] = "localName";
|
||||
const char js_xml_parent_str[] = "parent";
|
||||
const char js_prefix_str[] = "prefix";
|
||||
|
@ -565,7 +565,7 @@ js_InternalThrow(VMFrame &f)
|
||||
// property.
|
||||
JS_ASSERT(!f.fp()->finishedInInterpreter());
|
||||
UnwindScope(cx, 0);
|
||||
f.regs.sp = f.fp()->base();
|
||||
f.regs.setToEndOfScript();
|
||||
|
||||
if (cx->compartment->debugMode()) {
|
||||
// This can turn a throw or error into a healthy return. Note that
|
||||
|
@ -1076,6 +1076,9 @@ mjit::EnterMethodJIT(JSContext *cx, StackFrame *fp, void *code, Value *stackLimi
|
||||
return ok ? Jaeger_Returned : Jaeger_Throwing;
|
||||
}
|
||||
|
||||
cx->regs().refreshFramePointer(fp);
|
||||
cx->regs().setToEndOfScript();
|
||||
|
||||
/* The entry frame should have finished. */
|
||||
JS_ASSERT(fp == cx->fp());
|
||||
|
||||
|
@ -484,11 +484,16 @@ StackSpace::markFrameSlots(JSTracer *trc, StackFrame *fp, Value *slotsEnd, jsbyt
|
||||
for (Value *vp = slotsBegin; vp < fixedEnd; vp++) {
|
||||
uint32_t slot = analyze::LocalSlot(script, vp - slotsBegin);
|
||||
|
||||
/* Will this slot be synced by the JIT? */
|
||||
/*
|
||||
* Will this slot be synced by the JIT? If not, replace with a dummy
|
||||
* value with the same type tag.
|
||||
*/
|
||||
if (!analysis->trackSlot(slot) || analysis->liveness(slot).live(offset))
|
||||
gc::MarkValueRoot(trc, vp, "vm_stack");
|
||||
else
|
||||
*vp = UndefinedValue();
|
||||
else if (vp->isObject())
|
||||
*vp = ObjectValue(fp->scopeChain()->global());
|
||||
else if (vp->isString())
|
||||
*vp = StringValue(trc->runtime->atomState.nullAtom);
|
||||
}
|
||||
|
||||
gc::MarkValueRootRange(trc, fixedEnd, slotsEnd, "vm_stack");
|
||||
|
@ -42,6 +42,7 @@
|
||||
#define Stack_h__
|
||||
|
||||
#include "jsfun.h"
|
||||
#include "jsautooplen.h"
|
||||
|
||||
struct JSContext;
|
||||
struct JSCompartment;
|
||||
@ -1288,6 +1289,11 @@ class FrameRegs
|
||||
fp_ = (StackFrame *) newfp;
|
||||
}
|
||||
|
||||
/* For EnterMethodJIT: */
|
||||
void refreshFramePointer(StackFrame *fp) {
|
||||
fp_ = fp;
|
||||
}
|
||||
|
||||
/* For stubs::CompileFunction, ContextStack: */
|
||||
void prepareToRun(StackFrame &fp, JSScript *script) {
|
||||
pc = script->code;
|
||||
@ -1296,6 +1302,13 @@ class FrameRegs
|
||||
inlined_ = NULL;
|
||||
}
|
||||
|
||||
void setToEndOfScript() {
|
||||
JSScript *script = fp()->script();
|
||||
sp = fp()->base();
|
||||
pc = script->code + script->length - JSOP_STOP_LENGTH;
|
||||
JS_ASSERT(*pc == JSOP_STOP);
|
||||
}
|
||||
|
||||
/* For pushDummyFrame: */
|
||||
void initDummyFrame(StackFrame &fp) {
|
||||
pc = NULL;
|
||||
|
@ -3097,6 +3097,11 @@ bool BindPropertyOp(JSContext *cx, JSObject *targetObj, Op& op,
|
||||
return true;
|
||||
}
|
||||
|
||||
extern JSBool
|
||||
XPC_WN_Helper_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
|
||||
extern JSBool
|
||||
XPC_WN_Helper_SetProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
|
||||
|
||||
bool
|
||||
xpc::SandboxProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy,
|
||||
jsid id, bool set,
|
||||
@ -3120,10 +3125,16 @@ xpc::SandboxProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy,
|
||||
// ops can in theory rely on, but our property op forwarder doesn't know how
|
||||
// to make that happen. Since we really only need to rebind the DOM methods
|
||||
// here, not rebindings holder_get and holder_set is OK.
|
||||
//
|
||||
// Similarly, don't mess with XPC_WN_Helper_GetProperty and
|
||||
// XPC_WN_Helper_SetProperty, for the same reasons: that could confuse our
|
||||
// access to expandos when we're not doing Xrays.
|
||||
if (desc->getter != xpc::holder_get &&
|
||||
desc->getter != XPC_WN_Helper_GetProperty &&
|
||||
!BindPropertyOp(cx, obj, desc->getter, desc, id, JSPROP_GETTER))
|
||||
return false;
|
||||
if (desc->setter != xpc::holder_set &&
|
||||
desc->setter != XPC_WN_Helper_SetProperty &&
|
||||
!BindPropertyOp(cx, obj, desc->setter, desc, id, JSPROP_SETTER))
|
||||
return false;
|
||||
if (desc->value.isObject()) {
|
||||
|
@ -977,19 +977,17 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
flat = cache->GetWrapper();
|
||||
}
|
||||
|
||||
XPCCallContext &ccx = lccx.GetXPCCallContext();
|
||||
if (!ccx.IsValid())
|
||||
return false;
|
||||
|
||||
// We can't simply construct a slim wrapper. Go ahead and create an
|
||||
// XPCWrappedNative for this object. At this point, |flat| could be
|
||||
// non-null, meaning that either we already have a wrapped native from
|
||||
// the cache (which might need to be QI'd to the new interface) or that
|
||||
// we found a slim wrapper that we'll have to morph.
|
||||
AutoMarkingNativeInterfacePtr iface;
|
||||
AutoMarkingNativeInterfacePtr iface(ccx);
|
||||
if (iid) {
|
||||
XPCCallContext &ccx = lccx.GetXPCCallContext();
|
||||
if (!ccx.IsValid())
|
||||
return false;
|
||||
|
||||
iface.Init(ccx);
|
||||
|
||||
if (Interface)
|
||||
iface = *Interface;
|
||||
|
||||
@ -1010,10 +1008,6 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
XPCWrappedNative* wrapper;
|
||||
nsRefPtr<XPCWrappedNative> strongWrapper;
|
||||
if (!flat) {
|
||||
XPCCallContext &ccx = lccx.GetXPCCallContext();
|
||||
if (!ccx.IsValid())
|
||||
return false;
|
||||
|
||||
rv = XPCWrappedNative::GetNewOrUsed(ccx, aHelper, xpcscope, iface,
|
||||
getter_AddRefs(strongWrapper));
|
||||
|
||||
@ -1030,18 +1024,13 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
// a valid XPCCallContext because we checked when calling Init on
|
||||
// iface.
|
||||
if (iface)
|
||||
wrapper->FindTearOff(lccx.GetXPCCallContext(), iface, false,
|
||||
&rv);
|
||||
wrapper->FindTearOff(ccx, iface, false, &rv);
|
||||
else
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
NS_ASSERTION(IS_SLIM_WRAPPER(flat),
|
||||
"What kind of wrapper is this?");
|
||||
|
||||
XPCCallContext &ccx = lccx.GetXPCCallContext();
|
||||
if (!ccx.IsValid())
|
||||
return false;
|
||||
|
||||
SLIM_LOG(("***** morphing from XPCConvert::NativeInterface2JSObject"
|
||||
"(%p)\n",
|
||||
static_cast<nsISupports*>(xpc_GetJSPrivate(flat))));
|
||||
@ -1072,10 +1061,6 @@ XPCConvert::NativeInterface2JSObject(XPCLazyCallContext& lccx,
|
||||
return true;
|
||||
}
|
||||
|
||||
XPCCallContext &ccx = lccx.GetXPCCallContext();
|
||||
if (!ccx.IsValid())
|
||||
return false;
|
||||
|
||||
JSObject *original = flat;
|
||||
if (!JS_WrapObject(ccx, &flat))
|
||||
return false;
|
||||
|
@ -568,7 +568,7 @@ inline void XPCNativeSet::ASSERT_NotMarked()
|
||||
inline
|
||||
JSObject* XPCWrappedNativeTearOff::GetJSObjectPreserveColor() const
|
||||
{
|
||||
return mJSObject;
|
||||
return reinterpret_cast<JSObject *>(reinterpret_cast<uintptr_t>(mJSObject) & ~1);
|
||||
}
|
||||
|
||||
inline
|
||||
@ -582,6 +582,7 @@ JSObject* XPCWrappedNativeTearOff::GetJSObject()
|
||||
inline
|
||||
void XPCWrappedNativeTearOff::SetJSObject(JSObject* JSObj)
|
||||
{
|
||||
MOZ_ASSERT(!IsMarked());
|
||||
mJSObject = JSObj;
|
||||
}
|
||||
|
||||
|
@ -299,8 +299,7 @@ XPCPerThreadData::XPCPerThreadData()
|
||||
void
|
||||
XPCPerThreadData::Cleanup()
|
||||
{
|
||||
while (mAutoRoots)
|
||||
mAutoRoots->Unlink();
|
||||
MOZ_ASSERT(!mAutoRoots);
|
||||
NS_IF_RELEASE(mExceptionManager);
|
||||
NS_IF_RELEASE(mException);
|
||||
delete mJSContextStack;
|
||||
@ -369,13 +368,13 @@ void XPCPerThreadData::TraceJS(JSTracer *trc)
|
||||
#endif
|
||||
|
||||
if (mAutoRoots)
|
||||
mAutoRoots->TraceJS(trc);
|
||||
mAutoRoots->TraceJSAll(trc);
|
||||
}
|
||||
|
||||
void XPCPerThreadData::MarkAutoRootsAfterJSFinalize()
|
||||
{
|
||||
if (mAutoRoots)
|
||||
mAutoRoots->MarkAfterJSFinalize();
|
||||
mAutoRoots->MarkAfterJSFinalizeAll();
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -648,19 +648,7 @@ XPC_WN_NoHelper_Finalize(js::FreeOp *fop, JSObject *obj)
|
||||
static void
|
||||
TraceScopeJSObjects(JSTracer *trc, XPCWrappedNativeScope* scope)
|
||||
{
|
||||
NS_ASSERTION(scope, "bad scope");
|
||||
|
||||
JSObject* obj;
|
||||
|
||||
obj = scope->GetGlobalJSObjectPreserveColor();
|
||||
NS_ASSERTION(obj, "bad scope JSObject");
|
||||
JS_CALL_OBJECT_TRACER(trc, obj, "XPCWrappedNativeScope::mGlobalJSObject");
|
||||
|
||||
obj = scope->GetPrototypeJSObjectPreserveColor();
|
||||
if (obj) {
|
||||
JS_CALL_OBJECT_TRACER(trc, obj,
|
||||
"XPCWrappedNativeScope::mPrototypeJSObject");
|
||||
}
|
||||
scope->TraceSelf(trc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -965,7 +953,7 @@ XPC_WN_Helper_DelProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
POST_HELPER_STUB
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JSBool
|
||||
XPC_WN_Helper_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
PRE_HELPER_STUB
|
||||
@ -973,7 +961,7 @@ XPC_WN_Helper_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
POST_HELPER_STUB
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JSBool
|
||||
XPC_WN_Helper_SetProperty(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
|
||||
{
|
||||
PRE_HELPER_STUB
|
||||
|
@ -41,6 +41,82 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
* XPConnect allows JS code to manipulate C++ object and C++ code to manipulate
|
||||
* JS objects. JS manipulation of C++ objects tends to be significantly more
|
||||
* complex. This comment explains how it is orchestrated by XPConnect.
|
||||
*
|
||||
* For each C++ object to be manipulated in JS, there is a corresponding JS
|
||||
* object. This is called the "flattened JS object". By default, there is an
|
||||
* additional C++ object involved of type XPCWrappedNative. The XPCWrappedNative
|
||||
* holds pointers to the C++ object and the flat JS object.
|
||||
*
|
||||
* As an optimization, some C++ objects don't have XPCWrappedNatives, although
|
||||
* they still have a corresponding flattened JS object. These are called "slim
|
||||
* wrappers": all the wrapping information is stored in extra fields of the C++
|
||||
* object and the JS object. Slim wrappers are only used for DOM objects. As a
|
||||
* deoptimization, slim wrappers can be "morphed" into XPCWrappedNatives if the
|
||||
* extra fields of the XPCWrappedNative become necessary.
|
||||
*
|
||||
* All XPCWrappedNative objects belong to an XPCWrappedNativeScope. These scopes
|
||||
* are essentially in 1:1 correspondence with JS global objects. The
|
||||
* XPCWrappedNativeScope has a pointer to the JS global object. The parent of a
|
||||
* flattened JS object is, by default, the global JS object corresponding to the
|
||||
* wrapper's XPCWrappedNativeScope (the exception to this rule is when a
|
||||
* PreCreate hook asks for a different parent; see nsIXPCScriptable below).
|
||||
*
|
||||
* Some C++ objects (notably DOM objects) have information associated with them
|
||||
* that lists the interfaces implemented by these objects. A C++ object exposes
|
||||
* this information by implementing nsIClassInfo. If a C++ object implements
|
||||
* nsIClassInfo, then JS code can call its methods without needing to use
|
||||
* QueryInterface first. Typically, all instances of a C++ class share the same
|
||||
* nsIClassInfo instance. (That is, obj->QueryInterface(nsIClassInfo) returns
|
||||
* the same result for every obj of a given class.)
|
||||
*
|
||||
* XPConnect tracks nsIClassInfo information in an XPCWrappedNativeProto object.
|
||||
* A given XPCWrappedNativeScope will have one XPCWrappedNativeProto for each
|
||||
* nsIClassInfo instance being used. The XPCWrappedNativeProto has an associated
|
||||
* JS object, which is used as the prototype of all flattened JS objects created
|
||||
* for C++ objects with the given nsIClassInfo.
|
||||
*
|
||||
* Each XPCWrappedNativeProto has a pointer to its XPCWrappedNativeScope. If an
|
||||
* XPCWrappedNative wraps a C++ object with class info, then it points to its
|
||||
* XPCWrappedNativeProto. Otherwise it points to its XPCWrappedNativeScope. (The
|
||||
* pointers are smooshed together in a tagged union.) Either way it can reach
|
||||
* its scope.
|
||||
*
|
||||
* In the case of slim wrappers (where there is no XPCWrappedNative), the
|
||||
* flattened JS object has a pointer to the XPCWrappedNativeProto stored in a
|
||||
* reserved slot.
|
||||
*
|
||||
* An XPCWrappedNativeProto keeps track of the set of interfaces implemented by
|
||||
* the C++ object in an XPCNativeSet. (The list of interfaces is obtained by
|
||||
* calling a method on the nsIClassInfo.) An XPCNativeSet is a collection of
|
||||
* XPCNativeInterfaces. Each interface stores the list of members, which can be
|
||||
* methods, constants, getters, or setters.
|
||||
*
|
||||
* An XPCWrappedNative also points to an XPCNativeSet. Initially this starts out
|
||||
* the same as the XPCWrappedNativeProto's set. If there is no proto, it starts
|
||||
* out as a singleton set containing nsISupports. If JS code QI's new interfaces
|
||||
* outside of the existing set, the set will grow. All QueryInterface results
|
||||
* are cached in XPCWrappedNativeTearOff objects, which are linked off of the
|
||||
* XPCWrappedNative.
|
||||
*
|
||||
* Besides having class info, a C++ object may be "scriptable" (i.e., implement
|
||||
* nsIXPCScriptable). This allows it to implement a more DOM-like interface,
|
||||
* besides just exposing XPCOM methods and constants. An nsIXPCScriptable
|
||||
* instance has hooks that correspond to all the normal JSClass hooks. Each
|
||||
* nsIXPCScriptable instance is mirrored by an XPCNativeScriptableInfo in
|
||||
* XPConnect. These can have pointers from XPCWrappedNativeProto and
|
||||
* XPCWrappedNative (since C++ objects can have scriptable info without having
|
||||
* class info).
|
||||
*
|
||||
* Most data in an XPCNativeScriptableInfo is shared between instances. The
|
||||
* shared data is stored in an XPCNativeScriptableShared object. This type is
|
||||
* important because it holds the JSClass of the flattened JS objects with the
|
||||
* given scriptable info.
|
||||
*/
|
||||
|
||||
/* All the XPConnect private declarations - only include locally. */
|
||||
|
||||
#ifndef xpcprivate_h___
|
||||
@ -1497,6 +1573,16 @@ public:
|
||||
static void
|
||||
TraceJS(JSTracer* trc, XPCJSRuntime* rt);
|
||||
|
||||
void TraceSelf(JSTracer *trc) {
|
||||
JSObject *obj = GetGlobalJSObjectPreserveColor();
|
||||
MOZ_ASSERT(obj);
|
||||
JS_CALL_OBJECT_TRACER(trc, obj, "XPCWrappedNativeScope::mGlobalJSObject");
|
||||
|
||||
JSObject *proto = GetPrototypeJSObjectPreserveColor();
|
||||
if (proto)
|
||||
JS_CALL_OBJECT_TRACER(trc, proto, "XPCWrappedNativeScope::mPrototypeJSObject");
|
||||
}
|
||||
|
||||
static void
|
||||
SuspectAllWrappers(XPCJSRuntime* rt, nsCycleCollectionTraversalCallback &cb);
|
||||
|
||||
@ -1722,19 +1808,29 @@ public:
|
||||
|
||||
inline JSBool HasAncestor(const nsIID* iid) const;
|
||||
|
||||
PRUint16 GetMemberCount() const
|
||||
{NS_ASSERTION(!IsMarked(), "bad"); return mMemberCount;}
|
||||
XPCNativeMember* GetMemberAt(PRUint16 i)
|
||||
{NS_ASSERTION(i < mMemberCount, "bad index"); return &mMembers[i];}
|
||||
PRUint16 GetMemberCount() const {
|
||||
return mMemberCount;
|
||||
}
|
||||
XPCNativeMember* GetMemberAt(PRUint16 i) {
|
||||
NS_ASSERTION(i < mMemberCount, "bad index");
|
||||
return &mMembers[i];
|
||||
}
|
||||
|
||||
void DebugDump(PRInt16 depth);
|
||||
|
||||
#define XPC_NATIVE_IFACE_MARK_FLAG ((PRUint16)JS_BIT(15)) // only high bit of 16 is set
|
||||
|
||||
void Mark() {mMemberCount |= XPC_NATIVE_IFACE_MARK_FLAG;}
|
||||
void Unmark() {mMemberCount &= ~XPC_NATIVE_IFACE_MARK_FLAG;}
|
||||
JSBool IsMarked() const
|
||||
{return 0 != (mMemberCount & XPC_NATIVE_IFACE_MARK_FLAG);}
|
||||
void Mark() {
|
||||
mMarked = 1;
|
||||
}
|
||||
|
||||
void Unmark() {
|
||||
mMarked = 0;
|
||||
}
|
||||
|
||||
bool IsMarked() const {
|
||||
return mMarked != 0;
|
||||
}
|
||||
|
||||
// NOP. This is just here to make the AutoMarkingPtr code compile.
|
||||
inline void TraceJS(JSTracer* trc) {}
|
||||
@ -1750,9 +1846,13 @@ protected:
|
||||
|
||||
XPCNativeInterface(); // not implemented
|
||||
XPCNativeInterface(nsIInterfaceInfo* aInfo, jsid aName)
|
||||
: mInfo(aInfo), mName(aName), mMemberCount(0)
|
||||
{MOZ_COUNT_CTOR(XPCNativeInterface);}
|
||||
~XPCNativeInterface() {MOZ_COUNT_DTOR(XPCNativeInterface);}
|
||||
: mInfo(aInfo), mName(aName), mMemberCount(0), mMarked(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(XPCNativeInterface);
|
||||
}
|
||||
~XPCNativeInterface() {
|
||||
MOZ_COUNT_DTOR(XPCNativeInterface);
|
||||
}
|
||||
|
||||
void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
|
||||
|
||||
@ -1762,7 +1862,8 @@ protected:
|
||||
private:
|
||||
nsCOMPtr<nsIInterfaceInfo> mInfo;
|
||||
jsid mName;
|
||||
PRUint16 mMemberCount;
|
||||
PRUint16 mMemberCount : 15;
|
||||
PRUint16 mMarked : 1;
|
||||
XPCNativeMember mMembers[1]; // always last - object sized for array
|
||||
};
|
||||
|
||||
@ -1864,10 +1965,15 @@ public:
|
||||
|
||||
inline XPCNativeInterface* FindNamedInterface(jsid name) const;
|
||||
|
||||
PRUint16 GetMemberCount() const {return mMemberCount;}
|
||||
PRUint16 GetInterfaceCount() const
|
||||
{NS_ASSERTION(!IsMarked(), "bad"); return mInterfaceCount;}
|
||||
XPCNativeInterface** GetInterfaceArray() {return mInterfaces;}
|
||||
PRUint16 GetMemberCount() const {
|
||||
return mMemberCount;
|
||||
}
|
||||
PRUint16 GetInterfaceCount() const {
|
||||
return mInterfaceCount;
|
||||
}
|
||||
XPCNativeInterface **GetInterfaceArray() {
|
||||
return mInterfaces;
|
||||
}
|
||||
|
||||
XPCNativeInterface* GetInterfaceAt(PRUint16 i)
|
||||
{NS_ASSERTION(i < mInterfaceCount, "bad index"); return mInterfaces[i];}
|
||||
@ -1884,11 +1990,17 @@ public:
|
||||
inline void AutoTrace(JSTracer* trc) {}
|
||||
|
||||
private:
|
||||
void MarkSelfOnly() {mInterfaceCount |= XPC_NATIVE_SET_MARK_FLAG;}
|
||||
void MarkSelfOnly() {
|
||||
mMarked = 1;
|
||||
}
|
||||
|
||||
public:
|
||||
void Unmark() {mInterfaceCount &= ~XPC_NATIVE_SET_MARK_FLAG;}
|
||||
JSBool IsMarked() const
|
||||
{return 0 != (mInterfaceCount & XPC_NATIVE_SET_MARK_FLAG);}
|
||||
void Unmark() {
|
||||
mMarked = 0;
|
||||
}
|
||||
bool IsMarked() const {
|
||||
return !!mMarked;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
inline void ASSERT_NotMarked();
|
||||
@ -1907,13 +2019,20 @@ protected:
|
||||
static XPCNativeSet* NewInstanceMutate(XPCNativeSet* otherSet,
|
||||
XPCNativeInterface* newInterface,
|
||||
PRUint16 position);
|
||||
XPCNativeSet() {MOZ_COUNT_CTOR(XPCNativeSet);}
|
||||
~XPCNativeSet() {MOZ_COUNT_DTOR(XPCNativeSet);}
|
||||
XPCNativeSet()
|
||||
: mMemberCount(0), mInterfaceCount(0), mMarked(0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(XPCNativeSet);
|
||||
}
|
||||
~XPCNativeSet() {
|
||||
MOZ_COUNT_DTOR(XPCNativeSet);
|
||||
}
|
||||
void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
|
||||
|
||||
private:
|
||||
PRUint16 mMemberCount;
|
||||
PRUint16 mInterfaceCount;
|
||||
PRUint16 mInterfaceCount : 15;
|
||||
PRUint16 mMarked : 1;
|
||||
XPCNativeInterface* mInterfaces[1]; // always last - object sized for array
|
||||
};
|
||||
|
||||
@ -2254,15 +2373,23 @@ public:
|
||||
|
||||
void DebugDump(PRInt16 depth);
|
||||
|
||||
void TraceJS(JSTracer* trc)
|
||||
{
|
||||
if (mJSProtoObject) {
|
||||
JS_CALL_OBJECT_TRACER(trc, mJSProtoObject,
|
||||
"XPCWrappedNativeProto::mJSProtoObject");
|
||||
void TraceSelf(JSTracer *trc) {
|
||||
if (mJSProtoObject)
|
||||
JS_CALL_OBJECT_TRACER(trc, mJSProtoObject, "XPCWrappedNativeProto::mJSProtoObject");
|
||||
}
|
||||
if (mScriptableInfo && JS_IsGCMarkingTracer(trc))
|
||||
|
||||
void TraceInside(JSTracer *trc) {
|
||||
if (JS_IsGCMarkingTracer(trc)) {
|
||||
mSet->Mark();
|
||||
if (mScriptableInfo)
|
||||
mScriptableInfo->Mark();
|
||||
}
|
||||
}
|
||||
|
||||
void TraceJS(JSTracer *trc) {
|
||||
TraceSelf(trc);
|
||||
TraceInside(trc);
|
||||
}
|
||||
|
||||
void WriteBarrierPre(JSRuntime* rt)
|
||||
{
|
||||
@ -2638,22 +2765,29 @@ public:
|
||||
}
|
||||
|
||||
// Yes, we *do* need to mark the mScriptableInfo in both cases.
|
||||
inline void TraceJS(JSTracer* trc)
|
||||
{
|
||||
if (mScriptableInfo && JS_IsGCMarkingTracer(trc))
|
||||
inline void TraceInside(JSTracer *trc) {
|
||||
if (JS_IsGCMarkingTracer(trc)) {
|
||||
mSet->Mark();
|
||||
if (mScriptableInfo)
|
||||
mScriptableInfo->Mark();
|
||||
if (HasProto()) GetProto()->TraceJS(trc);
|
||||
}
|
||||
if (HasProto())
|
||||
GetProto()->TraceJS(trc);
|
||||
JSObject* wrapper = GetWrapperPreserveColor();
|
||||
if (wrapper)
|
||||
JS_CALL_OBJECT_TRACER(trc, wrapper, "XPCWrappedNative::mWrapper");
|
||||
if (mScriptableInfo &&
|
||||
(mScriptableInfo->GetJSClass()->flags & JSCLASS_XPCONNECT_GLOBAL))
|
||||
{
|
||||
TraceXPCGlobal(trc, mFlatJSObject);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inline void AutoTrace(JSTracer* trc)
|
||||
{
|
||||
void TraceJS(JSTracer *trc) {
|
||||
TraceInside(trc);
|
||||
}
|
||||
|
||||
void TraceSelf(JSTracer *trc) {
|
||||
// If this got called, we're being kept alive by someone who really
|
||||
// needs us alive and whole. Do not let our mFlatJSObject go away.
|
||||
// This is the only time we should be tracing our mFlatJSObject,
|
||||
@ -2665,6 +2799,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void AutoTrace(JSTracer *trc) {
|
||||
TraceSelf(trc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void ASSERT_SetsNotMarked() const
|
||||
{mSet->ASSERT_NotMarked();
|
||||
@ -4021,139 +4159,126 @@ private:
|
||||
class AutoMarkingPtr
|
||||
{
|
||||
public:
|
||||
AutoMarkingPtr(XPCCallContext& ccx)
|
||||
: mNext(nsnull), mTLS(ccx.GetThreadData()) {Link();}
|
||||
AutoMarkingPtr()
|
||||
: mNext(nsnull), mTLS(nsnull) {}
|
||||
|
||||
virtual ~AutoMarkingPtr() {Unlink();}
|
||||
|
||||
void Init(XPCCallContext& ccx)
|
||||
{NS_ASSERTION(!mTLS, "Already init'ed!");
|
||||
mTLS = ccx.GetThreadData();
|
||||
Link();}
|
||||
|
||||
void Link()
|
||||
{if (!mTLS) return;
|
||||
AutoMarkingPtr** list = mTLS->GetAutoRootsAdr();
|
||||
mNext = *list; *list = this;}
|
||||
|
||||
void Unlink()
|
||||
{if (!mTLS) return;
|
||||
AutoMarkingPtr** cur = mTLS->GetAutoRootsAdr();
|
||||
while (*cur != this) {
|
||||
NS_ASSERTION(*cur, "This object not in list!");
|
||||
cur = &(*cur)->mNext;
|
||||
}
|
||||
*cur = mNext;
|
||||
mTLS = nsnull;
|
||||
AutoMarkingPtr(XPCCallContext& ccx) {
|
||||
mRoot = ccx.GetThreadData()->GetAutoRootsAdr();
|
||||
mNext = *mRoot;
|
||||
*mRoot = this;
|
||||
}
|
||||
|
||||
AutoMarkingPtr* GetNext() {return mNext;}
|
||||
virtual ~AutoMarkingPtr() {
|
||||
if (mRoot) {
|
||||
MOZ_ASSERT(*mRoot == this);
|
||||
*mRoot = mNext;
|
||||
}
|
||||
}
|
||||
|
||||
void TraceJSAll(JSTracer* trc) {
|
||||
for (AutoMarkingPtr *cur = this; cur; cur = cur->mNext)
|
||||
cur->TraceJS(trc);
|
||||
}
|
||||
|
||||
void MarkAfterJSFinalizeAll() {
|
||||
for (AutoMarkingPtr *cur = this; cur; cur = cur->mNext)
|
||||
cur->MarkAfterJSFinalize();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void TraceJS(JSTracer* trc) = 0;
|
||||
virtual void MarkAfterJSFinalize() = 0;
|
||||
|
||||
protected:
|
||||
private:
|
||||
AutoMarkingPtr** mRoot;
|
||||
AutoMarkingPtr* mNext;
|
||||
XPCPerThreadData* mTLS;
|
||||
};
|
||||
|
||||
// More joy of macros...
|
||||
template<class T>
|
||||
class TypedAutoMarkingPtr : public AutoMarkingPtr
|
||||
{
|
||||
public:
|
||||
TypedAutoMarkingPtr(XPCCallContext& ccx) : AutoMarkingPtr(ccx), mPtr(nsnull) {}
|
||||
TypedAutoMarkingPtr(XPCCallContext& ccx, T* ptr) : AutoMarkingPtr(ccx), mPtr(ptr) {}
|
||||
|
||||
#define DEFINE_AUTO_MARKING_PTR_TYPE(class_, type_) \
|
||||
class class_ : public AutoMarkingPtr \
|
||||
{ \
|
||||
public: \
|
||||
class_ () \
|
||||
: AutoMarkingPtr(), mPtr(nsnull) {} \
|
||||
class_ (XPCCallContext& ccx, type_ * ptr = nsnull) \
|
||||
: AutoMarkingPtr(ccx), mPtr(ptr) {} \
|
||||
virtual ~ class_ () {} \
|
||||
\
|
||||
virtual void TraceJS(JSTracer* trc) \
|
||||
{if (mPtr) { \
|
||||
mPtr->TraceJS(trc); \
|
||||
mPtr->AutoTrace(trc); \
|
||||
} \
|
||||
if (mNext) mNext->TraceJS(trc);} \
|
||||
\
|
||||
virtual void MarkAfterJSFinalize() \
|
||||
{if (mPtr) mPtr->Mark(); \
|
||||
if (mNext) mNext->MarkAfterJSFinalize();} \
|
||||
\
|
||||
type_ * get() const {return mPtr;} \
|
||||
operator type_ *() const {return mPtr;} \
|
||||
type_ * operator->() const {return mPtr;} \
|
||||
\
|
||||
class_ & operator =(type_ * p) \
|
||||
{NS_ASSERTION(mTLS, "Hasn't been init'ed!"); \
|
||||
mPtr = p; return *this;} \
|
||||
\
|
||||
protected: \
|
||||
type_ * mPtr; \
|
||||
T* get() const { return mPtr; }
|
||||
operator T *() const { return mPtr; }
|
||||
T* operator->() const { return mPtr; }
|
||||
|
||||
TypedAutoMarkingPtr<T>& operator =(T* ptr) { mPtr = ptr; return *this; }
|
||||
|
||||
protected:
|
||||
virtual void TraceJS(JSTracer* trc)
|
||||
{
|
||||
if (mPtr) {
|
||||
mPtr->TraceJS(trc);
|
||||
mPtr->AutoTrace(trc);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MarkAfterJSFinalize()
|
||||
{
|
||||
if (mPtr)
|
||||
mPtr->Mark();
|
||||
}
|
||||
|
||||
private:
|
||||
T* mPtr;
|
||||
};
|
||||
|
||||
// Use the macro above to define our AutoMarking types...
|
||||
typedef TypedAutoMarkingPtr<XPCNativeInterface> AutoMarkingNativeInterfacePtr;
|
||||
typedef TypedAutoMarkingPtr<XPCNativeSet> AutoMarkingNativeSetPtr;
|
||||
typedef TypedAutoMarkingPtr<XPCWrappedNative> AutoMarkingWrappedNativePtr;
|
||||
typedef TypedAutoMarkingPtr<XPCWrappedNativeTearOff> AutoMarkingWrappedNativeTearOffPtr;
|
||||
typedef TypedAutoMarkingPtr<XPCWrappedNativeProto> AutoMarkingWrappedNativeProtoPtr;
|
||||
typedef TypedAutoMarkingPtr<XPCMarkableJSVal> AutoMarkingJSVal;
|
||||
|
||||
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeInterfacePtr, XPCNativeInterface)
|
||||
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeSetPtr, XPCNativeSet)
|
||||
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativePtr, XPCWrappedNative)
|
||||
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeTearOffPtr, XPCWrappedNativeTearOff)
|
||||
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeProtoPtr, XPCWrappedNativeProto)
|
||||
DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingJSVal, XPCMarkableJSVal)
|
||||
template<class T>
|
||||
class ArrayAutoMarkingPtr : public AutoMarkingPtr
|
||||
{
|
||||
public:
|
||||
ArrayAutoMarkingPtr(XPCCallContext& ccx)
|
||||
: AutoMarkingPtr(ccx), mPtr(nsnull), mCount(0) {}
|
||||
ArrayAutoMarkingPtr(XPCCallContext& ccx, T** ptr, PRUint32 count, bool clear)
|
||||
: AutoMarkingPtr(ccx), mPtr(ptr), mCount(count)
|
||||
{
|
||||
if (!mPtr) mCount = 0;
|
||||
else if (clear) memset(mPtr, 0, mCount*sizeof(T*));
|
||||
}
|
||||
|
||||
#define DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(class_, type_) \
|
||||
class class_ : public AutoMarkingPtr \
|
||||
{ \
|
||||
public: \
|
||||
class_ (XPCCallContext& ccx) \
|
||||
: AutoMarkingPtr(ccx), mPtr(nsnull), mCount(0) {} \
|
||||
class_ (XPCCallContext& ccx, type_** aPtr, PRUint32 aCount, \
|
||||
bool aClear = false) \
|
||||
: AutoMarkingPtr(ccx), mPtr(aPtr), mCount(aCount) \
|
||||
{ \
|
||||
if (!mPtr) mCount = 0; \
|
||||
else if (aClear) memset(mPtr, 0, mCount*sizeof(type_*)); \
|
||||
} \
|
||||
virtual ~ class_ () {} \
|
||||
\
|
||||
virtual void TraceJS(JSTracer* trc) \
|
||||
{ \
|
||||
for (PRUint32 i = 0; i < mCount; ++i) { \
|
||||
type_* cur = mPtr[i]; \
|
||||
if (cur) { \
|
||||
cur->TraceJS(trc); \
|
||||
cur->AutoTrace(trc); \
|
||||
} \
|
||||
} \
|
||||
if (mNext) mNext->TraceJS(trc); \
|
||||
} \
|
||||
\
|
||||
virtual void MarkAfterJSFinalize() \
|
||||
{ \
|
||||
for (PRUint32 i = 0; i < mCount; ++i) { \
|
||||
type_* cur = mPtr[i]; \
|
||||
if (cur) \
|
||||
cur->Mark(); \
|
||||
} \
|
||||
if (mNext) mNext->MarkAfterJSFinalize(); \
|
||||
} \
|
||||
\
|
||||
type_ ** get() const {return mPtr;} \
|
||||
operator type_ **() const {return mPtr;} \
|
||||
type_ ** operator->() const {return mPtr;} \
|
||||
\
|
||||
class_ & operator =(const class_ & inst) \
|
||||
{mPtr = inst.mPtr; mCount = inst.mCount; return *this;} \
|
||||
\
|
||||
protected: \
|
||||
type_ ** mPtr; \
|
||||
PRUint32 mCount; \
|
||||
T** get() const { return mPtr; }
|
||||
operator T **() const { return mPtr; }
|
||||
T** operator->() const { return mPtr; }
|
||||
|
||||
ArrayAutoMarkingPtr<T>& operator =(const ArrayAutoMarkingPtr<T> &other)
|
||||
{
|
||||
mPtr = other.mPtr;
|
||||
mCount = other.mCount;
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void TraceJS(JSTracer* trc)
|
||||
{
|
||||
for (PRUint32 i = 0; i < mCount; i++) {
|
||||
if (mPtr[i]) {
|
||||
mPtr[i]->TraceJS(trc);
|
||||
mPtr[i]->AutoTrace(trc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MarkAfterJSFinalize()
|
||||
{
|
||||
for (PRUint32 i = 0; i < mCount; i++) {
|
||||
if (mPtr[i])
|
||||
mPtr[i]->Mark();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
T** mPtr;
|
||||
PRUint32 mCount;
|
||||
};
|
||||
|
||||
DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(AutoMarkingNativeInterfacePtrArrayPtr,
|
||||
XPCNativeInterface)
|
||||
typedef ArrayAutoMarkingPtr<XPCNativeInterface> AutoMarkingNativeInterfacePtrArrayPtr;
|
||||
|
||||
// Note: It looked like I would need one of these AutoMarkingPtr types for
|
||||
// XPCNativeScriptableInfo in order to manage marking its
|
||||
|
@ -29,6 +29,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=726949
|
||||
isnot(desc, undefined,
|
||||
"Should have an own 'Cu' property");
|
||||
is(desc.value, Cu, "Should have the right value");
|
||||
var loc = Cu.evalInSandbox('location', s);
|
||||
is(loc.href, location.href, "Should have the right location");
|
||||
} catch (e) {
|
||||
ok(false, "Should not get an exception: " + e);
|
||||
}
|
||||
|
@ -374,10 +374,6 @@ nsFileControlFrame::CaptureMouseListener::HandleEvent(nsIDOMEvent* aMouseEvent)
|
||||
rv = capturePicker->Init(win, title, mMode);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Tell our text control frame to remember the currently focused value.
|
||||
nsTextControlFrame* textControlFrame = mFrame->GetTextControlFrame();
|
||||
textControlFrame->InitFocusedValue();
|
||||
|
||||
// Show dialog
|
||||
PRUint32 result;
|
||||
rv = capturePicker->Show(&result);
|
||||
@ -408,16 +404,15 @@ nsFileControlFrame::CaptureMouseListener::HandleEvent(nsIDOMEvent* aMouseEvent)
|
||||
// uneditable text box with the file name inside.
|
||||
// Set new selected files
|
||||
if (newFiles.Count()) {
|
||||
// Tell our text control frame that this update of the value is a user
|
||||
// Tell our input element that this update of the value is a user
|
||||
// initiated change. Otherwise it'll think that the value is being set by
|
||||
// a script and not fire onchange when it should.
|
||||
bool oldState = textControlFrame->GetFireChangeEventState();
|
||||
textControlFrame->SetFireChangeEventState(true);
|
||||
inputElement->SetFiles(newFiles, true);
|
||||
textControlFrame->SetFireChangeEventState(oldState);
|
||||
|
||||
// May need to fire an onchange here
|
||||
textControlFrame->CheckFireOnChange();
|
||||
inputElement->SetFiles(newFiles, true);
|
||||
|
||||
// Should fire a change event here since the SetFiles() call above ensures
|
||||
// a different value from the mFocusedValue of the inputElement.
|
||||
inputElement->FireChangeEventIfNeeded();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -478,12 +473,9 @@ nsFileControlFrame::BrowseMouseListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
nsCOMPtr<nsIDOMFileList> fileList;
|
||||
dataTransfer->GetFiles(getter_AddRefs(fileList));
|
||||
|
||||
nsTextControlFrame* textControlFrame = mFrame->GetTextControlFrame();
|
||||
bool oldState = textControlFrame->GetFireChangeEventState();
|
||||
textControlFrame->SetFireChangeEventState(true);
|
||||
|
||||
inputElement->SetFiles(fileList, true);
|
||||
textControlFrame->SetFireChangeEventState(oldState);
|
||||
textControlFrame->CheckFireOnChange();
|
||||
inputElement->FireChangeEventIfNeeded();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -113,8 +113,8 @@ protected:
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
MouseListener(nsFileControlFrame* aFrame) :
|
||||
mFrame(aFrame)
|
||||
MouseListener(nsFileControlFrame* aFrame)
|
||||
: mFrame(aFrame)
|
||||
{}
|
||||
|
||||
void ForgetFrame() {
|
||||
@ -148,15 +148,21 @@ protected:
|
||||
|
||||
class CaptureMouseListener: public MouseListener {
|
||||
public:
|
||||
CaptureMouseListener(nsFileControlFrame* aFrame) : MouseListener(aFrame),
|
||||
mMode(0) {};
|
||||
CaptureMouseListener(nsFileControlFrame* aFrame)
|
||||
: MouseListener(aFrame)
|
||||
, mMode(0)
|
||||
{}
|
||||
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
PRUint32 mMode;
|
||||
};
|
||||
|
||||
class BrowseMouseListener: public MouseListener {
|
||||
public:
|
||||
BrowseMouseListener(nsFileControlFrame* aFrame) : MouseListener(aFrame) {};
|
||||
BrowseMouseListener(nsFileControlFrame* aFrame)
|
||||
: MouseListener(aFrame)
|
||||
{}
|
||||
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
static bool IsValidDropData(nsIDOMDragEvent* aEvent);
|
||||
|
@ -60,11 +60,6 @@ public:
|
||||
|
||||
NS_IMETHOD GetTextLength(PRInt32* aTextLength) = 0;
|
||||
|
||||
/**
|
||||
* Fire onChange if the value has changed since it was focused or since it
|
||||
* was last fired.
|
||||
*/
|
||||
NS_IMETHOD CheckFireOnChange() = 0;
|
||||
NS_IMETHOD SetSelectionStart(PRInt32 aSelectionStart) = 0;
|
||||
NS_IMETHOD SetSelectionEnd(PRInt32 aSelectionEnd) = 0;
|
||||
|
||||
|
@ -169,7 +169,6 @@ nsTextControlFrame::nsTextControlFrame(nsIPresShell* aShell, nsStyleContext* aCo
|
||||
: nsStackFrame(aShell, aContext)
|
||||
, mUseEditor(false)
|
||||
, mIsProcessing(false)
|
||||
, mFireChangeEventState(false)
|
||||
#ifdef DEBUG
|
||||
, mInEditorInitialization(false)
|
||||
#endif
|
||||
@ -699,8 +698,6 @@ void nsTextControlFrame::SetFocus(bool aOn, bool aRepaint)
|
||||
}
|
||||
}
|
||||
|
||||
InitFocusedValue();
|
||||
|
||||
nsCOMPtr<nsISelection> ourSel;
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
||||
getter_AddRefs(ourSel));
|
||||
@ -1381,28 +1378,6 @@ nsTextControlFrame::GetMaxLength(PRInt32* aSize)
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextControlFrame::InitFocusedValue()
|
||||
{
|
||||
return GetText(mFocusedValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextControlFrame::CheckFireOnChange()
|
||||
{
|
||||
nsString value;
|
||||
GetText(value);
|
||||
if (!mFocusedValue.Equals(value))
|
||||
{
|
||||
mFocusedValue = value;
|
||||
// Dispatch the change event.
|
||||
nsContentUtils::DispatchTrustedEvent(mContent->OwnerDoc(), mContent,
|
||||
NS_LITERAL_STRING("change"), true,
|
||||
false);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// END IMPLEMENTING NS_IFORMCONTROLFRAME
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -143,7 +143,6 @@ public:
|
||||
|
||||
NS_IMETHOD GetEditor(nsIEditor **aEditor);
|
||||
NS_IMETHOD GetTextLength(PRInt32* aTextLength);
|
||||
NS_IMETHOD CheckFireOnChange();
|
||||
NS_IMETHOD SetSelectionStart(PRInt32 aSelectionStart);
|
||||
NS_IMETHOD SetSelectionEnd(PRInt32 aSelectionEnd);
|
||||
NS_IMETHOD SetSelectionRange(PRInt32 aSelectionStart,
|
||||
@ -192,18 +191,6 @@ public:
|
||||
|
||||
public: //for methods who access nsTextControlFrame directly
|
||||
void SetValueChanged(bool aValueChanged);
|
||||
/** Called when the frame is focused, to remember the value for onChange. */
|
||||
nsresult InitFocusedValue();
|
||||
|
||||
void SetFireChangeEventState(bool aNewState)
|
||||
{
|
||||
mFireChangeEventState = aNewState;
|
||||
}
|
||||
|
||||
bool GetFireChangeEventState() const
|
||||
{
|
||||
return mFireChangeEventState;
|
||||
}
|
||||
|
||||
// called by the focus listener
|
||||
nsresult MaybeBeginSecureKeyboardInput();
|
||||
@ -212,16 +199,9 @@ public: //for methods who access nsTextControlFrame directly
|
||||
NS_STACK_CLASS class ValueSetter {
|
||||
public:
|
||||
ValueSetter(nsTextControlFrame* aFrame,
|
||||
nsIEditor* aEditor,
|
||||
bool aHasFocusValue)
|
||||
nsIEditor* aEditor)
|
||||
: mFrame(aFrame)
|
||||
, mEditor(aEditor)
|
||||
// This method isn't used for user-generated changes, except for calls
|
||||
// from nsFileControlFrame which sets mFireChangeEventState==true and
|
||||
// restores it afterwards (ie. we want 'change' events for those changes).
|
||||
// Focused value must be updated to prevent incorrect 'change' events,
|
||||
// but only if user hasn't changed the value.
|
||||
, mFocusValueInit(!mFrame->mFireChangeEventState && aHasFocusValue)
|
||||
, mCanceled(false)
|
||||
{
|
||||
MOZ_ASSERT(aFrame);
|
||||
@ -244,17 +224,11 @@ public: //for methods who access nsTextControlFrame directly
|
||||
if (mCanceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFocusValueInit) {
|
||||
// Reset mFocusedValue so the onchange event doesn't fire incorrectly.
|
||||
mFrame->InitFocusedValue();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nsTextControlFrame* mFrame;
|
||||
nsCOMPtr<nsIEditor> mEditor;
|
||||
bool mFocusValueInit;
|
||||
bool mOuterTransaction;
|
||||
bool mCanceled;
|
||||
};
|
||||
@ -415,9 +389,6 @@ private:
|
||||
// these packed bools could instead use the high order bits on mState, saving 4 bytes
|
||||
bool mUseEditor;
|
||||
bool mIsProcessing;
|
||||
// Calls to SetValue will be treated as user values (i.e. trigger onChange
|
||||
// eventually) when mFireChangeEventState==true, this is used by nsFileControlFrame.
|
||||
bool mFireChangeEventState;
|
||||
// Keep track if we have asked a placeholder node creation.
|
||||
bool mUsePlaceholder;
|
||||
|
||||
@ -426,7 +397,6 @@ private:
|
||||
friend class EditorInitializerEntryTracker;
|
||||
#endif
|
||||
|
||||
nsString mFocusedValue;
|
||||
nsRevocableEventPtr<ScrollOnFocusEvent> mScrollEvent;
|
||||
};
|
||||
|
||||
|
@ -190,15 +190,17 @@ public abstract class Layer {
|
||||
public static class RenderContext {
|
||||
public final RectF viewport;
|
||||
public final FloatSize pageSize;
|
||||
public final IntSize screenSize;
|
||||
public final float zoomFactor;
|
||||
public final int positionHandle;
|
||||
public final int textureHandle;
|
||||
public final FloatBuffer coordBuffer;
|
||||
|
||||
public RenderContext(RectF aViewport, FloatSize aPageSize, float aZoomFactor,
|
||||
public RenderContext(RectF aViewport, FloatSize aPageSize, IntSize aScreenSize, float aZoomFactor,
|
||||
int aPositionHandle, int aTextureHandle, FloatBuffer aCoordBuffer) {
|
||||
viewport = aViewport;
|
||||
pageSize = aPageSize;
|
||||
screenSize = aScreenSize;
|
||||
zoomFactor = aZoomFactor;
|
||||
positionHandle = aPositionHandle;
|
||||
textureHandle = aTextureHandle;
|
||||
|
@ -124,6 +124,9 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||
private int mSampleHandle;
|
||||
private int mTMatrixHandle;
|
||||
|
||||
private int mSurfaceWidth;
|
||||
private int mSurfaceHeight;
|
||||
|
||||
// column-major matrix applied to each vertex to shift the viewport from
|
||||
// one ranging from (-1, -1),(1,1) to (0,0),(1,1) and to scale all sizes by
|
||||
// a factor of 2 to fill up the screen
|
||||
@ -344,11 +347,14 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||
}
|
||||
|
||||
private RenderContext createContext(RectF viewport, FloatSize pageSize, float zoomFactor) {
|
||||
return new RenderContext(viewport, pageSize, zoomFactor, mPositionHandle, mTextureHandle,
|
||||
return new RenderContext(viewport, pageSize, new IntSize(mSurfaceWidth, mSurfaceHeight), zoomFactor, mPositionHandle, mTextureHandle,
|
||||
mCoordBuffer);
|
||||
}
|
||||
|
||||
public void onSurfaceChanged(GL10 gl, final int width, final int height) {
|
||||
mSurfaceWidth = width;
|
||||
mSurfaceHeight = height;
|
||||
|
||||
GLES20.glViewport(0, 0, width, height);
|
||||
|
||||
if (mFrameRateLayer != null) {
|
||||
|
@ -157,7 +157,12 @@ public class PluginLayer extends TileLayer
|
||||
|
||||
// Viewport has changed from the last update
|
||||
|
||||
if (mLastViewport != null && mSurfaceView != null && !mShowPlaceholder && sUsePlaceholder) {
|
||||
// Attempt to figure out if this is a full page plugin or near to it. If so, we don't show the placeholder because
|
||||
// it just performs badly (flickering).
|
||||
boolean fullPagePlugin = (mLayoutParams.width >= (context.screenSize.width * 0.90f) ||
|
||||
mLayoutParams.height >= (context.screenSize.height * 0.90f));
|
||||
|
||||
if (!fullPagePlugin && mLastViewport != null && mSurfaceView != null && !mShowPlaceholder && sUsePlaceholder) {
|
||||
// We have a SurfaceView that we can snapshot for a placeholder, and we are
|
||||
// not currently showing a placeholder.
|
||||
|
||||
|
@ -414,8 +414,7 @@ nsHttpConnection::SetupNPN(PRUint8 caps)
|
||||
|
||||
mNPNComplete = true;
|
||||
|
||||
if (mConnInfo->UsingSSL() &&
|
||||
!mConnInfo->UsingHttpProxy()) {
|
||||
if (mConnInfo->UsingSSL()) {
|
||||
LOG(("nsHttpConnection::SetupNPN Setting up "
|
||||
"Next Protocol Negotiation"));
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
|
@ -1193,7 +1193,6 @@ nsHttpConnectionMgr::RestrictConnections(nsConnectionEntry *ent)
|
||||
|
||||
bool doRestrict = ent->mConnInfo->UsingSSL() &&
|
||||
gHttpHandler->IsSpdyEnabled() &&
|
||||
!ent->mConnInfo->UsingHttpProxy() &&
|
||||
(!ent->mTestedSpdy || ent->mUsingSpdy) &&
|
||||
(ent->mHalfOpens.Length() || ent->mActiveConns.Length());
|
||||
|
||||
@ -2273,6 +2272,13 @@ nsHttpConnectionMgr::OnMsgSpeculativeConnect(PRInt32, void *param)
|
||||
nsConnectionEntry *ent =
|
||||
GetOrCreateConnectionEntry(trans->ConnectionInfo());
|
||||
|
||||
// If spdy has previously made a preferred entry for this host via
|
||||
// the ip pooling rules. If so, connect to the preferred host instead of
|
||||
// the one directly passed in here.
|
||||
nsConnectionEntry *preferredEntry = GetSpdyPreferredEnt(ent);
|
||||
if (preferredEntry)
|
||||
ent = preferredEntry;
|
||||
|
||||
if (!ent->mIdleConns.Length() && !RestrictConnections(ent) &&
|
||||
!AtActiveConnectionLimit(ent, trans->Caps())) {
|
||||
CreateTransport(ent, trans, trans->Caps(), true);
|
||||
@ -2694,7 +2700,8 @@ nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport *trans,
|
||||
|
||||
// if we are doing spdy coalescing and haven't recorded the ip address
|
||||
// for this entry before then make the hash key if our dns lookup
|
||||
// just completed
|
||||
// just completed. We can't do coalescing if using a proxy because the
|
||||
// ip addresses are not available to the client.
|
||||
|
||||
if (status == nsISocketTransport::STATUS_CONNECTED_TO &&
|
||||
gHttpHandler->IsSpdyEnabled() &&
|
||||
|
@ -1226,6 +1226,12 @@ nsHttpTransaction::HandleContentStart()
|
||||
LOG(("this response should not contain a body.\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (mResponseHead->Status() == 200 &&
|
||||
mConnection->IsProxyConnectInProgress()) {
|
||||
// successful CONNECTs do not have response bodies
|
||||
mNoContent = true;
|
||||
}
|
||||
mConnection->SetLastTransactionExpectedNoContent(mNoContent);
|
||||
if (mInvalidResponseBytesRead)
|
||||
gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,300 +0,0 @@
|
||||
# This file was generated by Autom4te Sun May 1 09:53:53 UTC 2011.
|
||||
# It contains the lists of macros which have been traced.
|
||||
# It can be safely removed.
|
||||
|
||||
@request = (
|
||||
bless( [
|
||||
'0',
|
||||
1,
|
||||
[
|
||||
'/usr/share/autoconf'
|
||||
],
|
||||
[
|
||||
'/usr/share/autoconf/autoconf/autoconf.m4f',
|
||||
'/usr/share/aclocal/argz.m4',
|
||||
'/usr/share/aclocal/libtool.m4',
|
||||
'/usr/share/aclocal/ltdl.m4',
|
||||
'/usr/share/aclocal/ltoptions.m4',
|
||||
'/usr/share/aclocal/ltsugar.m4',
|
||||
'/usr/share/aclocal/ltversion.m4',
|
||||
'/usr/share/aclocal/lt~obsolete.m4',
|
||||
'/usr/share/aclocal-1.11/amversion.m4',
|
||||
'/usr/share/aclocal-1.11/as.m4',
|
||||
'/usr/share/aclocal-1.11/auxdir.m4',
|
||||
'/usr/share/aclocal-1.11/cond.m4',
|
||||
'/usr/share/aclocal-1.11/depend.m4',
|
||||
'/usr/share/aclocal-1.11/depout.m4',
|
||||
'/usr/share/aclocal-1.11/header.m4',
|
||||
'/usr/share/aclocal-1.11/init.m4',
|
||||
'/usr/share/aclocal-1.11/install-sh.m4',
|
||||
'/usr/share/aclocal-1.11/lead-dot.m4',
|
||||
'/usr/share/aclocal-1.11/maintainer.m4',
|
||||
'/usr/share/aclocal-1.11/make.m4',
|
||||
'/usr/share/aclocal-1.11/minuso.m4',
|
||||
'/usr/share/aclocal-1.11/missing.m4',
|
||||
'/usr/share/aclocal-1.11/mkdirp.m4',
|
||||
'/usr/share/aclocal-1.11/options.m4',
|
||||
'/usr/share/aclocal-1.11/runlog.m4',
|
||||
'/usr/share/aclocal-1.11/sanity.m4',
|
||||
'/usr/share/aclocal-1.11/silent.m4',
|
||||
'/usr/share/aclocal-1.11/strip.m4',
|
||||
'/usr/share/aclocal-1.11/substnot.m4',
|
||||
'/usr/share/aclocal-1.11/tar.m4',
|
||||
'acinclude.m4',
|
||||
'configure.in'
|
||||
],
|
||||
{
|
||||
'AM_ENABLE_STATIC' => 1,
|
||||
'AC_LIBTOOL_LANG_RC_CONFIG' => 1,
|
||||
'_LT_AC_SHELL_INIT' => 1,
|
||||
'AC_DEFUN' => 1,
|
||||
'LIBUNWIND___THREAD' => 1,
|
||||
'_LT_AC_LANG_CXX_CONFIG' => 1,
|
||||
'AC_PROG_LIBTOOL' => 1,
|
||||
'AM_PROG_MKDIR_P' => 1,
|
||||
'AM_AUTOMAKE_VERSION' => 1,
|
||||
'AM_SUBST_NOTMAKE' => 1,
|
||||
'AM_MISSING_PROG' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH' => 1,
|
||||
'_LT_AC_LANG_C_CONFIG' => 1,
|
||||
'AM_PROG_INSTALL_STRIP' => 1,
|
||||
'_m4_warn' => 1,
|
||||
'AC_LIBTOOL_OBJDIR' => 1,
|
||||
'gl_FUNC_ARGZ' => 1,
|
||||
'LTOBSOLETE_VERSION' => 1,
|
||||
'AM_SANITY_CHECK' => 1,
|
||||
'AC_LIBTOOL_LANG_GCJ_CONFIG' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_PIC' => 1,
|
||||
'LT_LIB_M' => 1,
|
||||
'_LT_AC_CHECK_DLFCN' => 1,
|
||||
'AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE' => 1,
|
||||
'LTSUGAR_VERSION' => 1,
|
||||
'_LT_PROG_LTMAIN' => 1,
|
||||
'LT_SYS_SYMBOL_USCORE' => 1,
|
||||
'_AM_PROG_TAR' => 1,
|
||||
'AC_LIBTOOL_GCJ' => 1,
|
||||
'_LT_WITH_SYSROOT' => 1,
|
||||
'LT_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'LT_FUNC_DLSYM_USCORE' => 1,
|
||||
'AC_LIBTOOL_CONFIG' => 1,
|
||||
'_LT_AC_LANG_F77' => 1,
|
||||
'AC_LTDL_DLLIB' => 1,
|
||||
'_AM_SUBST_NOTMAKE' => 1,
|
||||
'_AM_AUTOCONF_VERSION' => 1,
|
||||
'AM_DISABLE_SHARED' => 1,
|
||||
'_LT_PROG_ECHO_BACKSLASH' => 1,
|
||||
'_LTDL_SETUP' => 1,
|
||||
'_LT_AC_LANG_CXX' => 1,
|
||||
'AM_PROG_LIBTOOL' => 1,
|
||||
'AM_PROG_LD' => 1,
|
||||
'_LT_AC_FILE_LTDLL_C' => 1,
|
||||
'AC_LIB_LTDL' => 1,
|
||||
'AU_DEFUN' => 1,
|
||||
'AC_PROG_NM' => 1,
|
||||
'AC_LIBTOOL_DLOPEN' => 1,
|
||||
'AC_PROG_LD' => 1,
|
||||
'AC_PROG_LD_GNU' => 1,
|
||||
'AC_ENABLE_FAST_INSTALL' => 1,
|
||||
'AC_LIBTOOL_FC' => 1,
|
||||
'LTDL_CONVENIENCE' => 1,
|
||||
'_AM_SET_OPTION' => 1,
|
||||
'AC_LTDL_PREOPEN' => 1,
|
||||
'_LT_LINKER_BOILERPLATE' => 1,
|
||||
'_LT_PREPARE_SED_QUOTE_VARS' => 1,
|
||||
'AC_LIBTOOL_LANG_CXX_CONFIG' => 1,
|
||||
'AC_LIBTOOL_PROG_CC_C_O' => 1,
|
||||
'gl_PREREQ_ARGZ' => 1,
|
||||
'LT_SUPPORTED_TAG' => 1,
|
||||
'AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'LT_PROG_RC' => 1,
|
||||
'LT_SYS_MODULE_EXT' => 1,
|
||||
'AC_DEFUN_ONCE' => 1,
|
||||
'_LT_AC_LANG_GCJ' => 1,
|
||||
'AC_LTDL_OBJDIR' => 1,
|
||||
'_LT_PATH_TOOL_PREFIX' => 1,
|
||||
'AC_LIBTOOL_RC' => 1,
|
||||
'_LT_AC_PROG_ECHO_BACKSLASH' => 1,
|
||||
'AC_DISABLE_FAST_INSTALL' => 1,
|
||||
'AM_SILENT_RULES' => 1,
|
||||
'include' => 1,
|
||||
'_LT_AC_TRY_DLOPEN_SELF' => 1,
|
||||
'_LT_AC_SYS_LIBPATH_AIX' => 1,
|
||||
'LT_AC_PROG_SED' => 1,
|
||||
'AM_ENABLE_SHARED' => 1,
|
||||
'LTDL_INSTALLABLE' => 1,
|
||||
'_LT_AC_LANG_GCJ_CONFIG' => 1,
|
||||
'AC_ENABLE_SHARED' => 1,
|
||||
'CHECK_ATOMIC_OPS' => 1,
|
||||
'_LT_REQUIRED_DARWIN_CHECKS' => 1,
|
||||
'AC_LIBTOOL_SYS_HARD_LINK_LOCKS' => 1,
|
||||
'AC_ENABLE_STATIC' => 1,
|
||||
'AM_PROG_CC_C_O' => 1,
|
||||
'_LT_AC_TAGVAR' => 1,
|
||||
'AC_LIBTOOL_LANG_F77_CONFIG' => 1,
|
||||
'AM_CONDITIONAL' => 1,
|
||||
'LT_LIB_DLLOAD' => 1,
|
||||
'LTVERSION_VERSION' => 1,
|
||||
'_LT_PROG_CXX' => 1,
|
||||
'_LT_PROG_F77' => 1,
|
||||
'LTDL_INIT' => 1,
|
||||
'm4_include' => 1,
|
||||
'AM_PROG_INSTALL_SH' => 1,
|
||||
'AC_PROG_EGREP' => 1,
|
||||
'AC_PATH_MAGIC' => 1,
|
||||
'_AC_AM_CONFIG_HEADER_HOOK' => 1,
|
||||
'AC_LTDL_SYSSEARCHPATH' => 1,
|
||||
'AM_MAKE_INCLUDE' => 1,
|
||||
'LT_CMD_MAX_LEN' => 1,
|
||||
'_LT_AC_TAGCONFIG' => 1,
|
||||
'm4_pattern_forbid' => 1,
|
||||
'_LT_LINKER_OPTION' => 1,
|
||||
'AC_LIBTOOL_COMPILER_OPTION' => 1,
|
||||
'AC_DISABLE_SHARED' => 1,
|
||||
'_LT_COMPILER_BOILERPLATE' => 1,
|
||||
'AC_LIBTOOL_WIN32_DLL' => 1,
|
||||
'AC_LIBTOOL_SETUP' => 1,
|
||||
'AC_PROG_LD_RELOAD_FLAG' => 1,
|
||||
'AC_LTDL_DLSYM_USCORE' => 1,
|
||||
'AM_MISSING_HAS_RUN' => 1,
|
||||
'LT_LANG' => 1,
|
||||
'LT_SYS_DLSEARCH_PATH' => 1,
|
||||
'LT_CONFIG_LTDL_DIR' => 1,
|
||||
'AC_LIBTOOL_DLOPEN_SELF' => 1,
|
||||
'LT_OUTPUT' => 1,
|
||||
'AC_LIBTOOL_PROG_LD_SHLIBS' => 1,
|
||||
'AC_WITH_LTDL' => 1,
|
||||
'AC_LIBTOOL_LINKER_OPTION' => 1,
|
||||
'LT_AC_PROG_RC' => 1,
|
||||
'AC_LIBTOOL_CXX' => 1,
|
||||
'LT_INIT' => 1,
|
||||
'LT_AC_PROG_GCJ' => 1,
|
||||
'LT_SYS_DLOPEN_SELF' => 1,
|
||||
'_LT_AC_PROG_CXXCPP' => 1,
|
||||
'AM_DEP_TRACK' => 1,
|
||||
'AM_DISABLE_STATIC' => 1,
|
||||
'AM_CONFIG_HEADER' => 1,
|
||||
'_AC_PROG_LIBTOOL' => 1,
|
||||
'_AM_IF_OPTION' => 1,
|
||||
'AC_PATH_TOOL_PREFIX' => 1,
|
||||
'm4_pattern_allow' => 1,
|
||||
'AC_LIBTOOL_F77' => 1,
|
||||
'AM_SET_LEADING_DOT' => 1,
|
||||
'_LT_PROG_FC' => 1,
|
||||
'LT_AC_PROG_EGREP' => 1,
|
||||
'_AM_DEPENDENCIES' => 1,
|
||||
'AC_LIBTOOL_LANG_C_CONFIG' => 1,
|
||||
'LTOPTIONS_VERSION' => 1,
|
||||
'_LT_AC_SYS_COMPILER' => 1,
|
||||
'AM_PROG_NM' => 1,
|
||||
'AC_LIBLTDL_CONVENIENCE' => 1,
|
||||
'AC_DEPLIBS_CHECK_METHOD' => 1,
|
||||
'AC_LIBLTDL_INSTALLABLE' => 1,
|
||||
'jm_MAINTAINER_MODE' => 1,
|
||||
'AM_SET_CURRENT_AUTOMAKE_VERSION' => 1,
|
||||
'AC_LTDL_ENABLE_INSTALL' => 1,
|
||||
'LT_PROG_GCJ' => 1,
|
||||
'AC_LIBTOOL_SYS_DYNAMIC_LINKER' => 1,
|
||||
'AM_INIT_AUTOMAKE' => 1,
|
||||
'AC_DISABLE_STATIC' => 1,
|
||||
'LT_PATH_NM' => 1,
|
||||
'AM_MAINTAINER_MODE' => 1,
|
||||
'AC_LTDL_SHLIBEXT' => 1,
|
||||
'_LT_AC_LOCK' => 1,
|
||||
'_LT_AC_LANG_RC_CONFIG' => 1,
|
||||
'LT_SYS_MODULE_PATH' => 1,
|
||||
'LT_WITH_LTDL' => 1,
|
||||
'AC_LIBTOOL_POSTDEP_PREDEP' => 1,
|
||||
'AC_LTDL_SHLIBPATH' => 1,
|
||||
'AM_PROG_AS' => 1,
|
||||
'AM_AUX_DIR_EXPAND' => 1,
|
||||
'AC_LIBTOOL_PROG_COMPILER_NO_RTTI' => 1,
|
||||
'_LT_AC_LANG_F77_CONFIG' => 1,
|
||||
'_LT_COMPILER_OPTION' => 1,
|
||||
'_AM_SET_OPTIONS' => 1,
|
||||
'AM_RUN_LOG' => 1,
|
||||
'_AM_OUTPUT_DEPENDENCY_COMMANDS' => 1,
|
||||
'AC_LIBTOOL_PICMODE' => 1,
|
||||
'AC_LTDL_SYS_DLOPEN_DEPLIBS' => 1,
|
||||
'AC_LIBTOOL_SYS_OLD_ARCHIVE' => 1,
|
||||
'AC_CHECK_LIBM' => 1,
|
||||
'LT_PATH_LD' => 1,
|
||||
'AC_LIBTOOL_SYS_LIB_STRIP' => 1,
|
||||
'_AM_MANGLE_OPTION' => 1,
|
||||
'AC_LIBTOOL_SYS_MAX_CMD_LEN' => 1,
|
||||
'AC_LTDL_SYMBOL_USCORE' => 1,
|
||||
'AM_SET_DEPDIR' => 1,
|
||||
'_LT_CC_BASENAME' => 1,
|
||||
'_LT_LIBOBJ' => 1
|
||||
}
|
||||
], 'Autom4te::Request' ),
|
||||
bless( [
|
||||
'1',
|
||||
1,
|
||||
[
|
||||
'/usr/share/autoconf'
|
||||
],
|
||||
[
|
||||
'/usr/share/autoconf/autoconf/autoconf.m4f',
|
||||
'aclocal.m4',
|
||||
'configure.in'
|
||||
],
|
||||
{
|
||||
'_LT_AC_TAGCONFIG' => 1,
|
||||
'AM_PROG_F77_C_O' => 1,
|
||||
'm4_pattern_forbid' => 1,
|
||||
'AC_INIT' => 1,
|
||||
'_AM_COND_IF' => 1,
|
||||
'AC_CANONICAL_TARGET' => 1,
|
||||
'AC_SUBST' => 1,
|
||||
'AC_CONFIG_LIBOBJ_DIR' => 1,
|
||||
'AC_FC_SRCEXT' => 1,
|
||||
'AC_CANONICAL_HOST' => 1,
|
||||
'AC_PROG_LIBTOOL' => 1,
|
||||
'AM_INIT_AUTOMAKE' => 1,
|
||||
'AM_PATH_GUILE' => 1,
|
||||
'AC_CONFIG_SUBDIRS' => 1,
|
||||
'AM_AUTOMAKE_VERSION' => 1,
|
||||
'LT_CONFIG_LTDL_DIR' => 1,
|
||||
'AC_REQUIRE_AUX_FILE' => 1,
|
||||
'AC_CONFIG_LINKS' => 1,
|
||||
'm4_sinclude' => 1,
|
||||
'LT_SUPPORTED_TAG' => 1,
|
||||
'AM_MAINTAINER_MODE' => 1,
|
||||
'AM_NLS' => 1,
|
||||
'AM_GNU_GETTEXT_INTL_SUBDIR' => 1,
|
||||
'AM_MAKEFILE_INCLUDE' => 1,
|
||||
'_m4_warn' => 1,
|
||||
'AM_PROG_CXX_C_O' => 1,
|
||||
'_AM_COND_ENDIF' => 1,
|
||||
'_AM_MAKEFILE_INCLUDE' => 1,
|
||||
'AM_ENABLE_MULTILIB' => 1,
|
||||
'AM_SILENT_RULES' => 1,
|
||||
'AM_PROG_MOC' => 1,
|
||||
'AC_CONFIG_FILES' => 1,
|
||||
'LT_INIT' => 1,
|
||||
'include' => 1,
|
||||
'AM_PROG_AR' => 1,
|
||||
'AM_GNU_GETTEXT' => 1,
|
||||
'AC_LIBSOURCE' => 1,
|
||||
'AM_PROG_FC_C_O' => 1,
|
||||
'AC_CANONICAL_BUILD' => 1,
|
||||
'AC_FC_FREEFORM' => 1,
|
||||
'AH_OUTPUT' => 1,
|
||||
'_AM_SUBST_NOTMAKE' => 1,
|
||||
'AC_CONFIG_AUX_DIR' => 1,
|
||||
'sinclude' => 1,
|
||||
'AM_PROG_CC_C_O' => 1,
|
||||
'm4_pattern_allow' => 1,
|
||||
'AM_XGETTEXT_OPTION' => 1,
|
||||
'AC_CANONICAL_SYSTEM' => 1,
|
||||
'AM_CONDITIONAL' => 1,
|
||||
'AC_CONFIG_HEADERS' => 1,
|
||||
'AC_DEFINE_TRACE_LITERAL' => 1,
|
||||
'AM_POT_TOOLS' => 1,
|
||||
'm4_include' => 1,
|
||||
'_AM_COND_ELSE' => 1,
|
||||
'AC_SUBST_TRACE' => 1
|
||||
}
|
||||
], 'Autom4te::Request' )
|
||||
);
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -6,14 +6,13 @@ cd `dirname $0`
|
||||
|
||||
source upstream.info
|
||||
|
||||
hg rm -f src
|
||||
rm -rf src
|
||||
git clone "$UPSTREAM_REPO" src
|
||||
cd src
|
||||
git checkout "$UPSTREAM_COMMIT"
|
||||
autoreconf -i
|
||||
rm -rf .git .gitignore
|
||||
rm -rf .git .gitignore autom4te.cache
|
||||
cd ..
|
||||
hg add src
|
||||
hg addremove -q src
|
||||
|
||||
echo "libunwind has now been updated. Don't forget to run hg commit!"
|
||||
|
@ -7,14 +7,17 @@ topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = $(NULL)
|
||||
|
||||
# Include config.mk explicitly so we can override FINAL_TARGET.
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
# config.mk sets FINAL_TARGET to $(DIST)/bin, but we want to copy build products
|
||||
# into a WebappRT-specific subdirectory, so we redefine it here.
|
||||
FINAL_TARGET = $(DIST)/bin/webapprt
|
||||
|
||||
DIRS = $(NULL)
|
||||
|
||||
ifneq (,$(filter WINNT,$(OS_ARCH)))
|
||||
DIRS += win
|
||||
else
|
||||
|
@ -7,12 +7,12 @@ topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
# This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
|
||||
# shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
|
||||
NSDISTMODE = copy
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
PROGRAM = webapprt-stub$(BIN_SUFFIX)
|
||||
|
||||
CMMSRCS = webapprt.mm
|
||||
|
@ -912,6 +912,23 @@ NextPowerOfTwo(int value) {
|
||||
return value + 1;
|
||||
}
|
||||
|
||||
#define MAX_LOCK_ATTEMPTS 10
|
||||
|
||||
static bool LockWindowWithRetry(void* window, unsigned char** bits, int* width, int* height, int* format, int* stride)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
while (count < MAX_LOCK_ATTEMPTS) {
|
||||
if (AndroidBridge::Bridge()->LockWindow(window, bits, width, height, format, stride))
|
||||
return true;
|
||||
|
||||
count++;
|
||||
usleep(500);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_EXPORT jobject JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_getSurfaceBits(JNIEnv* jenv, jclass, jobject surface)
|
||||
{
|
||||
@ -931,15 +948,14 @@ Java_org_mozilla_gecko_GeckoAppShell_getSurfaceBits(JNIEnv* jenv, jclass, jobjec
|
||||
int srcWidth, srcHeight, format, srcStride;
|
||||
|
||||
// So we lock/unlock once here in order to get whatever is currently the front buffer. It sucks.
|
||||
while (!AndroidBridge::Bridge()->LockWindow(window, &bits, &srcWidth, &srcHeight, &format, &srcStride)) {
|
||||
usleep(1000);
|
||||
}
|
||||
if (!LockWindowWithRetry(window, &bits, &srcWidth, &srcHeight, &format, &srcStride))
|
||||
return nsnull;
|
||||
|
||||
AndroidBridge::Bridge()->UnlockWindow(window);
|
||||
|
||||
// This is lock will result in the front buffer, since the last unlock rotated it to the back. Probably.
|
||||
while (!AndroidBridge::Bridge()->LockWindow(window, &bits, &srcWidth, &srcHeight, &format, &srcStride)) {
|
||||
usleep(1000);
|
||||
}
|
||||
if (!LockWindowWithRetry(window, &bits, &srcWidth, &srcHeight, &format, &srcStride))
|
||||
return nsnull;
|
||||
|
||||
// These are from android.graphics.PixelFormat
|
||||
int bpp;
|
||||
|
Loading…
Reference in New Issue
Block a user