diff --git a/browser/devtools/commandline/CmdJsb.jsm b/browser/devtools/commandline/CmdJsb.jsm index 465be07eff1..08bd7b10776 100644 --- a/browser/devtools/commandline/CmdJsb.jsm +++ b/browser/devtools/commandline/CmdJsb.jsm @@ -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', diff --git a/browser/devtools/commandline/gcli.jsm b/browser/devtools/commandline/gcli.jsm index fa347eaf59f..0d77d2b6cde 100644 --- a/browser/devtools/commandline/gcli.jsm +++ b/browser/devtools/commandline/gcli.jsm @@ -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 }; }; diff --git a/browser/devtools/debugger/test/browser_dbg_location-changes-new.js b/browser/devtools/debugger/test/browser_dbg_location-changes-new.js index 4e9b2800cf4..28040421b4b 100644 --- a/browser/devtools/debugger/test/browser_dbg_location-changes-new.js +++ b/browser/devtools/debugger/test/browser_dbg_location-changes-new.js @@ -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, diff --git a/browser/devtools/debugger/test/browser_dbg_reload-same-script.js b/browser/devtools/debugger/test/browser_dbg_reload-same-script.js index 8304a30bb17..bc23e6ff0b1 100644 --- a/browser/devtools/debugger/test/browser_dbg_reload-same-script.js +++ b/browser/devtools/debugger/test/browser_dbg_reload-same-script.js @@ -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(); diff --git a/browser/devtools/shared/DeveloperToolbar.jsm b/browser/devtools/shared/DeveloperToolbar.jsm index f44f01b229f..07f4f7ae6b8 100644 --- a/browser/devtools/shared/DeveloperToolbar.jsm +++ b/browser/devtools/shared/DeveloperToolbar.jsm @@ -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; /* - @@ -559,15 +584,31 @@ function OutputPanel(aChromeDoc, aInput, aLoadCallback) id="gcli-output-frame" src="chrome://browser/content/devtools/commandlineoutput.xhtml" flex="1"/> - + */ // 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; /* - - + */ // 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(); } }; diff --git a/browser/devtools/styleinspector/CssHtmlTree.jsm b/browser/devtools/styleinspector/CssHtmlTree.jsm index 44a757bc807..b74b8f29131 100644 --- a/browser/devtools/styleinspector/CssHtmlTree.jsm +++ b/browser/devtools/styleinspector/CssHtmlTree.jsm @@ -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) { diff --git a/browser/devtools/styleinspector/test/browser_computedview_bug_703643_context_menu_copy.js b/browser/devtools/styleinspector/test/browser_computedview_bug_703643_context_menu_copy.js index 4b3f1376d2a..4f7bad0a241 100644 --- a/browser/devtools/styleinspector/test/browser_computedview_bug_703643_context_menu_copy.js +++ b/browser/devtools/styleinspector/test/browser_computedview_bug_703643_context_menu_copy.js @@ -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]+" + diff --git a/browser/devtools/webconsole/test/browser_webconsole_bug_599725_response_headers.js b/browser/devtools/webconsole/test/browser_webconsole_bug_599725_response_headers.js index 00529773baa..6aa629ceea8 100644 --- a/browser/devtools/webconsole/test/browser_webconsole_bug_599725_response_headers.js +++ b/browser/devtools/webconsole/test/browser_webconsole_bug_599725_response_headers.js @@ -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); } diff --git a/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties b/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties index ada42dc1508..0a978c27097 100644 --- a/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties +++ b/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties @@ -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 diff --git a/browser/themes/gnomestripe/browser.css b/browser/themes/gnomestripe/browser.css index 40a4344ce4d..e37a987b588 100644 --- a/browser/themes/gnomestripe/browser.css +++ b/browser/themes/gnomestripe/browser.css @@ -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 { diff --git a/browser/themes/gnomestripe/devtools/csshtmltree.css b/browser/themes/gnomestripe/devtools/csshtmltree.css index 68230a1554d..a4a624ecc03 100644 --- a/browser/themes/gnomestripe/devtools/csshtmltree.css +++ b/browser/themes/gnomestripe/devtools/csshtmltree.css @@ -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%; } diff --git a/browser/themes/pinstripe/devtools/csshtmltree.css b/browser/themes/pinstripe/devtools/csshtmltree.css index 54b775fb075..4f9935f6e08 100644 --- a/browser/themes/pinstripe/devtools/csshtmltree.css +++ b/browser/themes/pinstripe/devtools/csshtmltree.css @@ -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%; } diff --git a/browser/themes/winstripe/devtools/csshtmltree.css b/browser/themes/winstripe/devtools/csshtmltree.css index deca625ab92..eeceaf0bf56 100644 --- a/browser/themes/winstripe/devtools/csshtmltree.css +++ b/browser/themes/winstripe/devtools/csshtmltree.css @@ -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%; } diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index e6ffed37d6d..7550d7aaed2 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -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; } diff --git a/content/base/src/nsGenericElement.h b/content/base/src/nsGenericElement.h index 95a2cfee20e..8373f9e0ec2 100644 --- a/content/base/src/nsGenericElement.h +++ b/content/base/src/nsGenericElement.h @@ -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 diff --git a/content/base/src/nsINode.cpp b/content/base/src/nsINode.cpp index ea18104c62b..c1d74300b1a 100644 --- a/content/base/src/nsINode.cpp +++ b/content/base/src/nsINode.cpp @@ -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 diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index d849afad1f5..d4f74346aba 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -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; diff --git a/content/events/src/nsEventListenerManager.h b/content/events/src/nsEventListenerManager.h index 588255782d1..efaa18380bc 100644 --- a/content/events/src/nsEventListenerManager.h +++ b/content/events/src/nsEventListenerManager.h @@ -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, diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index a7950ef2447..1d7d446088b 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -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); } } diff --git a/content/svg/content/src/nsSVGElement.cpp b/content/svg/content/src/nsSVGElement.cpp index 8f80bac59c6..d9bfe8a117f 100644 --- a/content/svg/content/src/nsSVGElement.cpp +++ b/content/svg/content/src/nsSVGElement.cpp @@ -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); } } diff --git a/content/xul/content/src/nsXULElement.cpp b/content/xul/content/src/nsXULElement.cpp index 3958d3e1a57..8644282a35d 100644 --- a/content/xul/content/src/nsXULElement.cpp +++ b/content/xul/content/src/nsXULElement.cpp @@ -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); } } diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index f11d58c7a21..3e488f0aff4 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -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 diff --git a/dom/system/gonk/systemlibs.js b/dom/system/gonk/systemlibs.js index a585ed1eb53..d5d4a9e0101 100644 --- a/dom/system/gonk/systemlibs.js +++ b/dom/system/gonk/systemlibs.js @@ -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; diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js index 5be697bbea3..b4edeadb47c 100644 --- a/dom/wifi/WifiWorker.js +++ b/dom/wifi/WifiWorker.js @@ -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) { diff --git a/dom/wifi/wifi_worker.js b/dom/wifi/wifi_worker.js index 8760720c3da..5f3614a14c6 100644 --- a/dom/wifi/wifi_worker.js +++ b/dom/wifi/wifi_worker.js @@ -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);