commit 59007dd4dacb7ec4adb9f4f5340bbda51f2c68df Author: Nikola Forró Date: Wed Sep 2 12:38:49 2020 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85583dc --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.web-extension-id +improved-crowdcast-ux.xpi +improved-crowdcast-ux.crx +improved-crowdcast-ux.pem diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..31bd004 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2020 Nikola Forró + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/content.css b/content.css new file mode 100644 index 0000000..c6700d1 --- /dev/null +++ b/content.css @@ -0,0 +1,17 @@ +:root { + --default-chat-width: 300px; + --default-highlight-color: #FFEA9E; +} + +.theatre .theatre-left { + width: calc(100% - var(--chat-width, var(--default-chat-width)) - 9px) !important; +} + +.theatre .theatre-right { + width: var(--chat-width, var(--default-chat-width)) !important; + max-width: var(--chat-width, var(--default-chat-width)) !important; +} + +.message-content.highlighted { + background-color: var(--highlight-color, var(--default-highlight-color)) !important; +} diff --git a/content.js b/content.js new file mode 100644 index 0000000..3c7a19c --- /dev/null +++ b/content.js @@ -0,0 +1,135 @@ +function setChatWidth(width) { + document.querySelector('body').style.setProperty("--chat-width", width + 'px'); +} + +function setHighlightColor(color) { + document.querySelector('body').style.setProperty("--highlight-color", color); +} + +chrome.storage.onChanged.addListener((changes, areaName) => { + if ('chatWidth' in changes) { + setChatWidth(changes.chatWidth.newValue); + } + + if ('highlightColor' in changes) { + setHighlightColor(changes.highlightColor.newValue); + } +}); + +chrome.storage.sync.get(null, (settings) => { + if ('chatWidth' in settings) { + setChatWidth(settings.chatWidth); + } + + if ('highlightColor' in settings) { + setHighlightColor(settings.highlightColor); + } +}); + +class TabCompletion { + constructor() { + this.ownUsernameRegExp = null; + this.usernames = []; + } + + setOwnUsername(username) { + this.ownUsernameRegExp = new RegExp('@?' + username.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'gi'); + } + + addUsername(username) { + if (!this.usernames.includes(username)) { + this.usernames.push(username); + } + } + + complete(input, start, symbol, choices) { + let partial = input.value.substring(start + 1, input.selectionStart).trim(); + + if (partial === this[`suggestion_${symbol}`]) { + partial = this[`partial_${symbol}`]; + } else { + this[`partial_${symbol}`] = partial; + } + + const possibilities = choices.filter((choice) => choice.toLowerCase().startsWith(partial.toLowerCase())); + + if (this[`completionIndex_${symbol}`] === undefined || ++this[`completionIndex_${symbol}`] >= possibilities.length) { + this[`completionIndex_${symbol}`] = 0; + } + + if (possibilities.length > 0) { + this[`suggestion_${symbol}`] = possibilities[this[`completionIndex_${symbol}`]].trim(); + + input.value = input.value.substring(0, start + 1) + this[`suggestion_${symbol}`] + + ' ' + input.value.substring(input.selectionStart); + input.selectionStart = start + this[`suggestion_${symbol}`].length + 2; + input.selectionEnd = input.selectionStart; + } + } + + attempt(input) { + const at = input.value.lastIndexOf('@', input.selectionStart - 1); + let colon = input.value.lastIndexOf(':', input.selectionStart - 1); + + // ignore colon at the end of emoji shortname + if (colon !== -1) { + const match = emojis.shortnameRegExp.exec(input.value); + + if (match !== null) { + colon = match.index; + } + } + + if (at !== -1 && at > colon) { + this.complete(input, at, '@', this.usernames); + } else if (colon !== -1 && colon > at) { + this.complete(input, colon, ':', emojis.shortnames.map((s => s + ':'))); + } else { + return false; + } + + return true; + } +} + +const tabCompletion = new TabCompletion(); + +(new MutationObserver((mutationsList, observer) => { + for (let mutation of mutationsList) { + for (let node of mutation.addedNodes) { + if (node.nodeType === 1 && (username = node.querySelector('span.user-name')) !== null) { + (new MutationObserver((mutationsList, observer) => { + for (let mutation of mutationsList) { + tabCompletion.setOwnUsername(mutation.target.data.trim()); + } + })).observe(username, {characterData: true, subtree: true}); + } + + if (node.nodeType === 1 && (chatInput = node.querySelector('textarea#input-chat')) !== null) { + chatInput.addEventListener('keydown', (event) => { + if (event.key == 'Tab' && tabCompletion.attempt(event.currentTarget)) { + event.preventDefault(); + } + }); + } + + if (node.nodeType === 1 && (username = node.querySelector('a.name')) !== null) { + if (!username.text.trim().startsWith('{')) { + tabCompletion.addUsername(username.text.trim()); + } + } + + if (node.nodeType === 1 && (messageContent = node.querySelector('div.message-content-main')) !== null) { + if (tabCompletion.ownUsernameRegExp !== null) { + const updated = messageContent.innerHTML.replace(tabCompletion.ownUsernameRegExp, + '$&'); + + if (messageContent.innerHTML !== updated) { + messageContent.innerHTML = updated; + messageContent.parentNode.classList.add('highlighted'); + } + } + } + } + } +})).observe(document, {childList: true, subtree: true}); diff --git a/emojis.js b/emojis.js new file mode 100644 index 0000000..f14bd47 --- /dev/null +++ b/emojis.js @@ -0,0 +1,7 @@ +// JSON.stringify($('[data-wdt-emoji-shortnames]').map((i, e) => e.getAttribute('data-wdt-emoji-shortnames').replace(/:/g, '').split(' ')).get()); +const SHORTNAMES = ["grinning","grimacing","grin","joy","smiley","smile","sweat_smile","laughing","satisfied","innocent","wink","blush","slightly_smiling_face","upside_down_face","relaxed","yum","relieved","heart_eyes","kissing_heart","kissing","kissing_smiling_eyes","kissing_closed_eyes","stuck_out_tongue_winking_eye","stuck_out_tongue_closed_eyes","stuck_out_tongue","money_mouth_face","nerd_face","sunglasses","hugging_face","smirk","no_mouth","neutral_face","expressionless","unamused","face_with_rolling_eyes","thinking_face","flushed","disappointed","worried","angry","rage","pensive","confused","slightly_frowning_face","white_frowning_face","persevere","confounded","tired_face","weary","triumph","open_mouth","scream","fearful","cold_sweat","hushed","frowning","anguished","cry","disappointed_relieved","sleepy","sweat","sob","dizzy_face","astonished","zipper_mouth_face","mask","face_with_thermometer","face_with_head_bandage","sleeping","zzz","hankey","poop","shit","smiling_imp","imp","japanese_ogre","japanese_goblin","skull","ghost","alien","robot_face","smiley_cat","smile_cat","joy_cat","heart_eyes_cat","smirk_cat","kissing_cat","scream_cat","crying_cat_face","pouting_cat","raised_hands","clap","wave","+1","thumbsup","-1","thumbsdown","facepunch","punch","fist","v","ok_hand","hand","raised_hand","open_hands","muscle","pray","point_up","point_up_2","point_down","point_left","point_right","middle_finger","reversed_hand_with_middle_finger_extended","raised_hand_with_fingers_splayed","the_horns","sign_of_the_horns","spock-hand","writing_hand","nail_care","lips","tongue","ear","nose","eye","eyes","bust_in_silhouette","busts_in_silhouette","speaking_head_in_silhouette","baby","boy","girl","man","woman","person_with_blond_hair","older_man","older_woman","man_with_gua_pi_mao","man_with_turban","cop","construction_worker","guardsman","sleuth_or_spy","santa","angel","princess","bride_with_veil","walking","runner","running","dancer","dancers","couple","man_and_woman_holding_hands","two_men_holding_hands","two_women_holding_hands","bow","information_desk_person","no_good","ok_woman","raising_hand","person_with_pouting_face","person_frowning","haircut","massage","couple_with_heart","woman-heart-woman","man-heart-man","couplekiss","woman-kiss-woman","man-kiss-man","family","man-woman-boy","man-woman-girl","man-woman-girl-boy","man-woman-boy-boy","man-woman-girl-girl","woman-woman-boy","woman-woman-girl","woman-woman-girl-boy","woman-woman-boy-boy","woman-woman-girl-girl","man-man-boy","man-man-girl","man-man-girl-boy","man-man-boy-boy","man-man-girl-girl","womans_clothes","shirt","tshirt","jeans","necktie","dress","bikini","kimono","lipstick","kiss","footprints","high_heel","sandal","boot","mans_shoe","shoe","athletic_shoe","womans_hat","tophat","helmet_with_white_cross","mortar_board","crown","school_satchel","pouch","purse","handbag","briefcase","eyeglasses","dark_sunglasses","ring","closed_umbrella","dog","cat","mouse","hamster","rabbit","bear","panda_face","koala","tiger","lion_face","cow","pig","pig_nose","frog","octopus","monkey_face","see_no_evil","hear_no_evil","speak_no_evil","monkey","chicken","penguin","bird","baby_chick","hatching_chick","hatched_chick","wolf","boar","horse","unicorn_face","bee","honeybee","bug","snail","beetle","ant","spider","scorpion","crab","snake","turtle","tropical_fish","fish","blowfish","dolphin","flipper","whale","whale2","crocodile","leopard","tiger2","water_buffalo","ox","cow2","dromedary_camel","camel","elephant","goat","ram","sheep","racehorse","pig2","rat","mouse2","rooster","turkey","dove_of_peace","dog2","poodle","cat2","rabbit2","chipmunk","feet","paw_prints","dragon","dragon_face","cactus","christmas_tree","evergreen_tree","deciduous_tree","palm_tree","seedling","herb","shamrock","four_leaf_clover","bamboo","tanabata_tree","leaves","fallen_leaf","maple_leaf","ear_of_rice","hibiscus","sunflower","rose","tulip","blossom","cherry_blossom","bouquet","mushroom","chestnut","jack_o_lantern","shell","spider_web","earth_americas","earth_africa","earth_asia","full_moon","waning_gibbous_moon","last_quarter_moon","waning_crescent_moon","new_moon","waxing_crescent_moon","first_quarter_moon","moon","waxing_gibbous_moon","new_moon_with_face","full_moon_with_face","first_quarter_moon_with_face","last_quarter_moon_with_face","sun_with_face","crescent_moon","star","star2","dizzy","sparkles","comet","sunny","mostly_sunny","sun_small_cloud","partly_sunny","barely_sunny","sun_behind_cloud","partly_sunny_rain","sun_behind_rain_cloud","cloud","rain_cloud","thunder_cloud_and_rain","lightning","lightning_cloud","zap","fire","boom","collision","snowflake","snow_cloud","snowman","wind_blowing_face","dash","tornado","tornado_cloud","fog","umbrella","umbrella","droplet","sweat_drops","ocean","green_apple","apple","pear","tangerine","lemon","banana","watermelon","grapes","strawberry","melon","cherries","peach","pineapple","tomato","eggplant","hot_pepper","corn","sweet_potato","honey_pot","bread","cheese_wedge","poultry_leg","meat_on_bone","fried_shrimp","egg","hamburger","fries","hotdog","pizza","spaghetti","taco","burrito","ramen","stew","fish_cake","sushi","bento","curry","rice_ball","rice","rice_cracker","oden","dango","shaved_ice","ice_cream","icecream","cake","birthday","custard","candy","lollipop","chocolate_bar","popcorn","doughnut","cookie","beer","beers","wine_glass","cocktail","tropical_drink","champagne","sake","tea","coffee","baby_bottle","fork_and_knife","knife_fork_plate","soccer","basketball","football","baseball","tennis","volleyball","rugby_football","8ball","golf","golfer","table_tennis_paddle_and_ball","badminton_racquet_and_shuttlecock","ice_hockey_stick_and_puck","field_hockey_stick_and_ball","cricket_bat_and_ball","ski","skier","snowboarder","ice_skate","bow_and_arrow","fishing_pole_and_fish","rowboat","swimmer","surfer","bath","person_with_ball","weight_lifter","bicyclist","mountain_bicyclist","horse_racing","man_in_business_suit_levitating","trophy","running_shirt_with_sash","sports_medal","medal","reminder_ribbon","rosette","ticket","admission_tickets","performing_arts","art","circus_tent","microphone","headphones","musical_score","musical_keyboard","saxophone","trumpet","guitar","violin","clapper","video_game","space_invader","dart","game_die","slot_machine","bowling","car","red_car","taxi","blue_car","bus","trolleybus","racing_car","police_car","ambulance","fire_engine","minibus","truck","articulated_lorry","tractor","racing_motorcycle","bike","rotating_light","oncoming_police_car","oncoming_bus","oncoming_automobile","oncoming_taxi","aerial_tramway","mountain_cableway","suspension_railway","railway_car","train","monorail","bullettrain_side","bullettrain_front","light_rail","mountain_railway","steam_locomotive","train2","metro","tram","station","helicopter","small_airplane","airplane","airplane_departure","airplane_arriving","boat","sailboat","motor_boat","speedboat","ferry","passenger_ship","rocket","satellite","seat","anchor","construction","fuelpump","busstop","vertical_traffic_light","traffic_light","checkered_flag","ship","ferris_wheel","roller_coaster","carousel_horse","building_construction","foggy","tokyo_tower","factory","fountain","rice_scene","mountain","snow_capped_mountain","mount_fuji","volcano","japan","camping","tent","national_park","motorway","railway_track","sunrise","sunrise_over_mountains","desert","beach_with_umbrella","desert_island","city_sunrise","city_sunset","cityscape","night_with_stars","bridge_at_night","milky_way","stars","sparkler","fireworks","rainbow","house_buildings","european_castle","japanese_castle","stadium","statue_of_liberty","house","house_with_garden","derelict_house_building","office","department_store","post_office","european_post_office","hospital","bank","hotel","convenience_store","school","love_hotel","wedding","classical_building","church","mosque","synagogue","kaaba","shinto_shrine","watch","iphone","calling","computer","keyboard","desktop_computer","printer","three_button_mouse","trackball","joystick","compression","minidisc","floppy_disk","cd","dvd","vhs","camera","camera_with_flash","video_camera","movie_camera","film_projector","film_frames","telephone_receiver","phone","telephone","pager","fax","tv","radio","studio_microphone","level_slider","control_knobs","stopwatch","timer_clock","alarm_clock","mantelpiece_clock","hourglass_flowing_sand","hourglass","satellite","battery","electric_plug","bulb","flashlight","candle","wastebasket","oil_drum","money_with_wings","dollar","yen","euro","pound","moneybag","credit_card","gem","scales","wrench","hammer","hammer_and_pick","hammer_and_wrench","pick","nut_and_bolt","gear","chains","gun","bomb","hocho","knife","dagger_knife","crossed_swords","shield","smoking","skull_and_crossbones","coffin","funeral_urn","amphora","crystal_ball","prayer_beads","barber","alembic","telescope","microscope","hole","pill","syringe","thermometer","label","bookmark","toilet","shower","bathtub","key","old_key","couch_and_lamp","sleeping_accommodation","bed","door","bellhop_bell","frame_with_picture","world_map","umbrella_on_ground","moyai","shopping_bags","balloon","flags","ribbon","gift","confetti_ball","tada","dolls","wind_chime","crossed_flags","izakaya_lantern","lantern","email","envelope","envelope_with_arrow","incoming_envelope","e-mail","love_letter","postbox","mailbox_closed","mailbox","mailbox_with_mail","mailbox_with_no_mail","package","postal_horn","inbox_tray","outbox_tray","scroll","page_with_curl","bookmark_tabs","bar_chart","chart_with_upwards_trend","chart_with_downwards_trend","page_facing_up","date","calendar","spiral_calendar_pad","card_index","card_file_box","ballot_box_with_ballot","file_cabinet","clipboard","spiral_note_pad","file_folder","open_file_folder","card_index_dividers","rolled_up_newspaper","newspaper","notebook","closed_book","green_book","blue_book","orange_book","notebook_with_decorative_cover","ledger","books","book","open_book","link","paperclip","linked_paperclips","scissors","triangular_ruler","straight_ruler","pushpin","round_pushpin","triangular_flag_on_post","waving_white_flag","waving_black_flag","closed_lock_with_key","lock","unlock","lock_with_ink_pen","lower_left_ballpoint_pen","lower_left_fountain_pen","black_nib","memo","pencil","pencil2","lower_left_crayon","lower_left_paintbrush","mag","mag_right","heart","yellow_heart","green_heart","blue_heart","purple_heart","broken_heart","heavy_heart_exclamation_mark_ornament","two_hearts","revolving_hearts","heartbeat","heartpulse","sparkling_heart","cupid","gift_heart","heart_decoration","peace_symbol","latin_cross","star_and_crescent","om_symbol","wheel_of_dharma","star_of_david","six_pointed_star","menorah_with_nine_branches","yin_yang","orthodox_cross","place_of_worship","ophiuchus","aries","taurus","gemini","cancer","leo","virgo","libra","scorpius","sagittarius","capricorn","aquarius","pisces","id","atom_symbol","u7a7a","u5272","radioactive_sign","biohazard_sign","mobile_phone_off","vibration_mode","u6709","u7121","u7533","u55b6","u6708","eight_pointed_black_star","vs","accept","white_flower","ideograph_advantage","secret","congratulations","u5408","u6e80","u7981","a","b","ab","cl","o2","sos","no_entry","name_badge","no_entry_sign","x","o","anger","hotsprings","no_pedestrians","do_not_litter","no_bicycles","non-potable_water","underage","no_mobile_phones","exclamation","heavy_exclamation_mark","grey_exclamation","question","grey_question","bangbang","interrobang","100","low_brightness","high_brightness","trident","fleur_de_lis","part_alternation_mark","warning","children_crossing","beginner","recycle","u6307","chart","sparkle","eight_spoked_asterisk","negative_squared_cross_mark","white_check_mark","diamond_shape_with_a_dot_inside","cyclone","loop","globe_with_meridians","m","atm","sa","passport_control","customs","baggage_claim","left_luggage","wheelchair","no_smoking","wc","parking","potable_water","mens","womens","baby_symbol","restroom","put_litter_in_its_place","cinema","signal_strength","koko","ng","ok","up","cool","new","free","zero","one","two","three","four","five","six","seven","eight","nine","keycap_ten","1234","arrow_forward","double_vertical_bar","black_right_pointing_triangle_with_double_vertical_bar","black_square_for_stop","black_circle_for_record","black_right_pointing_double_triangle_with_vertical_bar","black_left_pointing_double_triangle_with_vertical_bar","fast_forward","rewind","twisted_rightwards_arrows","repeat","repeat_one","arrow_backward","arrow_up_small","arrow_down_small","arrow_double_up","arrow_double_down","arrow_right","arrow_left","arrow_up","arrow_down","arrow_upper_right","arrow_lower_right","arrow_lower_left","arrow_upper_left","arrow_up_down","left_right_arrow","arrows_counterclockwise","arrow_right_hook","leftwards_arrow_with_hook","arrow_heading_up","arrow_heading_down","hash","information_source","abc","abcd","capital_abcd","symbols","musical_note","notes","wavy_dash","curly_loop","heavy_check_mark","arrows_clockwise","heavy_plus_sign","heavy_minus_sign","heavy_division_sign","heavy_multiplication_x","heavy_dollar_sign","currency_exchange","copyright","registered","tm","end","back","on","top","soon","ballot_box_with_check","radio_button","white_circle","black_circle","red_circle","large_blue_circle","small_orange_diamond","small_blue_diamond","large_orange_diamond","large_blue_diamond","small_red_triangle","black_small_square","white_small_square","black_large_square","white_large_square","small_red_triangle_down","black_medium_square","white_medium_square","black_medium_small_square","white_medium_small_square","black_square_button","white_square_button","speaker","sound","loud_sound","mute","mega","loudspeaker","bell","no_bell","black_joker","mahjong","spades","clubs","hearts","diamonds","flower_playing_cards","thought_balloon","right_anger_bubble","speech_balloon","clock1","clock2","clock3","clock4","clock5","clock6","clock7","clock8","clock9","clock10","clock11","clock12","clock130","clock230","clock330","clock430","clock530","clock630","clock730","clock830","clock930","clock1030","clock1130","clock1230","flag-af","flag-ax","flag-al","flag-dz","flag-as","flag-ad","flag-ao","flag-ai","flag-aq","flag-ag","flag-ar","flag-am","flag-aw","flag-au","flag-at","flag-az","flag-bs","flag-bh","flag-bd","flag-bb","flag-by","flag-be","flag-bz","flag-bj","flag-bm","flag-bt","flag-bo","flag-bq","flag-ba","flag-bw","flag-br","flag-io","flag-vg","flag-bn","flag-bg","flag-bf","flag-bi","flag-cv","flag-kh","flag-cm","flag-ca","flag-ic","flag-ky","flag-cf","flag-td","flag-cl","flag-cn","cn","flag-cx","flag-cc","flag-co","flag-km","flag-cg","flag-cd","flag-ck","flag-cr","flag-hr","flag-cu","flag-cw","flag-cy","flag-cz","flag-dk","flag-dj","flag-dm","flag-do","flag-ec","flag-eg","flag-sv","flag-gq","flag-er","flag-ee","flag-et","flag-eu","flag-fk","flag-fo","flag-fj","flag-fi","flag-fr","fr","flag-gf","flag-pf","flag-tf","flag-ga","flag-gm","flag-ge","flag-de","de","flag-gh","flag-gi","flag-gr","flag-gl","flag-gd","flag-gp","flag-gu","flag-gt","flag-gg","flag-gn","flag-gw","flag-gy","flag-ht","flag-hn","flag-hk","flag-hu","flag-is","flag-in","flag-id","flag-ir","flag-iq","flag-ie","flag-im","flag-il","flag-it","it","flag-ci","flag-jm","flag-jp","jp","flag-je","flag-jo","flag-kz","flag-ke","flag-ki","flag-xk","flag-kw","flag-kg","flag-la","flag-lv","flag-lb","flag-ls","flag-lr","flag-ly","flag-li","flag-lt","flag-lu","flag-mo","flag-mk","flag-mg","flag-mw","flag-my","flag-mv","flag-ml","flag-mt","flag-mh","flag-mq","flag-mr","flag-mu","flag-yt","flag-mx","flag-fm","flag-md","flag-mc","flag-mn","flag-me","flag-ms","flag-ma","flag-mz","flag-mm","flag-na","flag-nr","flag-np","flag-nl","flag-nc","flag-nz","flag-ni","flag-ne","flag-ng","flag-nu","flag-nf","flag-mp","flag-kp","flag-no","flag-om","flag-pk","flag-pw","flag-ps","flag-pa","flag-pg","flag-py","flag-pe","flag-ph","flag-pn","flag-pl","flag-pt","flag-pr","flag-qa","flag-re","flag-ro","flag-ru","ru","flag-rw","flag-bl","flag-sh","flag-kn","flag-lc","flag-pm","flag-vc","flag-ws","flag-sm","flag-st","flag-sa","flag-sn","flag-rs","flag-sc","flag-sl","flag-sg","flag-sx","flag-sk","flag-si","flag-sb","flag-so","flag-za","flag-gs","flag-kr","kr","flag-ss","flag-es","es","flag-lk","flag-sd","flag-sr","flag-sz","flag-se","flag-ch","flag-sy","flag-tw","flag-tj","flag-tz","flag-th","flag-tl","flag-tg","flag-tk","flag-to","flag-tt","flag-tn","flag-tr","flag-tm","flag-tc","flag-tv","flag-ug","flag-ua","flag-ae","flag-gb","gb","uk","flag-us","us","flag-vi","flag-uy","flag-uz","flag-vu","flag-va","flag-ve","flag-vn","flag-wf","flag-eh","flag-ye","flag-zm","flag-zw"]; + +const emojis = { + shortnameRegExp: new RegExp(':(' + SHORTNAMES.map(s => s.replace(/[+-]/g, '\\$&')).join('|') + '):\\s*$'), + shortnames: SHORTNAMES +}; diff --git a/icons/128.png b/icons/128.png new file mode 100644 index 0000000..c4c3c2a Binary files /dev/null and b/icons/128.png differ diff --git a/icons/16.png b/icons/16.png new file mode 100644 index 0000000..b6de373 Binary files /dev/null and b/icons/16.png differ diff --git a/icons/32.png b/icons/32.png new file mode 100644 index 0000000..3133bbb Binary files /dev/null and b/icons/32.png differ diff --git a/icons/48.png b/icons/48.png new file mode 100644 index 0000000..4428644 Binary files /dev/null and b/icons/48.png differ diff --git a/icons/64.png b/icons/64.png new file mode 100644 index 0000000..74f1f0e Binary files /dev/null and b/icons/64.png differ diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..eca9c3a --- /dev/null +++ b/manifest.json @@ -0,0 +1,25 @@ +{ + "manifest_version": 2, + "name": "Improved Crowdcast UX", + "version": "0.1", + "icons": { + "16": "icons/16.png", + "32": "icons/32.png", + "48": "icons/48.png", + "64": "icons/64.png", + "128": "icons/128.png" + }, + "browser_action": { + "default_title": "Improved Crowdcast UX", + "default_icon": "icons/32.png", + "default_popup": "popup.html" + }, + "content_scripts": [ + { + "matches": ["https://*.crowdcast.io/*"], + "js": ["emojis.js", "content.js"], + "css": ["content.css"] + } + ], + "permissions": ["activeTab", "storage", "https://*.crowdcast.io/*"] +} diff --git a/popup.css b/popup.css new file mode 100644 index 0000000..b6bffc0 --- /dev/null +++ b/popup.css @@ -0,0 +1,18 @@ +body { + min-width: 18em; +} + +input[type="color"] { + padding: 2px 3px; +} + +#content div { + display: flex; + justify-content: space-between; + align-items: center; + margin: 0.5em 0 0.5em 0; +} + +#content div > input { + flex-basis: 6em; +} diff --git a/popup.html b/popup.html new file mode 100644 index 0000000..c5277c9 --- /dev/null +++ b/popup.html @@ -0,0 +1,25 @@ + + + + + + + + + +
+
+ + +
+
+ + +
+
+ +
+
+ + + diff --git a/popup.js b/popup.js new file mode 100644 index 0000000..387cdcf --- /dev/null +++ b/popup.js @@ -0,0 +1,20 @@ +const defaultSettings = { + chatWidth: 300, + highlightColor: '#FFEA9E' +}; + +chrome.storage.sync.get(defaultSettings, (settings) => { + document.querySelector('#chatWidth').value = settings.chatWidth; + document.querySelector('#highlightColor').value = settings.highlightColor; +}); + +document.querySelector('#saveButton').addEventListener('click', (event) => { + settings = { + chatWidth: document.querySelector('#chatWidth').value, + highlightColor: document.querySelector('#highlightColor').value + } + + chrome.storage.sync.set(settings, () => { + console.log('Settings saved'); + }); +}, false);