зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1164510: show a globe favicon as default when no favicon can be found for a Hello context in conversation. r=Standard8
This commit is contained in:
Родитель
fb6be5d957
Коммит
e71453a6fc
|
@ -9,6 +9,13 @@ let LoopUI;
|
|||
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const kBrowserSharingNotificationId = "loop-sharing-notification";
|
||||
const kPrefBrowserSharingInfoBar = "browserSharing.showInfoBar";
|
||||
// This is the default icon as provided by the favicon service when a website
|
||||
// doesn't provide its own. When the icon ever changes, this data-uri will need
|
||||
// to be updated as well. A unit test covers this event.
|
||||
const kDefaultFavicon = "data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAArklEQVR42t2TMQ4CIRBF" +
|
||||
"9xBGEw5AkBJKY7uhcHsCjfEkHkJDLOWiyDeTyWoFwcriMcD8/wMkTKWUId6DMUYrpa5Symddb1CB9/4IaM09aOHhgLpxyzlf6jxChErsibjuQQsPB1C" +
|
||||
"6hKARCQ8HcHof8eMEvQHwDAX89grOuVNvADx/9AbjJ7DWPkIIh1YztPBwQErprLW+t34maOFZv8G2MlcWIcSESuyI5as3k2d6AZGetvsfEgPvAAAAAE" +
|
||||
"lFTkSuQmCC";
|
||||
|
||||
LoopUI = {
|
||||
/**
|
||||
|
@ -548,7 +555,10 @@ let LoopUI;
|
|||
}
|
||||
|
||||
let reader = new FileReader();
|
||||
reader.onload = () => callback(null, reader.result);
|
||||
reader.onload = () => {
|
||||
let result = reader.result;
|
||||
callback(null, result && result != kDefaultFavicon ? result : null);
|
||||
};
|
||||
reader.onerror = callback;
|
||||
reader.readAsDataURL(xhr.response);
|
||||
};
|
||||
|
|
|
@ -269,10 +269,6 @@ body[dir=rtl] .new-room-view > .context > .context-content > .context-preview {
|
|||
float: left;
|
||||
}
|
||||
|
||||
.new-room-view > .context > .context-content > .context-preview[src=""] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.new-room-view > .context > .context-content > .context-description {
|
||||
flex: 0 1 auto;
|
||||
display: block;
|
||||
|
|
|
@ -29,7 +29,7 @@ loop.conversationViews = (function(mozL10n) {
|
|||
if (!contact.email || contact.email.length === 0) {
|
||||
return { value: "" };
|
||||
}
|
||||
return contact.email.find(e => e.pref) || contact.email[0];
|
||||
return contact.email.find(function find(e) { return e.pref; }) || contact.email[0];
|
||||
}
|
||||
|
||||
function _getContactDisplayName(contact) {
|
||||
|
|
|
@ -29,7 +29,7 @@ loop.conversationViews = (function(mozL10n) {
|
|||
if (!contact.email || contact.email.length === 0) {
|
||||
return { value: "" };
|
||||
}
|
||||
return contact.email.find(e => e.pref) || contact.email[0];
|
||||
return contact.email.find(function find(e) { return e.pref; }) || contact.email[0];
|
||||
}
|
||||
|
||||
function _getContactDisplayName(contact) {
|
||||
|
|
|
@ -500,9 +500,8 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
return (
|
||||
React.createElement("div", {className: "room-entry-context-item"},
|
||||
React.createElement("a", {href: roomUrl.location, onClick: this.handleClick},
|
||||
React.createElement("img", {title: roomUrl.description,
|
||||
src: roomUrl.thumbnail})
|
||||
React.createElement("a", {href: roomUrl.location, title: roomUrl.description, onClick: this.handleClick},
|
||||
React.createElement("img", {src: roomUrl.thumbnail || "loop/shared/img/icons-16x16.svg#globe"})
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -766,6 +765,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
hide: !hostname ||
|
||||
!this.props.mozLoop.getLoopPref("contextInConversations.enabled")
|
||||
});
|
||||
var thumbnail = this.state.previewImage || "loop/shared/img/icons-16x16.svg#globe";
|
||||
|
||||
return (
|
||||
React.createElement("div", {className: "new-room-view"},
|
||||
|
@ -773,7 +773,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
React.createElement(Checkbox, {label: mozL10n.get("context_inroom_label"),
|
||||
onChange: this.onCheckboxChange}),
|
||||
React.createElement("div", {className: "context-content"},
|
||||
React.createElement("img", {className: "context-preview", src: this.state.previewImage}),
|
||||
React.createElement("img", {className: "context-preview", src: thumbnail}),
|
||||
React.createElement("span", {className: "context-description"},
|
||||
this.state.description,
|
||||
React.createElement("span", {className: "context-url"}, hostname)
|
||||
|
|
|
@ -500,9 +500,8 @@ loop.panel = (function(_, mozL10n) {
|
|||
|
||||
return (
|
||||
<div className="room-entry-context-item">
|
||||
<a href={roomUrl.location} onClick={this.handleClick}>
|
||||
<img title={roomUrl.description}
|
||||
src={roomUrl.thumbnail} />
|
||||
<a href={roomUrl.location} title={roomUrl.description} onClick={this.handleClick}>
|
||||
<img src={roomUrl.thumbnail || "loop/shared/img/icons-16x16.svg#globe"} />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
@ -766,6 +765,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
hide: !hostname ||
|
||||
!this.props.mozLoop.getLoopPref("contextInConversations.enabled")
|
||||
});
|
||||
var thumbnail = this.state.previewImage || "loop/shared/img/icons-16x16.svg#globe";
|
||||
|
||||
return (
|
||||
<div className="new-room-view">
|
||||
|
@ -773,7 +773,7 @@ loop.panel = (function(_, mozL10n) {
|
|||
<Checkbox label={mozL10n.get("context_inroom_label")}
|
||||
onChange={this.onCheckboxChange} />
|
||||
<div className="context-content">
|
||||
<img className="context-preview" src={this.state.previewImage}/>
|
||||
<img className="context-preview" src={thumbnail} />
|
||||
<span className="context-description">
|
||||
{this.state.description}
|
||||
<span className="context-url">{hostname}</span>
|
||||
|
|
|
@ -473,7 +473,7 @@ loop.roomViews = (function(mozL10n) {
|
|||
}
|
||||
|
||||
var url = this._getURL();
|
||||
var thumbnail = url && url.thumbnail || "";
|
||||
var thumbnail = url && url.thumbnail || "loop/shared/img/icons-16x16.svg#globe";
|
||||
var urlDescription = url && url.description || "";
|
||||
var location = url && url.location || "";
|
||||
var locationData = null;
|
||||
|
|
|
@ -473,7 +473,7 @@ loop.roomViews = (function(mozL10n) {
|
|||
}
|
||||
|
||||
var url = this._getURL();
|
||||
var thumbnail = url && url.thumbnail || "";
|
||||
var thumbnail = url && url.thumbnail || "loop/shared/img/icons-16x16.svg#globe";
|
||||
var urlDescription = url && url.description || "";
|
||||
var location = url && url.location || "";
|
||||
var locationData = null;
|
||||
|
@ -546,7 +546,7 @@ loop.roomViews = (function(mozL10n) {
|
|||
<div className="room-context-label">{mozL10n.get("context_inroom_label")}</div>
|
||||
<div className="room-context-content"
|
||||
onClick={this.handleContextClick}>
|
||||
<img className="room-context-thumbnail" src={thumbnail}/>
|
||||
<img className="room-context-thumbnail" src={thumbnail} />
|
||||
<div className="room-context-description"
|
||||
title={urlDescription}>
|
||||
{this._truncate(urlDescription)}
|
||||
|
|
|
@ -979,10 +979,6 @@ body[platform="win"] .share-service-dropdown.overflow > .dropdown-menu-item {
|
|||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
.room-context-thumbnail[src=""] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.room-context > .error-display-area.error {
|
||||
display: block;
|
||||
background-color: rgba(215,67,69,.8);
|
||||
|
@ -1218,9 +1214,8 @@ body[dir=rtl] .room-context-btn-edit {
|
|||
|
||||
.standalone-context-url > img {
|
||||
margin: 1em auto;
|
||||
max-width: 50%;
|
||||
/* allows 20% for the description wrapper plus the margins */
|
||||
max-height: calc(80% - 2em);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.standalone-context-url-description-wrapper {
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
До Ширина: | Высота: | Размер: 13 KiB После Ширина: | Высота: | Размер: 73 KiB |
|
@ -262,7 +262,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
|
||||
return (
|
||||
React.createElement("div", {className: classes},
|
||||
React.createElement("img", {src: this.props.roomContextUrl.thumbnail}),
|
||||
React.createElement("img", {src: this.props.roomContextUrl.thumbnail || "shared/img/icons-16x16.svg#globe"}),
|
||||
React.createElement("div", {className: "standalone-context-url-description-wrapper"},
|
||||
this.props.roomContextUrl.description,
|
||||
React.createElement("br", null), React.createElement("a", {href: locationInfo.location,
|
||||
|
|
|
@ -262,7 +262,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
|||
|
||||
return (
|
||||
<div className={classes}>
|
||||
<img src={this.props.roomContextUrl.thumbnail} />
|
||||
<img src={this.props.roomContextUrl.thumbnail || "shared/img/icons-16x16.svg#globe"} />
|
||||
<div className="standalone-context-url-description-wrapper">
|
||||
{this.props.roomContextUrl.description}
|
||||
<br /><a href={locationInfo.location}
|
||||
|
|
|
@ -850,6 +850,24 @@ describe("loop.panel", function() {
|
|||
expect(contextContent).to.not.equal(null);
|
||||
});
|
||||
|
||||
it("should show a default favicon when none is available", function() {
|
||||
fakeMozLoop.getSelectedTabMetadata = function (callback) {
|
||||
callback({
|
||||
url: "https://www.example.com",
|
||||
description: "fake description",
|
||||
previews: [""]
|
||||
});
|
||||
};
|
||||
|
||||
var view = createTestComponent();
|
||||
|
||||
// Simulate being visible
|
||||
view.onDocumentVisible();
|
||||
|
||||
var previewImage = view.getDOMNode().querySelector(".context-preview");
|
||||
expect(previewImage.src).to.match(/loop\/shared\/img\/icons-16x16.svg#globe$/);
|
||||
});
|
||||
|
||||
it("should not show context information when a URL is unavailable", function() {
|
||||
fakeMozLoop.getSelectedTabMetadata = function (callback) {
|
||||
callback({
|
||||
|
|
|
@ -305,6 +305,19 @@ describe("loop.roomViews", function () {
|
|||
expect(view.getDOMNode().querySelector(".room-context-url").textContent)
|
||||
.eql("hostname");
|
||||
});
|
||||
|
||||
it("should show a default favicon when none is available", function() {
|
||||
fakeContextURL.thumbnail = null;
|
||||
view = mountTestComponent({
|
||||
showContext: true,
|
||||
roomData: {
|
||||
roomContextUrls: [fakeContextURL]
|
||||
}
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".room-context-thumbnail").src)
|
||||
.to.match(/loop\/shared\/img\/icons-16x16.svg#globe$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -35,3 +35,16 @@ add_task(function* test_mozLoop_getSelectedTabMetadata() {
|
|||
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(function* test_mozLoop_getSelectedTabMetadata_defaultIcon() {
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
yield promiseTabLoadEvent(tab, "http://example.com/");
|
||||
let metadata = yield promiseGetMetadata();
|
||||
|
||||
Assert.strictEqual(metadata.url, "http://example.com/", "URL should match");
|
||||
Assert.strictEqual(metadata.favicon, null, "Favicon should be empty");
|
||||
Assert.ok(metadata.title, "Title should be set");
|
||||
Assert.deepEqual(metadata.previews, [], "No previews available");
|
||||
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
|
|
@ -149,6 +149,20 @@ describe("loop.standaloneRoomViews", function() {
|
|||
linkInfo: "Shared URL"
|
||||
}));
|
||||
});
|
||||
|
||||
it("should display the default favicon when no thumbnail is available", function() {
|
||||
var view = mountTestComponent({
|
||||
roomName: "Mike's room",
|
||||
roomContextUrls: [{
|
||||
description: "Mark's super page",
|
||||
location: "http://invalid.com",
|
||||
thumbnail: ""
|
||||
}]
|
||||
});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".standalone-context-url > img").src)
|
||||
.to.match(/shared\/img\/icons-16x16.svg#globe$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("StandaloneRoomHeader", function() {
|
||||
|
|
|
@ -140,10 +140,6 @@ body {
|
|||
|
||||
.svg-icon {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: .5rem;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 16px 16px;
|
||||
background-position: center;
|
||||
border: 0;
|
||||
}
|
||||
|
|
|
@ -299,13 +299,12 @@
|
|||
|
||||
var SVGIcon = React.createClass({displayName: "SVGIcon",
|
||||
render: function() {
|
||||
var sizeUnit = this.props.size.split("x")[0] + "px";
|
||||
var sizeUnit = this.props.size.split("x");
|
||||
return (
|
||||
React.createElement("span", {className: "svg-icon", style: {
|
||||
"backgroundImage": "url(../content/shared/img/icons-" + this.props.size +
|
||||
".svg#" + this.props.shapeId + ")",
|
||||
"backgroundSize": sizeUnit + " " + sizeUnit
|
||||
}})
|
||||
React.createElement("img", {className: "svg-icon",
|
||||
src: "../content/shared/img/icons-" + this.props.size + ".svg#" + this.props.shapeId,
|
||||
width: sizeUnit[0],
|
||||
height: sizeUnit[1]})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -327,7 +326,7 @@
|
|||
],
|
||||
"16x16": ["add", "add-hover", "add-active", "audio", "audio-hover", "audio-active",
|
||||
"block", "block-red", "block-hover", "block-active", "contacts", "contacts-hover",
|
||||
"contacts-active", "copy", "checkmark", "delete", "google", "google-hover",
|
||||
"contacts-active", "copy", "checkmark", "delete", "globe", "google", "google-hover",
|
||||
"google-active", "history", "history-hover", "history-active", "leave",
|
||||
"precall", "precall-hover", "precall-active", "screen-white", "screenmute-white",
|
||||
"settings", "settings-hover", "settings-active", "share-darkgrey", "tag",
|
||||
|
|
|
@ -299,13 +299,12 @@
|
|||
|
||||
var SVGIcon = React.createClass({
|
||||
render: function() {
|
||||
var sizeUnit = this.props.size.split("x")[0] + "px";
|
||||
var sizeUnit = this.props.size.split("x");
|
||||
return (
|
||||
<span className="svg-icon" style={{
|
||||
"backgroundImage": "url(../content/shared/img/icons-" + this.props.size +
|
||||
".svg#" + this.props.shapeId + ")",
|
||||
"backgroundSize": sizeUnit + " " + sizeUnit
|
||||
}} />
|
||||
<img className="svg-icon"
|
||||
src={"../content/shared/img/icons-" + this.props.size + ".svg#" + this.props.shapeId}
|
||||
width={sizeUnit[0]}
|
||||
height={sizeUnit[1]} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -327,7 +326,7 @@
|
|||
],
|
||||
"16x16": ["add", "add-hover", "add-active", "audio", "audio-hover", "audio-active",
|
||||
"block", "block-red", "block-hover", "block-active", "contacts", "contacts-hover",
|
||||
"contacts-active", "copy", "checkmark", "delete", "google", "google-hover",
|
||||
"contacts-active", "copy", "checkmark", "delete", "globe", "google", "google-hover",
|
||||
"google-active", "history", "history-hover", "history-active", "leave",
|
||||
"precall", "precall-hover", "precall-active", "screen-white", "screenmute-white",
|
||||
"settings", "settings-hover", "settings-active", "share-darkgrey", "tag",
|
||||
|
|
Загрузка…
Ссылка в новой задаче