Commit a9714abce37feed0e829b0c5428df8fadb690524
Committed by
Antonio Terceiro
1 parent
0cc4c43f
Exists in
master
and in
29 other branches
Some improvements/fixes in chat messages
- render URLs - more emotes - title to emoticons images (ActionItem1635)
Showing
6 changed files
with
358 additions
and
96 deletions
Show diff stats
app/views/layouts/chat.rhtml
... | ... | @@ -5,7 +5,7 @@ |
5 | 5 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
6 | 6 | <meta name="description" content="<%= @environment.name %>" /> |
7 | 7 | <link rel="shortcut icon" href="<%= image_path(theme_favicon) %>" type="image/x-icon" /> |
8 | - <%= javascript_include_tag 'jquery-latest', 'jquery.noconflict', 'jquery-ui-1.8.2.custom.min', 'jquery.scrollTo', 'jquery.scrollabletab', 'strophejs-1.0.1/strophe', 'application', 'chat', 'jquery.emoticon', '/designs/icons/pidgin/emoticons.js', :cache => 'cache-chat' %> | |
8 | + <%= javascript_include_tag 'jquery-latest', 'jquery.noconflict', 'jquery-ui-1.8.2.custom.min', 'jquery.scrollTo', 'jquery.scrollabletab', 'strophejs-1.0.1/strophe', 'jquery.emoticon', '/designs/icons/pidgin/emoticons.js', 'ba-linkify', 'application', 'chat', :cache => 'cache-chat' %> | |
9 | 9 | <%= stylesheet_link_tag noosfero_stylesheets, :cache => 'cache' %> |
10 | 10 | <%= stylesheet_link_tag icon_theme_stylesheet_path %> |
11 | 11 | <%= stylesheet_link_tag theme_stylesheet_path %> | ... | ... |
public/designs/icons/pidgin/emoticons.js
1 | 1 | /* Copyright (c) 2010 Colivre - www.colivre.coop.br |
2 | -/* Copyright (c) 2009 Marak Squires - www.maraksquires.com | |
2 | + Copyright (c) 2009 Marak Squires - www.maraksquires.com | |
3 | 3 | |
4 | 4 | Permission is hereby granted, free of charge, to any person |
5 | 5 | obtaining a copy of this software and associated documentation |
... | ... | @@ -24,93 +24,128 @@ OTHER DEALINGS IN THE SOFTWARE. |
24 | 24 | */ |
25 | 25 | |
26 | 26 | var emoticons = { |
27 | - "image_path": '/designs/icons/pidgin/pidgin/emotes/default/', | |
28 | - "emoticon": { | |
29 | - "::smile": { | |
30 | - "image": "mean.png", | |
31 | - "emotes": { | |
32 | - ":-)": "", | |
33 | - ":)": "", | |
34 | - ":]": "", | |
35 | - "=]": "", | |
36 | - "=)": "" | |
37 | - } | |
38 | - }, | |
39 | - "::bigSmile": { | |
40 | - "image": "excited.png", | |
41 | - "emotes": { | |
42 | - ":D": "", | |
43 | - "=D": "", | |
44 | - ":-D": "", | |
45 | - "XD": "", | |
46 | - "BD": "" | |
47 | - } | |
48 | - }, | |
49 | - "::shock": { | |
50 | - "image": "shocked.png", | |
51 | - "emotes": { | |
52 | - ":O": "", | |
53 | - ":0": "", | |
54 | - "=O": "", | |
55 | - ":-0": "", | |
56 | - ":-O": "" | |
57 | - | |
58 | - } | |
59 | - }, | |
60 | - "::frown": { | |
61 | - "image": "sad.png", | |
62 | - "emotes": { | |
63 | - ":-(": "", | |
64 | - "=(": "", | |
65 | - ":[": "", | |
66 | - ":<": "", | |
67 | - "=[": "", | |
68 | - ":(": "", | |
69 | - ":-\\": "" | |
70 | - } | |
71 | - }, | |
72 | - "::tongue": { | |
73 | - "image": "tongue.png", | |
74 | - "emotes": { | |
75 | - ":P": "", | |
76 | - "=P": "", | |
77 | - "XP": "", | |
78 | - } | |
79 | - }, | |
80 | - "::bored": { | |
81 | - "image": "thinking.png", | |
82 | - "emotes": { | |
83 | - "=I": "", | |
84 | - ":/": "", | |
85 | - ":-\\": "", | |
86 | - ":|": "" | |
87 | - } | |
88 | - }, | |
89 | - "::wink": { | |
90 | - "image": "wink.png", | |
91 | - "emotes": { | |
92 | - ";-)": "", | |
93 | - ";)": "", | |
94 | - ";]": "" | |
95 | - } | |
96 | - }, | |
97 | - "::love": { | |
98 | - "image": "rose.png", | |
99 | - "emotes": { | |
100 | - "<3": "", | |
101 | - "<3": "", | |
102 | - "S2": "", | |
103 | - ":3": "" | |
104 | - } | |
105 | - } | |
106 | - , | |
107 | - "::confused": { | |
108 | - "image": "confused.png", | |
109 | - "emotes": { | |
110 | - ":S": "", | |
111 | - "=S": "", | |
112 | - ":\?": "" | |
113 | - } | |
114 | - } | |
115 | - } | |
27 | + "image_path": '/designs/icons/pidgin/pidgin/emotes/default/', | |
28 | + "emoticon": { | |
29 | + "::smile": { | |
30 | + "image": "mean.png", | |
31 | + "emotes": { | |
32 | + ":-)": "", | |
33 | + ":)": "", | |
34 | + ":]": "", | |
35 | + "=]": "", | |
36 | + "=)": "" | |
37 | + } | |
38 | + }, | |
39 | + "::bigSmile": { | |
40 | + "image": "excited.png", | |
41 | + "emotes": { | |
42 | + ":D": "", | |
43 | + "=D": "", | |
44 | + ":-D": "" | |
45 | + } | |
46 | + }, | |
47 | + "::shock": { | |
48 | + "image": "shocked.png", | |
49 | + "emotes": { | |
50 | + ":O": "", | |
51 | + ":0": "", | |
52 | + "=O": "", | |
53 | + ":-0": "", | |
54 | + ":-O": "" | |
55 | + } | |
56 | + }, | |
57 | + "::frown": { | |
58 | + "image": "sad.png", | |
59 | + "emotes": { | |
60 | + ":-(": "", | |
61 | + "=(": "", | |
62 | + ":[": "", | |
63 | + ":<": "", | |
64 | + "=[": "", | |
65 | + ":(": "", | |
66 | + ":-\\": "" | |
67 | + } | |
68 | + }, | |
69 | + "::tongue": { | |
70 | + "image": "tongue.png", | |
71 | + "emotes": { | |
72 | + ":P": "", | |
73 | + ":-P": "", | |
74 | + "=P": "" | |
75 | + } | |
76 | + }, | |
77 | + "::bored": { | |
78 | + "image": "thinking.png", | |
79 | + "emotes": { | |
80 | + "=I": "", | |
81 | + ":/": "", | |
82 | + ":-\\": "", | |
83 | + ":|": "" | |
84 | + } | |
85 | + }, | |
86 | + "::wink": { | |
87 | + "image": "wink.png", | |
88 | + "emotes": { | |
89 | + ";-)": "", | |
90 | + ";)": "", | |
91 | + ";]": "" | |
92 | + } | |
93 | + }, | |
94 | + "::love": { | |
95 | + "image": "in_love.png", | |
96 | + "emotes": { | |
97 | + "<3": "", | |
98 | + "<333": "" | |
99 | + } | |
100 | + }, | |
101 | + "::confused": { | |
102 | + "image": "confused.png", | |
103 | + "emotes": { | |
104 | + ":S": "", | |
105 | + "=S": "", | |
106 | + ":\?": "" | |
107 | + } | |
108 | + }, | |
109 | + "::crying": { | |
110 | + "image": "crying.png", | |
111 | + "emotes": { | |
112 | + ":'(": "", | |
113 | + ";*(": "" | |
114 | + } | |
115 | + }, | |
116 | + "::kiss": { | |
117 | + "image": "kiss.png", | |
118 | + "emotes": { | |
119 | + ":-*": "", | |
120 | + ":*": "" | |
121 | + } | |
122 | + }, | |
123 | + "::evil": { | |
124 | + "image": "devil.png", | |
125 | + "emotes": { | |
126 | + ">:)": "", | |
127 | + ">;)": "", | |
128 | + ">:-)": "" | |
129 | + } | |
130 | + }, | |
131 | + "::nolove": { | |
132 | + "image": "love-over.png", | |
133 | + "emotes": { | |
134 | + "</3": "" | |
135 | + } | |
136 | + }, | |
137 | + "::praise": { | |
138 | + "image": "victory.png", | |
139 | + "emotes": { | |
140 | + "\\o/": "" | |
141 | + } | |
142 | + }, | |
143 | + "::angel": { | |
144 | + "image": "angel.png", | |
145 | + "emotes": { | |
146 | + "O:-)": "", | |
147 | + "O:)": "" | |
148 | + } | |
149 | + } | |
150 | + } | |
116 | 151 | }; | ... | ... |
... | ... | @@ -0,0 +1,214 @@ |
1 | +/*! | |
2 | + * JavaScript Linkify - v0.3 - 6/27/2009 | |
3 | + * http://benalman.com/projects/javascript-linkify/ | |
4 | + * | |
5 | + * Copyright (c) 2009 "Cowboy" Ben Alman | |
6 | + * Dual licensed under the MIT and GPL licenses. | |
7 | + * http://benalman.com/about/license/ | |
8 | + * | |
9 | + * Some regexps adapted from http://userscripts.org/scripts/review/7122 | |
10 | + */ | |
11 | + | |
12 | +// Script: JavaScript Linkify: Process links in text! | |
13 | +// | |
14 | +// *Version: 0.3, Last updated: 6/27/2009* | |
15 | +// | |
16 | +// Project Home - http://benalman.com/projects/javascript-linkify/ | |
17 | +// GitHub - http://github.com/cowboy/javascript-linkify/ | |
18 | +// Source - http://github.com/cowboy/javascript-linkify/raw/master/ba-linkify.js | |
19 | +// (Minified) - http://github.com/cowboy/javascript-linkify/raw/master/ba-linkify.min.js (2.8kb) | |
20 | +// | |
21 | +// About: License | |
22 | +// | |
23 | +// Copyright (c) 2009 "Cowboy" Ben Alman, | |
24 | +// Dual licensed under the MIT and GPL licenses. | |
25 | +// http://benalman.com/about/license/ | |
26 | +// | |
27 | +// About: Examples | |
28 | +// | |
29 | +// This working example, complete with fully commented code, illustrates one way | |
30 | +// in which this code can be used. | |
31 | +// | |
32 | +// Linkify - http://benalman.com/code/projects/javascript-linkify/examples/linkify/ | |
33 | +// | |
34 | +// About: Support and Testing | |
35 | +// | |
36 | +// Information about what browsers this code has been tested in. | |
37 | +// | |
38 | +// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.7, Safari 3-4, Chrome, Opera 9.6-10. | |
39 | +// | |
40 | +// About: Release History | |
41 | +// | |
42 | +// 0.3 - (6/27/2009) Initial release | |
43 | + | |
44 | +// Function: linkify | |
45 | +// | |
46 | +// Turn text into linkified html. | |
47 | +// | |
48 | +// Usage: | |
49 | +// | |
50 | +// > var html = linkify( text [, options ] ); | |
51 | +// | |
52 | +// Arguments: | |
53 | +// | |
54 | +// text - (String) Non-HTML text containing links to be parsed. | |
55 | +// options - (Object) An optional object containing linkify parse options. | |
56 | +// | |
57 | +// Options: | |
58 | +// | |
59 | +// callback (Function) - If specified, this will be called once for each link- | |
60 | +// or non-link-chunk with two arguments, text and href. If the chunk is | |
61 | +// non-link, href will be omitted. If unspecified, the default linkification | |
62 | +// callback is used. | |
63 | +// punct_regexp (RegExp) - A RegExp that will be used to trim trailing | |
64 | +// punctuation from links, instead of the default. If set to null, trailing | |
65 | +// punctuation will not be trimmed. | |
66 | +// | |
67 | +// Returns: | |
68 | +// | |
69 | +// (String) An HTML string containing links. | |
70 | + | |
71 | +window.linkify = (function(){ | |
72 | + var | |
73 | + SCHEME = "[a-z\\d.-]+://", | |
74 | + IPV4 = "(?:(?:[0-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])\\.){3}(?:[0-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])", | |
75 | + HOSTNAME = "(?:(?:[^\\s!@#$%^&*()_=+[\\]{}\\\\|;:'\",.<>/?]+)\\.)+", | |
76 | + TLD = "(?:ac|ad|aero|ae|af|ag|ai|al|am|an|ao|aq|arpa|ar|asia|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|biz|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|cat|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|coop|com|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|info|int|in|io|iq|ir|is|it|je|jm|jobs|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mil|mk|ml|mm|mn|mobi|mo|mp|mq|mr|ms|mt|museum|mu|mv|mw|mx|my|mz|name|na|nc|net|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pro|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tel|tf|tg|th|tj|tk|tl|tm|tn|to|tp|travel|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|xn--0zwm56d|xn--11b5bs3a9aj6g|xn--80akhbyknj4f|xn--9t4b11yi5a|xn--deba0ad|xn--g6w251d|xn--hgbk6aj7f53bba|xn--hlcj6aya9esc7a|xn--jxalpdlp|xn--kgbechtv|xn--zckzah|ye|yt|yu|za|zm|zw)", | |
77 | + HOST_OR_IP = "(?:" + HOSTNAME + TLD + "|" + IPV4 + ")", | |
78 | + PATH = "(?:[;/][^#?<>\\s]*)?", | |
79 | + QUERY_FRAG = "(?:\\?[^#<>\\s]*)?(?:#[^<>\\s]*)?", | |
80 | + URI1 = "\\b" + SCHEME + "[^<>\\s]+", | |
81 | + URI2 = "\\b" + HOST_OR_IP + PATH + QUERY_FRAG + "(?!\\w)", | |
82 | + | |
83 | + MAILTO = "mailto:", | |
84 | + EMAIL = "(?:" + MAILTO + ")?[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@" + HOST_OR_IP + QUERY_FRAG + "(?!\\w)", | |
85 | + | |
86 | + URI_RE = new RegExp( "(?:" + URI1 + "|" + URI2 + "|" + EMAIL + ")", "ig" ), | |
87 | + SCHEME_RE = new RegExp( "^" + SCHEME, "i" ), | |
88 | + | |
89 | + quotes = { | |
90 | + "'": "`", | |
91 | + '>': '<', | |
92 | + ')': '(', | |
93 | + ']': '[', | |
94 | + '}': '{', | |
95 | + '»': '«', | |
96 | + '›': '‹' | |
97 | + }, | |
98 | + | |
99 | + default_options = { | |
100 | + callback: function( text, href ) { | |
101 | + return href ? '<a href="' + href + '" title="' + href + '">' + text + '</a>' : text; | |
102 | + }, | |
103 | + punct_regexp: /(?:[!?.,:;'"]|(?:&|&)(?:lt|gt|quot|apos|raquo|laquo|rsaquo|lsaquo);)$/ | |
104 | + }; | |
105 | + | |
106 | + return function( txt, options ) { | |
107 | + options = options || {}; | |
108 | + | |
109 | + // Temp variables. | |
110 | + var arr, | |
111 | + i, | |
112 | + link, | |
113 | + href, | |
114 | + | |
115 | + // Output HTML. | |
116 | + html = '', | |
117 | + | |
118 | + // Store text / link parts, in order, for re-combination. | |
119 | + parts = [], | |
120 | + | |
121 | + // Used for keeping track of indices in the text. | |
122 | + idx_prev, | |
123 | + idx_last, | |
124 | + idx, | |
125 | + link_last, | |
126 | + | |
127 | + // Used for trimming trailing punctuation and quotes from links. | |
128 | + matches_begin, | |
129 | + matches_end, | |
130 | + quote_begin, | |
131 | + quote_end; | |
132 | + | |
133 | + // Initialize options. | |
134 | + for ( i in default_options ) { | |
135 | + if ( options[ i ] === undefined ) { | |
136 | + options[ i ] = default_options[ i ]; | |
137 | + } | |
138 | + } | |
139 | + | |
140 | + // Find links. | |
141 | + while ( arr = URI_RE.exec( txt ) ) { | |
142 | + | |
143 | + link = arr[0]; | |
144 | + idx_last = URI_RE.lastIndex; | |
145 | + idx = idx_last - link.length; | |
146 | + | |
147 | + // Not a link if preceded by certain characters. | |
148 | + if ( /[\/:]/.test( txt.charAt( idx - 1 ) ) ) { | |
149 | + continue; | |
150 | + } | |
151 | + | |
152 | + // Trim trailing punctuation. | |
153 | + do { | |
154 | + // If no changes are made, we don't want to loop forever! | |
155 | + link_last = link; | |
156 | + | |
157 | + quote_end = link.substr( -1 ) | |
158 | + quote_begin = quotes[ quote_end ]; | |
159 | + | |
160 | + // Ending quote character? | |
161 | + if ( quote_begin ) { | |
162 | + matches_begin = link.match( new RegExp( '\\' + quote_begin + '(?!$)', 'g' ) ); | |
163 | + matches_end = link.match( new RegExp( '\\' + quote_end, 'g' ) ); | |
164 | + | |
165 | + // If quotes are unbalanced, remove trailing quote character. | |
166 | + if ( ( matches_begin ? matches_begin.length : 0 ) < ( matches_end ? matches_end.length : 0 ) ) { | |
167 | + link = link.substr( 0, link.length - 1 ); | |
168 | + idx_last--; | |
169 | + } | |
170 | + } | |
171 | + | |
172 | + // Ending non-quote punctuation character? | |
173 | + if ( options.punct_regexp ) { | |
174 | + link = link.replace( options.punct_regexp, function(a){ | |
175 | + idx_last -= a.length; | |
176 | + return ''; | |
177 | + }); | |
178 | + } | |
179 | + } while ( link.length && link !== link_last ); | |
180 | + | |
181 | + href = link; | |
182 | + | |
183 | + // Add appropriate protocol to naked links. | |
184 | + if ( !SCHEME_RE.test( href ) ) { | |
185 | + href = ( href.indexOf( '@' ) !== -1 ? ( !href.indexOf( MAILTO ) ? '' : MAILTO ) | |
186 | + : !href.indexOf( 'irc.' ) ? 'irc://' | |
187 | + : !href.indexOf( 'ftp.' ) ? 'ftp://' | |
188 | + : 'http://' ) | |
189 | + + href; | |
190 | + } | |
191 | + | |
192 | + // Push preceding non-link text onto the array. | |
193 | + if ( idx_prev != idx ) { | |
194 | + parts.push([ txt.slice( idx_prev, idx ) ]); | |
195 | + idx_prev = idx_last; | |
196 | + } | |
197 | + | |
198 | + // Push massaged link onto the array | |
199 | + parts.push([ link, href ]); | |
200 | + }; | |
201 | + | |
202 | + // Push remaining non-link text onto the array. | |
203 | + parts.push([ txt.substr( idx_prev ) ]); | |
204 | + | |
205 | + // Process the array items. | |
206 | + for ( i = 0; i < parts.length; i++ ) { | |
207 | + html += options.callback.apply( window, parts[i] ); | |
208 | + } | |
209 | + | |
210 | + // In case of catastrophic failure, return the original text; | |
211 | + return html || txt; | |
212 | + }; | |
213 | + | |
214 | +})(); | |
0 | 215 | \ No newline at end of file | ... | ... |
public/javascripts/chat.js
... | ... | @@ -50,11 +50,21 @@ jQuery(function($) { |
50 | 50 | $('#' + jid_id).parent('li').remove(); |
51 | 51 | }, |
52 | 52 | |
53 | + render_body_message: function(body) { | |
54 | + body = $().emoticon(body); | |
55 | + body = linkify(body, { | |
56 | + callback: function(text, href) { | |
57 | + return href ? '<a href="' + href + '" title="' + href + '" target="_blank">' + text + '</a>' : text; | |
58 | + } | |
59 | + }); | |
60 | + return body; | |
61 | + }, | |
62 | + | |
53 | 63 | show_message: function (jid, body, who) { |
54 | 64 | jid_id = Jabber.jid_to_id(jid); |
55 | 65 | if (body) { |
56 | 66 | var tab_id = '#' + Jabber.tab_prefix + jid_id; |
57 | - body = $().emoticon(body); | |
67 | + body = Jabber.render_body_message(body); | |
58 | 68 | if ($(tab_id).find('.message').length > 0 && $(tab_id).find('.message:last').hasClass(who)) { |
59 | 69 | $(tab_id).find('.history').find('.message:last').append('<p>' + body + '</p>'); |
60 | 70 | } |
... | ... | @@ -75,7 +85,7 @@ jQuery(function($) { |
75 | 85 | .replace('%{avatar_url}', '/chat/avatar/' + identifier); |
76 | 86 | $('#' + Jabber.tab_prefix + jid_id).find('.history').append(message_html); |
77 | 87 | } |
78 | - $(tab_id).find('.history').scrollTo('100%'); | |
88 | + $(tab_id).find('.history').scrollTo({top:'100%', left:'0%'}); | |
79 | 89 | if (who === "other" && $(tab_id).find('.history:visible').length == 0) { |
80 | 90 | count_unread_messages(jid_id); |
81 | 91 | } |
... | ... | @@ -361,7 +371,7 @@ jQuery(function($) { |
361 | 371 | // TODO notify window close |
362 | 372 | }, |
363 | 373 | show: function(event, ui) { |
364 | - $(ui.panel).find('.history').scrollTo('100%'); | |
374 | + $(ui.panel).find('.history').scrollTo({top:'100%', left:'0%'}); | |
365 | 375 | $(ui.panel).find('textarea').focus(); |
366 | 376 | var jid_id = ui.panel.id.replace('conversation-', ''); |
367 | 377 | count_unread_messages(jid_id, true); | ... | ... |
public/javascripts/jquery.emoticon.js
... | ... | @@ -44,8 +44,8 @@ RegExp.escape = function(text) { |
44 | 44 | for( var a in emoticons.emoticon ) { |
45 | 45 | emoticon = emoticons.emoticon[a]; |
46 | 46 | for( var emote in emoticon.emotes ) { |
47 | - emote = RegExp.escape(emote); | |
48 | - newText = newText.replace( new RegExp( emote, 'gi' ), '<img src="'+emoticons.image_path + emoticon.image + '" />'); | |
47 | + emote_pattern = RegExp.escape(emote) + "([^/]|$)"; | |
48 | + newText = newText.replace( new RegExp( emote_pattern, 'gi' ), '<img src="'+emoticons.image_path + emoticon.image + '" alt="'+ emote +'" title="'+ emote +'" />$1'); | |
49 | 49 | } |
50 | 50 | } |
51 | 51 | return newText; | ... | ... |
public/stylesheets/application.css
... | ... | @@ -4536,6 +4536,9 @@ h1#agenda-title { |
4536 | 4536 | overflow-y: scroll; |
4537 | 4537 | padding-top: 5px; |
4538 | 4538 | } |
4539 | +.msie7 #chat-window .conversation .history { | |
4540 | + overflow-x: hidden; | |
4541 | +} | |
4539 | 4542 | #chat .unread-messages { |
4540 | 4543 | background: red; |
4541 | 4544 | position: absolute; | ... | ... |