Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2012-08-30 18:03:00 -04:00
commit f32a23eff2
25 changed files with 313 additions and 237 deletions

View File

@ -25,8 +25,7 @@ gcli.addCommand({
{
name: 'url',
type: 'string',
description: gcli.lookup('jsbUrlDesc'),
manual: 'The URL of the JS to prettify'
description: gcli.lookup('jsbUrlDesc')
},
{
name: 'indentSize',

View File

@ -9340,11 +9340,27 @@ Inputter.prototype.getDimensions = function() {
return undefined;
}
var fixedLoc = {};
var currentElement = this.element.parentNode;
while (currentElement && currentElement.nodeName !== '#document') {
var style = this.document.defaultView.getComputedStyle(currentElement, '');
if (style) {
var position = style.getPropertyValue('position');
if (position === 'absolute' || position === 'fixed') {
var bounds = currentElement.getBoundingClientRect();
fixedLoc.top = bounds.top;
fixedLoc.left = bounds.left;
break;
}
}
currentElement = currentElement.parentNode;
}
var rect = this.element.getBoundingClientRect();
return {
top: rect.top + 1,
top: rect.top - (fixedLoc.top || 0) + 1,
height: rect.bottom - rect.top - 1,
left: rect.left + 2,
left: rect.left - (fixedLoc.left || 0) + 2,
width: rect.right - rect.left
};
};

View File

@ -59,7 +59,7 @@ function testLocationChange()
ok(true, "tabNavigated event was fired.");
info("Still attached to the tab.");
gDebugger.addEventListener("Debugger:AfterScriptsAdded", function _onEvent(aEvent) {
gDebugger.addEventListener("Debugger:AfterNewScript", function _onEvent(aEvent) {
gDebugger.removeEventListener(aEvent.type, _onEvent);
isnot(gDebugger.DebuggerView.Scripts.selected, null,

View File

@ -95,7 +95,7 @@ function test()
else if (step === 2) {
testCurrentScript("-01.js", step);
expectedScript = "-02.js";
gView.Scripts.selectScript(gView.Scripts.scriptLocations[1]);
switchScript(1);
}
else if (step === 3) {
testCurrentScript("-02.js", step);
@ -105,7 +105,7 @@ function test()
else if (step === 4) {
testCurrentScript("-02.js", step);
expectedScript = "-01.js";
gView.Scripts.selectScript(gView.Scripts.scriptLocations[0]);
switchScript(0);
}
else if (step === 5) {
testCurrentScript("-01.js", step);
@ -125,7 +125,7 @@ function test()
else if (step === 8) {
testCurrentScript("-01.js", step);
expectedScript = "-02.js";
gView.Scripts.selectScript(gView.Scripts.scriptLocations[1]);
switchScript(1);
}
else if (step === 9) {
testCurrentScript("-02.js", step);
@ -145,7 +145,7 @@ function test()
else if (step === 12) {
testCurrentScript("-02.js", step);
expectedScript = "-01.js";
gView.Scripts.selectScript(gView.Scripts.scriptLocations[0]);
switchScript(0);
}
else if (step === 13) {
testCurrentScript("-01.js", step);
@ -166,6 +166,24 @@ function test()
"The shown script is not the the correct one. (" + step + ")");
}
function switchScript(index)
{
let scriptsView = gView.Scripts;
let scriptLocations = scriptsView.scriptLocations;
info("Available scripts: " + scriptLocations);
if (scriptLocations.length === 2) {
// We got all the scripts, it's safe to switch.
scriptsView.selectScript(scriptLocations[index]);
return;
}
window.addEventListener("Debugger:AfterNewScript", function _onEvent(aEvent) {
window.removeEventListener(aEvent.type, _onEvent);
switchScript(index);
});
}
function reloadPage()
{
gDebuggee.location.reload();

View File

@ -24,6 +24,19 @@ XPCOMUtils.defineLazyModuleGetter(this, "gcli",
XPCOMUtils.defineLazyModuleGetter(this, "CmdCommands",
"resource:///modules/devtools/CmdCmd.jsm");
/**
* Due to a number of panel bugs we need a way to check if we are running on
* Linux. See the comments for TooltipPanel and OutputPanel for further details.
*
* When bug 780102 is fixed all isLinux checks can be removed and we can revert
* to using panels.
*/
XPCOMUtils.defineLazyGetter(this, "isLinux", function () {
let os = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULRuntime).OS;
return os == "Linux";
});
/**
* A component to manage the global developer toolbar, which contains a GCLI
* and buttons for various developer tools.
@ -539,6 +552,18 @@ function DT_resetErrorsCount(aTab)
/**
* Panel to handle command line output.
*
* There is a tooltip bug on Windows and OSX that prevents tooltips from being
* positioned properly (bug 786975). There is a Gnome panel bug on Linux that
* causes ugly focus issues (https://bugzilla.gnome.org/show_bug.cgi?id=621848).
* We now use a tooltip on Linux and a panel on OSX & Windows.
*
* If a panel has no content and no height it is not shown when openPopup is
* called on Windows and OSX (bug 692348) ... this prevents the panel from
* appearing the first time it is shown. Setting the panel's height to 1px
* before calling openPopup works around this issue as we resize it ourselves
* anyway.
*
* @param aChromeDoc document from which we can pull the parts we need.
* @param aInput the input element that should get focus.
* @param aLoadCallback called when the panel is loaded properly.
@ -551,7 +576,7 @@ function OutputPanel(aChromeDoc, aInput, aLoadCallback)
this._loadCallback = aLoadCallback;
/*
<tooltip id="gcli-output"
<tooltip|panel id="gcli-output"
noautofocus="true"
noautohide="true"
class="gcli-panel">
@ -559,15 +584,31 @@ function OutputPanel(aChromeDoc, aInput, aLoadCallback)
id="gcli-output-frame"
src="chrome://browser/content/devtools/commandlineoutput.xhtml"
flex="1"/>
</tooltip>
</tooltip|panel>
*/
// TODO: Switch back from tooltip to panel when metacity focus issue is fixed:
// https://bugzilla.mozilla.org/show_bug.cgi?id=780102
this._panel = aChromeDoc.createElement("tooltip");
this._panel = aChromeDoc.createElement(isLinux ? "tooltip" : "panel");
this._panel.id = "gcli-output";
this._panel.classList.add("gcli-panel");
if (isLinux) {
this.canHide = false;
this._onpopuphiding = this._onpopuphiding.bind(this);
this._panel.addEventListener("popuphiding", this._onpopuphiding, true);
} else {
this._panel.setAttribute("noautofocus", "true");
this._panel.setAttribute("noautohide", "true");
// Bug 692348: On Windows and OSX if a panel has no content and no height
// openPopup fails to display it. Setting the height to 1px alows the panel
// to be displayed before has content or a real height i.e. the first time
// it is displayed.
this._panel.setAttribute("height", "1px");
}
this._toolbar.parentElement.insertBefore(this._panel, this._toolbar);
this._frame = aChromeDoc.createElementNS(NS_XHTML, "iframe");
@ -582,10 +623,6 @@ function OutputPanel(aChromeDoc, aInput, aLoadCallback)
this._frame.addEventListener("load", this._onload, true);
this.loaded = false;
this.canHide = false;
this._onpopuphiding = this._onpopuphiding.bind(this);
this._panel.addEventListener("popuphiding", this._onpopuphiding, true);
}
/**
@ -620,7 +657,7 @@ OutputPanel.prototype._onpopuphiding = function OP_onpopuphiding(aEvent)
{
// TODO: When we switch back from tooltip to panel we can remove this hack:
// https://bugzilla.mozilla.org/show_bug.cgi?id=780102
if (!this.canHide) {
if (isLinux && !this.canHide) {
aEvent.preventDefault();
}
};
@ -637,7 +674,9 @@ OutputPanel.prototype.show = function OP_show()
this._resize();
}.bind(this), 0);
this.canHide = false;
if (isLinux) {
this.canHide = false;
}
this._panel.openPopup(this._input, "before_start", 0, 0, false, false, null);
this._resize();
@ -698,7 +737,9 @@ OutputPanel.prototype.update = function OP_update()
*/
OutputPanel.prototype.remove = function OP_remove()
{
this.canHide = true;
if (isLinux) {
this.canHide = true;
}
if (this._panel) {
this._panel.hidePopup();
@ -743,7 +784,9 @@ OutputPanel.prototype._visibilityChanged = function OP_visibilityChanged(aEvent)
if (aEvent.outputVisible === true) {
// this.show is called by _outputChanged
} else {
this.canHide = true;
if (isLinux) {
this.canHide = true;
}
this._panel.hidePopup();
}
};
@ -751,6 +794,18 @@ OutputPanel.prototype._visibilityChanged = function OP_visibilityChanged(aEvent)
/**
* Panel to handle tooltips.
*
* There is a tooltip bug on Windows and OSX that prevents tooltips from being
* positioned properly (bug 786975). There is a Gnome panel bug on Linux that
* causes ugly focus issues (https://bugzilla.gnome.org/show_bug.cgi?id=621848).
* We now use a tooltip on Linux and a panel on OSX & Windows.
*
* If a panel has no content and no height it is not shown when openPopup is
* called on Windows and OSX (bug 692348) ... this prevents the panel from
* appearing the first time it is shown. Setting the panel's height to 1px
* before calling openPopup works around this issue as we resize it ourselves
* anyway.
*
* @param aChromeDoc document from which we can pull the parts we need.
* @param aInput the input element that should get focus.
* @param aLoadCallback called when the panel is loaded properly.
@ -764,7 +819,7 @@ function TooltipPanel(aChromeDoc, aInput, aLoadCallback)
this._onload = this._onload.bind(this);
this._loadCallback = aLoadCallback;
/*
<tooltip id="gcli-tooltip"
<tooltip|panel id="gcli-tooltip"
type="arrow"
noautofocus="true"
noautohide="true"
@ -773,15 +828,31 @@ function TooltipPanel(aChromeDoc, aInput, aLoadCallback)
id="gcli-tooltip-frame"
src="chrome://browser/content/devtools/commandlinetooltip.xhtml"
flex="1"/>
</tooltip>
</tooltip|panel>
*/
// TODO: Switch back from tooltip to panel when metacity focus issue is fixed:
// https://bugzilla.mozilla.org/show_bug.cgi?id=780102
this._panel = aChromeDoc.createElement("tooltip");
this._panel = aChromeDoc.createElement(isLinux ? "tooltip" : "panel");
this._panel.id = "gcli-tooltip";
this._panel.classList.add("gcli-panel");
if (isLinux) {
this.canHide = false;
this._onpopuphiding = this._onpopuphiding.bind(this);
this._panel.addEventListener("popuphiding", this._onpopuphiding, true);
} else {
this._panel.setAttribute("noautofocus", "true");
this._panel.setAttribute("noautohide", "true");
// Bug 692348: On Windows and OSX if a panel has no content and no height
// openPopup fails to display it. Setting the height to 1px alows the panel
// to be displayed before has content or a real height i.e. the first time
// it is displayed.
this._panel.setAttribute("height", "1px");
}
this._toolbar.parentElement.insertBefore(this._panel, this._toolbar);
this._frame = aChromeDoc.createElementNS(NS_XHTML, "iframe");
@ -793,10 +864,6 @@ function TooltipPanel(aChromeDoc, aInput, aLoadCallback)
this._frame.addEventListener("load", this._onload, true);
this.loaded = false;
this.canHide = false;
this._onpopuphiding = this._onpopuphiding.bind(this);
this._panel.addEventListener("popuphiding", this._onpopuphiding, true);
}
/**
@ -829,7 +896,7 @@ TooltipPanel.prototype._onpopuphiding = function TP_onpopuphiding(aEvent)
{
// TODO: When we switch back from tooltip to panel we can remove this hack:
// https://bugzilla.mozilla.org/show_bug.cgi?id=780102
if (!this.canHide) {
if (isLinux && !this.canHide) {
aEvent.preventDefault();
}
};
@ -851,7 +918,9 @@ TooltipPanel.prototype.show = function TP_show(aDimensions)
this._resize();
}.bind(this), 0);
this.canHide = false;
if (isLinux) {
this.canHide = false;
}
this._resize();
this._panel.openPopup(this._input, "before_start", aDimensions.start * 10, 0, false, false, null);
@ -896,7 +965,9 @@ TooltipPanel.prototype._resize = function TP_resize()
*/
TooltipPanel.prototype.remove = function TP_remove()
{
this.canHide = true;
if (isLinux) {
this.canHide = true;
}
this._panel.hidePopup();
};
@ -934,7 +1005,9 @@ TooltipPanel.prototype._visibilityChanged = function TP_visibilityChanged(aEvent
if (aEvent.tooltipVisible === true) {
this.show(aEvent.dimensions);
} else {
this.canHide = true;
if (isLinux) {
this.canHide = true;
}
this._panel.hidePopup();
}
};

View File

@ -562,7 +562,7 @@ CssHtmlTree.prototype = {
// Tidy up block headings by moving CSS property names and their values onto
// the same line and inserting a colon between them.
text = text.replace(/(.+)\r?\n\s+/g, "$1: ");
text = text.replace(/\t(.+)\t\t(.+)/g, "$1: $2");
// Remove any MDN link titles
text = text.replace(CssHtmlTree.HELP_LINK_TITLE, "");
@ -866,9 +866,9 @@ PropertyView.prototype = {
this.element = doc.createElementNS(HTML_NS, "tr");
this.element.setAttribute("class", this.propertyHeaderClassName);
this.propertyHeader = doc.createElementNS(HTML_NS, "td");
this.element.appendChild(this.propertyHeader);
this.propertyHeader.setAttribute("class", "property-header");
this.expanderContainer = doc.createElementNS(HTML_NS, "td");
this.element.appendChild(this.expanderContainer);
this.expanderContainer.setAttribute("class", "expander-container");
this.matchedExpander = doc.createElementNS(HTML_NS, "div");
this.matchedExpander.setAttribute("class", "match expander");
@ -885,10 +885,10 @@ PropertyView.prototype = {
this.matchedExpanderClick(aEvent);
}
}.bind(this), false);
this.propertyHeader.appendChild(this.matchedExpander);
this.expanderContainer.appendChild(this.matchedExpander);
this.nameNode = doc.createElementNS(HTML_NS, "div");
this.propertyHeader.appendChild(this.nameNode);
this.nameNode = doc.createElementNS(HTML_NS, "td");
this.element.appendChild(this.nameNode);
this.nameNode.setAttribute("class", "property-name");
this.nameNode.textContent = this.name;
this.nameNode.addEventListener("click", function(aEvent) {

View File

@ -112,10 +112,10 @@ function checkCopySelection()
let range = document.createRange();
range.setStart(props[0], 0);
range.setEnd(props[3], 3);
range.setEnd(props[3], 4);
contentWindow.getSelection().addRange(range);
info("Checking that cssHtmlTree.siBoundCopyPropertyValue() " +
info("Checking that cssHtmlTree.siBoundCopy() " +
" returns the correct clipboard value");
let expectedPattern = "color: rgb\\(255, 255, 0\\)[\\r\\n]+" +

View File

@ -37,17 +37,11 @@ function test()
{
addTab(TEST_URI);
let initialLoad = true;
browser.addEventListener("load", function onLoad() {
if (initialLoad) {
openConsole(null, function() {
HUDService.lastFinishedRequestCallback = performTest;
content.location.reload();
});
initialLoad = false;
} else {
browser.removeEventListener("load", onLoad, true);
}
browser.removeEventListener("load", onLoad, true);
openConsole(null, function() {
HUDService.lastFinishedRequestCallback = performTest;
content.location.reload();
});
}, true);
}

View File

@ -350,11 +350,11 @@ dbgStepManual=Commands to step in, out and over lines of code
dbgStepOverDesc=Executes the current statement and then stops at the next statement. If the current statement is a function call then the debugger executes the whole function, and it stops at the next statement after the function call
# LOCALIZATION NOTE (dbgStepInDesc) A very short string used to describe the
# function of the dbg step over command.
# function of the dbg step in command.
dbgStepInDesc=Executes the current statement and then stops at the next statement. If the current statement is a function call, then the debugger steps into that function, otherwise it stops at the next statement
# LOCALIZATION NOTE (dbgStepOutDesc) A very short string used to describe the
# function of the dbg step over command.
# function of the dbg step out command.
dbgStepOutDesc=Steps out of the current function and up one level if the function is nested. If in the main body, the script is executed to the end, or to the next breakpoint. The skipped statements are executed, but not stepped through
# LOCALIZATION NOTE (consolecloseDesc) A very short description of the
@ -609,7 +609,7 @@ pagemodRemoveElementResultMatchedAndRemovedElements=Elements matched by selector
# 'pagemod remove attribute' command. This string is designed to be shown in
# a menu alongside the command name, which is why it should be as short as
# possible.
pagemodRemoveAttributeDesc=Remove matching atributes
pagemodRemoveAttributeDesc=Remove matching attributes
# LOCALIZATION NOTE (pagemodRemoveAttributeSearchAttributesDesc) A very short
# string to describe the 'searchAttributes' parameter to the 'pagemod remove

View File

@ -2602,6 +2602,7 @@ stack[anonid=browserStack][responsivemode] {
text-shadow: none;
background-image: -moz-linear-gradient(top, #B4211B, #8A1915);
border-radius: 1px;
-moz-margin-end: 2px;
}
#social-toolbar-button {

View File

@ -8,12 +8,6 @@
color: -moz-FieldText;
}
.property-header {
padding: 5px 0;
white-space: nowrap;
vertical-align: text-top;
}
/* Take away these two :visited rules to get a core dumper */
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
.link,
@ -53,7 +47,6 @@
-moz-appearance: treetwisty;
padding-top: 12px;
-moz-margin-start: 5px;
-moz-margin-end: 5px;
vertical-align: middle;
}
@ -70,15 +63,19 @@
visibility: visible;
}
.expander-container {
vertical-align: text-top;
}
.property-name {
font-size: 12px;
padding: 2px 0;
color: -moz-FieldText;
}
.property-value {
padding: 0;
font-size: 10px;
-moz-padding-end: 6px;
color: grey;
vertical-align: text-top;
width: 100%;
}

View File

@ -8,12 +8,6 @@
color: -moz-FieldText;
}
.property-header {
padding: 5px 0;
white-space: nowrap;
vertical-align: text-top;
}
/* Take away these two :visited rules to get a core dumper */
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
.link,
@ -55,7 +49,6 @@
height: 12px;
padding-top: 12px;
-moz-margin-start: 5px;
-moz-margin-end: 5px;
vertical-align: middle;
}
@ -72,15 +65,19 @@
visibility: visible;
}
.expander-container {
vertical-align: text-top;
}
.property-name {
font-size: 12px;
padding: 2px 0;
color: -moz-FieldText;
}
.property-value {
padding: 0;
font-size: 10px;
-moz-padding-end: 6px;
color: grey;
vertical-align: text-top;
width: 100%;
}

View File

@ -8,12 +8,6 @@
color: -moz-FieldText;
}
.property-header {
padding: 5px 0;
white-space: nowrap;
vertical-align: text-top;
}
/* Take away these two :visited rules to get a core dumper */
/* See https://bugzilla.mozilla.org/show_bug.cgi?id=575675#c30 */
.link,
@ -71,15 +65,19 @@
visibility: visible;
}
.expander-container {
vertical-align: text-top;
}
.property-name {
font-size: 12px;
padding: 2px 0;
color: -moz-FieldText;
}
.property-value {
padding: 0;
font-size: 10px;
-moz-padding-end: 6px;
color: grey;
vertical-align: text-top;
width: 100%;
}

View File

@ -1809,9 +1809,9 @@ nsGenericElement::LeaveLink(nsPresContext* aPresContext)
}
nsresult
nsGenericElement::AddScriptEventListener(nsIAtom* aEventName,
const nsAString& aValue,
bool aDefer)
nsGenericElement::SetEventHandler(nsIAtom* aEventName,
const nsAString& aValue,
bool aDefer)
{
nsIDocument *ownerDoc = OwnerDoc();
if (ownerDoc->IsLoadedAsData()) {
@ -1829,8 +1829,9 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aEventName,
}
defer = defer && aDefer; // only defer if everyone agrees...
manager->AddScriptEventListener(aEventName, aValue, nsIProgrammingLanguage::JAVASCRIPT,
defer, !nsContentUtils::IsChromeDoc(ownerDoc));
manager->SetEventHandler(aEventName, aValue,
nsIProgrammingLanguage::JAVASCRIPT,
defer, !nsContentUtils::IsChromeDoc(ownerDoc));
return NS_OK;
}

View File

@ -210,9 +210,9 @@ public:
* @param aValue the JS to attach
* @param aDefer indicates if deferred execution is allowed
*/
nsresult AddScriptEventListener(nsIAtom* aEventName,
const nsAString& aValue,
bool aDefer = true);
nsresult SetEventHandler(nsIAtom* aEventName,
const nsAString& aValue,
bool aDefer = true);
/**
* Do whatever needs to be done when the mouse leaves a link

View File

@ -1965,16 +1965,16 @@ nsINode::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
#define EVENT(name_, id_, type_, struct_) \
NS_IMETHODIMP nsINode::GetOn##name_(JSContext *cx, jsval *vp) { \
nsEventListenerManager *elm = GetListenerManager(false); \
nsEventListenerManager *elm = GetListenerManager(false); \
if (elm) { \
elm->GetJSEventListener(nsGkAtoms::on##name_, vp); \
elm->GetEventHandler(nsGkAtoms::on##name_, vp); \
} else { \
*vp = JSVAL_NULL; \
} \
return NS_OK; \
} \
NS_IMETHODIMP nsINode::SetOn##name_(JSContext *cx, const jsval &v) { \
nsEventListenerManager *elm = GetListenerManager(true); \
nsEventListenerManager *elm = GetListenerManager(true); \
if (!elm) { \
return NS_ERROR_OUT_OF_MEMORY; \
} \
@ -1984,7 +1984,7 @@ nsINode::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
/* Just silently do nothing */ \
return NS_OK; \
} \
return elm->SetJSEventListenerToJsval(nsGkAtoms::on##name_, cx, obj, v); \
return elm->SetEventHandlerToJsval(nsGkAtoms::on##name_, cx, obj, v); \
}
#define TOUCH_EVENT EVENT
#define DOCUMENT_ONLY_EVENT EVENT

View File

@ -455,8 +455,8 @@ nsEventListenerManager::RemoveEventListenerByType(nsIDOMEventListener *aListener
}
nsListenerStruct*
nsEventListenerManager::FindJSEventListener(uint32_t aEventType,
nsIAtom* aTypeAtom)
nsEventListenerManager::FindEventHandler(uint32_t aEventType,
nsIAtom* aTypeAtom)
{
// Run through the listeners for this type and see if a script
// listener is registered
@ -474,16 +474,16 @@ nsEventListenerManager::FindJSEventListener(uint32_t aEventType,
}
nsresult
nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
JSObject* aScopeObject,
nsIAtom* aName,
JSObject *aHandler,
bool aPermitUntrustedEvents,
nsListenerStruct **aListenerStruct)
nsEventListenerManager::SetEventHandlerInternal(nsIScriptContext *aContext,
JSObject* aScopeObject,
nsIAtom* aName,
JSObject *aHandler,
bool aPermitUntrustedEvents,
nsListenerStruct **aListenerStruct)
{
nsresult rv = NS_OK;
uint32_t eventType = nsContentUtils::GetEventId(aName);
nsListenerStruct* ls = FindJSEventListener(eventType, aName);
nsListenerStruct* ls = FindEventHandler(eventType, aName);
if (!ls) {
// If we didn't find a script listener or no listeners existed
@ -495,7 +495,7 @@ nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
AddEventListener(scriptListener, eventType, aName,
NS_EVENT_FLAG_BUBBLE | NS_PRIV_EVENT_FLAG_SCRIPT);
ls = FindJSEventListener(eventType, aName);
ls = FindEventHandler(eventType, aName);
}
} else {
ls->GetJSListener()->SetHandler(aHandler);
@ -517,11 +517,11 @@ nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
}
nsresult
nsEventListenerManager::AddScriptEventListener(nsIAtom *aName,
const nsAString& aBody,
uint32_t aLanguage,
bool aDeferCompilation,
bool aPermitUntrustedEvents)
nsEventListenerManager::SetEventHandler(nsIAtom *aName,
const nsAString& aBody,
uint32_t aLanguage,
bool aDeferCompilation,
bool aPermitUntrustedEvents)
{
NS_PRECONDITION(aLanguage != nsIProgrammingLanguage::UNKNOWN,
"Must know the language for the script event listener");
@ -627,8 +627,8 @@ nsEventListenerManager::AddScriptEventListener(nsIAtom *aName,
JSObject* scope = global->GetGlobalJSObject();
nsListenerStruct *ls;
rv = SetJSEventListener(context, scope, aName, nullptr,
aPermitUntrustedEvents, &ls);
rv = SetEventHandlerInternal(context, scope, aName, nullptr,
aPermitUntrustedEvents, &ls);
NS_ENSURE_SUCCESS(rv, rv);
if (!aDeferCompilation) {
@ -639,10 +639,10 @@ nsEventListenerManager::AddScriptEventListener(nsIAtom *aName,
}
void
nsEventListenerManager::RemoveScriptEventListener(nsIAtom* aName)
nsEventListenerManager::RemoveEventHandler(nsIAtom* aName)
{
uint32_t eventType = nsContentUtils::GetEventId(aName);
nsListenerStruct* ls = FindJSEventListener(eventType, aName);
nsListenerStruct* ls = FindEventHandler(eventType, aName);
if (ls) {
mListeners.RemoveElementAt(uint32_t(ls - &mListeners.ElementAt(0)));
@ -1026,15 +1026,15 @@ nsEventListenerManager::HasUnloadListeners()
}
nsresult
nsEventListenerManager::SetJSEventListenerToJsval(nsIAtom *aEventName,
JSContext *cx,
JSObject* aScope,
const jsval & v)
nsEventListenerManager::SetEventHandlerToJsval(nsIAtom *aEventName,
JSContext *cx,
JSObject* aScope,
const jsval & v)
{
JSObject *handler;
if (JSVAL_IS_PRIMITIVE(v) ||
!JS_ObjectIsCallable(cx, handler = JSVAL_TO_OBJECT(v))) {
RemoveScriptEventListener(aEventName);
RemoveEventHandler(aEventName);
return NS_OK;
}
@ -1057,15 +1057,15 @@ nsEventListenerManager::SetJSEventListenerToJsval(nsIAtom *aEventName,
// Untrusted events are always permitted for non-chrome script
// handlers.
nsListenerStruct *ignored;
return SetJSEventListener(context, scope, aEventName, handler,
!nsContentUtils::IsCallerChrome(), &ignored);
return SetEventHandlerInternal(context, scope, aEventName, handler,
!nsContentUtils::IsCallerChrome(), &ignored);
}
void
nsEventListenerManager::GetJSEventListener(nsIAtom *aEventName, jsval *vp)
nsEventListenerManager::GetEventHandler(nsIAtom *aEventName, jsval *vp)
{
uint32_t eventType = nsContentUtils::GetEventId(aEventName);
nsListenerStruct* ls = FindJSEventListener(eventType, aEventName);
nsListenerStruct* ls = FindEventHandler(eventType, aEventName);
*vp = JSVAL_NULL;

View File

@ -101,15 +101,15 @@ public:
*/
// XXXbz does that play correctly with nodes being adopted across
// documents? Need to double-check the spec here.
nsresult AddScriptEventListener(nsIAtom *aName,
const nsAString& aFunc,
uint32_t aLanguage,
bool aDeferCompilation,
bool aPermitUntrustedEvents);
nsresult SetEventHandler(nsIAtom *aName,
const nsAString& aFunc,
uint32_t aLanguage,
bool aDeferCompilation,
bool aPermitUntrustedEvents);
/**
* Remove the current "inline" event listener for aName.
*/
void RemoveScriptEventListener(nsIAtom *aName);
void RemoveEventHandler(nsIAtom *aName);
void HandleEvent(nsPresContext* aPresContext,
nsEvent* aEvent,
@ -242,7 +242,7 @@ protected:
/**
* Find the nsListenerStruct for the "inline" event listener for aTypeAtom.
*/
nsListenerStruct* FindJSEventListener(uint32_t aEventType, nsIAtom* aTypeAtom);
nsListenerStruct* FindEventHandler(uint32_t aEventType, nsIAtom* aTypeAtom);
/**
* Set the "inline" event listener for aName to aHandler. aHandler
@ -250,12 +250,12 @@ protected:
* string for this listener. The nsListenerStruct that results, if
* any, is returned in aListenerStruct.
*/
nsresult SetJSEventListener(nsIScriptContext *aContext,
JSObject* aScopeGlobal,
nsIAtom* aName,
JSObject *aHandler,
bool aPermitUntrustedEvents,
nsListenerStruct **aListenerStruct);
nsresult SetEventHandlerInternal(nsIScriptContext *aContext,
JSObject* aScopeGlobal,
nsIAtom* aName,
JSObject *aHandler,
bool aPermitUntrustedEvents,
nsListenerStruct **aListenerStruct);
bool IsDeviceType(uint32_t aType);
void EnableDevice(uint32_t aType);
@ -269,13 +269,13 @@ public:
* not be in the same compartment, though cx and v are guaranteed to
* be in the same compartment.
*/
nsresult SetJSEventListenerToJsval(nsIAtom *aEventName, JSContext *cx,
JSObject *aScope, const jsval &v);
nsresult SetEventHandlerToJsval(nsIAtom *aEventName, JSContext *cx,
JSObject *aScope, const jsval &v);
/**
* Get the value of the "inline" event listener for aEventName.
* This may cause lazy compilation if the listener is uncompiled.
*/
void GetJSEventListener(nsIAtom *aEventName, jsval *vp);
void GetEventHandler(nsIAtom *aEventName, jsval *vp);
protected:
void AddEventListener(nsIDOMEventListener *aListener,

View File

@ -1903,7 +1903,7 @@ nsGenericHTMLElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
aValue) {
NS_ABORT_IF_FALSE(aValue->Type() == nsAttrValue::eString,
"Expected string value for script body");
nsresult rv = AddScriptEventListener(aName, aValue->GetStringValue());
nsresult rv = SetEventHandler(aName, aValue->GetStringValue());
NS_ENSURE_SUCCESS(rv, rv);
}
else if (aNotify && aName == nsGkAtoms::spellcheck) {
@ -2043,7 +2043,7 @@ nsGenericHTMLElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
EventNameType_HTML)) {
nsEventListenerManager* manager = GetListenerManager(false);
if (manager) {
manager->RemoveScriptEventListener(aAttribute);
manager->RemoveEventHandler(aAttribute);
}
}
@ -4085,7 +4085,7 @@ nsGenericHTMLElement::RecompileScriptEventListeners()
nsAutoString value;
GetAttr(kNameSpaceID_None, attr, value);
AddScriptEventListener(attr, value, true);
SetEventHandler(attr, value, true);
}
}

View File

@ -251,8 +251,8 @@ nsSVGElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
if (IsEventName(aName) && aValue) {
NS_ABORT_IF_FALSE(aValue->Type() == nsAttrValue::eString,
"Expected string value for script body");
nsresult rv = AddScriptEventListener(GetEventNameForAttr(aName),
aValue->GetStringValue());
nsresult rv = SetEventHandler(GetEventNameForAttr(aName),
aValue->GetStringValue());
NS_ENSURE_SUCCESS(rv, rv);
}
@ -606,7 +606,7 @@ nsSVGElement::UnsetAttrInternal(int32_t aNamespaceID, nsIAtom* aName,
nsEventListenerManager* manager = GetListenerManager(false);
if (manager) {
nsIAtom* eventName = GetEventNameForAttr(aName);
manager->RemoveScriptEventListener(eventName);
manager->RemoveEventHandler(eventName);
}
return;
}
@ -2443,7 +2443,7 @@ nsSVGElement::RecompileScriptEventListeners()
nsAutoString value;
GetAttr(kNameSpaceID_None, attr, value);
AddScriptEventListener(GetEventNameForAttr(attr), value, true);
SetEventHandler(GetEventNameForAttr(attr), value, true);
}
}

View File

@ -656,7 +656,7 @@ nsXULElement::AddListenerFor(const nsAttrName& aName,
nsContentUtils::IsEventAttributeName(attr, EventNameType_XUL)) {
nsAutoString value;
GetAttr(kNameSpaceID_None, attr, value);
AddScriptEventListener(attr, value, true);
SetEventHandler(attr, value, true);
}
}
}
@ -919,11 +919,11 @@ nsXULElement::AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
MaybeAddPopupListener(aName);
if (nsContentUtils::IsEventAttributeName(aName, EventNameType_XUL)) {
if (aValue->Type() == nsAttrValue::eString) {
AddScriptEventListener(aName, aValue->GetStringValue(), true);
SetEventHandler(aName, aValue->GetStringValue(), true);
} else {
nsAutoString body;
aValue->ToString(body);
AddScriptEventListener(aName, body, true);
SetEventHandler(aName, body, true);
}
}
@ -1853,7 +1853,7 @@ nsXULElement::RecompileScriptEventListeners()
nsAutoString value;
GetAttr(kNameSpaceID_None, attr, value);
AddScriptEventListener(attr, value, true);
SetEventHandler(attr, value, true);
}
}

View File

@ -11076,9 +11076,9 @@ nsGlobalWindow::SetHasAudioAvailableEventListeners()
#define EVENT(name_, id_, type_, struct_) \
NS_IMETHODIMP nsGlobalWindow::GetOn##name_(JSContext *cx, \
jsval *vp) { \
nsEventListenerManager *elm = GetListenerManager(false); \
nsEventListenerManager *elm = GetListenerManager(false); \
if (elm) { \
elm->GetJSEventListener(nsGkAtoms::on##name_, vp); \
elm->GetEventHandler(nsGkAtoms::on##name_, vp); \
} else { \
*vp = JSVAL_NULL; \
} \
@ -11086,7 +11086,7 @@ nsGlobalWindow::SetHasAudioAvailableEventListeners()
} \
NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx, \
const jsval &v) { \
nsEventListenerManager *elm = GetListenerManager(true); \
nsEventListenerManager *elm = GetListenerManager(true); \
if (!elm) { \
return NS_ERROR_OUT_OF_MEMORY; \
} \
@ -11095,7 +11095,7 @@ nsGlobalWindow::SetHasAudioAvailableEventListeners()
if (!obj) { \
return NS_ERROR_UNEXPECTED; \
} \
return elm->SetJSEventListenerToJsval(nsGkAtoms::on##name_, cx, obj, v); \
return elm->SetEventHandlerToJsval(nsGkAtoms::on##name_, cx, obj, v); \
}
#define WINDOW_ONLY_EVENT EVENT
#define TOUCH_EVENT EVENT

View File

@ -145,10 +145,6 @@ let libnetutils = (function () {
ctypes.default_abi,
ctypes.int,
ctypes.char.ptr),
ifc_reset_connections: library.declare("ifc_reset_connections",
ctypes.default_abi,
ctypes.int,
ctypes.char.ptr),
ifc_configure: library.declare("ifc_configure", ctypes.default_abi,
ctypes.int,
ctypes.char.ptr,
@ -177,8 +173,16 @@ let libnetutils = (function () {
ctypes.char.ptr),
dhcp_get_errmsg: library.declare("dhcp_get_errmsg", ctypes.default_abi,
ctypes.char.ptr),
// Constants for ifc_reset_connections.
// NOTE: Ignored in versions before ICS.
RESET_IPV4_ADDRESSES: 0x01,
RESET_IPV6_ADDRESSES: 0x02,
};
iface.RESET_ALL_ADDRESSES = iface.RESET_IPV4_ADDRESSES |
iface.RESET_IPV6_ADDRESSES
// dhcp_do_request's interface changed in SDK version 15. We try to hide
// this here by implementing the same JS API for both versions.
@ -240,6 +244,17 @@ let libnetutils = (function () {
};
// dhcp_do_request_renew() went away in newer libnetutils.
iface.dhcp_do_request_renew = iface.dhcp_do_request;
// Same deal with ifc_reset_connections.
let c_ifc_reset_connections =
library.declare("ifc_reset_connections",
ctypes.default_abi,
ctypes.int,
ctypes.char.ptr,
ctypes.int);
iface.ifc_reset_connections = function(ifname, reset_mask) {
return c_ifc_reset_connections(ifname, reset_mask) | 0;
}
} else {
let ints = ctypes.int.array(8)();
let c_dhcp_do_request =
@ -291,6 +306,14 @@ let libnetutils = (function () {
};
iface.dhcp_do_request = wrapCFunc(c_dhcp_do_request);
iface.dhcp_do_request_renew = wrapCFunc(c_dhcp_do_request_renew);
let c_ifc_reset_connections =
library.declare("ifc_reset_connections",
ctypes.default_abi,
ctypes.int,
ctypes.char.ptr);
iface.ifc_reset_connections = function(ifname, reset_mask) {
return c_ifc_reset_connections(ifname) | 0;
}
}
return iface;

View File

@ -598,7 +598,7 @@ var WifiManager = (function() {
return true;
}
function parseStatus(status, reconnected) {
function parseStatus(status) {
if (status === null) {
debug("Unable to get wpa supplicant's status");
return;
@ -643,7 +643,7 @@ var WifiManager = (function() {
notifyStateChange({ state: state, fromStatus: true });
if (state === "COMPLETED")
onconnected(reconnected);
onconnected();
}
// try to connect to the supplicant
@ -653,7 +653,7 @@ var WifiManager = (function() {
if (ok === 0) {
// Tell the event worker to start waiting for events.
retryTimer = null;
didConnectSupplicant(false, function(){});
didConnectSupplicant(function(){});
return;
}
if (connectTries++ < 3) {
@ -683,15 +683,10 @@ var WifiManager = (function() {
manager.start = function() {
debug("detected SDK version " + sdkVersion + " and device " + device);
// If we reconnected to an already-running supplicant, then manager.state
// will have already been updated to the supplicant's state. Otherwise, we
// started the supplicant ourselves and need to connect.
if (manager.state === "UNINITIALIZED")
connectToSupplicant(connectCallback);
connectToSupplicant(connectCallback);
}
function dhcpAfterConnect() {
function onconnected() {
// For now we do our own DHCP. In the future, this should be handed
// off to the Network Manager.
runDhcp(manager.ifname, function (data) {
@ -725,32 +720,6 @@ var WifiManager = (function() {
});
}
function onconnected(reconnected) {
if (!reconnected) {
dhcpAfterConnect();
return;
}
// We're in the process of reconnecting to a pre-existing wpa_supplicant.
// Check to see if there was already a DHCP process:
getProperty("init.svc.dhcpcd_" + manager.ifname, "stopped", function(value) {
if (value === "running") {
notify("dhcpconnected");
return;
}
// Some phones use a different property name for the dhcpcd daemon.
getProperty("init.svc.dhcpcd", "stopped", function(value) {
if (value === "running") {
notify("dhcpconnected");
return;
}
dhcpAfterConnect();
});
});
}
var supplicantStatesMap = (sdkVersion >= 15) ?
["DISCONNECTED", "INTERFACE_DISABLED", "INACTIVE", "SCANNING",
"AUTHENTICATING", "ASSOCIATING", "ASSOCIATED", "FOUR_WAY_HANDSHAKE",
@ -851,7 +820,7 @@ var WifiManager = (function() {
// Don't call onconnected if we ignored this state change (since we were
// already connected).
if (notifyStateChange({ state: "CONNECTED", BSSID: bssid, id: id }))
onconnected(false);
onconnected();
return true;
}
if (eventData.indexOf("CTRL-EVENT-SCAN-RESULTS") === 0) {
@ -905,49 +874,27 @@ var WifiManager = (function() {
setProperty("ctl.stop", "wpa_supplicant", tick);
}
function didConnectSupplicant(reconnected, callback) {
function didConnectSupplicant(callback) {
waitForEvent();
// Load up the supplicant state.
statusCommand(function(status) {
parseStatus(status, reconnected);
parseStatus(status);
notify("supplicantconnection");
callback();
});
}
function prepareForStartup(callback) {
// First, check to see if there's a wpa_supplicant running that we can
// connect to.
getProperty(SUPP_PROP, "stopped", function (value) {
if (value !== "running") {
stopDhcp(manager.ifname, function() { callback(false) });
return;
}
// It's running, try to reconnect to it.
connectToSupplicant(function (retval) {
if (retval === 0) {
// Successfully reconnected! Don't do anything else.
debug("Successfully connected!");
manager.supplicantStarted = true;
// It is important that we call parseStatus (in
// didConnectSupplicant) before calling the callback here.
// Otherwise, WifiManager.start will reconnect to it.
didConnectSupplicant(true, function() { callback(true) });
return;
}
debug("Didn't connect, trying other method.");
suppressEvents = true;
stopDhcp(manager.ifname, function() {
// Ignore any errors.
killSupplicant(function() {
suppressEvents = false;
callback(false);
});
manager.connectionDropped(function() {
// Ignore any errors and kill any currently-running supplicants. On some
// phones, stopSupplicant won't work for a supplicant that we didn't
// start, so we hand-roll it here.
suppressEvents = true;
killSupplicant(function() {
disableInterface(manager.ifname, function (ok) {
suppressEvents = false;
callback();
});
});
});
@ -994,12 +941,7 @@ var WifiManager = (function() {
kNetworkInterfaceStateChangedTopic,
null);
prepareForStartup(function(already_connected) {
if (already_connected) {
callback(0);
return;
}
prepareForStartup(function() {
loadDriver(function (status) {
if (status < 0) {
callback(status);
@ -2057,10 +1999,23 @@ WifiWorker.prototype = {
return;
}
this.waitForScan((function (networks) {
let callback = (function (networks) {
this._sendMessage(message, networks !== null, networks, msg);
}).bind(this);
this.waitForScan(callback);
WifiManager.scan(true, (function(ok) {
// If the scan command succeeded, we're done.
if (ok)
return;
// Avoid sending multiple responses.
this.wantScanResults.splice(this.wantScanResults.indexOf(callback), 1);
// Otherwise, let the client know that it failed, it's responsible for
// trying again in a few seconds.
this._sendMessage(message, false, "ScanFailed", msg);
}).bind(this));
WifiManager.scan(true, function() {});
},
_notifyAfterStateChange: function(success, newState) {

View File

@ -58,11 +58,15 @@ self.onmessage = function(e) {
var event = cbuf.readString().substr(0, ret.value);
postMessage({ id: id, event: event });
break;
case "ifc_reset_connections":
var ret = libnetutils.ifc_reset_connections(data.ifname,
libnetutils.RESET_ALL_ADDRESSES);
postMessage({ id: id, status: ret });
break;
case "ifc_enable":
case "ifc_disable":
case "ifc_remove_host_routes":
case "ifc_remove_default_route":
case "ifc_reset_connections":
case "dhcp_stop":
case "dhcp_release_lease":
var ret = libnetutils[cmd](data.ifname);