From ea798ef3c491cfec5b863693cd583ec04b45c7bd Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 26 Oct 2013 02:36:06 -0400 Subject: [PATCH 1/8] Fix
 rendering on landing page

---
 index.html | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/index.html b/index.html
index 591e1ac..b28d6fb 100644
--- a/index.html
+++ b/index.html
@@ -89,9 +89,10 @@
             
To start using, please enable relay in your WeeChat client: -
-          /set relay.network.password yourpassword
-          /relay add weechat 9001
+
+/set relay.network.password yourpassword
+/relay add weechat 9001
+
WeeChat version 0.4.2 or higher is required.
The communication goes directly between your browser and your weechat in clear text. Connection settings are saved between sessions, including password, in your own browser. @@ -112,16 +113,16 @@ If you check the encryption box, communication between browser and WeeChat will be encrypted.
Note: Due to a bug encryption will not work in Firefox. You must also first visit the URL https://weechathost:relayport/ to accept the certificate

If you want to use encrypted session you first have to set up the relay using SSL like this: -
-          $ mkdir -p ~/.weechat/ssl
-          $ cd ~/.weechat/ssl
-          $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out relay.pem
-          
+
+$ mkdir -p ~/.weechat/ssl
+$ cd ~/.weechat/ssl
+$ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out relay.pem
+
If WeeChat is already running, you can reload the certificate and private key with command: -
-          /relay sslcertkey
-          /relay add ssl.weechat 8000
-          
+
+/relay sslcertkey
+/relay add ssl.weechat 8000
+
From 9772da00956aad5e5fc17d994a17f544a705be40 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 26 Oct 2013 04:30:35 -0400 Subject: [PATCH 2/8] Implement full support of WeeChat text styling --- css/style.css | 1929 +++++++++++++++++++++++++++++++++++++++++++++ index.html | 5 +- js/models.js | 75 +- js/websockets.js | 15 +- js/weechat.js | 1954 +++++++++++++++++++++++++++------------------- 5 files changed, 3135 insertions(+), 843 deletions(-) create mode 100644 css/style.css diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..a548f8c --- /dev/null +++ b/css/style.css @@ -0,0 +1,1929 @@ +/* style options, foreground */ +.cof-separator { + color: #68b5d4; +} +.cof-chat { + color: #f7f7f7; +} +.cof-chat_time { + color: #f7f7f7; +} +.cof-chat_time_delimiters { + color: #cc843b; +} +.cof-chat_prefix_error { + color: #ffe377; +} +.cof-chat_prefix_network { + color: #fbb1f9; +} +.cof-chat_prefix_action { + color: #f7f7f7; +} +.cof-chat_prefix_join { + color: #cdee69; +} +.cof-chat_prefix_quit { + color: #c75646; +} +.cof-chat_prefix_more { + color: #fbb1f9; +} +.cof-chat_prefix_suffix { + color: #cdee69; +} +.cof-chat_buffer { + color: #f7f7f7; +} +.cof-chat_server { + color: #cc843b; +} +.cof-chat_channel { + color: #f7f7f7; +} +.cof-chat_nick { + color: #77dfd8; +} +.cof-chat_nick_self { + color: #f7f7f7; +} +.cof-chat_nick_other { + color: #77dfd8; +} +.cof-invalid { + /* should never happen */ + color: #f7f7f7; + background-color: transparent; +} +.cof-chat_host { + color: #77dfd8; +} +.cof-chat_delimiters { + color: #cdee69; +} +.cof-chat_highlight { + color: #ffe377; + background-color: #c8a0d1; +} +.cof-chat_read_marker { + color: #fbb1f9; +} +.cof-chat_text_found { + color: #ffe377; +} +.cof-chat_value { + color: #77dfd8; +} +.cof-chat_prefix_buffer { + color: #cc843b; +} +.cof-chat_tags { + color: #c75646; +} +.cof-chat_inactive_window { + color: #5d5d5d; +} +.cof-chat_inactive_buffer { + color: #5d5d5d; +} +.cof-chat_prefix_buffer_inactive_buffer { + color: #5d5d5d; +} +.cof-chat_nick_offline { + color: #5d5d5d; +} +.cof-chat_nick_offline_highlight { + color: #f7f7f7; + background-color: #5d5d5d; +} +.cof-chat_nick_prefix { + color: #cdee69; +} +.cof-chat_nick_suffix { + color: #cdee69; +} +.cof-emphasis { + color: #ffe377; + background-color: #c8a0d1; +} +.cof-chat_day_change { + color: #77dfd8; +} + +/* style options, background */ +.cob-separator { +} +.cob-chat { +} +.cob-chat_time { +} +.cob-chat_time_delimiters { +} +.cob-chat_prefix_error { +} +.cob-chat_prefix_network { +} +.cob-chat_prefix_action { +} +.cob-chat_prefix_join { +} +.cob-chat_prefix_quit { +} +.cob-chat_prefix_more { +} +.cob-chat_prefix_suffix { +} +.cob-chat_buffer { +} +.cob-chat_server { +} +.cob-chat_channel { +} +.cob-chat_nick { +} +.cob-chat_nick_self { +} +.cob-chat_nick_other { +} +.cob-invalid { +} +.cob-chat_host { +} +.cob-chat_delimiters { +} +.cob-chat_highlight { + background-color: #c8a0d1; +} +.cob-chat_read_marker { +} +.cob-chat_text_found { +} +.cob-chat_value { +} +.cob-chat_prefix_buffer { +} +.cob-chat_tags { +} +.cob-chat_inactive_window { +} +.cob-chat_inactive_buffer { +} +.cob-chat_prefix_buffer_inactive_buffer { +} +.cob-chat_nick_offline { +} +.cob-chat_nick_offline_highlight { + background-color: #5d5d5d; +} +.cob-chat_nick_prefix { +} +.cob-chat_nick_suffix { +} +.cob-emphasis { + background-color: #c8a0d1; +} +.cob-chat_day_change { +} + +/* style options, attributes */ +.coa-separator { +} +.coa-chat { +} +.coa-chat_time { +} +.coa-chat_time_delimiters { +} +.coa-chat_prefix_error { +} +.coa-chat_prefix_network { +} +.coa-chat_prefix_action { +} +.coa-chat_prefix_join { +} +.coa-chat_prefix_quit { +} +.coa-chat_prefix_more { +} +.coa-chat_prefix_suffix { +} +.coa-chat_buffer { +} +.coa-chat_server { +} +.coa-chat_channel { +} +.coa-chat_nick { +} +.coa-chat_nick_self { +} +.coa-chat_nick_other { +} +.coa-invalid { +} +.coa-chat_host { +} +.coa-chat_delimiters { +} +.coa-chat_highlight { +} +.coa-chat_read_marker { +} +.coa-chat_text_found { +} +.coa-chat_value { +} +.coa-chat_prefix_buffer { +} +.coa-chat_tags { +} +.coa-chat_inactive_window { +} +.coa-chat_inactive_buffer { +} +.coa-chat_prefix_buffer_inactive_buffer { +} +.coa-chat_nick_offline { +} +.coa-chat_nick_offline_highlight { +} +.coa-chat_nick_prefix { +} +.coa-chat_nick_suffix { +} +.coa-emphasis { +} +.coa-chat_day_change { +} + +/* WeeChat colors, foreground */ +.cwf-default { + color: #f7f7f7; +} +.cwf-black { + color: #000000; +} +.cwf-darkgray { + color: #5d5d5d; +} +.cwf-darkred { + color: #c75646; +} +.cwf-lightred { + color: #e09690; +} +.cwf-darkgreen { + color: #8eb33b; +} +.cwf-lightgreen { + color: #cdee69; +} +.cwf-brown { + color: #b27232; +} +.cwf-yellow { + color: #ffe377; +} +.cwf-darkblue { + color: #72b3cc; +} +.cwf-lightblue { + color: #9cd9f0; +} +.cwf-darkmagenta { + color: #c8a0d1; +} +.cwf-lightmagenta { + color: #fbb1f9; +} +.cwf-darkcyan { + color: #218693; +} +.cwf-lightcyan { + color: #77dfd8; +} +.cwf-gray { + color: #b0b0b0; +} +.cwf-white { + color: #f7f7f7; +} + +/* WeeChat colors, background */ +.cwb-default { + background-color: transparent; +} +.cwb-black { + background-color: #000000; +} +.cwb-darkgray { + background-color: #5d5d5d; +} +.cwb-darkred { + background-color: #c75646; +} +.cwb-lightred { + background-color: #e09690; +} +.cwb-darkgreen { + background-color: #8eb33b; +} +.cwb-lightgreen { + background-color: #cdee69; +} +.cwb-brown { + background-color: #b27232; +} +.cwb-yellow { + background-color: #ffe377; +} +.cwb-darkblue { + background-color: #72b3cc; +} +.cwb-lightblue { + background-color: #9cd9f0; +} +.cwb-darkmagenta { + background-color: #c8a0d1; +} +.cwb-lightmagenta { + background-color: #fbb1f9; +} +.cwb-darkcyan { + background-color: #218693; +} +.cwb-lightcyan { + background-color: #77dfd8; +} +.cwb-gray { + background-color: #b0b0b0; +} +.cwb-white { + background-color: #f7f7f7; +} + +/* extended colors, foreground */ +.cef-0 { + color: #000000; /* 000 Black */ +} +.cef-1 { + color: #cd0000; /* 001 DarkRed */ +} +.cef-2 { + color: #00cd00; /* 002 DarkGreen */ +} +.cef-3 { + color: #cdcd00; /* 003 DarkYellow */ +} +.cef-4 { + color: #0000ee; /* 004 DarkBlue */ +} +.cef-5 { + color: #cd00cd; /* 005 DarkMagenta */ +} +.cef-6 { + color: #00cdcd; /* 006 DarkCyan */ +} +.cef-7 { + color: #e5e5e5; /* 007 LightGrey */ +} +.cef-8 { + color: #7f7f7f; /* 008 DarkGrey */ +} +.cef-9 { + color: #ff0000; /* 009 LightRed */ +} +.cef-10 { + color: #00ff00; /* 010 LightGreen */ +} +.cef-11 { + color: #ffff00; /* 011 LightYellow */ +} +.cef-12 { + color: #5c5cff; /* 012 LightBlue */ +} +.cef-13 { + color: #ff00ff; /* 013 LightMagenta */ +} +.cef-14 { + color: #00ffff; /* 014 LightCyan */ +} +.cef-15 { + color: #ffffff; /* 015 White */ +} +.cef-16 { + color: #000000; /* 016 Grey0 */ +} +.cef-17 { + color: #00005f; /* 017 NavyBlue */ +} +.cef-18 { + color: #000087; /* 018 DarkBlue */ +} +.cef-19 { + color: #0000af; /* 019 Blue3 */ +} +.cef-20 { + color: #0000d7; /* 020 Blue3 */ +} +.cef-21 { + color: #0000ff; /* 021 Blue1 */ +} +.cef-22 { + color: #005f00; /* 022 DarkGreen */ +} +.cef-23 { + color: #005f5f; /* 023 DeepSkyBlue4 */ +} +.cef-24 { + color: #005f87; /* 024 DeepSkyBlue4 */ +} +.cef-25 { + color: #005faf; /* 025 DeepSkyBlue4 */ +} +.cef-26 { + color: #005fd7; /* 026 DodgerBlue3 */ +} +.cef-27 { + color: #005fff; /* 027 DodgerBlue2 */ +} +.cef-28 { + color: #008700; /* 028 Green4 */ +} +.cef-29 { + color: #00875f; /* 029 SpringGreen4 */ +} +.cef-30 { + color: #008787; /* 030 Turquoise4 */ +} +.cef-31 { + color: #0087af; /* 031 DeepSkyBlue3 */ +} +.cef-32 { + color: #0087d7; /* 032 DeepSkyBlue3 */ +} +.cef-33 { + color: #0087ff; /* 033 DodgerBlue1 */ +} +.cef-34 { + color: #00af00; /* 034 Green3 */ +} +.cef-35 { + color: #00af5f; /* 035 SpringGreen3 */ +} +.cef-36 { + color: #00af87; /* 036 DarkCyan */ +} +.cef-37 { + color: #00afaf; /* 037 LightSeaGreen */ +} +.cef-38 { + color: #00afd7; /* 038 DeepSkyBlue2 */ +} +.cef-39 { + color: #00afff; /* 039 DeepSkyBlue1 */ +} +.cef-40 { + color: #00d700; /* 040 Green3 */ +} +.cef-41 { + color: #00d75f; /* 041 SpringGreen3 */ +} +.cef-42 { + color: #00d787; /* 042 SpringGreen2 */ +} +.cef-43 { + color: #00d7af; /* 043 Cyan3 */ +} +.cef-44 { + color: #00d7d7; /* 044 DarkTurquoise */ +} +.cef-45 { + color: #00d7ff; /* 045 Turquoise2 */ +} +.cef-46 { + color: #00ff00; /* 046 Green1 */ +} +.cef-47 { + color: #00ff5f; /* 047 SpringGreen2 */ +} +.cef-48 { + color: #00ff87; /* 048 SpringGreen1 */ +} +.cef-49 { + color: #00ffaf; /* 049 MediumSpringGreen */ +} +.cef-50 { + color: #00ffd7; /* 050 Cyan2 */ +} +.cef-51 { + color: #00ffff; /* 051 Cyan1 */ +} +.cef-52 { + color: #5f0000; /* 052 DarkRed */ +} +.cef-53 { + color: #5f005f; /* 053 DeepPink4 */ +} +.cef-54 { + color: #5f0087; /* 054 Purple4 */ +} +.cef-55 { + color: #5f00af; /* 055 Purple4 */ +} +.cef-56 { + color: #5f00d7; /* 056 Purple3 */ +} +.cef-57 { + color: #5f00ff; /* 057 BlueViolet */ +} +.cef-58 { + color: #5f5f00; /* 058 Orange4 */ +} +.cef-59 { + color: #5f5f5f; /* 059 Grey37 */ +} +.cef-60 { + color: #5f5f87; /* 060 MediumPurple4 */ +} +.cef-61 { + color: #5f5faf; /* 061 SlateBlue3 */ +} +.cef-62 { + color: #5f5fd7; /* 062 SlateBlue3 */ +} +.cef-63 { + color: #5f5fff; /* 063 RoyalBlue1 */ +} +.cef-64 { + color: #5f8700; /* 064 Chartreuse4 */ +} +.cef-65 { + color: #5f875f; /* 065 DarkSeaGreen4 */ +} +.cef-66 { + color: #5f8787; /* 066 PaleTurquoise4 */ +} +.cef-67 { + color: #5f87af; /* 067 SteelBlue */ +} +.cef-68 { + color: #5f87d7; /* 068 SteelBlue3 */ +} +.cef-69 { + color: #5f87ff; /* 069 CornflowerBlue */ +} +.cef-70 { + color: #5faf00; /* 070 Chartreuse3 */ +} +.cef-71 { + color: #5faf5f; /* 071 DarkSeaGreen4 */ +} +.cef-72 { + color: #5faf87; /* 072 CadetBlue */ +} +.cef-73 { + color: #5fafaf; /* 073 CadetBlue */ +} +.cef-74 { + color: #5fafd7; /* 074 SkyBlue3 */ +} +.cef-75 { + color: #5fafff; /* 075 SteelBlue1 */ +} +.cef-76 { + color: #5fd700; /* 076 Chartreuse3 */ +} +.cef-77 { + color: #5fd75f; /* 077 PaleGreen3 */ +} +.cef-78 { + color: #5fd787; /* 078 SeaGreen3 */ +} +.cef-79 { + color: #5fd7af; /* 079 Aquamarine3 */ +} +.cef-80 { + color: #5fd7d7; /* 080 MediumTurquoise */ +} +.cef-81 { + color: #5fd7ff; /* 081 SteelBlue1 */ +} +.cef-82 { + color: #5fff00; /* 082 Chartreuse2 */ +} +.cef-83 { + color: #5fff5f; /* 083 SeaGreen2 */ +} +.cef-84 { + color: #5fff87; /* 084 SeaGreen1 */ +} +.cef-85 { + color: #5fffaf; /* 085 SeaGreen1 */ +} +.cef-86 { + color: #5fffd7; /* 086 Aquamarine1 */ +} +.cef-87 { + color: #5fffff; /* 087 DarkSlateGray2 */ +} +.cef-88 { + color: #870000; /* 088 DarkRed */ +} +.cef-89 { + color: #87005f; /* 089 DeepPink4 */ +} +.cef-90 { + color: #870087; /* 090 DarkMagenta */ +} +.cef-91 { + color: #8700af; /* 091 DarkMagenta */ +} +.cef-92 { + color: #8700d7; /* 092 DarkViolet */ +} +.cef-93 { + color: #8700ff; /* 093 Purple */ +} +.cef-94 { + color: #875f00; /* 094 Orange4 */ +} +.cef-95 { + color: #875f5f; /* 095 LightPink4 */ +} +.cef-96 { + color: #875f87; /* 096 Plum4 */ +} +.cef-97 { + color: #875faf; /* 097 MediumPurple3 */ +} +.cef-98 { + color: #875fd7; /* 098 MediumPurple3 */ +} +.cef-99 { + color: #875fff; /* 099 SlateBlue1 */ +} +.cef-100 { + color: #878700; /* 100 Yellow4 */ +} +.cef-101 { + color: #87875f; /* 101 Wheat4 */ +} +.cef-102 { + color: #878787; /* 102 Grey53 */ +} +.cef-103 { + color: #8787af; /* 103 LightSlateGrey */ +} +.cef-104 { + color: #8787d7; /* 104 MediumPurple */ +} +.cef-105 { + color: #8787ff; /* 105 LightSlateBlue */ +} +.cef-106 { + color: #87af00; /* 106 Yellow4 */ +} +.cef-107 { + color: #87af5f; /* 107 DarkOliveGreen3 */ +} +.cef-108 { + color: #87af87; /* 108 DarkSeaGreen */ +} +.cef-109 { + color: #87afaf; /* 109 LightSkyBlue3 */ +} +.cef-110 { + color: #87afd7; /* 110 LightSkyBlue3 */ +} +.cef-111 { + color: #87afff; /* 111 SkyBlue2 */ +} +.cef-112 { + color: #87d700; /* 112 Chartreuse2 */ +} +.cef-113 { + color: #87d75f; /* 113 DarkOliveGreen3 */ +} +.cef-114 { + color: #87d787; /* 114 PaleGreen3 */ +} +.cef-115 { + color: #87d7af; /* 115 DarkSeaGreen3 */ +} +.cef-116 { + color: #87d7d7; /* 116 DarkSlateGray3 */ +} +.cef-117 { + color: #87d7ff; /* 117 SkyBlue1 */ +} +.cef-118 { + color: #87ff00; /* 118 Chartreuse1 */ +} +.cef-119 { + color: #87ff5f; /* 119 LightGreen */ +} +.cef-120 { + color: #87ff87; /* 120 LightGreen */ +} +.cef-121 { + color: #87ffaf; /* 121 PaleGreen1 */ +} +.cef-122 { + color: #87ffd7; /* 122 Aquamarine1 */ +} +.cef-123 { + color: #87ffff; /* 123 DarkSlateGray1 */ +} +.cef-124 { + color: #af0000; /* 124 Red3 */ +} +.cef-125 { + color: #af005f; /* 125 DeepPink4 */ +} +.cef-126 { + color: #af0087; /* 126 MediumVioletRed */ +} +.cef-127 { + color: #af00af; /* 127 Magenta3 */ +} +.cef-128 { + color: #af00d7; /* 128 DarkViolet */ +} +.cef-129 { + color: #af00ff; /* 129 Purple */ +} +.cef-130 { + color: #af5f00; /* 130 DarkOrange3 */ +} +.cef-131 { + color: #af5f5f; /* 131 IndianRed */ +} +.cef-132 { + color: #af5f87; /* 132 HotPink3 */ +} +.cef-133 { + color: #af5faf; /* 133 MediumOrchid3 */ +} +.cef-134 { + color: #af5fd7; /* 134 MediumOrchid */ +} +.cef-135 { + color: #af5fff; /* 135 MediumPurple2 */ +} +.cef-136 { + color: #af8700; /* 136 DarkGoldenrod */ +} +.cef-137 { + color: #af875f; /* 137 LightSalmon3 */ +} +.cef-138 { + color: #af8787; /* 138 RosyBrown */ +} +.cef-139 { + color: #af87af; /* 139 Grey63 */ +} +.cef-140 { + color: #af87d7; /* 140 MediumPurple2 */ +} +.cef-141 { + color: #af87ff; /* 141 MediumPurple1 */ +} +.cef-142 { + color: #afaf00; /* 142 Gold3 */ +} +.cef-143 { + color: #afaf5f; /* 143 DarkKhaki */ +} +.cef-144 { + color: #afaf87; /* 144 NavajoWhite3 */ +} +.cef-145 { + color: #afafaf; /* 145 Grey69 */ +} +.cef-146 { + color: #afafd7; /* 146 LightSteelBlue3 */ +} +.cef-147 { + color: #afafff; /* 147 LightSteelBlue */ +} +.cef-148 { + color: #afd700; /* 148 Yellow3 */ +} +.cef-149 { + color: #afd75f; /* 149 DarkOliveGreen3 */ +} +.cef-150 { + color: #afd787; /* 150 DarkSeaGreen3 */ +} +.cef-151 { + color: #afd7af; /* 151 DarkSeaGreen2 */ +} +.cef-152 { + color: #afd7d7; /* 152 LightCyan3 */ +} +.cef-153 { + color: #afd7ff; /* 153 LightSkyBlue1 */ +} +.cef-154 { + color: #afff00; /* 154 GreenYellow */ +} +.cef-155 { + color: #afff5f; /* 155 DarkOliveGreen2 */ +} +.cef-156 { + color: #afff87; /* 156 PaleGreen1 */ +} +.cef-157 { + color: #afffaf; /* 157 DarkSeaGreen2 */ +} +.cef-158 { + color: #afffd7; /* 158 DarkSeaGreen1 */ +} +.cef-159 { + color: #afffff; /* 159 PaleTurquoise1 */ +} +.cef-160 { + color: #d70000; /* 160 Red3 */ +} +.cef-161 { + color: #d7005f; /* 161 DeepPink3 */ +} +.cef-162 { + color: #d70087; /* 162 DeepPink3 */ +} +.cef-163 { + color: #d700af; /* 163 Magenta3 */ +} +.cef-164 { + color: #d700d7; /* 164 Magenta3 */ +} +.cef-165 { + color: #d700ff; /* 165 Magenta2 */ +} +.cef-166 { + color: #d75f00; /* 166 DarkOrange3 */ +} +.cef-167 { + color: #d75f5f; /* 167 IndianRed */ +} +.cef-168 { + color: #d75f87; /* 168 HotPink3 */ +} +.cef-169 { + color: #d75faf; /* 169 HotPink2 */ +} +.cef-170 { + color: #d75fd7; /* 170 Orchid */ +} +.cef-171 { + color: #d75fff; /* 171 MediumOrchid1 */ +} +.cef-172 { + color: #d78700; /* 172 Orange3 */ +} +.cef-173 { + color: #d7875f; /* 173 LightSalmon3 */ +} +.cef-174 { + color: #d78787; /* 174 LightPink3 */ +} +.cef-175 { + color: #d787af; /* 175 Pink3 */ +} +.cef-176 { + color: #d787d7; /* 176 Plum3 */ +} +.cef-177 { + color: #d787ff; /* 177 Violet */ +} +.cef-178 { + color: #d7af00; /* 178 Gold3 */ +} +.cef-179 { + color: #d7af5f; /* 179 LightGoldenrod3 */ +} +.cef-180 { + color: #d7af87; /* 180 Tan */ +} +.cef-181 { + color: #d7afaf; /* 181 MistyRose3 */ +} +.cef-182 { + color: #d7afd7; /* 182 Thistle3 */ +} +.cef-183 { + color: #d7afff; /* 183 Plum2 */ +} +.cef-184 { + color: #d7d700; /* 184 Yellow3 */ +} +.cef-185 { + color: #d7d75f; /* 185 Khaki3 */ +} +.cef-186 { + color: #d7d787; /* 186 LightGoldenrod2 */ +} +.cef-187 { + color: #d7d7af; /* 187 LightYellow3 */ +} +.cef-188 { + color: #d7d7d7; /* 188 Grey84 */ +} +.cef-189 { + color: #d7d7ff; /* 189 LightSteelBlue1 */ +} +.cef-190 { + color: #d7ff00; /* 190 Yellow2 */ +} +.cef-191 { + color: #d7ff5f; /* 191 DarkOliveGreen1 */ +} +.cef-192 { + color: #d7ff87; /* 192 DarkOliveGreen1 */ +} +.cef-193 { + color: #d7ffaf; /* 193 DarkSeaGreen1 */ +} +.cef-194 { + color: #d7ffd7; /* 194 Honeydew2 */ +} +.cef-195 { + color: #d7ffff; /* 195 LightCyan1 */ +} +.cef-196 { + color: #ff0000; /* 196 Red1 */ +} +.cef-197 { + color: #ff005f; /* 197 DeepPink2 */ +} +.cef-198 { + color: #ff0087; /* 198 DeepPink1 */ +} +.cef-199 { + color: #ff00af; /* 199 DeepPink1 */ +} +.cef-200 { + color: #ff00d7; /* 200 Magenta2 */ +} +.cef-201 { + color: #ff00ff; /* 201 Magenta1 */ +} +.cef-202 { + color: #ff5f00; /* 202 OrangeRed1 */ +} +.cef-203 { + color: #ff5f5f; /* 203 IndianRed1 */ +} +.cef-204 { + color: #ff5f87; /* 204 IndianRed1 */ +} +.cef-205 { + color: #ff5faf; /* 205 HotPink */ +} +.cef-206 { + color: #ff5fd7; /* 206 HotPink */ +} +.cef-207 { + color: #ff5fff; /* 207 MediumOrchid1 */ +} +.cef-208 { + color: #ff8700; /* 208 DarkOrange */ +} +.cef-209 { + color: #ff875f; /* 209 Salmon1 */ +} +.cef-210 { + color: #ff8787; /* 210 LightCoral */ +} +.cef-211 { + color: #ff87af; /* 211 PaleVioletRed1 */ +} +.cef-212 { + color: #ff87d7; /* 212 Orchid2 */ +} +.cef-213 { + color: #ff87ff; /* 213 Orchid1 */ +} +.cef-214 { + color: #ffaf00; /* 214 Orange1 */ +} +.cef-215 { + color: #ffaf5f; /* 215 SandyBrown */ +} +.cef-216 { + color: #ffaf87; /* 216 LightSalmon1 */ +} +.cef-217 { + color: #ffafaf; /* 217 LightPink1 */ +} +.cef-218 { + color: #ffafd7; /* 218 Pink1 */ +} +.cef-219 { + color: #ffafff; /* 219 Plum1 */ +} +.cef-220 { + color: #ffd700; /* 220 Gold1 */ +} +.cef-221 { + color: #ffd75f; /* 221 LightGoldenrod2 */ +} +.cef-222 { + color: #ffd787; /* 222 LightGoldenrod2 */ +} +.cef-223 { + color: #ffd7af; /* 223 NavajoWhite1 */ +} +.cef-224 { + color: #ffd7d7; /* 224 MistyRose1 */ +} +.cef-225 { + color: #ffd7ff; /* 225 Thistle1 */ +} +.cef-226 { + color: #ffff00; /* 226 Yellow1 */ +} +.cef-227 { + color: #ffff5f; /* 227 LightGoldenrod1 */ +} +.cef-228 { + color: #ffff87; /* 228 Khaki1 */ +} +.cef-229 { + color: #ffffaf; /* 229 Wheat1 */ +} +.cef-230 { + color: #ffffd7; /* 230 Cornsilk1 */ +} +.cef-231 { + color: #ffffff; /* 231 Grey100 */ +} +.cef-232 { + color: #080808; /* 232 Grey3 */ +} +.cef-233 { + color: #121212; /* 233 Grey7 */ +} +.cef-234 { + color: #1c1c1c; /* 234 Grey11 */ +} +.cef-235 { + color: #262626; /* 235 Grey15 */ +} +.cef-236 { + color: #303030; /* 236 Grey19 */ +} +.cef-237 { + color: #3a3a3a; /* 237 Grey23 */ +} +.cef-238 { + color: #444444; /* 238 Grey27 */ +} +.cef-239 { + color: #4e4e4e; /* 239 Grey30 */ +} +.cef-240 { + color: #585858; /* 240 Grey35 */ +} +.cef-241 { + color: #626262; /* 241 Grey39 */ +} +.cef-242 { + color: #6c6c6c; /* 242 Grey42 */ +} +.cef-243 { + color: #767676; /* 243 Grey46 */ +} +.cef-244 { + color: #808080; /* 244 Grey50 */ +} +.cef-245 { + color: #8a8a8a; /* 245 Grey54 */ +} +.cef-246 { + color: #949494; /* 246 Grey58 */ +} +.cef-247 { + color: #9e9e9e; /* 247 Grey62 */ +} +.cef-248 { + color: #a8a8a8; /* 248 Grey66 */ +} +.cef-249 { + color: #b2b2b2; /* 249 Grey70 */ +} +.cef-250 { + color: #bcbcbc; /* 250 Grey74 */ +} +.cef-251 { + color: #c6c6c6; /* 251 Grey78 */ +} +.cef-252 { + color: #d0d0d0; /* 252 Grey82 */ +} +.cef-253 { + color: #dadada; /* 253 Grey85 */ +} +.cef-254 { + color: #e4e4e4; /* 254 Grey89 */ +} +.cef-255 { + color: #eeeeee; /* 255 Grey93 */ +} + +/* extended colors, background */ +.ceb-0 { + background-color: #000000; /* 000 Black */ +} +.ceb-1 { + background-color: #cd0000; /* 001 DarkRed */ +} +.ceb-2 { + background-color: #00cd00; /* 002 DarkGreen */ +} +.ceb-3 { + background-color: #cdcd00; /* 003 DarkYellow */ +} +.ceb-4 { + background-color: #0000ee; /* 004 DarkBlue */ +} +.ceb-5 { + background-color: #cd00cd; /* 005 DarkMagenta */ +} +.ceb-6 { + background-color: #00cdcd; /* 006 DarkCyan */ +} +.ceb-7 { + background-color: #e5e5e5; /* 007 LightGrey */ +} +.ceb-8 { + background-color: #7f7f7f; /* 008 DarkGrey */ +} +.ceb-9 { + background-color: #ff0000; /* 009 LightRed */ +} +.ceb-10 { + background-color: #00ff00; /* 010 LightGreen */ +} +.ceb-11 { + background-color: #ffff00; /* 011 LightYellow */ +} +.ceb-12 { + background-color: #5c5cff; /* 012 LightBlue */ +} +.ceb-13 { + background-color: #ff00ff; /* 013 LightMagenta */ +} +.ceb-14 { + background-color: #00ffff; /* 014 LightCyan */ +} +.ceb-15 { + background-color: #ffffff; /* 015 White */ +} +.ceb-16 { + background-color: #000000; /* 016 Grey0 */ +} +.ceb-17 { + background-color: #00005f; /* 017 NavyBlue */ +} +.ceb-18 { + background-color: #000087; /* 018 DarkBlue */ +} +.ceb-19 { + background-color: #0000af; /* 019 Blue3 */ +} +.ceb-20 { + background-color: #0000d7; /* 020 Blue3 */ +} +.ceb-21 { + background-color: #0000ff; /* 021 Blue1 */ +} +.ceb-22 { + background-color: #005f00; /* 022 DarkGreen */ +} +.ceb-23 { + background-color: #005f5f; /* 023 DeepSkyBlue4 */ +} +.ceb-24 { + background-color: #005f87; /* 024 DeepSkyBlue4 */ +} +.ceb-25 { + background-color: #005faf; /* 025 DeepSkyBlue4 */ +} +.ceb-26 { + background-color: #005fd7; /* 026 DodgerBlue3 */ +} +.ceb-27 { + background-color: #005fff; /* 027 DodgerBlue2 */ +} +.ceb-28 { + background-color: #008700; /* 028 Green4 */ +} +.ceb-29 { + background-color: #00875f; /* 029 SpringGreen4 */ +} +.ceb-30 { + background-color: #008787; /* 030 Turquoise4 */ +} +.ceb-31 { + background-color: #0087af; /* 031 DeepSkyBlue3 */ +} +.ceb-32 { + background-color: #0087d7; /* 032 DeepSkyBlue3 */ +} +.ceb-33 { + background-color: #0087ff; /* 033 DodgerBlue1 */ +} +.ceb-34 { + background-color: #00af00; /* 034 Green3 */ +} +.ceb-35 { + background-color: #00af5f; /* 035 SpringGreen3 */ +} +.ceb-36 { + background-color: #00af87; /* 036 DarkCyan */ +} +.ceb-37 { + background-color: #00afaf; /* 037 LightSeaGreen */ +} +.ceb-38 { + background-color: #00afd7; /* 038 DeepSkyBlue2 */ +} +.ceb-39 { + background-color: #00afff; /* 039 DeepSkyBlue1 */ +} +.ceb-40 { + background-color: #00d700; /* 040 Green3 */ +} +.ceb-41 { + background-color: #00d75f; /* 041 SpringGreen3 */ +} +.ceb-42 { + background-color: #00d787; /* 042 SpringGreen2 */ +} +.ceb-43 { + background-color: #00d7af; /* 043 Cyan3 */ +} +.ceb-44 { + background-color: #00d7d7; /* 044 DarkTurquoise */ +} +.ceb-45 { + background-color: #00d7ff; /* 045 Turquoise2 */ +} +.ceb-46 { + background-color: #00ff00; /* 046 Green1 */ +} +.ceb-47 { + background-color: #00ff5f; /* 047 SpringGreen2 */ +} +.ceb-48 { + background-color: #00ff87; /* 048 SpringGreen1 */ +} +.ceb-49 { + background-color: #00ffaf; /* 049 MediumSpringGreen */ +} +.ceb-50 { + background-color: #00ffd7; /* 050 Cyan2 */ +} +.ceb-51 { + background-color: #00ffff; /* 051 Cyan1 */ +} +.ceb-52 { + background-color: #5f0000; /* 052 DarkRed */ +} +.ceb-53 { + background-color: #5f005f; /* 053 DeepPink4 */ +} +.ceb-54 { + background-color: #5f0087; /* 054 Purple4 */ +} +.ceb-55 { + background-color: #5f00af; /* 055 Purple4 */ +} +.ceb-56 { + background-color: #5f00d7; /* 056 Purple3 */ +} +.ceb-57 { + background-color: #5f00ff; /* 057 BlueViolet */ +} +.ceb-58 { + background-color: #5f5f00; /* 058 Orange4 */ +} +.ceb-59 { + background-color: #5f5f5f; /* 059 Grey37 */ +} +.ceb-60 { + background-color: #5f5f87; /* 060 MediumPurple4 */ +} +.ceb-61 { + background-color: #5f5faf; /* 061 SlateBlue3 */ +} +.ceb-62 { + background-color: #5f5fd7; /* 062 SlateBlue3 */ +} +.ceb-63 { + background-color: #5f5fff; /* 063 RoyalBlue1 */ +} +.ceb-64 { + background-color: #5f8700; /* 064 Chartreuse4 */ +} +.ceb-65 { + background-color: #5f875f; /* 065 DarkSeaGreen4 */ +} +.ceb-66 { + background-color: #5f8787; /* 066 PaleTurquoise4 */ +} +.ceb-67 { + background-color: #5f87af; /* 067 SteelBlue */ +} +.ceb-68 { + background-color: #5f87d7; /* 068 SteelBlue3 */ +} +.ceb-69 { + background-color: #5f87ff; /* 069 CornflowerBlue */ +} +.ceb-70 { + background-color: #5faf00; /* 070 Chartreuse3 */ +} +.ceb-71 { + background-color: #5faf5f; /* 071 DarkSeaGreen4 */ +} +.ceb-72 { + background-color: #5faf87; /* 072 CadetBlue */ +} +.ceb-73 { + background-color: #5fafaf; /* 073 CadetBlue */ +} +.ceb-74 { + background-color: #5fafd7; /* 074 SkyBlue3 */ +} +.ceb-75 { + background-color: #5fafff; /* 075 SteelBlue1 */ +} +.ceb-76 { + background-color: #5fd700; /* 076 Chartreuse3 */ +} +.ceb-77 { + background-color: #5fd75f; /* 077 PaleGreen3 */ +} +.ceb-78 { + background-color: #5fd787; /* 078 SeaGreen3 */ +} +.ceb-79 { + background-color: #5fd7af; /* 079 Aquamarine3 */ +} +.ceb-80 { + background-color: #5fd7d7; /* 080 MediumTurquoise */ +} +.ceb-81 { + background-color: #5fd7ff; /* 081 SteelBlue1 */ +} +.ceb-82 { + background-color: #5fff00; /* 082 Chartreuse2 */ +} +.ceb-83 { + background-color: #5fff5f; /* 083 SeaGreen2 */ +} +.ceb-84 { + background-color: #5fff87; /* 084 SeaGreen1 */ +} +.ceb-85 { + background-color: #5fffaf; /* 085 SeaGreen1 */ +} +.ceb-86 { + background-color: #5fffd7; /* 086 Aquamarine1 */ +} +.ceb-87 { + background-color: #5fffff; /* 087 DarkSlateGray2 */ +} +.ceb-88 { + background-color: #870000; /* 088 DarkRed */ +} +.ceb-89 { + background-color: #87005f; /* 089 DeepPink4 */ +} +.ceb-90 { + background-color: #870087; /* 090 DarkMagenta */ +} +.ceb-91 { + background-color: #8700af; /* 091 DarkMagenta */ +} +.ceb-92 { + background-color: #8700d7; /* 092 DarkViolet */ +} +.ceb-93 { + background-color: #8700ff; /* 093 Purple */ +} +.ceb-94 { + background-color: #875f00; /* 094 Orange4 */ +} +.ceb-95 { + background-color: #875f5f; /* 095 LightPink4 */ +} +.ceb-96 { + background-color: #875f87; /* 096 Plum4 */ +} +.ceb-97 { + background-color: #875faf; /* 097 MediumPurple3 */ +} +.ceb-98 { + background-color: #875fd7; /* 098 MediumPurple3 */ +} +.ceb-99 { + background-color: #875fff; /* 099 SlateBlue1 */ +} +.ceb-100 { + background-color: #878700; /* 100 Yellow4 */ +} +.ceb-101 { + background-color: #87875f; /* 101 Wheat4 */ +} +.ceb-102 { + background-color: #878787; /* 102 Grey53 */ +} +.ceb-103 { + background-color: #8787af; /* 103 LightSlateGrey */ +} +.ceb-104 { + background-color: #8787d7; /* 104 MediumPurple */ +} +.ceb-105 { + background-color: #8787ff; /* 105 LightSlateBlue */ +} +.ceb-106 { + background-color: #87af00; /* 106 Yellow4 */ +} +.ceb-107 { + background-color: #87af5f; /* 107 DarkOliveGreen3 */ +} +.ceb-108 { + background-color: #87af87; /* 108 DarkSeaGreen */ +} +.ceb-109 { + background-color: #87afaf; /* 109 LightSkyBlue3 */ +} +.ceb-110 { + background-color: #87afd7; /* 110 LightSkyBlue3 */ +} +.ceb-111 { + background-color: #87afff; /* 111 SkyBlue2 */ +} +.ceb-112 { + background-color: #87d700; /* 112 Chartreuse2 */ +} +.ceb-113 { + background-color: #87d75f; /* 113 DarkOliveGreen3 */ +} +.ceb-114 { + background-color: #87d787; /* 114 PaleGreen3 */ +} +.ceb-115 { + background-color: #87d7af; /* 115 DarkSeaGreen3 */ +} +.ceb-116 { + background-color: #87d7d7; /* 116 DarkSlateGray3 */ +} +.ceb-117 { + background-color: #87d7ff; /* 117 SkyBlue1 */ +} +.ceb-118 { + background-color: #87ff00; /* 118 Chartreuse1 */ +} +.ceb-119 { + background-color: #87ff5f; /* 119 LightGreen */ +} +.ceb-120 { + background-color: #87ff87; /* 120 LightGreen */ +} +.ceb-121 { + background-color: #87ffaf; /* 121 PaleGreen1 */ +} +.ceb-122 { + background-color: #87ffd7; /* 122 Aquamarine1 */ +} +.ceb-123 { + background-color: #87ffff; /* 123 DarkSlateGray1 */ +} +.ceb-124 { + background-color: #af0000; /* 124 Red3 */ +} +.ceb-125 { + background-color: #af005f; /* 125 DeepPink4 */ +} +.ceb-126 { + background-color: #af0087; /* 126 MediumVioletRed */ +} +.ceb-127 { + background-color: #af00af; /* 127 Magenta3 */ +} +.ceb-128 { + background-color: #af00d7; /* 128 DarkViolet */ +} +.ceb-129 { + background-color: #af00ff; /* 129 Purple */ +} +.ceb-130 { + background-color: #af5f00; /* 130 DarkOrange3 */ +} +.ceb-131 { + background-color: #af5f5f; /* 131 IndianRed */ +} +.ceb-132 { + background-color: #af5f87; /* 132 HotPink3 */ +} +.ceb-133 { + background-color: #af5faf; /* 133 MediumOrchid3 */ +} +.ceb-134 { + background-color: #af5fd7; /* 134 MediumOrchid */ +} +.ceb-135 { + background-color: #af5fff; /* 135 MediumPurple2 */ +} +.ceb-136 { + background-color: #af8700; /* 136 DarkGoldenrod */ +} +.ceb-137 { + background-color: #af875f; /* 137 LightSalmon3 */ +} +.ceb-138 { + background-color: #af8787; /* 138 RosyBrown */ +} +.ceb-139 { + background-color: #af87af; /* 139 Grey63 */ +} +.ceb-140 { + background-color: #af87d7; /* 140 MediumPurple2 */ +} +.ceb-141 { + background-color: #af87ff; /* 141 MediumPurple1 */ +} +.ceb-142 { + background-color: #afaf00; /* 142 Gold3 */ +} +.ceb-143 { + background-color: #afaf5f; /* 143 DarkKhaki */ +} +.ceb-144 { + background-color: #afaf87; /* 144 NavajoWhite3 */ +} +.ceb-145 { + background-color: #afafaf; /* 145 Grey69 */ +} +.ceb-146 { + background-color: #afafd7; /* 146 LightSteelBlue3 */ +} +.ceb-147 { + background-color: #afafff; /* 147 LightSteelBlue */ +} +.ceb-148 { + background-color: #afd700; /* 148 Yellow3 */ +} +.ceb-149 { + background-color: #afd75f; /* 149 DarkOliveGreen3 */ +} +.ceb-150 { + background-color: #afd787; /* 150 DarkSeaGreen3 */ +} +.ceb-151 { + background-color: #afd7af; /* 151 DarkSeaGreen2 */ +} +.ceb-152 { + background-color: #afd7d7; /* 152 LightCyan3 */ +} +.ceb-153 { + background-color: #afd7ff; /* 153 LightSkyBlue1 */ +} +.ceb-154 { + background-color: #afff00; /* 154 GreenYellow */ +} +.ceb-155 { + background-color: #afff5f; /* 155 DarkOliveGreen2 */ +} +.ceb-156 { + background-color: #afff87; /* 156 PaleGreen1 */ +} +.ceb-157 { + background-color: #afffaf; /* 157 DarkSeaGreen2 */ +} +.ceb-158 { + background-color: #afffd7; /* 158 DarkSeaGreen1 */ +} +.ceb-159 { + background-color: #afffff; /* 159 PaleTurquoise1 */ +} +.ceb-160 { + background-color: #d70000; /* 160 Red3 */ +} +.ceb-161 { + background-color: #d7005f; /* 161 DeepPink3 */ +} +.ceb-162 { + background-color: #d70087; /* 162 DeepPink3 */ +} +.ceb-163 { + background-color: #d700af; /* 163 Magenta3 */ +} +.ceb-164 { + background-color: #d700d7; /* 164 Magenta3 */ +} +.ceb-165 { + background-color: #d700ff; /* 165 Magenta2 */ +} +.ceb-166 { + background-color: #d75f00; /* 166 DarkOrange3 */ +} +.ceb-167 { + background-color: #d75f5f; /* 167 IndianRed */ +} +.ceb-168 { + background-color: #d75f87; /* 168 HotPink3 */ +} +.ceb-169 { + background-color: #d75faf; /* 169 HotPink2 */ +} +.ceb-170 { + background-color: #d75fd7; /* 170 Orchid */ +} +.ceb-171 { + background-color: #d75fff; /* 171 MediumOrchid1 */ +} +.ceb-172 { + background-color: #d78700; /* 172 Orange3 */ +} +.ceb-173 { + background-color: #d7875f; /* 173 LightSalmon3 */ +} +.ceb-174 { + background-color: #d78787; /* 174 LightPink3 */ +} +.ceb-175 { + background-color: #d787af; /* 175 Pink3 */ +} +.ceb-176 { + background-color: #d787d7; /* 176 Plum3 */ +} +.ceb-177 { + background-color: #d787ff; /* 177 Violet */ +} +.ceb-178 { + background-color: #d7af00; /* 178 Gold3 */ +} +.ceb-179 { + background-color: #d7af5f; /* 179 LightGoldenrod3 */ +} +.ceb-180 { + background-color: #d7af87; /* 180 Tan */ +} +.ceb-181 { + background-color: #d7afaf; /* 181 MistyRose3 */ +} +.ceb-182 { + background-color: #d7afd7; /* 182 Thistle3 */ +} +.ceb-183 { + background-color: #d7afff; /* 183 Plum2 */ +} +.ceb-184 { + background-color: #d7d700; /* 184 Yellow3 */ +} +.ceb-185 { + background-color: #d7d75f; /* 185 Khaki3 */ +} +.ceb-186 { + background-color: #d7d787; /* 186 LightGoldenrod2 */ +} +.ceb-187 { + background-color: #d7d7af; /* 187 LightYellow3 */ +} +.ceb-188 { + background-color: #d7d7d7; /* 188 Grey84 */ +} +.ceb-189 { + background-color: #d7d7ff; /* 189 LightSteelBlue1 */ +} +.ceb-190 { + background-color: #d7ff00; /* 190 Yellow2 */ +} +.ceb-191 { + background-color: #d7ff5f; /* 191 DarkOliveGreen1 */ +} +.ceb-192 { + background-color: #d7ff87; /* 192 DarkOliveGreen1 */ +} +.ceb-193 { + background-color: #d7ffaf; /* 193 DarkSeaGreen1 */ +} +.ceb-194 { + background-color: #d7ffd7; /* 194 Honeydew2 */ +} +.ceb-195 { + background-color: #d7ffff; /* 195 LightCyan1 */ +} +.ceb-196 { + background-color: #ff0000; /* 196 Red1 */ +} +.ceb-197 { + background-color: #ff005f; /* 197 DeepPink2 */ +} +.ceb-198 { + background-color: #ff0087; /* 198 DeepPink1 */ +} +.ceb-199 { + background-color: #ff00af; /* 199 DeepPink1 */ +} +.ceb-200 { + background-color: #ff00d7; /* 200 Magenta2 */ +} +.ceb-201 { + background-color: #ff00ff; /* 201 Magenta1 */ +} +.ceb-202 { + background-color: #ff5f00; /* 202 OrangeRed1 */ +} +.ceb-203 { + background-color: #ff5f5f; /* 203 IndianRed1 */ +} +.ceb-204 { + background-color: #ff5f87; /* 204 IndianRed1 */ +} +.ceb-205 { + background-color: #ff5faf; /* 205 HotPink */ +} +.ceb-206 { + background-color: #ff5fd7; /* 206 HotPink */ +} +.ceb-207 { + background-color: #ff5fff; /* 207 MediumOrchid1 */ +} +.ceb-208 { + background-color: #ff8700; /* 208 DarkOrange */ +} +.ceb-209 { + background-color: #ff875f; /* 209 Salmon1 */ +} +.ceb-210 { + background-color: #ff8787; /* 210 LightCoral */ +} +.ceb-211 { + background-color: #ff87af; /* 211 PaleVioletRed1 */ +} +.ceb-212 { + background-color: #ff87d7; /* 212 Orchid2 */ +} +.ceb-213 { + background-color: #ff87ff; /* 213 Orchid1 */ +} +.ceb-214 { + background-color: #ffaf00; /* 214 Orange1 */ +} +.ceb-215 { + background-color: #ffaf5f; /* 215 SandyBrown */ +} +.ceb-216 { + background-color: #ffaf87; /* 216 LightSalmon1 */ +} +.ceb-217 { + background-color: #ffafaf; /* 217 LightPink1 */ +} +.ceb-218 { + background-color: #ffafd7; /* 218 Pink1 */ +} +.ceb-219 { + background-color: #ffafff; /* 219 Plum1 */ +} +.ceb-220 { + background-color: #ffd700; /* 220 Gold1 */ +} +.ceb-221 { + background-color: #ffd75f; /* 221 LightGoldenrod2 */ +} +.ceb-222 { + background-color: #ffd787; /* 222 LightGoldenrod2 */ +} +.ceb-223 { + background-color: #ffd7af; /* 223 NavajoWhite1 */ +} +.ceb-224 { + background-color: #ffd7d7; /* 224 MistyRose1 */ +} +.ceb-225 { + background-color: #ffd7ff; /* 225 Thistle1 */ +} +.ceb-226 { + background-color: #ffff00; /* 226 Yellow1 */ +} +.ceb-227 { + background-color: #ffff5f; /* 227 LightGoldenrod1 */ +} +.ceb-228 { + background-color: #ffff87; /* 228 Khaki1 */ +} +.ceb-229 { + background-color: #ffffaf; /* 229 Wheat1 */ +} +.ceb-230 { + background-color: #ffffd7; /* 230 Cornsilk1 */ +} +.ceb-231 { + background-color: #ffffff; /* 231 Grey100 */ +} +.ceb-232 { + background-color: #080808; /* 232 Grey3 */ +} +.ceb-233 { + background-color: #121212; /* 233 Grey7 */ +} +.ceb-234 { + background-color: #1c1c1c; /* 234 Grey11 */ +} +.ceb-235 { + background-color: #262626; /* 235 Grey15 */ +} +.ceb-236 { + background-color: #303030; /* 236 Grey19 */ +} +.ceb-237 { + background-color: #3a3a3a; /* 237 Grey23 */ +} +.ceb-238 { + background-color: #444444; /* 238 Grey27 */ +} +.ceb-239 { + background-color: #4e4e4e; /* 239 Grey30 */ +} +.ceb-240 { + background-color: #585858; /* 240 Grey35 */ +} +.ceb-241 { + background-color: #626262; /* 241 Grey39 */ +} +.ceb-242 { + background-color: #6c6c6c; /* 242 Grey42 */ +} +.ceb-243 { + background-color: #767676; /* 243 Grey46 */ +} +.ceb-244 { + background-color: #808080; /* 244 Grey50 */ +} +.ceb-245 { + background-color: #8a8a8a; /* 245 Grey54 */ +} +.ceb-246 { + background-color: #949494; /* 246 Grey58 */ +} +.ceb-247 { + background-color: #9e9e9e; /* 247 Grey62 */ +} +.ceb-248 { + background-color: #a8a8a8; /* 248 Grey66 */ +} +.ceb-249 { + background-color: #b2b2b2; /* 249 Grey70 */ +} +.ceb-250 { + background-color: #bcbcbc; /* 250 Grey74 */ +} +.ceb-251 { + background-color: #c6c6c6; /* 251 Grey78 */ +} +.ceb-252 { + background-color: #d0d0d0; /* 252 Grey82 */ +} +.ceb-253 { + background-color: #dadada; /* 253 Grey85 */ +} +.ceb-254 { + background-color: #e4e4e4; /* 254 Grey89 */ +} +.ceb-255 { + background-color: #eeeeee; /* 255 Grey93 */ +} + +/* attributes overrides */ +.a-bold { + font-weight: bold; +} +.a-no-bold { + font-weight: normal; +} +.a-italic { + font-style: italic; +} +.a-no-italic { + font-style: normal; +} +.a-underline { + text-decoration: underline; +} +.a-no-underline { + text-decoration: none; +} +.a-reset { + font-weight: normal; + font-style: normal; + text-decoration: none; +} diff --git a/index.html b/index.html index b28d6fb..b1d4e64 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,7 @@ + @@ -221,9 +222,9 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel {{ bufferline.date | date:'HH:mm' }} - {{ part.text }} + {{ part.text }} - +
diff --git a/js/models.js b/js/models.js index ce8bbea..9d53c61 100644 --- a/js/models.js +++ b/js/models.js @@ -4,7 +4,7 @@ */ var models = angular.module('weechatModels', []); -models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { +models.service('models', ['$rootScope', function($rootScope) { /* * Buffer class */ @@ -59,36 +59,64 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { * BufferLine class */ this.BufferLine = function(message) { - - /* - * Parse the text elements from the buffer line added - * - * @param message weechat message - */ - function parseLineAddedTextElements(message) { - var text = colors.parse(message); - text_elements =_.map(text, function(text_element) { - if (text_element && ('fg' in text_element)) { - text_element['fg'] = colors.prepareCss(text_element['fg']); - } - // TODO: parse background as well - - return text_element; - }); - return text_elements; - } - - var buffer = message['buffer']; var date = message['date']; + function addClasses(textElements) { + var typeToClassPrefixFg = { + 'option': 'cof-', + 'weechat': 'cwf-', + 'ext': 'cef-' + }; + var typeToClassPrefixBg = { + 'option': 'cob-', + 'weechat': 'cwb-', + 'ext': 'ceb-' + }; + textElements.forEach(function(textEl) { + textEl.classes = []; - var prefix = parseLineAddedTextElements(message['prefix']); + // foreground color + var prefix = typeToClassPrefixFg[textEl.fgColor.type]; + textEl.classes.push(prefix + textEl.fgColor.name); + + // background color + prefix = typeToClassPrefixBg[textEl.bgColor.type]; + textEl.classes.push(prefix + textEl.bgColor.name); + + // attributes + if (textEl.attrs.name !== null) { + textEl.classes.push('coa-' + textEl.attrs.name); + } + var allReset = true; + for (var attr in textEl.attrs.override) { + if (textEl.attrs.override[attr]) { + allReset = false; + break; + } + } + if (allReset) { + textEl.classes.push('a-reset'); + } else for (var attr in textEl.attrs.override) { + val = textEl.attrs.override[attr]; + if (val) { + textEl.classes.push('a-' + attr); + } else { + textEl.classes.push('a-no-' + attr); + } + } + }); + } + + + var prefix = weeChat.Protocol.rawText2Rich(message['prefix']); + addClasses(prefix); var tags_array = message['tags_array']; var displayed = message['displayed']; var highlight = message['highlight']; - var content = parseLineAddedTextElements(message['message']); + var content = weeChat.Protocol.rawText2Rich(message['message']); + addClasses(content); var rtext = ""; if(content[0] != undefined) { @@ -104,6 +132,7 @@ models.service('models', ['$rootScope', 'colors', function($rootScope, colors) { highlight: highlight, displayed: displayed, text: rtext, + } } diff --git a/js/websockets.js b/js/websockets.js index f44cf38..5a515bd 100644 --- a/js/websockets.js +++ b/js/websockets.js @@ -14,16 +14,7 @@ weechat.filter('toArray', function () { } }); -weechat.factory('colors', [function($scope) { - - return { - prepareCss: weeChat.color.prepareCss, - parse: weeChat.color.parse - }; - -}]); - -weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', function($rootScope, colors, models, plugins) { +weechat.factory('handlers', ['$rootScope', 'models', 'plugins', function($rootScope, models, plugins) { var handleBufferClosing = function(message) { var bufferMessage = message['objects'][0]['content'][0]; @@ -147,7 +138,7 @@ weechat.factory('handlers', ['$rootScope', 'colors', 'models', 'plugins', functi }]); -weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers', 'colors', 'models', function($q, $rootScope, $log, storage, handlers, colors, models) { +weechat.factory('connection', ['$q', '$rootScope', '$log', '$store', 'handlers', 'models', function($q, $rootScope, $log, storage, handlers, models) { protocol = new weeChat.Protocol(); var websocket = null; @@ -570,4 +561,4 @@ weechat.controller('WeechatCtrl', ['$rootScope', '$scope', '$store', '$timeout', } }] - ); +); diff --git a/js/weechat.js b/js/weechat.js index 31b5d5f..698113a 100644 --- a/js/weechat.js +++ b/js/weechat.js @@ -1,829 +1,1171 @@ (function(exports) {// http://weechat.org/files/doc/devel/weechat_dev.en.html#color_codes_in_strings -(function() { - // http://weechat.org/files/doc/devel/weechat_dev.en.html#color_codes_in_strings - var part, fg, bg, attrs; - - // XTerm 8-bit pallete - var colors = [ - '#666666', '#AA0000', '#00AA00', '#AA5500', '#0000AA', - '#AA00AA', '#00AAAA', '#AAAAAA', '#555555', '#FF5555', - '#55FF55', '#FFFF55', '#5555FF', '#FF55FF', '#55FFFF', - '#FFFFFF', '#666666', '#00005F', '#000087', '#0000AF', - '#0000D7', '#0000FF', '#005F00', '#005F5F', '#005F87', - '#005FAF', '#005FD7', '#005FFF', '#008700', '#00875F', - '#008787', '#0087AF', '#0087D7', '#00AF00', '#00AF5F', - '#00AF87', '#00AFAF', '#00AFD7', '#00AFFF', '#00D700', - '#00D75F', '#00D787', '#00D7AF', '#00D7D7', '#00D7FF', - '#00FF00', '#00FF5F', '#00FF87', '#00FFAF', '#00FFD7', - '#00FFFF', '#5F0000', '#5F005F', '#5F0087', '#5F00AF', - '#5F00D7', '#5F00FF', '#5F5F00', '#5F5F5F', '#5F5F87', - '#5F5FAF', '#5F5FD7', '#5F5FFF', '#5F8700', '#5F875F', - '#5F8787', '#5F87AF', '#5F87D7', '#5F87FF', '#5FAF00', - '#5FAF5F', '#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF', - '#5FD700', '#5FD75F', '#5FD787', '#5FD7AF', '#5FD7D7', - '#5FD7FF', '#5FFF00', '#5FFF5F', '#5FFF87', '#5FFFAF', - '#5FFFD7', '#5FFFFF', '#870000', '#87005F', '#870087', - '#8700AF', '#8700D7', '#8700FF', '#875F00', '#875F5F', - '#875F87', '#875FAF', '#875FD7', '#875FFF', '#878700', - '#87875F', '#878787', '#8787AF', '#8787D7', '#8787FF', - '#87AF00', '#87AF5F', '#87AF87', '#87AFAF', '#87AFD7', - '#87AFFF', '#87D700', '#87D75F', '#87D787', '#87D7AF', - '#87D7D7', '#87D7FF', '#87FF00', '#87FF5F', '#87FF87', - '#87FFAF', '#87FFD7', '#87FFFF', '#AF0000', '#AF005F', - '#AF0087', '#AF00AF', '#AF00D7', '#AF00FF', '#AF5F00', - '#AF5F5F', '#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF', - '#AF8700', '#AF875F', '#AF8787', '#AF87AF', '#AF87D7', - '#AF87FF', '#AFAF00', '#AFAF5F', '#AFAF87', '#AFAFAF', - '#AFAFD7', '#AFAFFF', '#AFD700', '#AFD75F', '#AFD787', - '#AFD7AF', '#AFD7D7', '#AFD7FF', '#AFFF00', '#AFFF5F', - '#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF', '#D70000', - '#D7005F', '#D70087', '#D700AF', '#D700D7', '#D700FF', - '#D75F00', '#D75F5F', '#D75F87', '#D75FAF', '#D75FD7', - '#D75FFF', '#D78700', '#D7875F', '#D78787', '#D787AF', - '#D787D7', '#D787FF', '#D7AF00', '#D7AF5F', '#D7AF87', - '#D7AFAF', '#D7AFD7', '#D7AFFF', '#D7D700', '#D7D75F', - '#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF', '#D7FF00', - '#D7FF5F', '#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF', - '#FF0000', '#FF005F', '#FF0087', '#FF00AF', '#FF00D7', - '#FF00FF', '#FF5F00', '#FF5F5F', '#FF5F87', '#FF5FAF', - '#FF5FD7', '#FF5FFF', '#FF8700', '#FF875F', '#FF8787', - '#FF87AF', '#FF87D7', '#FF87FF', '#FFAF00', '#FFAF5F', - '#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF', '#FFD700', - '#FFD75F', '#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF', - '#FFFF00', '#FFFF5F', '#FFFF87', '#FFFFAF', '#FFFFD7', - '#FFFFFF', '#080808', '#121212', '#1C1C1C', '#262626', - '#303030', '#3A3A3A', '#444444', '#4E4E4E', '#585858', - '#626262', '#6C6C6C', '#767676', '#808080', '#8A8A8A', - '#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', - '#C6C6C6', '#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE' - ]; - - // Push the basic color list on top of the extended color list - // and then when weechat requests a basic color (0-15) we rewrite - // it to be a number in the extended color table - colors.push.apply(colors, ['', 'black', 'darkgray', 'darkred', 'red', 'darkgreen', 'lightgreen', 'brown', - 'yellow', 'darkblue', 'lightblue', 'darkmagenta', 'magenta', 'darkcyan', 'lightcyan', 'gray', 'white' - ]); - - function setAttrs() { - while (part.match(/^[\*\/\_\|]/)) { - attrs.push(part.charAt(0)); - part = part.slice(1); - } - } - - function getColor() { - var c; - if (part.match(/^@/)) { - c = part.slice(1, 6); - part = part.slice(6); - } else { - c = part.slice(0, 2); - // Rewrite the basic color value to the part in the extended - // palette where we store the basic colors - c = parseInt(c, 10) + 255; - part = part.slice(2); - } - return c; - } - - function prepareCss(color) { - /* - * Translates a weechat color to CSS - */ - return 'color: ' + color; - } - - var prefixes = { - '\x19': function() { - if (part.match(/^F/)) { - part = part.slice(1); - setAttrs(); - fg = getColor(); - } else if (part.match(/^B/)) { - part = part.slice(1); - setAttrs(); - bg = getColor(); - } else { - setAttrs(); - fg = getColor(); - if (part.match(/^,/)) { - part = part.slice(1); - bg = getColor(); - } - } - }, - '\x1A': function() { - // Don't know what to do - }, - '\x1B': function() { - attrs = []; - }, - '\x1C': function() { - fg = ''; - bg = ''; - } - }; - - function parse(text) { - if (!text) { - return text; - } - var f, parts = text.split(/(\x19|\x1A|\x1B|\x1C)/); - if (parts.length === 1) return [{ - text: parts[0] - }]; - attrs = []; - - return parts.map(function(p) { - var res, tmp = prefixes[p.charAt(0)]; - if (f) { - part = p; - f(); - res = { - text: part, - fg: colors[parseInt(fg, 10)], - bg: colors[parseInt(bg, 10)], - attrs: attrs - }; - if (!res.fg) res.fg = fg; - if (!res.bg) res.bg = bg; - } - f = tmp; - return res; - }).filter(function(p) { - return p; - }); - } - - exports.color = { - prepareCss: prepareCss, - parse: parse - }; -})(); -;/** +/** * WeeChat protocol handling. * * This object parses messages and formats commands for the WeeChat * protocol. It's independent from the communication layer and thus * may be used with any network mechanism. */ - (function() { - var WeeChatProtocol = function() { - // specific parsing for each message type - this._types = { - 'chr': this._getChar, - 'int': this._getInt, - 'str': this._getString, - 'inf': this._getInfo, - 'hda': this._getHdata, - 'ptr': this._getPointer, - 'lon': this._getStrNumber, - 'tim': this._getTime, - 'buf': this._getString, - 'arr': this._getArray, - 'htb': this._getHashTable, - 'inl': function() { - this._warnUnimplemented('infolist'); - } - }; - - // string value for some message types - this._typesStr = { - 'chr': this._strDirect, - 'str': this._strDirect, - 'int': this._strToString, - 'tim': this._strToString, - 'ptr': this._strDirect - }; - }; - - /** - * Unsigned integer array to string. - * - * @param uia Unsigned integer array - * @return Decoded string - */ - WeeChatProtocol._uia2s = function(uia) { - var str = []; - - for (var c = 0; c < uia.length; c++) { - str.push(String.fromCharCode(uia[c])); - } - - return decodeURIComponent(escape(str.join(''))); - }; - - /** - * Merges default parameters with overriding parameters. - * - * @param defaults Default parameters - * @param override Overriding parameters - * @return Merged parameters - */ - WeeChatProtocol._mergeParams = function(defaults, override) { - for (var v in override) { - defaults[v] = override[v]; - } - - return defaults; - }; - - /** - * Formats a command. - * - * @param id Command ID (null for no ID) - * @param name Command name - * @param parts Command parts - * @return Formatted command string - */ - WeeChatProtocol._formatCmd = function(id, name, parts) { - var cmdIdName; - var cmd; - - cmdIdName = (id !== null) ? '(' + id + ') ' : ''; - cmdIdName += name; - parts.unshift(cmdIdName); - cmd = parts.join(' '); - cmd += '\n'; - - return cmd; - }; - - /** - * Formats an init command. - * - * @param params Parameters: - * password: password (optional) - * compression: compression ('off' or 'zlib') (optional) - * @return Formatted init command string - */ - WeeChatProtocol.formatInit = function(params) { - var defaultParams = { - password: null, - compression: 'off' - }; - var keys = []; - var parts = []; - - params = WeeChatProtocol._mergeParams(defaultParams, params); - keys.push('compression=' + params.compression); - if (params.password !== null) { - keys.push('password=' + params.password); - } - parts.push(keys.join(',')); - - return WeeChatProtocol._formatCmd(null, 'init', parts); - }; - - /** - * Formats an hdata command. - * - * @param params Parameters: - * id: command ID (optional) - * path: hdata path (mandatory) - * keys: array of keys (optional) - * @return Formatted hdata command string - */ - WeeChatProtocol.formatHdata = function(params) { - var defaultParams = { - id: null, - keys: null - }; - var parts = []; - - params = WeeChatProtocol._mergeParams(defaultParams, params); - parts.push(params.path); - if (params.keys !== null) { - parts.push(params.keys.join(',')); - } - - return WeeChatProtocol._formatCmd(params.id, 'hdata', parts); - }; - - /** - * Formats an info command. - * - * @param params Parameters: - * id: command ID (optional) - * name: info name (mandatory) - * @return Formatted info command string - */ - WeeChatProtocol.formatInfo = function(params) { - var defaultParams = { - id: null - }; - var parts = []; - - params = WeeChatProtocol._mergeParams(defaultParams, params); - parts.push(params.name); - - return WeeChatProtocol._formatCmd(params.id, 'info', parts); - }; - - /** - * Formats a nicklist command. - * - * @param params Parameters: - * id: command ID (optional) - * buffer: buffer name (optional) - * @return Formatted nicklist command string - */ - WeeChatProtocol.formatNicklist = function(params) { - var defaultParams = { - id: null, - buffer: null - }; - var parts = []; - - params = WeeChatProtocol._mergeParams(defaultParams, params); - if (params.buffer !== null) { - parts.push(params.buffer); - } - - return WeeChatProtocol._formatCmd(params.id, 'nicklist', parts); - }; - - /** - * Formats an input command. - * - * @param params Parameters: - * id: command ID (optional) - * buffer: target buffer (mandatory) - * data: input data (mandatory) - * @return Formatted input command string - */ - WeeChatProtocol.formatInput = function(params) { - var defaultParams = { - id: null - }; - var parts = []; - - params = WeeChatProtocol._mergeParams(defaultParams, params); - parts.push(params.buffer); - parts.push(params.data); - - return WeeChatProtocol._formatCmd(params.id, 'input', parts); - }; - - /** - * Formats a sync or a desync command. - * - * @param params Parameters (see _formatSync and _formatDesync) - * @return Formatted sync/desync command string - */ - WeeChatProtocol._formatSyncDesync = function(cmdName, params) { - var defaultParams = { - id: null, - buffers: null, - options: null - }; - var parts = []; - - params = WeeChatProtocol._mergeParams(defaultParams, params); - if (params.buffers !== null) { - parts.push(params.buffers.join(',')); - if (params.options !== null) { - parts.push(params.options.join(',')); - } - } - - return WeeChatProtocol._formatCmd(params.id, cmdName, parts); - }; - - /** - * Formats a sync command. - * - * @param params Parameters: - * id: command ID (optional) - * buffers: array of buffers to sync (optional) - * options: array of options (optional) - * @return Formatted sync command string - */ - WeeChatProtocol.formatSync = function(params) { - return WeeChatProtocol._formatSyncDesync('sync', params); - }; - - /** - * Formats a desync command. - * - * @param params Parameters: - * id: command ID (optional) - * buffers: array of buffers to desync (optional) - * options: array of options (optional) - * @return Formatted desync command string - */ - WeeChatProtocol.formatDesync = function(params) { - return WeeChatProtocol._formatSyncDesync('desync', params); - }; - - /** - * Formats a test command. - * - * @param params Parameters: - * id: command ID (optional) - * @return Formatted test command string - */ - WeeChatProtocol.formatTest = function(params) { - var defaultParams = { - id: null - }; - var parts = []; - - params = WeeChatProtocol._mergeParams(defaultParams, params); - - return WeeChatProtocol._formatCmd(params.id, 'test', parts); - }; - - /** - * Formats a quit command. - * - * @return Formatted quit command string - */ - WeeChatProtocol.formatQuit = function() { - return WeeChatProtocol._formatCmd(null, 'quit', []); - }; - - /** - * Formats a ping command. - * - * @param params Parameters: - * id: command ID (optional) - * args: array of custom arguments (optional) - * @return Formatted ping command string - */ - WeeChatProtocol.formatPing = function(params) { - var defaultParams = { - id: null, - args: null - }; - var parts = []; - - params = WeeChatProtocol._mergeParams(defaultParams, params); - if (params.args !== null) { - parts.push(params.args.join(' ')); - } - - return WeeChatProtocol._formatCmd(params.id, 'ping', parts); - }; - - WeeChatProtocol.prototype = { - /** - * Warns that message parsing is not implemented for a - * specific type. - * - * @param type Message type to display - */ - _warnUnimplemented: function(type) { - console.log('Warning: ' + type + ' message parsing is not implemented'); - }, - - /** - * Reads a 3-character message type token value from current - * set data. - * - * @return Type - */ - _getType: function() { - var t = this._getSlice(3); - - if (!t) { - return null; - } - - return WeeChatProtocol._uia2s(new Uint8Array(t)); - }, - - /** - * Runs the appropriate read routine for the specified message type. - * - * @param type Message type - * @return Data value - */ - _runType: function(type) { - var cb = this._types[type]; - var boundCb = cb.bind(this); - - return boundCb(); - }, - - /** - * Reads a "number as a string" token value from current set data. - * - * @return Number as a string - */ - _getStrNumber: function() { - var len = this._getByte(); - var str = this._getSlice(len); - - return WeeChatProtocol._uia2s(new Uint8Array(str)); - }, - - /** - * Returns the passed object. - * - * @param obj Object - * @return Passed object - */ - _strDirect: function(obj) { - return obj; - }, - - /** - * Calls toString() on the passed object and returns the value. - * - * @param obj Object to call toString() on - * @return String value of object - */ - _strToString: function(obj) { - return obj.toString(); - }, - - /** - * Gets the string value of an object representing the message - * value for a specified type. - * - * @param obj Object for which to get the string value - * @param type Message type - * @return String value of object - */ - _objToString: function(obj, type) { - var cb = this._typesStr[type]; - var boundCb = cb.bind(this); - - return boundCb(obj); - }, - - /** - * Reads an info token value from current set data. - * - * @return Info object - */ - _getInfo: function() { - var info = {}; - info.key = this._getString(); - info.value = this._getString(); - - return info; - }, - - /** - * Reads an hdata token value from current set data. - * - * @return Hdata object - */ - _getHdata: function() { - var self = this; - var paths; - var count; - var objs = []; - var hpath = this._getString(); - - keys = this._getString().split(','); - paths = hpath.split('/'); - count = this._getInt(); - - keys = keys.map(function(key) { - return key.split(':'); - }); - - function runType() { - var tmp = {}; - - tmp.pointers = paths.map(function(path) { - return self._getPointer(); - }); - keys.forEach(function(key) { - tmp[key[0]] = self._runType(key[1]); - }); - objs.push(tmp); - } - - for (var i = 0; i < count; i++) { - runType(); - } - - return objs; - }, - - /** - * Reads a pointer token value from current set data. - * - * @return Pointer value - */ - _getPointer: function() { - return this._getStrNumber(); - }, - - /** - * Reads a time token value from current set data. - * - * @return Time value (Date) - */ - _getTime: function() { - var str = this._getStrNumber(); - - return new Date(parseInt(str, 10) * 1000); - }, - - /** - * Reads an integer token value from current set data. - * - * @return Integer value - */ - _getInt: function() { - var parsedData = new Uint8Array(this._getSlice(4)); - - return ((parsedData[0] & 0xff) << 24) | - ((parsedData[1] & 0xff) << 16) | - ((parsedData[2] & 0xff) << 8) | - (parsedData[3] & 0xff); - }, - - /** - * Reads a byte from current set data. - * - * @return Byte value (integer) - */ - _getByte: function() { - var parsedData = new Uint8Array(this._getSlice(1)); - - return parsedData[0]; - }, - - /** - * Reads a character token value from current set data. - * - * @return Character (string) - */ - _getChar: function() { - return this._getByte(); - }, - - /** - * Reads a string token value from current set data. - * - * @return String value - */ - _getString: function() { - var l = this._getInt(); - - if (l > 0) { - var s = this._getSlice(l); - var parsedData = new Uint8Array(s); - - return WeeChatProtocol._uia2s(parsedData); - } - - return ""; - }, - - /** - * Reads a message header from current set data. - * - * @return Header object - */ - _getHeader: function() { - var len = this._getInt(); - var comp = this._getByte(); - - return { - length: len, - compression: comp, - }; - }, - - /** - * Reads a message header ID from current set data. - * - * @return Message ID (string) - */ - _getId: function() { - return this._getString(); - }, - - /** - * Reads an arbitrary object token from current set data. - * - * @return Object value - */ - _getObject: function() { - var self = this; - var type = this._getType(); - - if (type) { - return { - type: type, - content: self._runType(type), + var WeeChatProtocol = function() { + // specific parsing for each object type + this._types = { + 'chr': this._getChar, + 'int': this._getInt, + 'str': this._getString, + 'inf': this._getInfo, + 'hda': this._getHdata, + 'ptr': this._getPointer, + 'lon': this._getStrNumber, + 'tim': this._getTime, + 'buf': this._getString, + 'arr': this._getArray, + 'htb': this._getHashTable, + 'inl': function() { + this._warnUnimplemented('infolist'); + } }; - } - }, + + // string value for some object types + this._typesStr = { + 'chr': this._strDirect, + 'str': this._strDirect, + 'int': this._strToString, + 'tim': this._strToString, + 'ptr': this._strDirect + }; + }; /** - * Reads an hash table token from current set data. - * - * @return Hash table + * WeeChat colors names. */ - _getHashTable: function() { - var self = this; - var typeKeys, typeValues, count; - var dict = {}; - - typeKeys = this._getType(); - typeValues = this._getType(); - count = this._getInt(); - - for (var i = 0; i < count; ++i) { - var key = self._runType(typeKeys); - var keyStr = self._objToString(key, typeKeys); - var value = self._runType(typeValues); - dict[keyStr] = value; - } - - return dict; - }, + WeeChatProtocol._weeChatColorsNames = [ + 'default', + 'black', + 'darkgray', + 'darkred', + 'lightred', + 'darkgreen', + 'lightgreen', + 'brown', + 'yellow', + 'darkblue', + 'lightblue', + 'darkmagenta', + 'lightmagenta', + 'darkcyan', + 'lightcyan', + 'gray', + 'white' + ]; /** - * Reads an array token from current set data. - * - * @return Array + * Style options names. */ - _getArray: function() { - var self = this; - var type; - var count; - var values; - - type = this._getType(); - count = this._getInt(); - values = []; - - for (var i = 0; i < count; i++) { - values.push(self._runType(type)); - } - - return values; - }, + WeeChatProtocol._colorsOptionsNames = [ + 'separator', + 'chat', + 'chat_time', + 'chat_time_delimiters', + 'chat_prefix_error', + 'chat_prefix_network', + 'chat_prefix_action', + 'chat_prefix_join', + 'chat_prefix_quit', + 'chat_prefix_more', + 'chat_prefix_suffix', + 'chat_buffer', + 'chat_server', + 'chat_channel', + 'chat_nick', + 'chat_nick_self', + 'chat_nick_other', + 'invalid', + 'invalid', + 'invalid', + 'invalid', + 'invalid', + 'invalid', + 'invalid', + 'invalid', + 'invalid', + 'invalid', + 'chat_host', + 'chat_delimiters', + 'chat_highlight', + 'chat_read_marker', + 'chat_text_found', + 'chat_value', + 'chat_prefix_buffer', + 'chat_tags', + 'chat_inactive_window', + 'chat_inactive_buffer', + 'chat_prefix_buffer_inactive_buffer', + 'chat_nick_offline', + 'chat_nick_offline_highlight', + 'chat_nick_prefix', + 'chat_nick_suffix', + 'emphasis', + 'chat_day_change' + ]; /** - * Reads a specified number of bytes from current set data. + * Gets the default color. * - * @param length Number of bytes to read - * @return Sliced array + * @return Default color */ - _getSlice: function(length) { - if (this.dataAt + length > this._data.byteLength) { - return null; - } - - var slice = this._data.slice(this._dataAt, this._dataAt + length); - - this._dataAt += length; - - return slice; - }, - - /** - * Sets the current data. - * - * @param data Current data - */ - _setData: function(data) { - this._data = data; - }, - - /** - * Parses a WeeChat message. - * - * @param data Message data (ArrayBuffer) - * @return Message value - */ - parse: function(data) { - var self = this; - - this._setData(data); - this._dataAt = 0; - - var header = this._getHeader(); - var id = this._getId(); - var objects = []; - var object = this._getObject(); - - while (object) { - objects.push(object); - object = self._getObject(); - } - - return { - header: header, - id: id, - objects: objects, - }; + WeeChatProtocol._getDefaultColor = function() { + return { + type: 'weechat', + name: 'default' + }; } - }; - exports.Protocol = WeeChatProtocol; + /** + * Gets the default attributes. + * + * @return Default attributes + */ + WeeChatProtocol._getDefaultAttributes = function() { + return { + name: null, + override: { + 'bold': false, + 'reverse': false, + 'italic': false, + 'underline': false + } + }; + } + + /** + * Gets the default style (default colors and attributes). + * + * @return Default style + */ + WeeChatProtocol._getDefaultStyle = function() { + return { + fgColor: WeeChatProtocol._getDefaultColor(), + bgColor: WeeChatProtocol._getDefaultColor(), + attrs: WeeChatProtocol._getDefaultAttributes() + }; + } + + /** + * Clones a color object. + * + * @param color Color object to clone + * @return Cloned color object + */ + WeeChatProtocol._cloneColor = function(color) { + var clone = {}; + + for (var key in color) { + clone[key] = color[key]; + } + + return clone; + } + + /** + * Clones an attributes object. + * + * @param attrs Attributes object to clone + * @return Cloned attributes object + */ + WeeChatProtocol._cloneAttrs = function(attrs) { + var clone = {}; + + clone.name = attrs.name; + clone.override = {}; + for (var attr in attrs.override) { + clone.override[attr] = attrs.override[attr]; + } + + return clone; + } + + /** + * Gets the name of an attribute from its character. + * + * @param ch Character of attribute + * @return Name of attribute + */ + WeeChatProtocol._attrNameFromChar = function(ch) { + var chars = { + '*': 'bold', + '!': 'reverse', + '/': 'italic', + '_': 'underline' + }; + + if (ch in chars) { + return chars[ch]; + } + + return null; + } + + + /** + * Gets an attributes object from a string of attribute characters. + * + * @param str String of attribute characters + * @return Attributes object (null if unchanged) + */ + WeeChatProtocol._attrsFromStr = function(str) { + var attrs = WeeChatProtocol._getDefaultAttributes(); + + for (var i = 0; i < str.length; ++i) { + var ch = str.charAt(i); + if (ch == '|') { + // means keep attributes, so unchanged + return null; + } + var attrName = WeeChatProtocol._attrNameFromChar(ch); + if (attrName === null) { + // ignore invalid attribute + continue; + } + attrs.override[attrName] = true; + } + + return attrs; + } + + /** + * Gets a single color from a string representing its index (WeeChat and + * extended colors only, NOT colors options). + * + * @param str Color string (e.g., "05" or "00134") + * @return Color object + */ + WeeChatProtocol._getColorObj = function(str) { + if (str.length == 2) { + var code = parseInt(str); + if (code > 16) { + // should never happen + return WeeChatProtocol._getDefaultColor(); + } else { + return { + type: 'weechat', + name: WeeChatProtocol._weeChatColorsNames[code] + }; + } + } else { + var codeStr = str.substring(1); + return { + type: 'ext', + name: parseInt(codeStr).toString() + }; + } + } + + /** + * Gets colors and attributes of text element. + * + * See . + * + * @param txt Text element + * @return Colors, attributes and plain text of this text element: + * fgColor: Foreground color (null if unchanged) + * bgColor: Background color (null if unchanged) + * attrs: Attributes (null if unchanged) + * text: Plain text element + */ + WeeChatProtocol._getStyle = function(txt) { + var matchers = [ + { + // color option + // STD + regex: /^(\d{2})/, + fn: function(m) { + var ret = {}; + var optionCode = parseInt(m[1]); + + if (optionCode > 43) { + // should never happen + return { + fgColor: null, + bgColor: null, + attrs: null + }; + } + var optionName = WeeChatProtocol._colorsOptionsNames[optionCode]; + ret.fgColor = { + type: 'option', + name: optionName + }; + ret.bgColor = WeeChatProtocol._cloneColor(ret.fgColor); + ret.attrs = { + name: optionName, + override: {} + }; + + return ret; + } + }, + { + // ncurses pair + // EXT + regex: /^@(\d{5})/, + fn: function(m) { + // unimplemented case + return { + fgColor: null, + bgColor: null, + attrs: null + }; + } + }, + { + // foreground color with F + // "F" + (A)STD + // "F" + (A)EXT + regex: /^F(?:([*!\/_|]*)(\d{2})|@([*!\/_|]*)(\d{5}))/, + fn: function(m) { + var ret = { + bgColor: null + }; + + if (m[2]) { + ret.attrs = WeeChatProtocol._attrsFromStr(m[1]); + ret.fgColor = WeeChatProtocol._getColorObj(m[2]); + } else { + ret.attrs = WeeChatProtocol._attrsFromStr(m[3]); + ret.fgColor = WeeChatProtocol._getColorObj(m[4]); + } + + return ret; + } + }, + { + // background color (no attributes) + // "B" + STD + // "B" + EXT + regex: /^B(\d{2}|@\d{5})/, + fn: function(m) { + return { + fgColor: null, + bgColor: WeeChatProtocol._getColorObj(m[1]), + attrs: null + }; + } + }, + { + // foreground, background (+ attributes) + // "*" + (A)STD + "," + (A)STD + // "*" + (A)STD + "," + (A)EXT + // "*" + (A)EXT + "," + (A)STD + // "*" + (A)EXT + "," + (A)EXT + regex: /^\*(?:([*!\/_|]*)(\d{2})|@([*!\/_|]*)(\d{5})),(\d{2}|@\d{5})/, + fn: function(m) { + var ret = {}; + + if (m[2]) { + ret.attrs = WeeChatProtocol._attrsFromStr(m[1]); + ret.fgColor = WeeChatProtocol._getColorObj(m[2]); + } else { + ret.attrs = WeeChatProtocol._attrsFromStr(m[3]); + ret.fgColor = WeeChatProtocol._getColorObj(m[4]); + } + ret.bgColor = WeeChatProtocol._getColorObj(m[5]); + + return ret; + } + }, + { + // foreground color with * (+ attributes) (fall back, must be checked before previous case) + // "*" + (A)STD + // "*" + (A)EXT + regex: /^\*([*!\/_|]*)(\d{2}|@\d{5})/, + fn: function(m) { + return { + fgColor: WeeChatProtocol._getColorObj(m[2]), + bgColor: null, + attrs: WeeChatProtocol._attrsFromStr(m[1]) + }; + } + }, + { + // emphasis + // "E" + regex: /^E/, + fn: function(m) { + var ret = {}; + + ret.fgColor = { + type: 'option', + name: 'emphasis' + }; + ret.bgColor = WeeChatProtocol._cloneColor(ret.fgColor); + ret.attrs = { + name: 'emphasis', + override: {} + }; + + return ret; + } + } + ]; + + // parse + var ret = { + fgColor: null, + bgColor: null, + attrs: null, + text: txt + }; + matchers.some(function(matcher) { + var m = txt.match(matcher.regex); + if (m) { + ret = matcher.fn(m); + ret.text = txt.substring(m[0].length); + return true; + } + + return false; + }); + + return ret; + } + + /** + * Transforms a raw text into an array of text elements with integrated + * colors and attributes. + * + * @param rawText Raw text to transform + * @return Array of text elements + */ + WeeChatProtocol.rawText2Rich = function(rawText) { + /* This is subtle, but JavaScript adds the token to the output list + * when it's surrounded by capturing parentheses. + */ + var parts = rawText.split(/(\x19|\x1a|\x1b|\x1c)/); + + // no colors/attributes + if (parts.length == 1) { + return [ + { + attrs: WeeChatProtocol._getDefaultAttributes(), + fgColor: WeeChatProtocol._getDefaultColor(), + bgColor: WeeChatProtocol._getDefaultColor(), + text: parts[0] + } + ]; + } + + // find the style of every part + var curFgColor = WeeChatProtocol._getDefaultColor(); + var curBgColor = WeeChatProtocol._getDefaultColor(); + var curAttrs = WeeChatProtocol._getDefaultAttributes(); + var curSpecialToken = null; + + return parts.map(function(p) { + if (p.length == 0) { + return null; + } + var firstCharCode = p.charCodeAt(0); + var firstChar = p.charAt(0); + + if (firstCharCode >= 0x19 && firstCharCode <= 0x1c) { + // special token + if (firstCharCode == 0x1c) { + // always reset colors + curFgColor = WeeChatProtocol._getDefaultColor(); + curBgColor = WeeChatProtocol._getDefaultColor(); + if (curSpecialToken != 0x19) { + // also reset attributes + curAttrs = WeeChatProtocol._getDefaultAttributes(); + } + } + curSpecialToken = firstCharCode; + return null; + } + + var text = p; + if (curSpecialToken == 0x19) { + // get new style + var style = WeeChatProtocol._getStyle(p); + + // set foreground color if changed + if (style.fgColor !== null) { + curFgColor = style.fgColor; + } + + // set background color if changed + if (style.bgColor !== null) { + curBgColor = style.bgColor; + } + + // set attibutes if changed + if (style.attrs !== null) { + curAttrs = style.attrs; + } + + // set plain text + text = style.text; + } else if (curSpecialToken == 0x1a || curSpecialToken == 0x1b) { + // set/reset attribute + var orideVal = (curSpecialToken == 0x1a); + + // set attribute override if we don't have to keep all of them + if (firstChar != '|') { + var orideName = WeeChatProtocol._attrNameFromChar(firstChar); + if (orideName) { + // known attribute + curAttrs.override[orideName] = orideVal; + text = p.substring(1); + } + } + } + + // reset current special token + curSpecialToken = null; + + // if text is empty, don't bother returning it + if (text.length == 0) { + return null; + } + + // parsed text element + return { + fgColor: WeeChatProtocol._cloneColor(curFgColor), + bgColor: WeeChatProtocol._cloneColor(curBgColor), + attrs: WeeChatProtocol._cloneAttrs(curAttrs), + text: text + }; + }).filter(function(p) { + return p !== null; + }); + }; + + /** + * Unsigned integer array to string. + * + * @param uia Unsigned integer array + * @return Decoded string + */ + WeeChatProtocol._uia2s = function(uia) { + var str = []; + + for (var c = 0; c < uia.length; c++) { + str.push(String.fromCharCode(uia[c])); + } + + return decodeURIComponent(escape(str.join(''))); + }; + + /** + * Merges default parameters with overriding parameters. + * + * @param defaults Default parameters + * @param override Overriding parameters + * @return Merged parameters + */ + WeeChatProtocol._mergeParams = function(defaults, override) { + for (var v in override) { + defaults[v] = override[v]; + } + + return defaults; + }; + + /** + * Formats a command. + * + * @param id Command ID (null for no ID) + * @param name Command name + * @param parts Command parts + * @return Formatted command string + */ + WeeChatProtocol._formatCmd = function(id, name, parts) { + var cmdIdName; + var cmd; + + cmdIdName = (id !== null) ? '(' + id + ') ' : ''; + cmdIdName += name; + parts.unshift(cmdIdName); + cmd = parts.join(' '); + cmd += '\n'; + + return cmd; + }; + + /** + * Formats an init command. + * + * @param params Parameters: + * password: password (optional) + * compression: compression ('off' or 'zlib') (optional) + * @return Formatted init command string + */ + WeeChatProtocol.formatInit = function(params) { + var defaultParams = { + password: null, + compression: 'off' + }; + var keys = []; + var parts = []; + + params = WeeChatProtocol._mergeParams(defaultParams, params); + keys.push('compression=' + params.compression); + if (params.password !== null) { + keys.push('password=' + params.password); + } + parts.push(keys.join(',')); + + return WeeChatProtocol._formatCmd(null, 'init', parts); + }; + + /** + * Formats an hdata command. + * + * @param params Parameters: + * id: command ID (optional) + * path: hdata path (mandatory) + * keys: array of keys (optional) + * @return Formatted hdata command string + */ + WeeChatProtocol.formatHdata = function(params) { + var defaultParams = { + id: null, + keys: null + }; + var parts = []; + + params = WeeChatProtocol._mergeParams(defaultParams, params); + parts.push(params.path); + if (params.keys !== null) { + parts.push(params.keys.join(',')); + } + + return WeeChatProtocol._formatCmd(params.id, 'hdata', parts); + }; + + /** + * Formats an info command. + * + * @param params Parameters: + * id: command ID (optional) + * name: info name (mandatory) + * @return Formatted info command string + */ + WeeChatProtocol.formatInfo = function(params) { + var defaultParams = { + id: null + }; + var parts = []; + + params = WeeChatProtocol._mergeParams(defaultParams, params); + parts.push(params.name); + + return WeeChatProtocol._formatCmd(params.id, 'info', parts); + }; + + /** + * Formats a nicklist command. + * + * @param params Parameters: + * id: command ID (optional) + * buffer: buffer name (optional) + * @return Formatted nicklist command string + */ + WeeChatProtocol.formatNicklist = function(params) { + var defaultParams = { + id: null, + buffer: null + }; + var parts = []; + + params = WeeChatProtocol._mergeParams(defaultParams, params); + if (params.buffer !== null) { + parts.push(params.buffer); + } + + return WeeChatProtocol._formatCmd(params.id, 'nicklist', parts); + }; + + /** + * Formats an input command. + * + * @param params Parameters: + * id: command ID (optional) + * buffer: target buffer (mandatory) + * data: input data (mandatory) + * @return Formatted input command string + */ + WeeChatProtocol.formatInput = function(params) { + var defaultParams = { + id: null + }; + var parts = []; + + params = WeeChatProtocol._mergeParams(defaultParams, params); + parts.push(params.buffer); + parts.push(params.data); + + return WeeChatProtocol._formatCmd(params.id, 'input', parts); + }; + + /** + * Formats a sync or a desync command. + * + * @param params Parameters (see _formatSync and _formatDesync) + * @return Formatted sync/desync command string + */ + WeeChatProtocol._formatSyncDesync = function(cmdName, params) { + var defaultParams = { + id: null, + buffers: null, + options: null + }; + var parts = []; + + params = WeeChatProtocol._mergeParams(defaultParams, params); + if (params.buffers !== null) { + parts.push(params.buffers.join(',')); + if (params.options !== null) { + parts.push(params.options.join(',')); + } + } + + return WeeChatProtocol._formatCmd(params.id, cmdName, parts); + }; + + /** + * Formats a sync command. + * + * @param params Parameters: + * id: command ID (optional) + * buffers: array of buffers to sync (optional) + * options: array of options (optional) + * @return Formatted sync command string + */ + WeeChatProtocol.formatSync = function(params) { + return WeeChatProtocol._formatSyncDesync('sync', params); + }; + + /** + * Formats a desync command. + * + * @param params Parameters: + * id: command ID (optional) + * buffers: array of buffers to desync (optional) + * options: array of options (optional) + * @return Formatted desync command string + */ + WeeChatProtocol.formatDesync = function(params) { + return WeeChatProtocol._formatSyncDesync('desync', params); + }; + + /** + * Formats a test command. + * + * @param params Parameters: + * id: command ID (optional) + * @return Formatted test command string + */ + WeeChatProtocol.formatTest = function(params) { + var defaultParams = { + id: null + }; + var parts = []; + + params = WeeChatProtocol._mergeParams(defaultParams, params); + + return WeeChatProtocol._formatCmd(params.id, 'test', parts); + }; + + /** + * Formats a quit command. + * + * @return Formatted quit command string + */ + WeeChatProtocol.formatQuit = function() { + return WeeChatProtocol._formatCmd(null, 'quit', []); + }; + + /** + * Formats a ping command. + * + * @param params Parameters: + * id: command ID (optional) + * args: array of custom arguments (optional) + * @return Formatted ping command string + */ + WeeChatProtocol.formatPing = function(params) { + var defaultParams = { + id: null, + args: null + }; + var parts = []; + + params = WeeChatProtocol._mergeParams(defaultParams, params); + if (params.args !== null) { + parts.push(params.args.join(' ')); + } + + return WeeChatProtocol._formatCmd(params.id, 'ping', parts); + }; + + WeeChatProtocol.prototype = { + /** + * Warns that message parsing is not implemented for a + * specific type. + * + * @param type Message type to display + */ + _warnUnimplemented: function(type) { + console.log('Warning: ' + type + ' message parsing is not implemented'); + }, + + /** + * Reads a 3-character message type token value from current + * set data. + * + * @return Type + */ + _getType: function() { + var t = this._getSlice(3); + + if (!t) { + return null; + } + + return WeeChatProtocol._uia2s(new Uint8Array(t)); + }, + + /** + * Runs the appropriate read routine for the specified message type. + * + * @param type Message type + * @return Data value + */ + _runType: function(type) { + var cb = this._types[type]; + var boundCb = cb.bind(this); + + return boundCb(); + }, + + /** + * Reads a "number as a string" token value from current set data. + * + * @return Number as a string + */ + _getStrNumber: function() { + var len = this._getByte(); + var str = this._getSlice(len); + + return WeeChatProtocol._uia2s(new Uint8Array(str)); + }, + + /** + * Returns the passed object. + * + * @param obj Object + * @return Passed object + */ + _strDirect: function(obj) { + return obj; + }, + + /** + * Calls toString() on the passed object and returns the value. + * + * @param obj Object to call toString() on + * @return String value of object + */ + _strToString: function(obj) { + return obj.toString(); + }, + + /** + * Gets the string value of an object representing the message + * value for a specified type. + * + * @param obj Object for which to get the string value + * @param type Message type + * @return String value of object + */ + _objToString: function(obj, type) { + var cb = this._typesStr[type]; + var boundCb = cb.bind(this); + + return boundCb(obj); + }, + + /** + * Reads an info token value from current set data. + * + * @return Info object + */ + _getInfo: function() { + var info = {}; + info.key = this._getString(); + info.value = this._getString(); + + return info; + }, + + /** + * Reads an hdata token value from current set data. + * + * @return Hdata object + */ + _getHdata: function() { + var self = this; + var paths; + var count; + var objs = []; + var hpath = this._getString(); + + keys = this._getString().split(','); + paths = hpath.split('/'); + count = this._getInt(); + + keys = keys.map(function(key) { + return key.split(':'); + }); + + function runType() { + var tmp = {}; + + tmp.pointers = paths.map(function(path) { + return self._getPointer(); + }); + keys.forEach(function(key) { + tmp[key[0]] = self._runType(key[1]); + }); + objs.push(tmp); + } + + for (var i = 0; i < count; i++) { + runType(); + } + + return objs; + }, + + /** + * Reads a pointer token value from current set data. + * + * @return Pointer value + */ + _getPointer: function() { + return this._getStrNumber(); + }, + + /** + * Reads a time token value from current set data. + * + * @return Time value (Date) + */ + _getTime: function() { + var str = this._getStrNumber(); + + return new Date(parseInt(str, 10) * 1000); + }, + + /** + * Reads an integer token value from current set data. + * + * @return Integer value + */ + _getInt: function() { + var parsedData = new Uint8Array(this._getSlice(4)); + + return ((parsedData[0] & 0xff) << 24) | + ((parsedData[1] & 0xff) << 16) | + ((parsedData[2] & 0xff) << 8) | + (parsedData[3] & 0xff); + }, + + /** + * Reads a byte from current set data. + * + * @return Byte value (integer) + */ + _getByte: function() { + var parsedData = new Uint8Array(this._getSlice(1)); + + return parsedData[0]; + }, + + /** + * Reads a character token value from current set data. + * + * @return Character (string) + */ + _getChar: function() { + return this._getByte(); + }, + + /** + * Reads a string token value from current set data. + * + * @return String value + */ + _getString: function() { + var l = this._getInt(); + + if (l > 0) { + var s = this._getSlice(l); + var parsedData = new Uint8Array(s); + + return WeeChatProtocol._uia2s(parsedData); + } + + return ""; + }, + + /** + * Reads a message header from current set data. + * + * @return Header object + */ + _getHeader: function() { + var len = this._getInt(); + var comp = this._getByte(); + + return { + length: len, + compression: comp, + }; + }, + + /** + * Reads a message header ID from current set data. + * + * @return Message ID (string) + */ + _getId: function() { + return this._getString(); + }, + + /** + * Reads an arbitrary object token from current set data. + * + * @return Object value + */ + _getObject: function() { + var self = this; + var type = this._getType(); + + if (type) { + return { + type: type, + content: self._runType(type), + }; + } + }, + + /** + * Reads an hash table token from current set data. + * + * @return Hash table + */ + _getHashTable: function() { + var self = this; + var typeKeys, typeValues, count; + var dict = {}; + + typeKeys = this._getType(); + typeValues = this._getType(); + count = this._getInt(); + + for (var i = 0; i < count; ++i) { + var key = self._runType(typeKeys); + var keyStr = self._objToString(key, typeKeys); + var value = self._runType(typeValues); + dict[keyStr] = value; + } + + return dict; + }, + + /** + * Reads an array token from current set data. + * + * @return Array + */ + _getArray: function() { + var self = this; + var type; + var count; + var values; + + type = this._getType(); + count = this._getInt(); + values = []; + + for (var i = 0; i < count; i++) { + values.push(self._runType(type)); + } + + return values; + }, + + /** + * Reads a specified number of bytes from current set data. + * + * @param length Number of bytes to read + * @return Sliced array + */ + _getSlice: function(length) { + if (this.dataAt + length > this._data.byteLength) { + return null; + } + + var slice = this._data.slice(this._dataAt, this._dataAt + length); + + this._dataAt += length; + + return slice; + }, + + /** + * Sets the current data. + * + * @param data Current data + */ + _setData: function(data) { + this._data = data; + }, + + /** + * Parses a WeeChat message. + * + * @param data Message data (ArrayBuffer) + * @return Message value + */ + parse: function(data, optionsValues) { + var self = this; + + this._setData(data); + this._dataAt = 0; + + var header = this._getHeader(); + var id = this._getId(); + var objects = []; + var object = this._getObject(); + + while (object) { + objects.push(object); + object = self._getObject(); + } + var msg = { + header: header, + id: id, + objects: objects, + }; + + return msg; + } + }; + + exports.Protocol = WeeChatProtocol; })(); -})(typeof exports === "undefined" ? this.weeChat = {} : exports) \ No newline at end of file +})(typeof exports === "undefined" ? this.weeChat = {} : exports) From f15878b533c10992cc77d39c76f6ff03eb248b8a Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 26 Oct 2013 04:31:58 -0400 Subject: [PATCH 3/8] Colors look better on a slightly darker bg --- css/glowingbear.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/css/glowingbear.css b/css/glowingbear.css index b4c407e..75f6c99 100644 --- a/css/glowingbear.css +++ b/css/glowingbear.css @@ -85,7 +85,7 @@ hr { body { color: #ddd; - background-color: #222; + background-color: #181818; padding-left: 0; padding-right: 5px; padding-bottom:70px; @@ -190,6 +190,9 @@ input[type=text], input[type=password], .badge { .navbar-fixed-bottom { margin: 0 5px 0 14%; } +.navbar-inverse { + background-color: #181818; +} @media (max-width: 968px) { #sidebar, #bufferlines { position: relative; From e019c8ea8bbad089f736e6b07e05ef6e76bc4062 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 26 Oct 2013 04:32:17 -0400 Subject: [PATCH 4/8] Minor UI improvements --- css/glowingbear.css | 4 +++- index.html | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/css/glowingbear.css b/css/glowingbear.css index 75f6c99..cc62f72 100644 --- a/css/glowingbear.css +++ b/css/glowingbear.css @@ -59,6 +59,7 @@ td.prefix { vertical-align: top; padding-right: 5px; white-space: pre; + border-right: 1px solid #444; } td.message { word-wrap: break-word; @@ -175,13 +176,14 @@ input[type=text], input[type=password], .badge { } #bufferlines { - font-family: 'Terminus', 'Inconsolata', 'Consolas', 'Monaco', 'Ubuntu Mono', monospace; + font-family: 'Terminus', 'Consolas', 'Monaco', 'Inconsolata', 'Ubuntu Mono', monospace; position: relative; height: 99%; overflow-y: auto; margin-left: 14%; width: auto; top: 25px; /* topbar */ + padding-bottom: 10px; } #bufferlines .btn { font-family: sans-serif; diff --git a/index.html b/index.html index b1d4e64..a0783cb 100644 --- a/index.html +++ b/index.html @@ -222,7 +222,7 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel {{ bufferline.date | date:'HH:mm' }} - {{ part.text }} + {{ part.text }} From 51916ebba33a58790bde77726743f8a7b5c16b84 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 26 Oct 2013 04:42:11 -0400 Subject: [PATCH 5/8] Support WeeChat color scheming of date prefixes --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index a0783cb..67d06c1 100644 --- a/index.html +++ b/index.html @@ -219,7 +219,7 @@ $ openssl req -nodes -newkey rsa:2048 -keyout relay.pem -x509 -days 365 -out rel - {{ bufferline.date | date:'HH:mm' }} + {{ bufferline.date | date:'HH' }}:{{ bufferline.date | date:'mm' }} {{ part.text }} From 439734a49bb122dbf0c4213ef244ba51b2718c21 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 26 Oct 2013 04:49:37 -0400 Subject: [PATCH 6/8] Optimize style attributes overriding --- js/models.js | 9 --------- js/weechat.js | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/js/models.js b/js/models.js index 9d53c61..a0c066b 100644 --- a/js/models.js +++ b/js/models.js @@ -88,16 +88,7 @@ models.service('models', ['$rootScope', function($rootScope) { if (textEl.attrs.name !== null) { textEl.classes.push('coa-' + textEl.attrs.name); } - var allReset = true; for (var attr in textEl.attrs.override) { - if (textEl.attrs.override[attr]) { - allReset = false; - break; - } - } - if (allReset) { - textEl.classes.push('a-reset'); - } else for (var attr in textEl.attrs.override) { val = textEl.attrs.override[attr]; if (val) { textEl.classes.push('a-' + attr); diff --git a/js/weechat.js b/js/weechat.js index 698113a..d4f122a 100644 --- a/js/weechat.js +++ b/js/weechat.js @@ -461,6 +461,7 @@ var curBgColor = WeeChatProtocol._getDefaultColor(); var curAttrs = WeeChatProtocol._getDefaultAttributes(); var curSpecialToken = null; + var curAttrsOnlyFalseOverrides = true; return parts.map(function(p) { if (p.length == 0) { @@ -529,6 +530,24 @@ return null; } + /* As long as attributes are only false overrides, without any option + * name, it's safe to remove them. + */ + if (curAttrsOnlyFalseOverrides && curAttrs.name === null) { + var allReset = true; + for (var attr in curAttrs.override) { + if (curAttrs.override[attr]) { + allReset = false; + break; + } + } + if (allReset) { + curAttrs.override = {}; + } else { + curAttrsOnlyFalseOverrides = false; + } + } + // parsed text element return { fgColor: WeeChatProtocol._cloneColor(curFgColor), From 2d90c66dfa929fab46f607e20633c5a39986542e Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 26 Oct 2013 04:58:23 -0400 Subject: [PATCH 7/8] Subtle bufferline hover background color This helps reading long lines by providing a visual linear horizontal guide. --- css/glowingbear.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/css/glowingbear.css b/css/glowingbear.css index cc62f72..cb46578 100644 --- a/css/glowingbear.css +++ b/css/glowingbear.css @@ -49,6 +49,9 @@ table { tr { line-height: 100%; } +tr:hover { + background-color: #222222; +} td.time { padding-right: 5px; vertical-align: top; From c7a0ab0715f7faa3fcb245b52abef6a8d15778a4 Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Sat, 26 Oct 2013 05:17:12 -0400 Subject: [PATCH 8/8] Fix comment following FlashCode's update of doc --- js/weechat.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/weechat.js b/js/weechat.js index d4f122a..8260eea 100644 --- a/js/weechat.js +++ b/js/weechat.js @@ -355,10 +355,10 @@ }, { // foreground, background (+ attributes) - // "*" + (A)STD + "," + (A)STD - // "*" + (A)STD + "," + (A)EXT - // "*" + (A)EXT + "," + (A)STD - // "*" + (A)EXT + "," + (A)EXT + // "*" + (A)STD + "," + STD + // "*" + (A)STD + "," + EXT + // "*" + (A)EXT + "," + STD + // "*" + (A)EXT + "," + EXT regex: /^\*(?:([*!\/_|]*)(\d{2})|@([*!\/_|]*)(\d{5})),(\d{2}|@\d{5})/, fn: function(m) { var ret = {};