Bug 1538549 - [de-xbl] convert contact binding to custom element. r=mkmelin DONTBUILD
--HG-- rename : mail/components/im/content/imcontact.xml => mail/components/im/content/chat-contact.js
This commit is contained in:
Родитель
08bb5a6f90
Коммит
7f335f59f7
|
@ -433,7 +433,7 @@
|
||||||
if (localName == "imconv" && elt.conv)
|
if (localName == "imconv" && elt.conv)
|
||||||
return updateTooltipFromConversation(elt.conv);
|
return updateTooltipFromConversation(elt.conv);
|
||||||
|
|
||||||
if (localName == "imcontact")
|
if (localName == "richlistitem" && elt.getAttribute("is") == "chat-contact")
|
||||||
return updateTooltipFromBuddy(elt.contact.preferredBuddy.preferredAccountBuddy);
|
return updateTooltipFromBuddy(elt.contact.preferredBuddy.preferredAccountBuddy);
|
||||||
|
|
||||||
if (localName == "richlistitem") {
|
if (localName == "richlistitem") {
|
||||||
|
|
|
@ -150,6 +150,7 @@
|
||||||
<script type="application/javascript" src="chrome://messenger/content/newmailaccount/uriListener.js"/>
|
<script type="application/javascript" src="chrome://messenger/content/newmailaccount/uriListener.js"/>
|
||||||
<script type="application/javascript" src="chrome://messenger/content/chat/chat-conversation-info.js"/>
|
<script type="application/javascript" src="chrome://messenger/content/chat/chat-conversation-info.js"/>
|
||||||
<script type="application/javascript" src="chrome://gloda/content/autocomplete-richlistitem.js"/>
|
<script type="application/javascript" src="chrome://gloda/content/autocomplete-richlistitem.js"/>
|
||||||
|
<script type="application/javascript" src="chrome://messenger/content/chat/chat-contact.js"/>
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
<script type="application/javascript" src="chrome://messenger/content/macMessengerMenu.js"/>
|
<script type="application/javascript" src="chrome://messenger/content/macMessengerMenu.js"/>
|
||||||
<script type="application/javascript" src="chrome://global/content/macWindowMenu.js"/>
|
<script type="application/javascript" src="chrome://global/content/macWindowMenu.js"/>
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
overrides: [{
|
overrides: [{
|
||||||
files: [
|
files: [
|
||||||
"imcontact.xml",
|
|
||||||
"imconv.xml",
|
"imconv.xml",
|
||||||
"imconversation.xml",
|
"imconversation.xml",
|
||||||
],
|
],
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/* global MozXULElement, MozElements, Status, chatHandler */
|
||||||
|
|
||||||
|
{
|
||||||
|
let { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The MozChatContact widget displays contact information about user under
|
||||||
|
* chat-groups, online contacts and offline contacts: i.e. icon and username.
|
||||||
|
* On double clicking the element, it gets moved into the conversations.
|
||||||
|
*
|
||||||
|
* @extends {MozElements.MozRichlistitem}
|
||||||
|
*/
|
||||||
|
class MozChatContact extends MozElements.MozRichlistitem {
|
||||||
|
static get inheritedAttributes() {
|
||||||
|
return {
|
||||||
|
".box-line": "selected",
|
||||||
|
".protoIcon": "src=iconPrpl,status",
|
||||||
|
".statusIcon": "status",
|
||||||
|
".contactDisplayName": "value=displayname,status",
|
||||||
|
".contactStatusText": "value=statusTextWithDash",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
if (this.delayConnectedCallback() || this.hasChildNodes()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setAttribute("is", "chat-contact");
|
||||||
|
|
||||||
|
this.addEventListener("blur", (event) => {
|
||||||
|
if (!this.hasAttribute("aliasing")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Services.focus.activeWindow == document.defaultView) {
|
||||||
|
this.finishAliasing(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addEventListener("mousedown", (event) => {
|
||||||
|
if (!this.hasAttribute("aliasing") && this.canOpenConversation() &&
|
||||||
|
event.originalTarget.classList.contains("startChatBubble")) {
|
||||||
|
this.openConversation();
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addEventListener("click", (event) => {
|
||||||
|
if (!this.hasAttribute("aliasing") && this.canOpenConversation() &&
|
||||||
|
event.detail == 2) {
|
||||||
|
this.openConversation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.parentNode.addEventListener("mousedown", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
|
// @implements {nsIObserver}
|
||||||
|
this.observer = {
|
||||||
|
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver]),
|
||||||
|
observe: (function(subject, topic, data) {
|
||||||
|
if (topic == "contact-preferred-buddy-changed" ||
|
||||||
|
topic == "contact-display-name-changed" ||
|
||||||
|
topic == "contact-status-changed") {
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
if ((topic == "contact-availability-changed" ||
|
||||||
|
topic == "contact-display-name-changed")) {
|
||||||
|
this.group.updateContactPosition(subject);
|
||||||
|
}
|
||||||
|
}).bind(this),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.appendChild(MozXULElement.parseXULToFragment(`
|
||||||
|
<vbox class="box-line"></vbox>
|
||||||
|
<stack class="prplBuddyIcon" mousethrough="always">
|
||||||
|
<image class="protoIcon"></image>
|
||||||
|
<image class="statusIcon"></image>
|
||||||
|
</stack>
|
||||||
|
<hbox flex="1" class="contact-hbox" mousethrough="always">
|
||||||
|
<label crop="end" flex="1" mousethrough="always"
|
||||||
|
class="contactDisplayName blistDisplayName">
|
||||||
|
</label>
|
||||||
|
<label crop="end" flex="100000" mousethrough="always"
|
||||||
|
class="contactStatusText">
|
||||||
|
</label>
|
||||||
|
<button class="startChatBubble" tooltiptext="&openConversationButton.tooltip;">
|
||||||
|
</button>
|
||||||
|
</hbox>
|
||||||
|
`, ["chrome://messenger/locale/chat.dtd"]));
|
||||||
|
|
||||||
|
this.initializeAttributeInheritance();
|
||||||
|
}
|
||||||
|
|
||||||
|
get displayName() {
|
||||||
|
return this.contact.displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.setAttribute("displayname", this.contact.displayName);
|
||||||
|
|
||||||
|
let statusText = this.contact.statusText;
|
||||||
|
if (statusText) {
|
||||||
|
statusText = " - " + statusText;
|
||||||
|
}
|
||||||
|
this.setAttribute("statusTextWithDash", statusText);
|
||||||
|
let statusType = this.contact.statusType;
|
||||||
|
this.setAttribute("statusText", Status.toLabel(statusType) + statusText);
|
||||||
|
this.setAttribute("status", Status.toAttribute(statusType));
|
||||||
|
|
||||||
|
if (this.contact.canSendMessage) {
|
||||||
|
this.setAttribute("cansend", "true");
|
||||||
|
} else {
|
||||||
|
this.removeAttribute("cansend");
|
||||||
|
}
|
||||||
|
|
||||||
|
let proto = this.contact.preferredBuddy.protocol;
|
||||||
|
this.setAttribute("iconPrpl", proto.iconBaseURI + "icon.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
build(contact) {
|
||||||
|
this.contact = contact;
|
||||||
|
this.contact.addObserver(this.observer);
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.contact.removeObserver(this.observer);
|
||||||
|
delete this.contact;
|
||||||
|
this.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
startAliasing() {
|
||||||
|
if (this.hasAttribute("aliasing")) {
|
||||||
|
return; // prevent re-entry.
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setAttribute("aliasing", "true");
|
||||||
|
let textbox = this.querySelector(".contactDisplayName");
|
||||||
|
textbox.getBoundingClientRect(); // force binding attachmant by forcing layout
|
||||||
|
textbox.select();
|
||||||
|
|
||||||
|
// Some keys (home/end for example) can make the selected item
|
||||||
|
// of the richlistbox change without producing a blur event on
|
||||||
|
// our textbox. Make sure we watch richlistbox selection changes.
|
||||||
|
this._parentSelectListener = (function(event) {
|
||||||
|
if (event.target == this.parentNode) {
|
||||||
|
this.finishAliasing(true);
|
||||||
|
}
|
||||||
|
}).bind(this);
|
||||||
|
this.parentNode.addEventListener("select", this._parentSelectListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
finishAliasing(save) {
|
||||||
|
// Cache the parentNode because when we change the contact alias, we
|
||||||
|
// trigger a re-order (and a removeContact call), which sets
|
||||||
|
// this.parentNode to undefined.
|
||||||
|
let listbox = this.parentNode;
|
||||||
|
if (save) {
|
||||||
|
this.contact.alias = this.querySelector(".contactDisplayName").value;
|
||||||
|
}
|
||||||
|
this.removeAttribute("aliasing");
|
||||||
|
listbox.removeEventListener("select", this._parentSelectListener);
|
||||||
|
delete this._parentSelectListener;
|
||||||
|
listbox.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteContact() {
|
||||||
|
this.contact.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
canOpenConversation() {
|
||||||
|
return this.contact.canSendMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
openConversation() {
|
||||||
|
let prplConv = this.contact.createConversation();
|
||||||
|
let uiConv = Services.conversations.getUIConversation(prplConv);
|
||||||
|
chatHandler.focusConversation(uiConv);
|
||||||
|
}
|
||||||
|
|
||||||
|
keyPress(event) {
|
||||||
|
switch (event.keyCode) {
|
||||||
|
// If Enter or Return is pressed, open a new conversation
|
||||||
|
case event.DOM_VK_RETURN:
|
||||||
|
if (this.hasAttribute("aliasing")) {
|
||||||
|
this.finishAliasing(true);
|
||||||
|
} else if (this.canOpenConversation()) {
|
||||||
|
this.openConversation();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case event.DOM_VK_F2:
|
||||||
|
if (!this.hasAttribute("aliasing")) {
|
||||||
|
this.startAliasing();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case event.DOM_VK_ESCAPE:
|
||||||
|
if (this.hasAttribute("aliasing")) {
|
||||||
|
this.finishAliasing(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
disconnectedCallback() {
|
||||||
|
if (this.contact) {
|
||||||
|
this.contact.removeObserver(this.observer);
|
||||||
|
delete this.contact;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MozXULElement.implementCustomInterface(
|
||||||
|
MozChatContact, [Ci.nsIDOMXULSelectControlItemElement]
|
||||||
|
);
|
||||||
|
|
||||||
|
customElements.define("chat-contact", MozChatContact, { "extends": "richlistitem" });
|
||||||
|
}
|
|
@ -18,7 +18,9 @@ function buddyListContextMenu(aXulMenu) {
|
||||||
this.target = aXulMenu.triggerNode;
|
this.target = aXulMenu.triggerNode;
|
||||||
this.menu = aXulMenu;
|
this.menu = aXulMenu;
|
||||||
let localName = this.target.localName;
|
let localName = this.target.localName;
|
||||||
this.onContact = localName == "imcontact";
|
document.getElementById("contactlistbox").selectedItem = this.target;
|
||||||
|
this.onContact = (localName == "richlistitem" &&
|
||||||
|
this.target.getAttribute("is") == "chat-contact");
|
||||||
this.onConv = localName == "imconv";
|
this.onConv = localName == "imconv";
|
||||||
this.shouldDisplay = this.onContact || this.onConv;
|
this.shouldDisplay = this.onContact || this.onConv;
|
||||||
|
|
||||||
|
@ -283,8 +285,9 @@ var chatHandler = {
|
||||||
(!selectedItem || (selectedItem == convs &&
|
(!selectedItem || (selectedItem == convs &&
|
||||||
convs.nextSibling.localName != "imconv"));
|
convs.nextSibling.localName != "imconv"));
|
||||||
let elt = convs.addContact(aConv, "imconv");
|
let elt = convs.addContact(aConv, "imconv");
|
||||||
if (shouldSelect)
|
if (shouldSelect) {
|
||||||
list.selectedItem = elt;
|
list.selectedItem = elt;
|
||||||
|
}
|
||||||
|
|
||||||
if (aConv.isChat || !aConv.buddy)
|
if (aConv.isChat || !aConv.buddy)
|
||||||
return;
|
return;
|
||||||
|
@ -293,8 +296,9 @@ var chatHandler = {
|
||||||
elt.imContact = contact;
|
elt.imContact = contact;
|
||||||
let groupName = (contact.online ? "on" : "off") + "linecontactsGroup";
|
let groupName = (contact.online ? "on" : "off") + "linecontactsGroup";
|
||||||
let item = document.getElementById(groupName).removeContact(contact);
|
let item = document.getElementById(groupName).removeContact(contact);
|
||||||
if (list.selectedItem == item)
|
if (list.selectedItem == item) {
|
||||||
list.selectedItem = elt;
|
list.selectedItem = elt;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_hasConversationForContact(aContact) {
|
_hasConversationForContact(aContact) {
|
||||||
|
@ -552,7 +556,7 @@ var chatHandler = {
|
||||||
document.getElementById("conversationsDeck").selectedPanel = item.convView;
|
document.getElementById("conversationsDeck").selectedPanel = item.convView;
|
||||||
document.getElementById("logTree").view.selection.clearSelection();
|
document.getElementById("logTree").view.selection.clearSelection();
|
||||||
item.convView.focus();
|
item.convView.focus();
|
||||||
} else if (item.localName == "imcontact") {
|
} else if (item.localName == "richlistitem" && item.getAttribute("is") == "chat-contact") {
|
||||||
item.openConversation();
|
item.openConversation();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -680,12 +684,12 @@ var chatHandler = {
|
||||||
button.label = bundle.getString("goBackToCurrentConversation.button");
|
button.label = bundle.getString("goBackToCurrentConversation.button");
|
||||||
button.disabled = false;
|
button.disabled = false;
|
||||||
this.observedContact = null;
|
this.observedContact = null;
|
||||||
} else if (item.localName == "imcontact") {
|
} else if (item.localName == "richlistitem" && item.getAttribute("is") == "chat-contact") {
|
||||||
let contact = item.contact;
|
let contact = item.contact;
|
||||||
if (this.observedContact && contact &&
|
if (this.observedContact && contact &&
|
||||||
this.observedContact.id == contact.id) {
|
this.observedContact.id == contact.id) {
|
||||||
return; // onselect has just been fired again because a status
|
return; // onselect has just been fired again because a status
|
||||||
// change caused the imcontact to move.
|
// change caused the chat-contact to move.
|
||||||
// Return early to avoid flickering and changing the selected log.
|
// Return early to avoid flickering and changing the selected log.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,7 @@ imgroup {
|
||||||
-moz-box-align: center;
|
-moz-box-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
imcontact {
|
richlistitem[is="chat-contact"] {
|
||||||
-moz-binding: url("chrome://messenger/content/chat/imcontact.xml#contact");
|
|
||||||
-moz-box-align: center;
|
-moz-box-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ imcontact {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
imcontact[cansend]:hover .startChatBubble {
|
richlistitem[is="chat-contact"][cansend]:hover .startChatBubble {
|
||||||
display: -moz-box;
|
display: -moz-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,245 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!-- 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/. -->
|
|
||||||
|
|
||||||
<!DOCTYPE bindings [
|
|
||||||
<!ENTITY % chatDTD SYSTEM "chrome://messenger/locale/chat.dtd" >
|
|
||||||
%chatDTD;
|
|
||||||
]>
|
|
||||||
|
|
||||||
<bindings id="contactBindings"
|
|
||||||
xmlns="http://www.mozilla.org/xbl"
|
|
||||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
||||||
xmlns:xbl="http://www.mozilla.org/xbl"
|
|
||||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
|
||||||
|
|
||||||
<binding id="contact" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
|
||||||
<content>
|
|
||||||
<xul:vbox class="box-line" xbl:inherits="selected"/>
|
|
||||||
<xul:stack class="prplBuddyIcon" mousethrough="always">
|
|
||||||
<xul:image class="protoIcon" xbl:inherits="src=iconPrpl,status"/>
|
|
||||||
<xul:image class="statusIcon" xbl:inherits="status"/>
|
|
||||||
</xul:stack>
|
|
||||||
<xul:hbox flex="1" class="contact-hbox" mousethrough="always">
|
|
||||||
<xul:label crop="end" flex="1" mousethrough="always"
|
|
||||||
anonid="displayname" class="contactDisplayName blistDisplayName"
|
|
||||||
xbl:inherits="value=displayname,status"/>
|
|
||||||
<xul:label crop="end" flex="100000" mousethrough="always"
|
|
||||||
anonid="statusText" class="contactStatusText"
|
|
||||||
xbl:inherits="value=statusTextWithDash"/>
|
|
||||||
<xul:button anonid="startChatBubble" class="startChatBubble"
|
|
||||||
tooltiptext="&openConversationButton.tooltip;"/>
|
|
||||||
</xul:hbox>
|
|
||||||
</content>
|
|
||||||
<implementation implements="nsIObserver">
|
|
||||||
|
|
||||||
<destructor>
|
|
||||||
<![CDATA[
|
|
||||||
if (this.contact) {
|
|
||||||
this.contact.removeObserver(this);
|
|
||||||
delete this.contact;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</destructor>
|
|
||||||
|
|
||||||
<method name="build">
|
|
||||||
<parameter name="aContact"/>
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
this.contact = aContact;
|
|
||||||
this.contact.addObserver(this);
|
|
||||||
this.update();
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<property name="displayName"
|
|
||||||
onget="return this.contact.displayName;"/>
|
|
||||||
|
|
||||||
<!-- nsIObserver implementation -->
|
|
||||||
<method name="observe">
|
|
||||||
<parameter name="aSubject"/>
|
|
||||||
<parameter name="aTopic"/>
|
|
||||||
<parameter name="aData"/>
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
if (aTopic == "contact-preferred-buddy-changed" ||
|
|
||||||
aTopic == "contact-display-name-changed" ||
|
|
||||||
aTopic == "contact-status-changed")
|
|
||||||
this.update();
|
|
||||||
|
|
||||||
if (aTopic == "contact-availability-changed" ||
|
|
||||||
aTopic == "contact-display-name-changed")
|
|
||||||
this.group.updateContactPosition(aSubject);
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="destroy">
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
this.contact.removeObserver(this);
|
|
||||||
delete this.contact;
|
|
||||||
this.remove();
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="update">
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
this.setAttribute("displayname", this.contact.displayName);
|
|
||||||
|
|
||||||
let statusText = this.contact.statusText;
|
|
||||||
if (statusText)
|
|
||||||
statusText = " - " + statusText;
|
|
||||||
this.setAttribute("statusTextWithDash", statusText);
|
|
||||||
let statusType = this.contact.statusType;
|
|
||||||
this.setAttribute("statusText", Status.toLabel(statusType) + statusText);
|
|
||||||
this.setAttribute("status", Status.toAttribute(statusType));
|
|
||||||
|
|
||||||
if (this.contact.canSendMessage)
|
|
||||||
this.setAttribute("cansend", "true");
|
|
||||||
else
|
|
||||||
this.removeAttribute("cansend");
|
|
||||||
|
|
||||||
let proto = this.contact.preferredBuddy.protocol;
|
|
||||||
this.setAttribute("iconPrpl", proto.iconBaseURI + "icon.png");
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="startAliasing">
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
if (this.hasAttribute("aliasing"))
|
|
||||||
return; // prevent re-entry.
|
|
||||||
|
|
||||||
this.setAttribute("aliasing", "true");
|
|
||||||
let textbox =
|
|
||||||
document.getAnonymousElementByAttribute(this, "anonid", "displayname");
|
|
||||||
textbox.getBoundingClientRect(); // force binding attachmant by forcing layout
|
|
||||||
textbox.select();
|
|
||||||
|
|
||||||
// Some keys (home/end for example) can make the selected item
|
|
||||||
// of the richlistbox change without producing a blur event on
|
|
||||||
// our textbox. Make sure we watch richlistbox selection changes.
|
|
||||||
this._parentSelectListener = (function(aEvent) {
|
|
||||||
if (aEvent.target == this.parentNode)
|
|
||||||
this.finishAliasing(true);
|
|
||||||
}).bind(this);
|
|
||||||
this.parentNode.addEventListener("select", this._parentSelectListener);
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="finishAliasing">
|
|
||||||
<parameter name="aSave"/>
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
// Cache the parentNode because when we change the contact alias, we
|
|
||||||
// trigger a re-order (and a removeContact call), which sets
|
|
||||||
// this.parentNode to undefined.
|
|
||||||
let listbox = this.parentNode;
|
|
||||||
if (aSave) {
|
|
||||||
this.contact.alias = document.getAnonymousElementByAttribute(this, "anonid",
|
|
||||||
"displayname").value;
|
|
||||||
}
|
|
||||||
this.removeAttribute("aliasing");
|
|
||||||
listbox.removeEventListener("select", this._parentSelectListener);
|
|
||||||
delete this._parentSelectListener;
|
|
||||||
listbox.focus();
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="deleteContact">
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
this.contact.remove();
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="canOpenConversation">
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
return this.contact.canSendMessage;
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="openConversation">
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
let prplConv = this.contact.createConversation();
|
|
||||||
let uiConv = Services.conversations.getUIConversation(prplConv);
|
|
||||||
chatHandler.focusConversation(uiConv);
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
|
|
||||||
<method name="keyPress">
|
|
||||||
<parameter name="aEvent"/>
|
|
||||||
<body>this._keyPress(aEvent);</body>
|
|
||||||
</method>
|
|
||||||
<method name="_keyPress">
|
|
||||||
<parameter name="aEvent"/>
|
|
||||||
<body>
|
|
||||||
<![CDATA[
|
|
||||||
switch (aEvent.keyCode) {
|
|
||||||
// If Enter or Return is pressed, open a new conversation
|
|
||||||
case aEvent.DOM_VK_RETURN:
|
|
||||||
if (this.hasAttribute("aliasing"))
|
|
||||||
this.finishAliasing(true);
|
|
||||||
else if (this.canOpenConversation())
|
|
||||||
this.openConversation();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case aEvent.DOM_VK_F2:
|
|
||||||
if (!this.hasAttribute("aliasing"))
|
|
||||||
this.startAliasing();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case aEvent.DOM_VK_ESCAPE:
|
|
||||||
if (this.hasAttribute("aliasing"))
|
|
||||||
this.finishAliasing(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</body>
|
|
||||||
</method>
|
|
||||||
</implementation>
|
|
||||||
<handlers>
|
|
||||||
<handler event="blur">
|
|
||||||
<![CDATA[
|
|
||||||
if (!this.hasAttribute("aliasing"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (Services.focus.activeWindow == document.defaultView)
|
|
||||||
this.finishAliasing(true);
|
|
||||||
]]>
|
|
||||||
</handler>
|
|
||||||
|
|
||||||
<handler event="mousedown">
|
|
||||||
<![CDATA[
|
|
||||||
if (!this.hasAttribute("aliasing") && this.canOpenConversation() &&
|
|
||||||
event.originalTarget.getAttribute("anonid") == "startChatBubble") {
|
|
||||||
this.openConversation();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
]]>
|
|
||||||
</handler>
|
|
||||||
|
|
||||||
<handler event="click">
|
|
||||||
<![CDATA[
|
|
||||||
if (!this.hasAttribute("aliasing") && this.canOpenConversation() &&
|
|
||||||
event.detail == 2 &&
|
|
||||||
event.originalTarget.getAttribute("anonid") != "expander")
|
|
||||||
this.openConversation();
|
|
||||||
]]>
|
|
||||||
</handler>
|
|
||||||
</handlers>
|
|
||||||
</binding>
|
|
||||||
</bindings>
|
|
|
@ -55,7 +55,12 @@
|
||||||
if (this.contactsById.hasOwnProperty(aContact.id))
|
if (this.contactsById.hasOwnProperty(aContact.id))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
let contactElt = document.createElement(aTagName || "imcontact");
|
let contactElt;
|
||||||
|
if (aTagName) {
|
||||||
|
contactElt = document.createElement(aTagName);
|
||||||
|
} else {
|
||||||
|
contactElt = document.createElement("richlistitem", { is: "chat-contact" });
|
||||||
|
}
|
||||||
if (this.hasAttribute("closed"))
|
if (this.hasAttribute("closed"))
|
||||||
contactElt.setAttribute("collapsed", "true");
|
contactElt.setAttribute("collapsed", "true");
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ messenger.jar:
|
||||||
content/messenger/chat/imAccountWizard.js (content/imAccountWizard.js)
|
content/messenger/chat/imAccountWizard.js (content/imAccountWizard.js)
|
||||||
content/messenger/chat/imContextMenu.js (content/imContextMenu.js)
|
content/messenger/chat/imContextMenu.js (content/imContextMenu.js)
|
||||||
content/messenger/chat/imStatusSelector.js (content/imStatusSelector.js)
|
content/messenger/chat/imStatusSelector.js (content/imStatusSelector.js)
|
||||||
content/messenger/chat/imcontact.xml (content/imcontact.xml)
|
content/messenger/chat/chat-contact.js (content/chat-contact.js)
|
||||||
content/messenger/chat/imconversation.xml (content/imconversation.xml)
|
content/messenger/chat/imconversation.xml (content/imconversation.xml)
|
||||||
content/messenger/chat/imconv.xml (content/imconv.xml)
|
content/messenger/chat/imconv.xml (content/imconv.xml)
|
||||||
content/messenger/chat/imgroup.xml (content/imgroup.xml)
|
content/messenger/chat/imgroup.xml (content/imgroup.xml)
|
||||||
|
|
|
@ -96,12 +96,12 @@
|
||||||
|
|
||||||
/* move the scrollbar to the left */
|
/* move the scrollbar to the left */
|
||||||
#contactlistbox:-moz-locale-dir(ltr),
|
#contactlistbox:-moz-locale-dir(ltr),
|
||||||
#contactlistbox:-moz-locale-dir(rtl) > :-moz-any(imconv, imcontact, imgroup) {
|
#contactlistbox:-moz-locale-dir(rtl) > :-moz-any(imconv, richlistitem[is="chat-contact"], imgroup) {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#contactlistbox:-moz-locale-dir(rtl),
|
#contactlistbox:-moz-locale-dir(rtl),
|
||||||
#contactlistbox:-moz-locale-dir(ltr) > :-moz-any(imconv, imcontact, imgroup) {
|
#contactlistbox:-moz-locale-dir(ltr) > :-moz-any(imconv, richlistitem[is="chat-contact"], imgroup) {
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ imgroup[selected] {
|
||||||
}
|
}
|
||||||
|
|
||||||
imconv,
|
imconv,
|
||||||
imcontact {
|
richlistitem[is="chat-contact"] {
|
||||||
border-top: 1px solid transparent;
|
border-top: 1px solid transparent;
|
||||||
border-bottom: 1px solid transparent;
|
border-bottom: 1px solid transparent;
|
||||||
-moz-box-align: stretch;
|
-moz-box-align: stretch;
|
||||||
|
@ -139,7 +139,7 @@ imcontact {
|
||||||
width: 2px;
|
width: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
imcontact > .box-line {
|
richlistitem[is="chat-contact"] > .box-line {
|
||||||
/* equalize the space, the .closeConversationButton uses */
|
/* equalize the space, the .closeConversationButton uses */
|
||||||
margin-inline-end: 22px;
|
margin-inline-end: 22px;
|
||||||
}
|
}
|
||||||
|
@ -148,45 +148,45 @@ imcontact > .box-line {
|
||||||
background-color: var(--tabline-color);
|
background-color: var(--tabline-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
:-moz-any(imconv, imcontact, imgroup) {
|
:-moz-any(imconv, richlistitem[is="chat-contact"], imgroup) {
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
:-moz-any(imconv, imcontact, imgroup):not([selected=true]):hover {
|
:-moz-any(imconv, richlistitem[is="chat-contact"], imgroup):not([selected=true]):hover {
|
||||||
background-color: rgba(0,0,0,.1);
|
background-color: rgba(0,0,0,.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[lwt-tree] imgroup,
|
:root[lwt-tree] imgroup,
|
||||||
:root[lwt-tree] imconv:not([selected]),
|
:root[lwt-tree] imconv:not([selected]),
|
||||||
:root[lwt-tree] imcontact:not([selected]) {
|
:root[lwt-tree] richlistitem[is="chat-contact"]:not([selected]) {
|
||||||
color: var(--sidebar-text-color);
|
color: var(--sidebar-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
imconv[selected=true],
|
imconv[selected=true],
|
||||||
imcontact[selected=true] {
|
richlistitem[is="chat-contact"][selected=true] {
|
||||||
background-color: var(--imbox-selected-background-color);
|
background-color: var(--imbox-selected-background-color);
|
||||||
border-color: var(--imbox-selected-border-color);
|
border-color: var(--imbox-selected-border-color);
|
||||||
color: var(--imbox-selected-text-color);
|
color: var(--imbox-selected-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[lwt-tree] imgroup[selected],
|
:root[lwt-tree] imgroup[selected],
|
||||||
:root[lwt-tree] :-moz-any(imconv, imcontact, imgroup):not([selected=true]):hover {
|
:root[lwt-tree] :-moz-any(imconv, richlistitem[is="chat-contact"], imgroup):not([selected=true]):hover {
|
||||||
background-color: var(--sidebar-highlight-background-color, hsla(0,0%,80%,.3));
|
background-color: var(--sidebar-highlight-background-color, hsla(0,0%,80%,.3));
|
||||||
color: var(--sidebar-highlight-text-color, var(--sidebar-text-color));
|
color: var(--sidebar-highlight-text-color, var(--sidebar-text-color));
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[lwt-tree-brighttext] imgroup[selected],
|
:root[lwt-tree-brighttext] imgroup[selected],
|
||||||
:root[lwt-tree-brighttext] :-moz-any(imconv, imcontact, imgroup):not([selected=true]):hover {
|
:root[lwt-tree-brighttext] :-moz-any(imconv, richlistitem[is="chat-contact"], imgroup):not([selected=true]):hover {
|
||||||
background-color: var(--sidebar-highlight-background-color, rgba(249,249,250,.1));
|
background-color: var(--sidebar-highlight-background-color, rgba(249,249,250,.1));
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[lwt-tree] imconv[selected=true],
|
:root[lwt-tree] imconv[selected=true],
|
||||||
:root[lwt-tree] imcontact[selected=true] {
|
:root[lwt-tree] richlistitem[is="chat-contact"][selected=true] {
|
||||||
border-color: var(--sidebar-border-color, hsla(0,0%,60%,.4))
|
border-color: var(--sidebar-border-color, hsla(0,0%,60%,.4))
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[lwt-tree-brighttext] imconv[selected=true],
|
:root[lwt-tree-brighttext] imconv[selected=true],
|
||||||
:root[lwt-tree-brighttext] imcontact[selected=true] {
|
:root[lwt-tree-brighttext] richlistitem[is="chat-contact"][selected=true] {
|
||||||
border-color: var(--sidebar-border-color, rgba(249,249,250,.2))
|
border-color: var(--sidebar-border-color, rgba(249,249,250,.2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче