mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge fx-team to m-c a=merge
This commit is contained in:
commit
764c4772f3
@ -431,6 +431,7 @@ skip-if = e10s # Bug 940206 - nsIWebContentHandlerRegistrar::registerProtocolHan
|
||||
[browser_no_mcb_on_http_site.js]
|
||||
skip-if = e10s # Bug 516755 - SessionStore disabled for e10s
|
||||
[browser_bug1003461-switchtab-override.js]
|
||||
[browser_bug1024133-switchtab-override-keynav.js]
|
||||
[browser_bug1025195_switchToTabHavingURI_ignoreFragment.js]
|
||||
[browser_addCertException.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content (content.document.getElementById)
|
||||
|
@ -0,0 +1,52 @@
|
||||
/* 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/. */
|
||||
|
||||
add_task(function* test_switchtab_override_keynav() {
|
||||
let testURL = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
|
||||
|
||||
info("Opening first tab");
|
||||
let tab = gBrowser.addTab(testURL);
|
||||
let tabLoadDeferred = Promise.defer();
|
||||
whenTabLoaded(tab, tabLoadDeferred.resolve);
|
||||
yield tabLoadDeferred.promise;
|
||||
|
||||
info("Opening and selecting second tab");
|
||||
let secondTab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
registerCleanupFunction(() => {
|
||||
try {
|
||||
gBrowser.removeTab(tab);
|
||||
gBrowser.removeTab(secondTab);
|
||||
} catch(ex) { /* tabs may have already been closed in case of failure */ }
|
||||
return promiseClearHistory();
|
||||
});
|
||||
|
||||
info("Wait for autocomplete")
|
||||
let searchDeferred = Promise.defer();
|
||||
let onSearchComplete = gURLBar.onSearchComplete;
|
||||
registerCleanupFunction(() => {
|
||||
gURLBar.onSearchComplete = onSearchComplete;
|
||||
});
|
||||
gURLBar.onSearchComplete = function () {
|
||||
ok(gURLBar.popupOpen, "The autocomplete popup is correctly open");
|
||||
onSearchComplete.apply(gURLBar);
|
||||
searchDeferred.resolve();
|
||||
}
|
||||
|
||||
gURLBar.focus();
|
||||
gURLBar.value = "dummy_pag";
|
||||
EventUtils.synthesizeKey("e" , {});
|
||||
yield searchDeferred.promise;
|
||||
|
||||
info("Select first autocomplete popup entry");
|
||||
EventUtils.synthesizeKey("VK_DOWN" , {});
|
||||
ok(/moz-action:switchtab/.test(gURLBar.value), "switch to tab entry found");
|
||||
|
||||
info("Shift+left on switch-to-tab entry");
|
||||
|
||||
EventUtils.synthesizeKey("VK_SHIFT" , { type: "keydown" });
|
||||
EventUtils.synthesizeKey("VK_LEFT", { shiftKey: true });
|
||||
EventUtils.synthesizeKey("VK_SHIFT" , { type: "keyup" });
|
||||
|
||||
ok(!/moz-action:switchtab/.test(gURLBar.inputField.value), "switch to tab should be hidden");
|
||||
});
|
@ -146,10 +146,13 @@
|
||||
this._value = aValue;
|
||||
var returnValue = aValue;
|
||||
var action = this._parseActionUrl(aValue);
|
||||
// Don't put back the action if we are invoked while override actions
|
||||
// is active.
|
||||
if (action && this._numNoActionsKeys <= 0) {
|
||||
|
||||
if (action) {
|
||||
returnValue = action.param;
|
||||
}
|
||||
|
||||
// Set the actiontype only if the user is not overriding actions.
|
||||
if (action && this._noActionsKeys.size == 0) {
|
||||
this.setAttribute("actiontype", action.type);
|
||||
} else {
|
||||
this.removeAttribute("actiontype");
|
||||
@ -717,14 +720,14 @@
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<field name="_numNoActionsKeys"><![CDATA[
|
||||
0
|
||||
<field name="_noActionsKeys"><![CDATA[
|
||||
new Set();
|
||||
]]></field>
|
||||
|
||||
<method name="_clearNoActions">
|
||||
<parameter name="aURL"/>
|
||||
<body><![CDATA[
|
||||
this._numNoActionsKeys = 0;
|
||||
this._noActionsKeys.clear();
|
||||
this.popup.removeAttribute("noactions");
|
||||
let action = this._parseActionUrl(this._value);
|
||||
if (action)
|
||||
@ -746,19 +749,22 @@
|
||||
<handler event="keydown"><![CDATA[
|
||||
if ((event.keyCode === KeyEvent.DOM_VK_ALT ||
|
||||
event.keyCode === KeyEvent.DOM_VK_SHIFT) &&
|
||||
this.popup.selectedIndex >= 0) {
|
||||
this._numNoActionsKeys++;
|
||||
this.popup.selectedIndex >= 0 &&
|
||||
!this._noActionsKeys.has(event.keyCode)) {
|
||||
if (this._noActionsKeys.size == 0) {
|
||||
this.popup.setAttribute("noactions", "true");
|
||||
this.removeAttribute("actiontype");
|
||||
}
|
||||
this._noActionsKeys.add(event.keyCode);
|
||||
}
|
||||
]]></handler>
|
||||
|
||||
<handler event="keyup"><![CDATA[
|
||||
if ((event.keyCode === KeyEvent.DOM_VK_ALT ||
|
||||
event.keyCode === KeyEvent.DOM_VK_SHIFT) &&
|
||||
this._numNoActionsKeys > 0) {
|
||||
this._numNoActionsKeys--;
|
||||
if (this._numNoActionsKeys == 0)
|
||||
this._noActionsKeys.has(event.keyCode)) {
|
||||
this._noActionsKeys.delete(event.keyCode);
|
||||
if (this._noActionsKeys.size == 0)
|
||||
this._clearNoActions();
|
||||
}
|
||||
]]></handler>
|
||||
|
@ -14,3 +14,16 @@ dictionary InspectorRGBTriple {
|
||||
octet g = 0;
|
||||
octet b = 0;
|
||||
};
|
||||
|
||||
dictionary InspectorRGBATuple {
|
||||
/*
|
||||
* NOTE: This tuple is in the normal 0-255-sized RGB space but can be
|
||||
* fractional and may extend outside the 0-255 range.
|
||||
*
|
||||
* a is in the range 0 - 1.
|
||||
*/
|
||||
double r = 0;
|
||||
double g = 0;
|
||||
double b = 0;
|
||||
double a = 1;
|
||||
};
|
||||
|
@ -39,9 +39,12 @@
|
||||
#include "nsCSSRuleProcessor.h"
|
||||
#include "mozilla/dom/InspectorUtilsBinding.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsCSSValue.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsStyleSet.h"
|
||||
#include "nsStyleUtil.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::css;
|
||||
@ -795,6 +798,66 @@ inDOMUtils::RgbToColorName(uint8_t aR, uint8_t aG, uint8_t aB,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
inDOMUtils::ColorToRGBA(const nsAString& aColorString, JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
nscolor color = 0;
|
||||
nsCSSParser cssParser;
|
||||
nsCSSValue cssValue;
|
||||
|
||||
bool isColor = cssParser.ParseColorString(aColorString, nullptr, 0,
|
||||
cssValue, true);
|
||||
|
||||
if (!isColor) {
|
||||
aValue.setNull();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRuleNode::ComputeColor(cssValue, nullptr, nullptr, color);
|
||||
|
||||
InspectorRGBATuple tuple;
|
||||
tuple.mR = NS_GET_R(color);
|
||||
tuple.mG = NS_GET_G(color);
|
||||
tuple.mB = NS_GET_B(color);
|
||||
tuple.mA = nsStyleUtil::ColorComponentToFloat(NS_GET_A(color));
|
||||
|
||||
if (!ToJSValue(aCx, tuple, aValue)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
inDOMUtils::IsValidCSSColor(const nsAString& aColorString, bool *_retval)
|
||||
{
|
||||
nsCSSParser cssParser;
|
||||
nsCSSValue cssValue;
|
||||
*_retval = cssParser.ParseColorString(aColorString, nullptr, 0, cssValue, true);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
inDOMUtils::CssPropertyIsValid(const nsAString& aPropertyName,
|
||||
const nsAString& aPropertyValue,
|
||||
bool *_retval)
|
||||
{
|
||||
nsCSSProperty propertyID =
|
||||
nsCSSProps::LookupProperty(aPropertyName, nsCSSProps::eIgnoreEnabledState);
|
||||
|
||||
if (propertyID == eCSSProperty_UNKNOWN) {
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get a parser, parse the property.
|
||||
nsCSSParser parser;
|
||||
*_retval = parser.IsValueValidForProperty(propertyID, aPropertyValue);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
inDOMUtils::GetBindingURLs(nsIDOMElement *aElement, nsIArray **_retval)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ interface nsIDOMFontFaceList;
|
||||
interface nsIDOMRange;
|
||||
interface nsIDOMCSSStyleSheet;
|
||||
|
||||
[scriptable, uuid(fd529e53-f734-4d15-83ce-d545a631d668)]
|
||||
[scriptable, uuid(bd6b3dee-b8dd-40c7-a40a-ad8455b49917)]
|
||||
interface inIDOMUtils : nsISupports
|
||||
{
|
||||
// CSS utilities
|
||||
@ -69,8 +69,25 @@ interface inIDOMUtils : nsISupports
|
||||
jsval colorNameToRGB(in DOMString aColorName);
|
||||
AString rgbToColorName(in octet aR, in octet aG, in octet aB);
|
||||
|
||||
// Convert a given CSS color string to rgba. Returns null on failure or an
|
||||
// InspectorRGBATuple on success.
|
||||
//
|
||||
// NOTE: Converting a color to RGBA may be lossy when converting from some
|
||||
// formats e.g. CMYK.
|
||||
[implicit_jscontext]
|
||||
jsval colorToRGBA(in DOMString aColorString);
|
||||
|
||||
// Check whether a given color is a valid CSS color.
|
||||
bool isValidCSSColor(in AString aColorString);
|
||||
|
||||
// Utilities for obtaining information about a CSS property.
|
||||
|
||||
// Check whether a CSS property and value are a valid combination. If the
|
||||
// property is pref-disabled it will still be processed.
|
||||
// aPropertyName: A property name e.g. "color"
|
||||
// aPropertyValue: A property value e.g. "red" or "red !important"
|
||||
bool cssPropertyIsValid(in AString aPropertyName, in AString aPropertyValue);
|
||||
|
||||
// Get a list of the longhands corresponding to the given CSS property. If
|
||||
// the property is a longhand already, just returns the property itself.
|
||||
// Throws on unsupported property names.
|
||||
|
@ -12,5 +12,8 @@ support-files = bug856317.css
|
||||
[test_bug856317.html]
|
||||
[test_bug877690.html]
|
||||
[test_bug1006595.html]
|
||||
[test_color_to_rgba.html]
|
||||
[test_is_valid_css_color.html]
|
||||
[test_css_property_is_valid.html]
|
||||
[test_get_all_style_sheets.html]
|
||||
[test_isinheritableproperty.html]
|
||||
|
50
layout/inspector/tests/test_color_to_rgba.html
Normal file
50
layout/inspector/tests/test_color_to_rgba.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test inDOMUtils::ColorToRGBA</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript;version=1.8">
|
||||
let utils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(SpecialPowers.Ci.inIDOMUtils);
|
||||
|
||||
testColor("red", {r:255, g:0, b:0, a:1});
|
||||
testColor("#f00", {r:255, g:0, b:0, a:1});
|
||||
testColor("#ff0000", {r:255, g:0, b:0, a:1});
|
||||
testColor("ff0000", null);
|
||||
testColor("rgb(255,0,0)", {r:255, g:0, b:0, a:1});
|
||||
testColor("rgba(255,0,0,0.7)", {r:255, g:0, b:0, a:0.7});
|
||||
testColor("rgb(255,0,0,0.7)", null);
|
||||
testColor("rgb(50%,75%,60%)", {r:128, g:191, b:153, a:1});
|
||||
testColor("rgba(100%,50%,25%,0.7)", {r:255, g:128, b:64, a:0.7});
|
||||
testColor("hsl(320,30%,10%)", {r:33, g:17, b:28, a:1});
|
||||
testColor("hsla(170,60%,40%,0.9)", {r:40, g:163, b:142, a:0.9});
|
||||
|
||||
function testColor(color, expected) {
|
||||
let rgb = utils.colorToRGBA(color);
|
||||
|
||||
if (rgb === null) {
|
||||
ok(expected === null, "color: " + color + " returns null");
|
||||
return;
|
||||
}
|
||||
|
||||
let {r, g, b, a} = rgb;
|
||||
|
||||
is(r, expected.r, "color: " + color + ", red component is converted correctly");
|
||||
is(g, expected.g, "color: " + color + ", green component is converted correctly");
|
||||
is(b, expected.b, "color: " + color + ", blue component is converted correctly");
|
||||
is(Math.round(a * 10) / 10, expected.a, "color: " + color + ", alpha component is a converted correctly");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test inDOMUtils::ColorToRGBA</h1>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
100
layout/inspector/tests/test_css_property_is_valid.html
Normal file
100
layout/inspector/tests/test_css_property_is_valid.html
Normal file
@ -0,0 +1,100 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test inDOMUtils::CssPropertyIsValid</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript;version=1.8">
|
||||
let utils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(SpecialPowers.Ci.inIDOMUtils);
|
||||
|
||||
let tests = [
|
||||
{
|
||||
property: "color",
|
||||
value: "red",
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
property: "display",
|
||||
value: "none",
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
property: "display",
|
||||
value: "red",
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
property: "displayx",
|
||||
value: "none",
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
property: "border",
|
||||
value: "1px solid blue",
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
property: "border",
|
||||
value: "1 solid blue",
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
property: "border",
|
||||
value: "1px underline blue",
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
property: "border",
|
||||
value: "1px solid",
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
property: "color",
|
||||
value: "blue !important",
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
property: "color",
|
||||
value: "blue ! important",
|
||||
expected: true
|
||||
},
|
||||
{
|
||||
property: "color",
|
||||
value: "blue !impoxxxrtant",
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
property: "color",
|
||||
value: "red; background:green;",
|
||||
expected: false
|
||||
},
|
||||
{
|
||||
property: "content",
|
||||
value: "\"hello\"",
|
||||
expected: true
|
||||
}
|
||||
];
|
||||
|
||||
for (let {property, value, expected} of tests) {
|
||||
let valid = utils.cssPropertyIsValid(property, value);
|
||||
|
||||
if (expected) {
|
||||
ok(valid, property + ":" + value + " is valid");
|
||||
} else {
|
||||
ok(!valid, property + ":" + value + " is not valid");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test inDOMUtils::CssPropertyIsValid</h1>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
90
layout/inspector/tests/test_is_valid_css_color.html
Normal file
90
layout/inspector/tests/test_is_valid_css_color.html
Normal file
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test inDOMUtils::isValidCSSColor</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript;version=1.8">
|
||||
let utils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||
.getService(SpecialPowers.Ci.inIDOMUtils);
|
||||
|
||||
// Color names
|
||||
let colors = utils.getCSSValuesForProperty("color");
|
||||
let notColor = ["hsl", "hsla", "inherit", "initial", "rgb", "rgba", "unset"];
|
||||
for (let color of colors) {
|
||||
if (notColor.indexOf(color) !== -1) {
|
||||
continue;
|
||||
}
|
||||
ok(utils.isValidCSSColor(color), color + " is a valid color");
|
||||
ok(!utils.isValidCSSColor("xxx" + color), "xxx" + color + " is not a valid color");
|
||||
}
|
||||
|
||||
// rgb(a)
|
||||
for (let i = 0; i <= 265; i++) {
|
||||
ok(utils.isValidCSSColor("rgb(" + i + ",0,0)"), "rgb(" + i + ",0,0) is a valid color");
|
||||
ok(utils.isValidCSSColor("rgb(0," + i + ",0)"), "rgb(0," + i + ",0) is a valid color");
|
||||
ok(utils.isValidCSSColor("rgb(0,0," + i + ")"), "rgb(0,0," + i + ") is a valid color");
|
||||
ok(utils.isValidCSSColor("rgba(" + i + ",0,0,0.2)"), "rgba(" + i + ",0,0,0.2) is a valid color");
|
||||
ok(utils.isValidCSSColor("rgba(0," + i + ",0,0.5)"), "rgba(0," + i + ",0,0.5) is a valid color");
|
||||
ok(utils.isValidCSSColor("rgba(0,0," + i + ",0.7)"), "rgba(0,0," + i + ",0.7) is a valid color");
|
||||
|
||||
ok(!utils.isValidCSSColor("rgbxxx(" + i + ",0,0)"), "rgbxxx(" + i + ",0,0) is not a valid color");
|
||||
ok(!utils.isValidCSSColor("rgbxxx(0," + i + ",0)"), "rgbxxx(0," + i + ",0) is not a valid color");
|
||||
ok(!utils.isValidCSSColor("rgbxxx(0,0," + i + ")"), "rgbxxx(0,0," + i + ") is not a valid color");
|
||||
}
|
||||
|
||||
// rgb(a) (%)
|
||||
for (let i = 0; i <= 110; i++) {
|
||||
ok(utils.isValidCSSColor("rgb(" + i + "%,0%,0%)"), "rgb(" + i + "%,0%,0%) is a valid color");
|
||||
ok(utils.isValidCSSColor("rgb(0%," + i + "%,0%)"), "rgb(0%," + i + "%,0%) is a valid color");
|
||||
ok(utils.isValidCSSColor("rgb(0%,0%," + i + "%)"), "rgb(0%,0%," + i + "%) is a valid color");
|
||||
ok(utils.isValidCSSColor("rgba(" + i + "%,0%,0%,0.2)"), "rgba(" + i + "%,0%,0%,0.2) is a valid color");
|
||||
ok(utils.isValidCSSColor("rgba(0%," + i + "%,0%,0.5)"), "rgba(0%," + i + "%,0%,0.5) is a valid color");
|
||||
ok(utils.isValidCSSColor("rgba(0%,0%," + i + "%,0.7)"), "rgba(0%,0%," + i + "%,0.7) is a valid color");
|
||||
|
||||
ok(!utils.isValidCSSColor("rgbaxxx(" + i + "%,0%,0%,0.2)"), "rgbaxxx(" + i + "%,0%,0%,0.2) is not a valid color");
|
||||
ok(!utils.isValidCSSColor("rgbaxxx(0%," + i + "%,0%,0.5)"), "rgbaxxx(0%," + i + "%,0%,0.5) is not a valid color");
|
||||
ok(!utils.isValidCSSColor("rgbaxxx(0%,0%," + i + "%,0.7)"), "rgbaxxx(0%,0%," + i + "%,0.7) is not a valid color");
|
||||
}
|
||||
|
||||
// hsl(a)
|
||||
for (let i = 0; i <= 370; i++) {
|
||||
ok(utils.isValidCSSColor("hsl(" + i + ",30%,10%)"), "rgb(" + i + ",30%,10%) is a valid color");
|
||||
ok(utils.isValidCSSColor("hsla(" + i + ",60%,70%,0.2)"), "rgba(" + i + ",60%,70%,0.2) is a valid color");
|
||||
}
|
||||
for (let i = 0; i <= 110; i++) {
|
||||
ok(utils.isValidCSSColor("hsl(100," + i + "%,20%)"), "hsl(100," + i + "%,20%) is a valid color");
|
||||
ok(utils.isValidCSSColor("hsla(100,20%," + i + "%,0.6)"), "hsla(100,20%," + i + "%,0.6) is a valid color");
|
||||
}
|
||||
|
||||
// hex
|
||||
for (let i = 0; i <= 255; i++) {
|
||||
let hex = (i).toString(16);
|
||||
if (hex.length === 1) {
|
||||
hex = 0 + hex;
|
||||
}
|
||||
ok(utils.isValidCSSColor("#" + hex + "7777"), "#" + hex + "7777 is a valid color");
|
||||
ok(utils.isValidCSSColor("#77" + hex + "77"), "#77" + hex + "77 is a valid color");
|
||||
ok(utils.isValidCSSColor("#7777" + hex), "#7777" + hex + " is a valid color");
|
||||
}
|
||||
ok(!utils.isValidCSSColor("#kkkkkk"), "#kkkkkk is not a valid color");
|
||||
|
||||
// short hex
|
||||
for (let i = 0; i <= 16; i++) {
|
||||
let hex = (i).toString(16);
|
||||
ok(utils.isValidCSSColor("#" + hex + hex + hex), "#" + hex + hex + hex + " is a valid color");
|
||||
}
|
||||
ok(!utils.isValidCSSColor("#ggg"), "#ggg is not a valid color");
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Test inDOMUtils::isValidCSSColor</h1>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -177,7 +177,8 @@ public:
|
||||
bool ParseColorString(const nsSubstring& aBuffer,
|
||||
nsIURI* aURL, // for error reporting
|
||||
uint32_t aLineNumber, // for error reporting
|
||||
nsCSSValue& aValue);
|
||||
nsCSSValue& aValue,
|
||||
bool aSuppressErrors /* false */);
|
||||
|
||||
nsresult ParseSelectorString(const nsSubstring& aSelectorString,
|
||||
nsIURI* aURL, // for error reporting
|
||||
@ -216,6 +217,8 @@ public:
|
||||
nsIPrincipal* aSheetPrincipal,
|
||||
nsCSSValue& aValue);
|
||||
|
||||
bool IsValueValidForProperty(const nsCSSProperty aPropID,
|
||||
const nsAString& aPropValue);
|
||||
|
||||
typedef nsCSSParser::VariableEnumFunc VariableEnumFunc;
|
||||
|
||||
@ -1707,15 +1710,24 @@ bool
|
||||
CSSParserImpl::ParseColorString(const nsSubstring& aBuffer,
|
||||
nsIURI* aURI, // for error reporting
|
||||
uint32_t aLineNumber, // for error reporting
|
||||
nsCSSValue& aValue)
|
||||
nsCSSValue& aValue,
|
||||
bool aSuppressErrors /* false */)
|
||||
{
|
||||
nsCSSScanner scanner(aBuffer, aLineNumber);
|
||||
css::ErrorReporter reporter(scanner, mSheet, mChildLoader, aURI);
|
||||
InitScanner(scanner, reporter, aURI, aURI, nullptr);
|
||||
|
||||
nsAutoSuppressErrors suppressErrors(this, aSuppressErrors);
|
||||
|
||||
// Parse a color, and check that there's nothing else after it.
|
||||
bool colorParsed = ParseColor(aValue) && !GetToken(true);
|
||||
|
||||
if (aSuppressErrors) {
|
||||
CLEAR_ERROR();
|
||||
} else {
|
||||
OUTPUT_ERROR();
|
||||
}
|
||||
|
||||
ReleaseScanner();
|
||||
return colorParsed;
|
||||
}
|
||||
@ -14668,6 +14680,47 @@ CSSParserImpl::ParseValueWithVariables(CSSVariableDeclarations::Type* aType,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::IsValueValidForProperty(const nsCSSProperty aPropID,
|
||||
const nsAString& aPropValue)
|
||||
{
|
||||
mData.AssertInitialState();
|
||||
mTempData.AssertInitialState();
|
||||
|
||||
nsCSSScanner scanner(aPropValue, 0);
|
||||
css::ErrorReporter reporter(scanner, mSheet, mChildLoader, nullptr);
|
||||
InitScanner(scanner, reporter, nullptr, nullptr, nullptr);
|
||||
|
||||
nsAutoSuppressErrors suppressErrors(this);
|
||||
|
||||
mSection = eCSSSection_General;
|
||||
scanner.SetSVGMode(false);
|
||||
|
||||
// Check for unknown properties
|
||||
if (eCSSProperty_UNKNOWN == aPropID) {
|
||||
ReleaseScanner();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the property and value parse successfully
|
||||
bool parsedOK = ParseProperty(aPropID);
|
||||
|
||||
// Check for priority
|
||||
parsedOK = parsedOK && ParsePriority() != ePriority_Error;
|
||||
|
||||
// We should now be at EOF
|
||||
parsedOK = parsedOK && !GetToken(true);
|
||||
|
||||
mTempData.ClearProperty(aPropID);
|
||||
mTempData.AssertInitialState();
|
||||
mData.AssertInitialState();
|
||||
|
||||
CLEAR_ERROR();
|
||||
ReleaseScanner();
|
||||
|
||||
return parsedOK;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// Recycling of parser implementation objects
|
||||
@ -14860,10 +14913,11 @@ bool
|
||||
nsCSSParser::ParseColorString(const nsSubstring& aBuffer,
|
||||
nsIURI* aURI,
|
||||
uint32_t aLineNumber,
|
||||
nsCSSValue& aValue)
|
||||
nsCSSValue& aValue,
|
||||
bool aSuppressErrors /* false */)
|
||||
{
|
||||
return static_cast<CSSParserImpl*>(mImpl)->
|
||||
ParseColorString(aBuffer, aURI, aLineNumber, aValue);
|
||||
ParseColorString(aBuffer, aURI, aLineNumber, aValue, aSuppressErrors);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -14981,3 +15035,12 @@ nsCSSParser::ParseCounterDescriptor(nsCSSCounterDesc aDescID,
|
||||
ParseCounterDescriptor(aDescID, aBuffer,
|
||||
aSheetURL, aBaseURL, aSheetPrincipal, aValue);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSSParser::IsValueValidForProperty(const nsCSSProperty aPropID,
|
||||
const nsAString& aPropValue)
|
||||
{
|
||||
return static_cast<CSSParserImpl*>(mImpl)->
|
||||
IsValueValidForProperty(aPropID, aPropValue);
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,8 @@ public:
|
||||
bool ParseColorString(const nsSubstring& aBuffer,
|
||||
nsIURI* aURL,
|
||||
uint32_t aLineNumber,
|
||||
nsCSSValue& aValue);
|
||||
nsCSSValue& aValue,
|
||||
bool aSuppressErrors = false);
|
||||
|
||||
/**
|
||||
* Parse aBuffer into a selector list. On success, caller must
|
||||
@ -296,6 +297,10 @@ public:
|
||||
nsIPrincipal* aSheetPrincipal,
|
||||
nsCSSValue& aValue);
|
||||
|
||||
// Check whether a given value can be applied to a property.
|
||||
bool IsValueValidForProperty(const nsCSSProperty aPropID,
|
||||
const nsAString& aPropValue);
|
||||
|
||||
protected:
|
||||
// This is a CSSParserImpl*, but if we expose that type name in this
|
||||
// header, we can't put the type definition (in nsCSSParser.cpp) in
|
||||
|
@ -26,7 +26,9 @@ function discovery_observer(subject, topic, data) {
|
||||
|
||||
var testTarget = {
|
||||
target: "test:service",
|
||||
factory: function(service) { /* dummy */ }
|
||||
factory: function(service) { /* dummy */ },
|
||||
types: ["video/mp4"],
|
||||
extensions: ["mp4"]
|
||||
};
|
||||
|
||||
add_test(function test_default() {
|
||||
|
@ -46,8 +46,10 @@ let videoDiscoveryTests = [
|
||||
{ id: "simple-mp4", source: "http://mochi.test:8888/simple.mp4", poster: "http://mochi.test:8888/simple.png", text: "simple video with mp4 src" },
|
||||
{ id: "simple-fail", pass: false, text: "simple video with no mp4 src" },
|
||||
{ id: "with-sources-mp4", source: "http://mochi.test:8888/simple.mp4", text: "video with mp4 extension source child" },
|
||||
{ id: "with-sources-webm", source: "http://mochi.test:8888/simple.webm", text: "video with webm extension source child" },
|
||||
{ id: "with-sources-fail", pass: false, text: "video with no mp4 extension source child" },
|
||||
{ id: "with-sources-mimetype", source: "http://mochi.test:8888/simple-video-mp4", text: "video with mp4 mimetype source child" },
|
||||
{ id: "with-sources-mimetype-mp4", source: "http://mochi.test:8888/simple-video-mp4", text: "video with mp4 mimetype source child" },
|
||||
{ id: "with-sources-mimetype-webm", source: "http://mochi.test:8888/simple-video-webm", text: "video with webm mimetype source child" },
|
||||
{ id: "video-overlay", source: "http://mochi.test:8888/simple.mp4", text: "div overlay covering a simple video with mp4 src" }
|
||||
];
|
||||
|
||||
|
@ -31,18 +31,29 @@
|
||||
<source src="/simple.mp4">
|
||||
</video>
|
||||
|
||||
<!-- FAIL: source list uses a mp4 extension -->
|
||||
<video id="with-sources-fail">
|
||||
<!-- PASS: source list uses a webm extension -->
|
||||
<video id="with-sources-webm">
|
||||
<source src="/simple.ogg">
|
||||
<source src="/simple.webm">
|
||||
</video>
|
||||
|
||||
<!-- FAIL: source list has no mp4 or webm extension -->
|
||||
<video id="with-sources-fail">
|
||||
<source src="/simple.ogg">
|
||||
</video>
|
||||
|
||||
<!-- PASS: source list uses a mp4 mimetype -->
|
||||
<video id="with-sources-mimetype">
|
||||
<video id="with-sources-mimetype-mp4">
|
||||
<source src="/simple-video-ogg" type="video/ogg">
|
||||
<source src="/simple-video-mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
<!-- PASS: source list uses a webm mimetype -->
|
||||
<video id="with-sources-mimetype-webm">
|
||||
<source src="/simple-video-ogg" type="video/ogg">
|
||||
<source src="/simple-video-webm" type="video/webm">
|
||||
</video>
|
||||
|
||||
<!-- PASS: source list uses a mp4 mimetype and extra data -->
|
||||
<video id="with-sources-mimetype-plus">
|
||||
<source src="/simple-video-ogg" type="video/ogg">
|
||||
|
@ -1,3 +1,4 @@
|
||||
// -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
|
||||
/* 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/. */
|
||||
@ -10,7 +11,9 @@ var rokuTarget = {
|
||||
factory: function(aService) {
|
||||
Cu.import("resource://gre/modules/RokuApp.jsm");
|
||||
return new RokuApp(aService);
|
||||
}
|
||||
},
|
||||
types: ["video/mp4"],
|
||||
extensions: ["mp4"]
|
||||
};
|
||||
|
||||
var fireflyTarget = {
|
||||
@ -22,7 +25,9 @@ var fireflyTarget = {
|
||||
factory: function(aService) {
|
||||
Cu.import("resource://gre/modules/FireflyApp.jsm");
|
||||
return new FireflyApp(aService);
|
||||
}
|
||||
},
|
||||
types: ["video/mp4", "video/webm"],
|
||||
extensions: ["mp4", "webm"]
|
||||
};
|
||||
|
||||
var mediaPlayerTarget = {
|
||||
@ -30,7 +35,9 @@ var mediaPlayerTarget = {
|
||||
factory: function(aService) {
|
||||
Cu.import("resource://gre/modules/MediaPlayerApp.jsm");
|
||||
return new MediaPlayerApp(aService);
|
||||
}
|
||||
},
|
||||
types: ["video/mp4", "video/webm", "application/x-mpegurl"],
|
||||
extensions: ["mp4", "webm", "m3u", "m3u8"]
|
||||
};
|
||||
|
||||
var CastingApps = {
|
||||
@ -173,8 +180,11 @@ var CastingApps = {
|
||||
},
|
||||
|
||||
getVideo: function(aElement, aX, aY) {
|
||||
let extensions = SimpleServiceDiscovery.getSupportedExtensions();
|
||||
let types = SimpleServiceDiscovery.getSupportedMimeTypes();
|
||||
|
||||
// Fast path: Is the given element a video element
|
||||
let video = this._getVideo(aElement);
|
||||
let video = this._getVideo(aElement, types, extensions);
|
||||
if (video) {
|
||||
return video;
|
||||
}
|
||||
@ -189,7 +199,7 @@ var CastingApps = {
|
||||
// Look for a video element contained in the overlay bounds
|
||||
let rect = element.getBoundingClientRect();
|
||||
if (aY >= rect.top && aX >= rect.left && aY <= rect.bottom && aX <= rect.right) {
|
||||
video = this._getVideo(element);
|
||||
video = this._getVideo(element, types, extensions);
|
||||
if (video) {
|
||||
break;
|
||||
}
|
||||
@ -201,18 +211,11 @@ var CastingApps = {
|
||||
return video;
|
||||
},
|
||||
|
||||
_getVideo: function(aElement) {
|
||||
_getVideo: function(aElement, aTypes, aExtensions) {
|
||||
if (!(aElement instanceof HTMLVideoElement)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Given the hardware support for H264, let's only look for 'mp4' sources
|
||||
function allowableExtension(aURI) {
|
||||
if (aURI && aURI instanceof Ci.nsIURL) {
|
||||
return (aURI.fileExtension == "mp4");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Grab the poster attribute from the <video>
|
||||
let posterURL = aElement.poster;
|
||||
@ -228,8 +231,8 @@ var CastingApps = {
|
||||
if (sourceURL) {
|
||||
// Use the file extension to guess the mime type
|
||||
let sourceURI = this.makeURI(sourceURL, null, this.makeURI(aElement.baseURI));
|
||||
if (allowableExtension(sourceURI)) {
|
||||
return { element: aElement, source: sourceURI.spec, poster: posterURL };
|
||||
if (this.allowableExtension(sourceURI, aExtensions)) {
|
||||
return { element: aElement, source: sourceURI.spec, poster: posterURL, sourceURI: sourceURI};
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,8 +244,8 @@ var CastingApps = {
|
||||
|
||||
// Using the type attribute is our ideal way to guess the mime type. Otherwise,
|
||||
// fallback to using the file extension to guess the mime type
|
||||
if (sourceNode.type == "video/mp4" || allowableExtension(sourceURI)) {
|
||||
return { element: aElement, source: sourceURI.spec, poster: posterURL };
|
||||
if (this.allowableMimeType(sourceNode.type, aTypes) || this.allowableExtension(sourceURI, aExtensions)) {
|
||||
return { element: aElement, source: sourceURI.spec, poster: posterURL, sourceURI: sourceURI, type: sourceNode.type };
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,21 +364,25 @@ var CastingApps = {
|
||||
}
|
||||
},
|
||||
|
||||
prompt: function(aCallback) {
|
||||
prompt: function(aCallback, aFilterFunc) {
|
||||
let items = [];
|
||||
let filteredServices = [];
|
||||
SimpleServiceDiscovery.services.forEach(function(aService) {
|
||||
let item = {
|
||||
label: aService.friendlyName,
|
||||
selected: false
|
||||
};
|
||||
if (!aFilterFunc || aFilterFunc(aService)) {
|
||||
filteredServices.push(aService);
|
||||
items.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
let prompt = new Prompt({
|
||||
title: Strings.browser.GetStringFromName("casting.prompt")
|
||||
}).setSingleChoiceItems(items).show(function(data) {
|
||||
let selected = data.button;
|
||||
let service = selected == -1 ? null : SimpleServiceDiscovery.services[selected];
|
||||
let service = selected == -1 ? null : filteredServices[selected];
|
||||
if (aCallback)
|
||||
aCallback(service);
|
||||
});
|
||||
@ -394,6 +401,10 @@ var CastingApps = {
|
||||
return;
|
||||
}
|
||||
|
||||
function filterFunc(service) {
|
||||
return this.allowableExtension(video.sourceURI, service.extensions) || this.allowableMimeType(video.type, service.types);
|
||||
}
|
||||
|
||||
this.prompt(function(aService) {
|
||||
if (!aService)
|
||||
return;
|
||||
@ -438,7 +449,7 @@ var CastingApps = {
|
||||
}.bind(this), this);
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}.bind(this), filterFunc.bind(this));
|
||||
},
|
||||
|
||||
closeExternal: function() {
|
||||
@ -487,5 +498,21 @@ var CastingApps = {
|
||||
if (status == "completed") {
|
||||
this.closeExternal();
|
||||
}
|
||||
},
|
||||
|
||||
allowableExtension: function(aURI, aExtensions) {
|
||||
if (aURI && aURI instanceof Ci.nsIURL) {
|
||||
for (let x in aExtensions) {
|
||||
if (aURI.fileExtension == aExtensions[x]) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
allowableMimeType: function(aType, aTypes) {
|
||||
for (let x in aTypes) {
|
||||
if (aType == aTypes[x]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
// -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
|
||||
/* 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/. */
|
||||
@ -243,6 +243,26 @@ var SimpleServiceDiscovery = {
|
||||
}
|
||||
},
|
||||
|
||||
getSupportedExtensions: function() {
|
||||
let extensions = [];
|
||||
this._targets.forEach(function(target) {
|
||||
extensions = extensions.concat(target.extensions);
|
||||
}, this);
|
||||
return extensions.filter(function(extension, pos) {
|
||||
return extensions.indexOf(extension) == pos;
|
||||
});
|
||||
},
|
||||
|
||||
getSupportedMimeTypes: function() {
|
||||
let types = [];
|
||||
this._targets.forEach(function(target) {
|
||||
types = types.concat(target.types);
|
||||
}, this);
|
||||
return types.filter(function(type, pos) {
|
||||
return types.indexOf(type) == pos;
|
||||
});
|
||||
},
|
||||
|
||||
registerTarget: function registerTarget(aTarget) {
|
||||
// We must have "target" and "factory" defined
|
||||
if (!("target" in aTarget) || !("factory" in aTarget)) {
|
||||
@ -291,6 +311,9 @@ var SimpleServiceDiscovery = {
|
||||
get services() {
|
||||
let array = [];
|
||||
for (let [key, service] of this._services) {
|
||||
let target = this._targets.get(service.target);
|
||||
service.extensions = target.extensions;
|
||||
service.types = target.types;
|
||||
array.push(service);
|
||||
}
|
||||
return array;
|
||||
|
@ -134,12 +134,111 @@ Transport.prototype = {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Manages the local device's name. The name can be generated in serveral
|
||||
* platform-specific ways (see |_generate|). The aim is for each device on the
|
||||
* same local network to have a unique name. If the Settings API is available,
|
||||
* the name is saved there to persist across reboots.
|
||||
*/
|
||||
function LocalDevice() {
|
||||
this._name = LocalDevice.UNKNOWN;
|
||||
if ("@mozilla.org/settingsService;1" in Cc) {
|
||||
this._settings =
|
||||
Cc["@mozilla.org/settingsService;1"].getService(Ci.nsISettingsService);
|
||||
Services.obs.addObserver(this, "mozsettings-changed", false);
|
||||
}
|
||||
this._get(); // Trigger |_get| to load name eagerly
|
||||
}
|
||||
|
||||
LocalDevice.SETTING = "devtools.discovery.device";
|
||||
LocalDevice.UNKNOWN = "unknown";
|
||||
|
||||
LocalDevice.prototype = {
|
||||
|
||||
_get: function() {
|
||||
if (!this._settings) {
|
||||
// Without Settings API, just generate a name and stop, since the value
|
||||
// can't be persisted.
|
||||
this._generate();
|
||||
return;
|
||||
}
|
||||
// Initial read of setting value
|
||||
this._settings.createLock().get(LocalDevice.SETTING, {
|
||||
handle: (_, name) => {
|
||||
if (name && name !== LocalDevice.UNKNOWN) {
|
||||
this._name = name;
|
||||
log("Device: " + this._name);
|
||||
return;
|
||||
}
|
||||
// No existing name saved, so generate one.
|
||||
this._generate();
|
||||
},
|
||||
handleError: () => log("Failed to get device name setting")
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Generate a new device name from various platform-specific properties.
|
||||
* Triggers the |name| setter to persist if needed.
|
||||
*/
|
||||
_generate: function() {
|
||||
if (Services.appinfo.widgetToolkit == "gonk") {
|
||||
// For Gonk devices, create one from the device name plus a little
|
||||
// randomness. The goal is just to distinguish devices in an office
|
||||
// environment where many people may have the same device model for
|
||||
// testing purposes (which would otherwise all report the same name).
|
||||
let name = libcutils.property_get("ro.product.device");
|
||||
// Pick a random number from [0, 2^32)
|
||||
let randomID = Math.floor(Math.random() * Math.pow(2, 32));
|
||||
// To hex and zero pad
|
||||
randomID = ("00000000" + randomID.toString(16)).slice(-8);
|
||||
this.name = name + "-" + randomID;
|
||||
} else {
|
||||
this.name = sysInfo.get("host");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Observe any changes that might be made via the Settings app
|
||||
*/
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic !== "mozsettings-changed") {
|
||||
return;
|
||||
}
|
||||
let setting = JSON.parse(data);
|
||||
if (setting.key !== LocalDevice.SETTING) {
|
||||
return;
|
||||
}
|
||||
this._name = setting.value;
|
||||
log("Device: " + this._name);
|
||||
},
|
||||
|
||||
get name() {
|
||||
return this._name;
|
||||
},
|
||||
|
||||
set name(name) {
|
||||
if (!this._settings) {
|
||||
this._name = name;
|
||||
log("Device: " + this._name);
|
||||
return;
|
||||
}
|
||||
// Persist to Settings API
|
||||
// The new value will be seen and stored by the observer above
|
||||
this._settings.createLock().set(LocalDevice.SETTING, name, {
|
||||
handle: () => {},
|
||||
handleError: () => log("Failed to set device name setting")
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function Discovery() {
|
||||
EventEmitter.decorate(this);
|
||||
|
||||
this.localServices = {};
|
||||
this.remoteServices = {};
|
||||
this.device = { name: "unknown" };
|
||||
this.device = new LocalDevice();
|
||||
this.replyTimeout = REPLY_TIMEOUT;
|
||||
|
||||
// Defaulted to Transport, but can be altered by tests
|
||||
@ -158,8 +257,6 @@ function Discovery() {
|
||||
this._purgeMissingDevices = this._purgeMissingDevices.bind(this);
|
||||
|
||||
Services.obs.addObserver(this, "network-active-changed", false);
|
||||
|
||||
this._getSystemInfo();
|
||||
}
|
||||
|
||||
Discovery.prototype = {
|
||||
@ -238,24 +335,6 @@ Discovery.prototype = {
|
||||
setTimeout(this._purgeMissingDevices, this.replyTimeout);
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine a unique name to identify the current device.
|
||||
*/
|
||||
_getSystemInfo: function() {
|
||||
// TODO Bug 1027787: Uniquify device name somehow?
|
||||
try {
|
||||
if (Services.appinfo.widgetToolkit == "gonk") {
|
||||
this.device.name = libcutils.property_get("ro.product.device");
|
||||
} else {
|
||||
this.device.name = sysInfo.get("host");
|
||||
}
|
||||
log("Device: " + this.device.name);
|
||||
} catch(e) {
|
||||
log("Failed to get system info");
|
||||
this.device.name = "unknown";
|
||||
}
|
||||
},
|
||||
|
||||
get Transport() {
|
||||
return this._factories.Transport;
|
||||
},
|
||||
|
@ -69,7 +69,13 @@ TestTransport.prototype = {
|
||||
|
||||
// Use TestTransport instead of the usual Transport
|
||||
discovery._factories.Transport = TestTransport;
|
||||
discovery.device.name = "test-device";
|
||||
|
||||
// Ignore name generation on b2g and force a fixed value
|
||||
Object.defineProperty(discovery.device, "name", {
|
||||
get: function() {
|
||||
return "test-device";
|
||||
}
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
|
@ -3,3 +3,4 @@ head =
|
||||
tail =
|
||||
|
||||
[test_discovery.js]
|
||||
skip-if = toolkit == 'gonk' && debug # Debug doesn't like settings read
|
||||
|
Loading…
Reference in New Issue
Block a user