]>
git.wh0rd.org - tt-rss.git/blob - functions.js
1 var hotkeys_enabled
= true;
3 function browser_has_opacity() {
4 return navigator
.userAgent
.match("Gecko") != null ||
5 navigator
.userAgent
.match("Opera") != null;
8 function exception_error(location
, e
) {
12 var base_fname
= e
.fileName
.substring(e
.fileName
.lastIndexOf("/") + 1);
14 msg
= "Exception: " + e
.name
+ ", " + e
.message
+
15 "\nFunction: " + location
+ "()" +
16 "\nLocation: " + base_fname
+ ":" + e
.lineNumber
;
18 msg
= "Exception: " + e
+ "\nFunction: " + location
+ "()";
24 function disableHotkeys() {
25 hotkeys_enabled
= false;
28 function enableHotkeys() {
29 hotkeys_enabled
= true;
32 function xmlhttp_ready(obj
) {
33 return obj
.readyState
== 4 || obj
.readyState
== 0 || !obj
.readyState
;
36 function notify_callback() {
37 var container
= document
.getElementById('notify');
38 if (xmlhttp
.readyState
== 4) {
39 container
.innerHTML
=xmlhttp
.responseText
;
43 function rpc_notify_callback() {
44 var container
= document
.getElementById('notify');
45 if (xmlhttp_rpc
.readyState
== 4) {
46 container
.innerHTML
=xmlhttp_rpc
.responseText
;
50 function rpc_pnotify_callback() {
51 var container
= parent
.document
.getElementById('notify');
52 if (xmlhttp_rpc
.readyState
== 4) {
53 container
.innerHTML
=xmlhttp_rpc
.responseText
;
57 function param_escape(arg
) {
58 if (typeof encodeURIComponent
!= 'undefined')
59 return encodeURIComponent(arg
);
64 function param_unescape(arg
) {
65 if (typeof decodeURIComponent
!= 'undefined')
66 return decodeURIComponent(arg
);
73 then
=new Date().getTime();
75 while((now
-then
)<gap
) {
76 now
=new Date().getTime();
80 var notify_hide_timerid
= false;
81 var notify_last_doc
= false;
83 var notify_effect
= false;
85 function hide_notify() {
86 if (notify_last_doc
) {
87 var n
= notify_last_doc
.getElementById("notify");
88 if (browser_has_opacity()) {
89 if (notify_opacity
>= 0) {
90 notify_opacity
= notify_opacity
- 0.1;
91 n
.style
.opacity
= notify_opacity
;
92 notify_hide_timerid
= window
.setTimeout("hide_notify()", 20);
94 n
.style
.display
= "none";
98 n
.style
.display
= "none";
103 function notify_real(msg
, doc
, no_hide
, is_err
) {
105 var n
= doc
.getElementById("notify");
106 var nb
= doc
.getElementById("notify_body");
108 if (!n
|| !nb
) return;
110 if (notify_hide_timerid
) {
111 window
.clearTimeout(notify_hide_timerid
);
114 notify_last_doc
= doc
;
118 if (n
.style
.display
== "block") {
119 notify_hide_timerid
= window
.setTimeout("hide_notify()", 0);
123 n
.style
.display
= "block";
127 n
.style
.backgroundColor
= "#ffcccc";
128 n
.style
.color
= "black";
129 n
.style
.borderColor
= "#ff0000";
131 n
.style
.backgroundColor
= "#fff7d5";
132 n
.style
.borderColor
= "#d7c47a";
133 n
.style
.color
= "black";
139 notify_hide_timerid
= window
.setTimeout("hide_notify()", 3000);
143 function p_notify(msg
, no_hide
, is_err
) {
144 notify_real(msg
, parent
.document
, no_hide
, is_err
);
147 function notify(msg
, no_hide
, is_err
) {
148 notify_real(msg
, document
, no_hide
, is_err
);
151 function printLockingError() {
152 notify("Please wait until operation finishes");}
156 function hotkey_handler(e
) {
160 if (!hotkeys_enabled
) return;
163 keycode
= window
.event
.keyCode
;
168 if (keycode
== 13 || keycode
== 27) {
171 seq
= seq
+ "" + keycode
;
174 if (document
.getElementById("piggie")) {
176 if (seq
.match("807371717369")) {
178 localPiggieFunction(true);
180 localPiggieFunction(false);
184 if (typeof localHotkeyHandler
!= 'undefined') {
186 localHotkeyHandler(keycode
);
188 exception_error("hotkey_handler", e
);
194 function cleanSelectedList(element
) {
195 var content
= document
.getElementById(element
);
197 if (!document
.getElementById("feedCatHolder")) {
198 for (i
= 0; i
< content
.childNodes
.length
; i
++) {
199 var child
= content
.childNodes
[i
];
201 child
.className
= child
.className
.replace("Selected", "");
207 for (i
= 0; i
< content
.childNodes
.length
; i
++) {
208 var child
= content
.childNodes
[i
];
209 if (child
.id
== "feedCatHolder") {
210 parent
.debug(child
.id
);
211 var fcat
= child
.lastChild
;
212 for (j
= 0; j
< fcat
.childNodes
.length
; j
++) {
213 var feed
= fcat
.childNodes
[j
];
214 feed
.className
= feed
.className
.replace("Selected", "");
222 function cleanSelected(element
) {
223 var content
= document
.getElementById(element
);
225 for (i
= 0; i
< content
.rows
.length
; i
++) {
226 content
.rows
[i
].className
= content
.rows
[i
].className
.replace("Selected", "");
230 function getVisibleUnreadHeadlines() {
231 var content
= document
.getElementById("headlinesList");
233 var rows
= new Array();
235 for (i
= 0; i
< content
.rows
.length
; i
++) {
236 var row_id
= content
.rows
[i
].id
.replace("RROW-", "");
237 if (row_id
.length
> 0 && content
.rows
[i
].className
.match("Unread")) {
244 function getVisibleHeadlineIds() {
246 var content
= document
.getElementById("headlinesList");
248 var rows
= new Array();
250 for (i
= 0; i
< content
.rows
.length
; i
++) {
251 var row_id
= content
.rows
[i
].id
.replace("RROW-", "");
252 if (row_id
.length
> 0) {
259 function getFirstVisibleHeadlineId() {
260 var rows
= getVisibleHeadlineIds();
264 function getLastVisibleHeadlineId() {
265 var rows
= getVisibleHeadlineIds();
266 return rows
[rows
.length
-1];
269 function markHeadline(id
) {
270 var row
= document
.getElementById("RROW-" + id
);
272 var is_active
= false;
274 if (row
.className
.match("Active")) {
277 row
.className
= row
.className
.replace("Selected", "");
278 row
.className
= row
.className
.replace("Active", "");
279 row
.className
= row
.className
.replace("Insensitive", "");
282 row
.className
= row
.className
= "Active";
285 var check
= document
.getElementById("RCHK-" + id
);
288 check
.checked
= true;
291 row
.className
= row
.className
+ "Selected";
296 function getFeedIds() {
297 var content
= document
.getElementById("feedsList");
299 var rows
= new Array();
301 for (i
= 0; i
< content
.rows
.length
; i
++) {
302 var id
= content
.rows
[i
].id
.replace("FEEDR-", "");
311 function setCookie(name
, value
, lifetime
, path
, domain
, secure
) {
317 d
.setTime(lifetime
* 1000);
320 int_setCookie(name
, value
, d
, path
, domain
, secure
);
324 function int_setCookie(name
, value
, expires
, path
, domain
, secure
) {
325 document
.cookie
= name
+ "=" + escape(value
) +
326 ((expires
) ? "; expires=" + expires
.toGMTString() : "") +
327 ((path
) ? "; path=" + path
: "") +
328 ((domain
) ? "; domain=" + domain
: "") +
329 ((secure
) ? "; secure" : "");
332 function delCookie(name
, path
, domain
) {
333 if (getCookie(name
)) {
334 document
.cookie
= name
+ "=" +
335 ((path
) ? ";path=" + path
: "") +
336 ((domain
) ? ";domain=" + domain
: "" ) +
337 ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
342 function getCookie(name
) {
344 var dc
= document
.cookie
;
345 var prefix
= name
+ "=";
346 var begin
= dc
.indexOf("; " + prefix
);
348 begin
= dc
.indexOf(prefix
);
349 if (begin
!= 0) return null;
354 var end
= document
.cookie
.indexOf(";", begin
);
358 return unescape(dc
.substring(begin
+ prefix
.length
, end
));
361 function disableContainerChildren(id
, disable
, doc
) {
363 if (!doc
) doc
= document
;
365 var container
= doc
.getElementById(id
);
367 for (var i
= 0; i
< container
.childNodes
.length
; i
++) {
368 var child
= container
.childNodes
[i
];
371 child
.disabled
= disable
;
377 if (child
.className
&& child
.className
.match("button")) {
378 child
.className
= "disabledButton";
381 if (child
.className
&& child
.className
.match("disabledButton")) {
382 child
.className
= "button";
389 function gotoPreferences() {
390 document
.location
.href
= "prefs.php";
393 function gotoMain() {
394 document
.location
.href
= "tt-rss.php";
397 function gotoExportOpml() {
398 document
.location
.href
= "opml.php?op=Export";
401 function getActiveFeedId() {
402 return getCookie("ttrss_vf_actfeed");
405 function setActiveFeedId(id
) {
406 return setCookie("ttrss_vf_actfeed", id
);
409 var xmlhttp_rpc
= Ajax
.getTransport();
411 function parse_counters(reply
, f_document
, title_obj
, scheduled_call
) {
413 for (var l
= 0; l
< reply
.childNodes
.length
; l
++) {
414 if (!reply
.childNodes
[l
] ||
415 typeof(reply
.childNodes
[l
].getAttribute
) == "undefined") {
416 // where did this come from?
420 var id
= reply
.childNodes
[l
].getAttribute("id");
421 var t
= reply
.childNodes
[l
].getAttribute("type");
422 var ctr
= reply
.childNodes
[l
].getAttribute("counter");
423 var error
= reply
.childNodes
[l
].getAttribute("error");
424 var has_img
= reply
.childNodes
[l
].getAttribute("hi");
425 var updated
= reply
.childNodes
[l
].getAttribute("updated");
427 if (id
== "global-unread") {
428 title_obj
.global_unread
= ctr
;
429 title_obj
.updateTitle();
433 if (t
== "category") {
434 var catctr
= f_document
.getElementById("FCATCTR-" + id
);
436 catctr
.innerHTML
= "(" + ctr
+ " unread)";
441 var feedctr
= f_document
.getElementById("FEEDCTR-" + id
);
442 var feedu
= f_document
.getElementById("FEEDU-" + id
);
443 var feedr
= f_document
.getElementById("FEEDR-" + id
);
444 var feed_img
= f_document
.getElementById("FIMG-" + id
);
445 var feedlink
= f_document
.getElementById("FEEDL-" + id
);
447 if (updated
&& feedlink
) {
449 feedlink
.title
= "Error: " + error
+ " (" + updated
+ ")";
451 feedlink
.title
= "Updated: " + updated
;
455 if (feedctr
&& feedu
&& feedr
) {
457 if (feedu
.innerHTML
!= ctr
&& id
== getActiveFeedId() && scheduled_call
) {
458 var hf
= title_obj
.parent
.frames
["headlines-frame"];
459 hf
.location
.reload(true);
462 feedu
.innerHTML
= ctr
;
465 feedr
.className
= feedr
.className
.replace("feed", "error");
467 feedr
.className
= feedr
.className
.replace("error", "feed");
471 feedctr
.className
= "odd";
472 if (!feedr
.className
.match("Unread")) {
473 var is_selected
= feedr
.className
.match("Selected");
475 feedr
.className
= feedr
.className
.replace("Selected", "");
476 feedr
.className
= feedr
.className
.replace("Unread", "");
478 feedr
.className
= feedr
.className
+ "Unread";
481 feedr
.className
= feedr
.className
+ "Selected";
486 feedctr
.className
= "invisible";
487 feedr
.className
= feedr
.className
.replace("Unread", "");
492 exception_error("parse_counters", e
);
496 // this one is called from feedlist context
497 // thus title_obj passed to parse_counters is parent (e.g. main ttrss window)
499 function all_counters_callback() {
500 if (xmlhttp_rpc
.readyState
== 4) {
502 if (!xmlhttp_rpc
.responseXML
|| !xmlhttp_rpc
.responseXML
.firstChild
) {
503 notify("[all_counters_callback] backend did not return valid XML");
507 if (!parent
.frames
["feeds-frame"]) {
508 notify("[all_counters_callback] no parent feeds-frame");
512 var reply
= xmlhttp_rpc
.responseXML
.firstChild
;
513 var f_document
= parent
.frames
["feeds-frame"].document
;
515 parse_counters(reply
, f_document
, parent
);
518 exception_error("all_counters_callback", e
);
523 function update_all_counters(feed
) {
524 if (xmlhttp_ready(xmlhttp_rpc
)) {
525 var query
= "backend.php?op=rpc&subop=getAllCounters";
528 query
= query
+ "&aid=" + feed
;
531 xmlhttp_rpc
.open("GET", query
, true);
532 xmlhttp_rpc
.onreadystatechange
=all_counters_callback
;
533 xmlhttp_rpc
.send(null);
537 function popupHelp(tid
) {
538 var w
= window
.open("backend.php?op=help&tid=" + tid
,
540 "menubar=no,location=no,resizable=yes,scrollbars=yes,status=no");
543 /** * @(#)isNumeric.js * * Copyright (c) 2000 by Sundar Dorai-Raj
544 * * @author Sundar Dorai-Raj
545 * * Email: sdoraira@vt.edu
546 * * This program is free software; you can redistribute it and/or
547 * * modify it under the terms of the GNU General Public License
548 * * as published by the Free Software Foundation; either version 2
549 * * of the License, or (at your option) any later version,
550 * * provided that any use properly credits the author.
551 * * This program is distributed in the hope that it will be useful,
552 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
553 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
554 * * GNU General Public License for more details at http://www.gnu.org * * */
556 var numbers
=".0123456789";
557 function isNumeric(x
) {
558 // is x a String or a character?
560 // remove negative sign
562 for(j
=0;j
<x
.length
;j
++) {
563 // call isNumeric recursively for each character
564 number
=isNumeric(x
.substring(j
,j
+1));
565 if(!number
) return number
;
570 // if x is number return true
571 if(numbers
.indexOf(x
)>=0) return true;
577 function hideOrShowFeeds(doc
, hide
) {
579 if (!doc
.styleSheets
) return;
581 var css_rules
= doc
.styleSheets
[0].cssRules
;
583 if (!css_rules
|| !css_rules
.length
) return;
585 for (i
= 0; i
< css_rules
.length
; i
++) {
586 var rule
= css_rules
[i
];
588 if (rule
.selectorText
== "ul.feedList li.feed") {
590 rule
.style
.display
= "block";
592 rule
.style
.display
= "none";
600 function selectTableRow(r
, do_select
) {
601 r
.className
= r
.className
.replace("Selected", "");
604 r
.className
= r
.className
+ "Selected";
608 function selectTableRowById(elem_id
, check_id
, do_select
) {
612 var row
= document
.getElementById(elem_id
);
615 selectTableRow(row
, do_select
);
618 var check
= document
.getElementById(check_id
);
621 check
.checked
= do_select
;
624 exception_error("selectTableRowById", e
);
628 function selectTableRowsByIdPrefix(content_id
, prefix
, check_prefix
, do_select
,
629 classcheck
, reset_others
) {
631 var content
= document
.getElementById(content_id
);
634 alert("[selectTableRows] Element " + content_id
+ " not found.");
638 for (i
= 0; i
< content
.rows
.length
; i
++) {
639 if (!classcheck
|| content
.rows
[i
].className
.match(classcheck
)) {
641 if (content
.rows
[i
].id
.match(prefix
)) {
642 selectTableRow(content
.rows
[i
], do_select
);
644 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
645 var check
= document
.getElementById(check_prefix
+ row_id
);
648 check
.checked
= do_select
;
650 } else if (reset_others
) {
651 selectTableRow(content
.rows
[i
], false);
653 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
654 var check
= document
.getElementById(check_prefix
+ row_id
);
657 check
.checked
= false;
661 } else if (reset_others
) {
662 selectTableRow(content
.rows
[i
], false);
664 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
665 var check
= document
.getElementById(check_prefix
+ row_id
);
668 check
.checked
= false;
675 function getSelectedTableRowIds(content_id
, prefix
) {
677 var content
= document
.getElementById(content_id
);
680 alert("[getSelectedTableRowIds] Element " + content_id
+ " not found.");
684 var sel_rows
= new Array();
686 for (i
= 0; i
< content
.rows
.length
; i
++) {
687 if (content
.rows
[i
].id
.match(prefix
) &&
688 content
.rows
[i
].className
.match("Selected")) {
690 var row_id
= content
.rows
[i
].id
.replace(prefix
+ "-", "");
691 sel_rows
.push(row_id
);
699 function toggleSelectRowById(sender
, id
) {
700 var row
= document
.getElementById(id
);
702 if (sender
.checked
) {
703 if (!row
.className
.match("Selected")) {
704 row
.className
= row
.className
+ "Selected";
707 if (row
.className
.match("Selected")) {
708 row
.className
= row
.className
.replace("Selected", "");
713 function toggleSelectListRow(sender
) {
714 var parent_row
= sender
.parentNode
;
716 if (sender
.checked
) {
717 if (!parent_row
.className
.match("Selected")) {
718 parent_row
.className
= parent_row
.className
+ "Selected";
721 if (parent_row
.className
.match("Selected")) {
722 parent_row
.className
= parent_row
.className
.replace("Selected", "");
728 function toggleSelectRow(sender
) {
729 var parent_row
= sender
.parentNode
.parentNode
;
731 if (sender
.checked
) {
732 if (!parent_row
.className
.match("Selected")) {
733 parent_row
.className
= parent_row
.className
+ "Selected";
736 if (parent_row
.className
.match("Selected")) {
737 parent_row
.className
= parent_row
.className
.replace("Selected", "");
742 function openExternalUrl(url
) {
743 var w
= window
.open(url
);
746 function getRelativeFeedId(list
, id
, direction
, unread_only
) {
748 if (direction
== "next") {
749 for (i
= 0; i
< list
.childNodes
.length
; i
++) {
750 var child
= list
.childNodes
[i
];
751 if (child
.id
&& child
.id
== "feedCatHolder") {
752 if (child
.lastChild
) {
753 var cr
= getRelativeFeedId(child
.firstChild
, id
, direction
);
756 } else if (child
.id
&& child
.id
.match("FEEDR-")) {
757 return child
.id
.replace('FEEDR-', '');
762 // FIXME select last feed doesn't work when only unread feeds are visible
764 if (direction
== "prev") {
765 for (i
= list
.childNodes
.length
-1; i
>= 0; i
--) {
766 var child
= list
.childNodes
[i
];
767 if (child
.id
== "feedCatHolder") {
768 if (child
.firstChild
) {
769 var cr
= getRelativeFeedId(child
.firstChild
, id
, direction
);
772 } else if (child
.id
.match("FEEDR-")) {
774 if (getCookie("ttrss_vf_hreadf") == 1) {
775 if (child
.className
!= "feed") {
776 alert(child
.className
);
777 return child
.id
.replace('FEEDR-', '');
780 return child
.id
.replace('FEEDR-', '');
787 var feed
= list
.ownerDocument
.getElementById("FEEDR-" + getActiveFeedId());
789 if (getCookie("ttrss_vf_hreadf") == 1) {
793 if (direction
== "next") {
803 } else if (e
.parentNode
.parentNode
.nextSibling
) {
805 var this_cat
= e
.parentNode
.parentNode
;
809 if (this_cat
&& this_cat
.nextSibling
) {
810 while (!e
&& this_cat
.nextSibling
) {
811 this_cat
= this_cat
.nextSibling
;
812 if (this_cat
.id
== "feedCatHolder") {
813 e
= this_cat
.firstChild
.firstChild
;
823 if (!unread_only
|| (unread_only
&& e
.className
!= "feed" &&
824 e
.className
!= "error")) {
825 return e
.id
.replace("FEEDR-", "");
830 } else if (direction
== "prev") {
836 if (e
.previousSibling
) {
838 e
= e
.previousSibling
;
840 } else if (e
.parentNode
.parentNode
.previousSibling
) {
842 var this_cat
= e
.parentNode
.parentNode
;
846 if (this_cat
&& this_cat
.previousSibling
) {
847 while (!e
&& this_cat
.previousSibling
) {
848 this_cat
= this_cat
.previousSibling
;
849 if (this_cat
.id
== "feedCatHolder") {
850 e
= this_cat
.firstChild
.lastChild
;
860 if (!unread_only
|| (unread_only
&& e
.className
!= "feed" &&
861 e
.className
!= "error")) {
862 return e
.id
.replace("FEEDR-", "");
870 function showBlockElement(id
) {
871 var elem
= document
.getElementById(id
);
874 elem
.style
.display
= "block";
876 alert("[showBlockElement] can't find element with id " + id
);
880 function hideParentElement(e
) {
881 e
.parentNode
.style
.display
= "none";
884 function dropboxSelect(e
, v
) {
885 for (i
= 0; i
< e
.length
; i
++) {
886 if (e
[i
].value
== v
) {
893 // originally stolen from http://www.11tmr.com/11tmr.nsf/d6plinks/MWHE-695L9Z
894 // bugfixed just a little bit :-)
895 function getURLParam(strParamName
){
897 var strHref
= window
.location
.href
;
899 if (strHref
.indexOf("#") == strHref
.length
-1) {
900 strHref
= strHref
.substring(0, strHref
.length
-1);
903 if ( strHref
.indexOf("?") > -1 ){
904 var strQueryString
= strHref
.substr(strHref
.indexOf("?"));
905 var aQueryString
= strQueryString
.split("&");
906 for ( var iParam
= 0; iParam
< aQueryString
.length
; iParam
++ ){
907 if (aQueryString
[iParam
].indexOf(strParamName
+ "=") > -1 ){
908 var aParam
= aQueryString
[iParam
].split("=");
909 strReturn
= aParam
[1];
917 function leading_zero(p
) {
919 if (s
.length
== 1) s
= "0" + s
;
923 function closeInfoBox(cleanup
) {
924 var box
= document
.getElementById('infoBox');
925 var shadow
= document
.getElementById('infoBoxShadow');
928 shadow
.style
.display
= "none";
930 box
.style
.display
= "none";
933 if (cleanup
) box
.innerHTML
= " ";
940 function displayDlg(id
, param
) {
942 if (!xmlhttp_ready(xmlhttp
)) {
949 xmlhttp
.open("GET", "backend.php?op=dlg&id=" +
950 param_escape(id
) + "¶m=" + param_escape(param
), true);
951 xmlhttp
.onreadystatechange
=infobox_callback
;
958 function infobox_submit_callback() {
959 if (xmlhttp
.readyState
== 4) {
962 // called from prefs, reload tab
964 selectTab(active_tab
, false);
967 notify(xmlhttp
.responseText
);
972 function infobox_callback() {
973 if (xmlhttp
.readyState
== 4) {
974 var box
= document
.getElementById('infoBox');
975 var shadow
= document
.getElementById('infoBoxShadow');
977 box
.innerHTML
=xmlhttp
.responseText
;
979 shadow
.style
.display
= "block";
981 box
.style
.display
= "block";
987 function qaddFilter() {
989 if (!xmlhttp_ready(xmlhttp
)) {
994 var query
= Form
.serialize("filter_add_form");
996 xmlhttp
.open("GET", "backend.php?" + query
, true);
997 xmlhttp
.onreadystatechange
=infobox_submit_callback
;
1003 function toggleSubmitNotEmpty(e
, submit_id
) {
1005 document
.getElementById(submit_id
).disabled
= (e
.value
== "")
1007 exception_error("toggleSubmitNotEmpty", e
);
1011 function isValidURL(s
) {
1012 return s
.match("http://") != null || s
.match("https://") != null;
1017 if (!xmlhttp_ready(xmlhttp
)) {
1018 printLockingError();
1022 notify("Adding feed...");
1026 var feeds_doc
= window
.frames
["feeds-frame"].document
;
1028 feeds_doc
.location
.href
= "backend.php?op=error&msg=Loading,%20please wait...";
1030 var query
= Form
.serialize("feed_add_form");
1032 xmlhttp
.open("GET", "backend.php?" + query
, true);
1033 xmlhttp
.onreadystatechange
=dlg_frefresh_callback
;
1037 function filterCR(e
)
1042 key
= window
.event
.keyCode
; //IE
1044 key
= e
.which
; //firefox