Bug 1146921: disable the window sharing dropdown item in Loop conversation windows on unsupported platforms. r=Standard8

This commit is contained in:
Mike de Boer 2015-04-02 13:24:31 +02:00
parent ad0a7a714a
commit 15c4148374
5 changed files with 269 additions and 3 deletions

View File

@ -141,6 +141,116 @@ loop.shared.utils = (function(mozL10n) {
return null;
}
/**
* Helper to get the Operating System name.
*
* @param {String} [platform] The platform this is running on, will fall
* back to navigator.oscpu and navigator.userAgent
* respectively if not supplied.
* @param {Boolean} [withVersion] Optional flag to keep the version number
* included in the resulting string. Defaults to
* `false`.
* @return {String} The platform we're currently running on, in lower-case.
*/
var getOS = _.memoize(function(platform, withVersion) {
if (!platform) {
if ("oscpu" in window.navigator) {
// See https://developer.mozilla.org/en-US/docs/Web/API/Navigator/oscpu
platform = window.navigator.oscpu.split(";")[0].trim();
} else {
// Fall back to navigator.userAgent as a last resort.
platform = window.navigator.userAgent;
}
}
if (!platform) {
return "unknown";
}
// Support passing in navigator.userAgent.
var platformPart = platform.match(/\((.*)\)/);
if (platformPart) {
platform = platformPart[1];
}
platform = platform.toLowerCase().split(";");
if (/macintosh/.test(platform[0]) || /x11/.test(platform[0])) {
platform = platform[1];
} else {
if (platform[0].indexOf("win") > -1 && platform.length > 4) {
// Skip the security notation.
platform = platform[2];
} else {
platform = platform[0];
}
}
if (!withVersion) {
platform = platform.replace(/\s[0-9.]+/g, "");
}
return platform.trim();
}, function(platform, withVersion) {
// Cache the return values with the following key.
return (platform + "") + (withVersion + "");
});
/**
* Helper to get the Operating System version.
* See http://en.wikipedia.org/wiki/Windows_NT for a table of Windows NT
* versions.
*
* @param {String} [platform] The platform this is running on, will fall back
* to navigator.oscpu and navigator.userAgent
* respectively if not supplied.
* @return {String} The current version of the platform we're currently running
* on.
*/
var getOSVersion = _.memoize(function(platform) {
var os = getOS(platform, true);
var digitsRE = /\s([0-9.]+)/;
var version = os.match(digitsRE);
if (!version) {
if (os.indexOf("win") > -1) {
if (os.indexOf("xp")) {
return { major: 5, minor: 2 };
} else if (os.indexOf("vista") > -1) {
return { major: 6, minor: 0 };
}
}
} else {
version = version[1];
// Windows versions have an interesting scheme.
if (os.indexOf("win") > -1) {
switch (parseFloat(version)) {
case 98:
return { major: 4, minor: 1 };
case 2000:
return { major: 5, minor: 0 };
case 2003:
return { major: 5, minor: 2 };
case 7:
case 2008:
case 2011:
return { major: 6, minor: 1 };
case 8:
return { major: 6, minor: 2 };
case 8.1:
case 2012:
return { major: 6, minor: 3 };
}
}
version = version.split(".");
return {
major: parseInt(version[0].trim(), 10),
minor: parseInt(version[1] ? version[1].trim() : 0, 10)
};
}
return { major: Infinity, minor: 0 };
});
/**
* Helper to allow getting some of the location data in a way that's compatible
* with stubbing for unit tests.
@ -418,6 +528,8 @@ loop.shared.utils = (function(mozL10n) {
composeCallUrlEmail: composeCallUrlEmail,
formatDate: formatDate,
getBoolPreference: getBoolPreference,
getOS: getOS,
getOSVersion: getOSVersion,
isChrome: isChrome,
isFirefox: isFirefox,
isFirefoxOS: isFirefoxOS,

View File

@ -93,6 +93,17 @@ loop.shared.views = (function(_, l10n) {
state: React.PropTypes.string.isRequired,
},
getInitialState: function() {
var os = loop.shared.utils.getOS();
var osVersion = loop.shared.utils.getOSVersion();
// Disable screensharing on older OSX and Windows versions.
if ((os.indexOf("mac") > -1 && osVersion.major <= 10 && osVersion.minor <= 6) ||
(os.indexOf("win") > -1 && osVersion.major <= 5 && osVersion.minor <= 2)) {
return { windowSharingDisabled: true };
}
return { windowSharingDisabled: false };
},
handleClick: function() {
if (this.props.state === SCREEN_SHARE_STATES.ACTIVE) {
this.props.dispatcher.dispatch(
@ -144,6 +155,9 @@ loop.shared.views = (function(_, l10n) {
"conversation-window-dropdown": true,
"visually-hidden": !this.state.showMenu
});
var windowSharingClasses = cx({
"disabled": this.state.windowSharingDisabled
});
return (
React.createElement("div", null,
@ -156,7 +170,7 @@ loop.shared.views = (function(_, l10n) {
React.createElement("li", {onClick: this._handleShareTabs},
l10n.get("share_tabs_button_title")
),
React.createElement("li", {onClick: this._handleShareWindows},
React.createElement("li", {onClick: this._handleShareWindows, className: windowSharingClasses},
l10n.get("share_windows_button_title")
)
)

View File

@ -93,6 +93,17 @@ loop.shared.views = (function(_, l10n) {
state: React.PropTypes.string.isRequired,
},
getInitialState: function() {
var os = loop.shared.utils.getOS();
var osVersion = loop.shared.utils.getOSVersion();
// Disable screensharing on older OSX and Windows versions.
if ((os.indexOf("mac") > -1 && osVersion.major <= 10 && osVersion.minor <= 6) ||
(os.indexOf("win") > -1 && osVersion.major <= 5 && osVersion.minor <= 2)) {
return { windowSharingDisabled: true };
}
return { windowSharingDisabled: false };
},
handleClick: function() {
if (this.props.state === SCREEN_SHARE_STATES.ACTIVE) {
this.props.dispatcher.dispatch(
@ -144,6 +155,9 @@ loop.shared.views = (function(_, l10n) {
"conversation-window-dropdown": true,
"visually-hidden": !this.state.showMenu
});
var windowSharingClasses = cx({
"disabled": this.state.windowSharingDisabled
});
return (
<div>
@ -156,7 +170,7 @@ loop.shared.views = (function(_, l10n) {
<li onClick={this._handleShareTabs}>
{l10n.get("share_tabs_button_title")}
</li>
<li onClick={this._handleShareWindows}>
<li onClick={this._handleShareWindows} className={windowSharingClasses}>
{l10n.get("share_windows_button_title")}
</li>
</ul>

View File

@ -218,4 +218,79 @@ describe("loop.shared.utils", function() {
expect(result).eql("\uFDFD");
});
});
describe("#getOS", function() {
it("should recognize the OSX userAgent string", function() {
var UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:37.0) Gecko/20100101 Firefox/37.0";
var result = sharedUtils.getOS(UA);
expect(result).eql("intel mac os x");
});
it("should recognize the OSX userAgent string with version", function() {
var UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:37.0) Gecko/20100101 Firefox/37.0";
var result = sharedUtils.getOS(UA, true);
expect(result).eql("intel mac os x 10.10");
});
it("should recognize the Windows userAgent string with version", function() {
var UA = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:10.0) Gecko/20100101 Firefox/10.0";
var result = sharedUtils.getOS(UA, true);
expect(result).eql("windows nt 6.1");
});
it("should recognize the Linux userAgent string", function() {
var UA = "Mozilla/5.0 (X11; Linux i686 on x86_64; rv:10.0) Gecko/20100101 Firefox/10.0";
var result = sharedUtils.getOS(UA);
expect(result).eql("linux i686 on x86_64");
});
it("should recognize the OSX oscpu string", function() {
var oscpu = "Intel Mac OS X 10.10";
var result = sharedUtils.getOS(oscpu, true);
expect(result).eql("intel mac os x 10.10");
});
it("should recognize the Windows oscpu string", function() {
var oscpu = "Windows NT 5.3; Win64; x64";
var result = sharedUtils.getOS(oscpu, true);
expect(result).eql("windows nt 5.3");
});
});
describe("#getOSVersion", function() {
it("should fetch the correct version info for OSX", function() {
var UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:37.0) Gecko/20100101 Firefox/37.0";
var result = sharedUtils.getOSVersion(UA);
expect(result).eql({ major: 10, minor: 10 });
});
it("should fetch the correct version info for Windows", function() {
var UA = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:10.0) Gecko/20100101 Firefox/10.0";
var result = sharedUtils.getOSVersion(UA);
expect(result).eql({ major: 6, minor: 1 });
});
it("should fetch the correct version info for Windows XP", function() {
var oscpu = "Windows XP";
var result = sharedUtils.getOSVersion(oscpu);
expect(result).eql({ major: 5, minor: 2 });
});
it("should fetch the correct version info for Linux", function() {
var UA = "Mozilla/5.0 (X11; Linux i686 on x86_64; rv:10.0) Gecko/20100101 Firefox/10.0";
var result = sharedUtils.getOSVersion(UA);
// Linux version can't be determined correctly.
expect(result).eql({ major: Infinity, minor: 0 });
});
});
});

View File

@ -16,7 +16,7 @@ describe("loop.shared.views", function() {
var sharedViews = loop.shared.views;
var SCREEN_SHARE_STATES = loop.shared.utils.SCREEN_SHARE_STATES;
var getReactElementByClass = TestUtils.findRenderedDOMComponentWithClass;
var sandbox, fakeAudioXHR, dispatcher;
var sandbox, fakeAudioXHR, dispatcher, OS, OSVersion;
beforeEach(function() {
sandbox = sinon.sandbox.create();
@ -40,6 +40,15 @@ describe("loop.shared.views", function() {
response: new ArrayBuffer(10),
onload: null
};
OS = "mac";
OSVersion = { major: 10, minor: 10 };
sandbox.stub(loop.shared.utils, "getOS", function() {
return OS;
});
sandbox.stub(loop.shared.utils, "getOSVersion", function() {
return OSVersion;
});
});
afterEach(function() {
@ -186,6 +195,48 @@ describe("loop.shared.views", function() {
new sharedActions.StartScreenShare({ type: "window" }));
});
it("should have the 'window' option enabled", function() {
var comp = TestUtils.renderIntoDocument(
React.createElement(sharedViews.ScreenShareControlButton, {
dispatcher: dispatcher,
visible: true,
state: SCREEN_SHARE_STATES.INACTIVE
}));
var node = comp.getDOMNode().querySelector(".conversation-window-dropdown > li:last-child");
expect(node.classList.contains("disabled")).eql(false);
});
it("should disable the 'window' option on Windows XP", function() {
OS = "win";
OSVersion = { major: 5, minor: 1 };
var comp = TestUtils.renderIntoDocument(
React.createElement(sharedViews.ScreenShareControlButton, {
dispatcher: dispatcher,
visible: true,
state: SCREEN_SHARE_STATES.INACTIVE
}));
var node = comp.getDOMNode().querySelector(".conversation-window-dropdown > li:last-child");
expect(node.classList.contains("disabled")).eql(true);
});
it("should disable the 'window' option on OSX 10.6", function() {
OS = "mac";
OSVersion = { major: 10, minor: 6 };
var comp = TestUtils.renderIntoDocument(
React.createElement(sharedViews.ScreenShareControlButton, {
dispatcher: dispatcher,
visible: true,
state: SCREEN_SHARE_STATES.INACTIVE
}));
var node = comp.getDOMNode().querySelector(".conversation-window-dropdown > li:last-child");
expect(node.classList.contains("disabled")).eql(true);
});
it("should dispatch a EndScreenShare action on click when the state is active",
function() {
var comp = TestUtils.renderIntoDocument(