Add smileys.
|
@ -20,6 +20,9 @@ pref("messenger.options.playSounds", true);
|
|||
// 2 = permissive mode (colors, font face, font size, ...)
|
||||
pref("messenger.options.filterMode", 1);
|
||||
|
||||
// use "none" to disable
|
||||
pref("messenger.options.emoticonsTheme", "default");
|
||||
|
||||
pref("messenger.proxies", "");
|
||||
pref("messenger.globalProxy", "none");
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ VPATH = @srcdir@
|
|||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
EXTRA_JS_MODULES = instantbird/imContentSink.jsm
|
||||
EXTRA_JS_MODULES = instantbird/imContentSink.jsm instantbird/imSmileys.jsm
|
||||
EXTRA_COMPONENTS = instantbird/smileProtocolHandler.js
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<html><head></head><body id="ibcontent"></body></html>
|
|
@ -117,8 +117,9 @@
|
|||
if (!sss.sheetRegistered(uri, sss.USER_SHEET))
|
||||
sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
|
||||
|
||||
var url = 'data:text/html,<html><head></head><body id="ibcontent"></body></html>';
|
||||
browser.setAttribute("src", url);//"chrome://instantbird/content/conv.html"
|
||||
//'data:text/html,<html><head></head><body id="ibcontent"></body></html>';
|
||||
var url = "chrome://instantbird/content/conv.html";
|
||||
browser.setAttribute("src", url);
|
||||
browser.addProgressListener(this);
|
||||
|
||||
var editor = document.getAnonymousElementByAttribute(this, "anonid", "editor");
|
||||
|
@ -139,6 +140,8 @@
|
|||
|
||||
if (!("cleanupImMarkup" in window))
|
||||
Components.utils.import("resource://app/modules/imContentSink.jsm");
|
||||
if (!("smileImMarkup" in window))
|
||||
Components.utils.import("resource://app/modules/imSmileys.jsm");
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
|
@ -208,6 +211,7 @@
|
|||
.scanHTML(msg, 2)
|
||||
.replace(/&(apos|quot);/g, "&$1;");
|
||||
}
|
||||
msg = smileImMarkup(this.browser.contentDocument, msg);
|
||||
|
||||
var me = msg.match("^((<[^>]+>)*)/me (.*)$");
|
||||
if (!aMsg.system) {
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Instantbird messenging client, released
|
||||
* 2009.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Florian QUEZE <florian@instantbird.org>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var EXPORTED_SYMBOLS = [
|
||||
"smileImMarkup", // used to add smile:// img tags into IM markup.
|
||||
"getSmileRealURI", // used to retrive the chrome URI for a smile:// URI
|
||||
];
|
||||
|
||||
const emoticonsThemePref = "messenger.options.emoticonsTheme";
|
||||
const themeFile = "theme.js";
|
||||
|
||||
var gTheme = null;
|
||||
|
||||
var gPrefObserver = {
|
||||
init: function po_init() {
|
||||
Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch2)
|
||||
.addObserver(emoticonsThemePref, gPrefObserver, false);
|
||||
// We want to add this observer only once, make this method a no-op
|
||||
gPrefObserver.init = function() {};
|
||||
},
|
||||
|
||||
observe: function so_observe(aObject, aTopic, aMsg) {
|
||||
if (aTopic != "nsPref:changed" || aMsg != emoticonsThemePref)
|
||||
throw "bad notification";
|
||||
|
||||
gTheme = null;
|
||||
}
|
||||
};
|
||||
|
||||
function getSmileRealURI(aSmile)
|
||||
{
|
||||
let theme = getTheme();
|
||||
aSmile = Components.classes["@mozilla.org/intl/texttosuburi;1"]
|
||||
.getService(Components.interfaces.nsITextToSubURI)
|
||||
.unEscapeURIForUI("UTF-8", aSmile);
|
||||
if (aSmile in theme.iconsHash)
|
||||
return theme.baseUri + theme.iconsHash[aSmile].filename;
|
||||
|
||||
throw "Invalid smile!";
|
||||
}
|
||||
|
||||
function getTheme()
|
||||
{
|
||||
if (gTheme)
|
||||
return gTheme;
|
||||
|
||||
gTheme = {
|
||||
name: "default",
|
||||
iconsHash: null,
|
||||
json: null,
|
||||
regExp: null
|
||||
};
|
||||
|
||||
gTheme.name =
|
||||
Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch)
|
||||
.getCharPref(emoticonsThemePref);
|
||||
if (gTheme.name == "none")
|
||||
return gTheme;
|
||||
|
||||
if (gTheme.name == "default")
|
||||
gTheme.baseUri = "chrome://instantbird/skin/smileys/";
|
||||
else
|
||||
gTheme.baseUri = "chrome://" + gTheme.name + "/skin/";
|
||||
let ios = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
try {
|
||||
let channel = ios.newChannel(gTheme.baseUri + themeFile, null, null);
|
||||
let stream = channel.open();
|
||||
let json = Components.classes["@mozilla.org/dom/json;1"]
|
||||
.createInstance(Components.interfaces.nsIJSON);
|
||||
gTheme.json = json.decodeFromStream(stream, stream.available());
|
||||
stream.close();
|
||||
gTheme.iconsHash = {};
|
||||
for each (smile in gTheme.json.smileys) {
|
||||
for each (text in smile.texts)
|
||||
gTheme.iconsHash[text] = smile;
|
||||
}
|
||||
} catch(e) {
|
||||
Components.utils.reportError(e);
|
||||
}
|
||||
return gTheme;
|
||||
}
|
||||
|
||||
function getRegexp(aIconsHash)
|
||||
{
|
||||
let theme = getTheme();
|
||||
if (theme.regExp) {
|
||||
theme.regExp.lastIndex = 0;
|
||||
return theme.regExp;
|
||||
}
|
||||
|
||||
let emoticonList = [];
|
||||
for (let emoticon in theme.iconsHash)
|
||||
emoticonList.push(emoticon);
|
||||
|
||||
let exp = /([\][)(\\|?^*+])/g;
|
||||
emoticonList = emoticonList.sort()
|
||||
.reverse()
|
||||
.map(function(x) x.replace(exp, "\\$1"));
|
||||
|
||||
theme.regExp = new RegExp('(' + emoticonList.join('|') + ')', 'g');
|
||||
return theme.regExp;
|
||||
}
|
||||
|
||||
// unused. May be useful later to process a string instead of an HTML node
|
||||
function smileString(aString)
|
||||
{
|
||||
const smileFormat = '<img src="smile://$1" alt="$1" title="$1"/>';
|
||||
return aString.replace(getRegexp(), smileFormat);
|
||||
}
|
||||
|
||||
function smileNode(aNode)
|
||||
{
|
||||
for (var i = 0; i < aNode.childNodes.length; ++i) {
|
||||
let node = aNode.childNodes[i];
|
||||
if (node instanceof Components.interfaces.nsIDOMHTMLElement) {
|
||||
// we are on a tag, recurse to process its children
|
||||
smileNode(node);
|
||||
} else if (node instanceof Components.interfaces.nsIDOMText) {
|
||||
// we are on a text node, process it
|
||||
let exp = getRegexp();
|
||||
let match;
|
||||
while (match = exp(node.data)) {
|
||||
let smileNode = node.splitText(match.index);
|
||||
node = smileNode.splitText(exp.lastIndex - match.index);
|
||||
// at this point, smileNode is a text node with only the text
|
||||
// of the smiley and node is a text node with the text after
|
||||
// the smiley. The text in node hasn't been processed yet.
|
||||
let smile = smileNode.data;
|
||||
let elt = node.ownerDocument.createElement("img");
|
||||
elt.setAttribute("src", "smile://" + smile);
|
||||
elt.setAttribute("title", smile);
|
||||
elt.setAttribute("alt", smile);
|
||||
smileNode.parentNode.replaceChild(elt, smileNode);
|
||||
exp.lastIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function smileImMarkup(aDocument, aText)
|
||||
{
|
||||
if (!aDocument)
|
||||
throw "providing an HTML document is required";
|
||||
|
||||
gPrefObserver.init();
|
||||
|
||||
// return early if smileys are disabled
|
||||
if (!getTheme().iconsHash)
|
||||
return aText;
|
||||
|
||||
var div = aDocument.createElement("div");
|
||||
div.innerHTML = aText;
|
||||
smileNode(div);
|
||||
return div.innerHTML;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Instantbird messenging client, released
|
||||
* 2009.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Florian QUEZE <florian@instantbird.org>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Components.utils.import("resource://app/modules/imSmileys.jsm");
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const smileRegexp = /^smile:\/\//;
|
||||
|
||||
function smileProtocolHandler() { }
|
||||
|
||||
smileProtocolHandler.prototype = {
|
||||
scheme: "smile",
|
||||
defaultPort: -1,
|
||||
protocolFlags: Ci.nsIProtocolHandler.URI_NORELATIVE |
|
||||
Ci.nsIProtocolHandler.URI_NOAUTH |
|
||||
Ci.nsIProtocolHandler.URI_IS_UI_RESOURCE |
|
||||
Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE,
|
||||
newURI: function SPH_newURI(aSpec, aOriginCharset, aBaseURI) {
|
||||
let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
|
||||
uri.spec = aSpec;
|
||||
uri.QueryInterface(Ci.nsIMutable);
|
||||
uri.mutable = false;
|
||||
return uri;
|
||||
},
|
||||
newChannel: function SPH_newChannel(aURI) {
|
||||
let smile = aURI.spec.replace(smileRegexp, "");
|
||||
let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
let channel = ios.newChannel(getSmileRealURI(smile), null, null);
|
||||
channel.originalURI = aURI;
|
||||
return channel;
|
||||
},
|
||||
allowPort: function SPH_allowPort(aPort, aScheme) false,
|
||||
|
||||
classDescription: "Smile Protocol Handler",
|
||||
classID: Components.ID("{04e58eae-dfbc-4c9e-8130-6d9ef19cbff4}"),
|
||||
contractID: "@mozilla.org/network/protocol;1?name=smile",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler])
|
||||
};
|
||||
|
||||
function NSGetModule(aCompMgr, aFileSpec) {
|
||||
return XPCOMUtils.generateModule([smileProtocolHandler]);
|
||||
}
|
|
@ -19,6 +19,7 @@ instantbird.jar:
|
|||
content/instantbird/buddy.xml (instantbird/buddy.xml)
|
||||
content/instantbird/core.js (instantbird/core.js)
|
||||
* content/instantbird/conversation.xml (instantbird/conversation.xml)
|
||||
content/instantbird/conv.html (instantbird/conv.html)
|
||||
content/instantbird/credits.xhtml (instantbird/credits.xhtml)
|
||||
content/instantbird/group.xml (instantbird/group.xml)
|
||||
content/instantbird/instantbird.css (instantbird/instantbird.css)
|
||||
|
|
|
@ -76,6 +76,16 @@ p {
|
|||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
p img {
|
||||
margin-bottom: -3px;
|
||||
}
|
||||
|
||||
p *:-moz-any-link img {
|
||||
border: none;
|
||||
border-bottom: solid 1px;
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
|
||||
#welcome {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
|
@ -88,3 +88,29 @@ classic.jar:
|
|||
skin/winstripe/instantbird/tabbrowser/tab-right-bkgnd.png (tabbrowser/tab-right-bkgnd.png)
|
||||
skin/winstripe/instantbird/tabbrowser/tab-right-hover.png (tabbrowser/tab-right-hover.png)
|
||||
skin/winstripe/instantbird/tabbrowser/tab-right.png (tabbrowser/tab-right.png)
|
||||
skin/winstripe/instantbird/smileys/theme.js (smileys/theme.js)
|
||||
skin/winstripe/instantbird/smileys/smile.png (smileys/smile.png)
|
||||
skin/winstripe/instantbird/smileys/smile-big.png (smileys/smile-big.png)
|
||||
skin/winstripe/instantbird/smileys/wink.png (smileys/wink.png)
|
||||
skin/winstripe/instantbird/smileys/tongue.png (smileys/tongue.png)
|
||||
skin/winstripe/instantbird/smileys/neutral.png (smileys/neutral.png)
|
||||
skin/winstripe/instantbird/smileys/thinking.png (smileys/thinking.png)
|
||||
skin/winstripe/instantbird/smileys/thinking2.png (smileys/thinking2.png)
|
||||
skin/winstripe/instantbird/smileys/confused.png (smileys/confused.png)
|
||||
skin/winstripe/instantbird/smileys/crying.png (smileys/crying.png)
|
||||
skin/winstripe/instantbird/smileys/sad.png (smileys/sad.png)
|
||||
skin/winstripe/instantbird/smileys/angry.png (smileys/angry.png)
|
||||
skin/winstripe/instantbird/smileys/shout.png (smileys/shout.png)
|
||||
skin/winstripe/instantbird/smileys/shock.png (smileys/shock.png)
|
||||
skin/winstripe/instantbird/smileys/shut-mouth.png (smileys/shut-mouth.png)
|
||||
skin/winstripe/instantbird/smileys/shy.png (smileys/shy.png)
|
||||
skin/winstripe/instantbird/smileys/embarrassed.png (smileys/embarrassed.png)
|
||||
skin/winstripe/instantbird/smileys/laugh.png (smileys/laugh.png)
|
||||
skin/winstripe/instantbird/smileys/cool.png (smileys/cool.png)
|
||||
skin/winstripe/instantbird/smileys/kiss.png (smileys/kiss.png)
|
||||
skin/winstripe/instantbird/smileys/love.png (smileys/love.png)
|
||||
skin/winstripe/instantbird/smileys/happy.png (smileys/happy.png)
|
||||
skin/winstripe/instantbird/smileys/embarrassed-laugh.png (smileys/embarrassed-laugh.png)
|
||||
skin/winstripe/instantbird/smileys/bored.png (smileys/bored.png)
|
||||
skin/winstripe/instantbird/smileys/annoyed.png (smileys/annoyed.png)
|
||||
skin/winstripe/instantbird/smileys/big-eyes.png (smileys/big-eyes.png)
|
||||
|
|
После Ширина: | Высота: | Размер: 215 B |
После Ширина: | Высота: | Размер: 230 B |
После Ширина: | Высота: | Размер: 296 B |
После Ширина: | Высота: | Размер: 198 B |
После Ширина: | Высота: | Размер: 206 B |
После Ширина: | Высота: | Размер: 215 B |
После Ширина: | Высота: | Размер: 217 B |
После Ширина: | Высота: | Размер: 262 B |
После Ширина: | Высота: | Размер: 214 B |
После Ширина: | Высота: | Размер: 230 B |
После Ширина: | Высота: | Размер: 215 B |
После Ширина: | Высота: | Размер: 302 B |
После Ширина: | Высота: | Размер: 218 B |
После Ширина: | Высота: | Размер: 230 B |
После Ширина: | Высота: | Размер: 230 B |
После Ширина: | Высота: | Размер: 214 B |
После Ширина: | Высота: | Размер: 299 B |
После Ширина: | Высота: | Размер: 238 B |
После Ширина: | Высота: | Размер: 218 B |
После Ширина: | Высота: | Размер: 245 B |
После Ширина: | Высота: | Размер: 230 B |
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"smileys": [
|
||||
{"filename": "smile.png", "texts": [":-)", ":)"]},
|
||||
{"filename": "smile-big.png", "texts": [":-D", ":D"]},
|
||||
{"filename": "wink.png", "texts": [";-)", ";)"]},
|
||||
{"filename": "tongue.png", "texts": [":-P", ":P", ":-p", ":p"]},
|
||||
{"filename": "neutral.png", "texts": [":-|", ":|"]},
|
||||
{"filename": "thinking.png", "texts": [":-/"]},
|
||||
{"filename": "thinking2.png", "texts": [":-\\"], "hidden": true},
|
||||
{"filename": "confused.png", "texts": [":-S", ":-s", ":-$"]},
|
||||
{"filename": "crying.png", "texts": [":'("]},
|
||||
{"filename": "sad.png", "texts": [":-(", ":("]},
|
||||
{"filename": "angry.png", "texts": ["x-(", "X-("]},
|
||||
{"filename": "shout.png", "texts": [">:o", ">:O"]},
|
||||
{"filename": "shock.png", "texts": ["=-O", "=-o", ":-O", ":-o"]},
|
||||
{"filename": "shut-mouth.png", "texts": [":-X", ":X"]},
|
||||
{"filename": "shy.png", "texts": [":-]", ":]"]},
|
||||
{"filename": "embarrassed.png", "texts": [":-[", ":["]},
|
||||
{"filename": "laugh.png", "texts": ["XD"]},
|
||||
{"filename": "cool.png", "texts": ["B-)", "8-)"]},
|
||||
{"filename": "kiss.png", "texts": [":-*"]},
|
||||
{"filename": "love.png", "texts": ["<3"]},
|
||||
{"filename": "happy.png", "texts": ["^^"]},
|
||||
{"filename": "embarrassed-laugh.png", "texts": ["^^'"]},
|
||||
{"filename": "bored.png", "texts": ["-_-"]},
|
||||
{"filename": "annoyed.png", "texts": ["-_-'"]},
|
||||
{"filename": "big-eyes.png", "texts": ["O_O", "o_o"]}
|
||||
]
|
||||
}
|
После Ширина: | Высота: | Размер: 206 B |
После Ширина: | Высота: | Размер: 230 B |
После Ширина: | Высота: | Размер: 233 B |
После Ширина: | Высота: | Размер: 230 B |