Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name         WhatsApp Web+ Beta
  3. // @namespace    de.liltv.apps.web.waplus
  4. // @version      0.2
  5. // @description  Enhance WhatsApp Web with new options provided by this script
  6. // @author       liltv.media
  7. // @match        *://web.whatsapp.com/*
  8. // @grant        none
  9. // ==/UserScript==
  10.  
  11. // Build: 21.06.2017 17:50
  12.  
  13. // ===========================================================================
  14. // ===========================================================================
  15.  
  16. /* Initializing WhatsApp Web+ JS Class and hook to window namespace */
  17. window.WAWebPlus = {};
  18. var wawp = window.WAWebPlus;
  19.  
  20. /* Initialize class structure */
  21.  
  22. wawp.core = {
  23.     version: "0.2",
  24.     buildtime: "21.06.2017 17:50"
  25. };
  26.  
  27. wawp.helper = {
  28.     lang: {},
  29.     log: {},
  30.     init: {
  31.         inject: {}
  32.     },
  33.     gui: {},
  34.     uri: {},
  35.     backup: {}
  36. };
  37.  
  38. wawp.cache = {
  39.     prefs: {},
  40.     qresps: {},
  41.     chats: {},
  42.     msgs: {},
  43.     current: {
  44.         id: 0,
  45.         name: "",
  46.         info: ""
  47.     }
  48. };
  49.  
  50. wawp.defaults = {
  51.     storage: {
  52.         prefs: {
  53.             enabled: true,
  54.             man_chatTitle: true,
  55.             man_wideTextBubbles: true,
  56.             man_chatBackground: false,
  57.             man_chatBackground_img: false,
  58.             css_colorbarTop: true,
  59.             css_colorbarTopColor: "#009668",
  60.             css_imgRoundness: "7%",
  61.             css_drawerHeaderColor: "#00bfa5",
  62.             css_paneHeaderColor: "#eee",
  63.             css_chatBackground_color: "#fffcef",
  64.             css_chatBackground_img: ""
  65.         },
  66.         qresps: {}
  67.     }
  68. };
  69.  
  70. var waz = wawp.core;
  71. var wah = wawp.helper;
  72. var wac = wawp.cache;
  73. var wad = wawp.defaults;
  74.  
  75. var wal = wah.lang;
  76. var wai = wah.init;
  77. var wag = wah.gui;
  78. var wau = wah.uri;
  79. var wab = wah.backup;
  80. var wao = wah.log;
  81.  
  82. var wap = wac.prefs;
  83. var waq = wac.qresps;
  84. var way = wac.current;
  85.  
  86. var was = wad.storage;
  87.  
  88. var wp = window.localStorage;
  89. var ws = window.sessionStorage;
  90. var wl = document.location;
  91.  
  92. // ===========================================================================
  93.  
  94. /** Initializes WAWebPlus
  95. * @namespace WAWebPlus.core
  96. * @method init
  97. */
  98. waz.init = function (){
  99.  
  100.     //# If WAWebPlus was not installed before, run setup
  101.     if(wp.getItem("WAWebPlus") !== "true"){
  102.         waz.setup();
  103.     }
  104.  
  105.     //# Get installed version, compare with this version and if older, make backup and run setup
  106.     let ver = wp.getItem("WAWebPlus:version");
  107.     let comp = wah.compareVersionStr(ver, waz.version);
  108.     if(comp.isOlder === true){
  109.         wab.createCompatBackup();
  110.         waz.setup();
  111.         wag.promptLoadCompatBackup();
  112.     }
  113.     if(comp.isNewer === true){
  114.         wag.showNewerVersionInstalledInfo();
  115.     }
  116.  
  117.     //# Load preferences, quick-responses
  118.     wai.loadPrefs();
  119.     wai.loadQuickResps();
  120.  
  121.     //# If WAWebPlus is disabled in Preferences, quit execution
  122.     if(wap.enabled !== "true"){
  123.         return false;
  124.     }
  125.  
  126.     //# Inject css and custom HTML for GUI
  127.     wai.inject.css_man();
  128.     wai.inject.css_gui();
  129.     wai.inject.html_gui();
  130.  
  131.     //# Initialize (250ms) interval for checking whether WA has loaded
  132.     wai.intvLoaded = setInterval(wai.checkWALoaded, 250);
  133.  
  134.     //# Bind WAWebPlus after-loading init to WALoaded event
  135.     window.addEventListener("WALoaded", wai.initAfterLoading);
  136.  
  137.     //# Bind WAWebPlus closing action handler to before-unload event
  138.     window.addEventListener("beforeunload", waz.closingHandler);
  139. };
  140.  
  141. /** Setup for first-time install or newer version install
  142. * @namespace WAWebPlus.core
  143. * @method setup
  144. */
  145. waz.setup = function (){
  146.  
  147.     //# Create indicator and version information in permanent local storage
  148.     wp.setItem("WAWebPlus", "true");
  149.     wp.setItem("WAWebPlus:version", waz.version);
  150.  
  151.     //# Load preferences from defaults and write to permanent local storage
  152.     for (pref in was.prefs){
  153.  
  154.         //# Safety check for for-in array loop (https://stackoverflow.com/a/9329476)
  155.         if(was.prefs.hasOwnProperty(pref)){
  156.  
  157.             //# Set item in permanent local storage
  158.             wp.setItem("WAWebPlus:p:" + pref, was.prefs[pref]);
  159.         }
  160.     }
  161.  
  162.     //# Load quick responses from defaults and write to permanent local storage
  163.     for (qresp in was.qresps){
  164.  
  165.         //# Safety check for for-in array loop (https://stackoverflow.com/a/9329476)
  166.         if(was.qresps.hasOwnProperty(qresp)){
  167.  
  168.             //# Set item in local storage
  169.             wp.setItem("WAWebPlus:q:" + qresp, was.qresps[qresp]);
  170.         }
  171.     }
  172. };
  173.  
  174. /** Core function; will be called at every mouse click or every 12 seconds
  175. * @namespace WAWebPlus.core
  176. * @method run
  177. */
  178. waz.run = function (){
  179.  
  180. };
  181.  
  182. // ===========================================================================
  183.  
  184. /** Direct user call to disable WAWebPlus
  185. * @namespace WAWebPlus
  186. * @method disable
  187. */
  188. wawp.disable = function (){
  189.  
  190.     //# Write disabled property to permanent local storage
  191.     wp.setItem("WAWebPlus:p:enabled", false);
  192.  
  193.     //# Reload WAWeb to kill timers etc.
  194.     wl.reload();
  195. };
  196.  
  197. /** Direct user call to enable WAWebPlus again
  198. * @namespace WAWebPlus
  199. * @method enable
  200. */
  201. wawp.enable = function (){
  202.  
  203.     //# Write disabled property to permanent local storage
  204.     wp.setItem("WAWebPlus:p:enabled", true);
  205.  
  206.     //# Reload WAWeb to initalize WAWebPlus
  207.     wl.reload();
  208. };
  209.  
  210. // ===========================================================================
  211.  
  212. /** Load preferences from permanent local storage to array cache
  213. * @namespace WAWebPlus.helper.init
  214. * @method loadPrefs
  215. */
  216. wai.loadPrefs = function (){
  217.  
  218.     //# Loop through default preferences and get the values for those preferences
  219.     for (pref in was.prefs){
  220.  
  221.         //# Safety check for for-in array loop (https://stackoverflow.com/a/9329476)
  222.         if(was.prefs.hasOwnProperty(pref)){
  223.  
  224.             //# Check if permanent local storage has that preference stored
  225.             if(wp.getItem("WAWebPlus:p:" + pref) !== null){
  226.                 wap[pref] = wp.getItem("WAWebPlus:p:" + pref);
  227.             }
  228.             else{
  229.  
  230.                 //# Preference not stored, use default value instead
  231.                 wap[pref] = was.prefs[pref];
  232.             }
  233.         }
  234.     }
  235. };
  236.  
  237. /** Load quick-responses from permanent local storage to array cache
  238. * @namespace WAWebPlus.helper.init
  239. * @method loadQuickResps
  240. */
  241. wai.loadQuickResps = function (){
  242.  
  243.     //# Loop through default preferences and get the values for those preferences
  244.     for (qresp in was.qresps){
  245.  
  246.         //# Safety check for for-in array loop (https://stackoverflow.com/a/9329476)
  247.         if(was.qresps.hasOwnProperty(qresp)){
  248.  
  249.             //# Check if permanent local storage has that preference stored
  250.             if(wp.getItem("WAWebPlus:p:" + qresp) !== null){
  251.                 waq[qresp] = wp.getItem("WAWebPlus:p:" + qresp);
  252.             }
  253.             else{
  254.  
  255.                 //# Preference not stored, use default value instead
  256.                 waq[qresp] = was.qresps[qresp];
  257.             }
  258.         }
  259.     }
  260. };
  261.  
  262.  
  263. /** Event to be fired when WAWeb has finished loading the main interface
  264. * @namespace WAWebPlus.helper.init
  265. * @event WALoaded
  266. */
  267. wai.WALoaded = new Event("WALoaded");
  268.  
  269. /** Test whether main interface of WAWeb has finished loading
  270. * @namespace WAWebPlus.helper.init
  271. * @method checkWALoaded
  272. */
  273. wai.checkWALoaded = function (){
  274.  
  275.     //# Test for existence of app-div
  276.     if(!!document.querySelector("div.app")){
  277.  
  278.         //# If existing, fire "loaded" event
  279.         window.dispatchEvent(wai.WALoaded);
  280.         return true;
  281.     }
  282.     return false;
  283. };
  284.  
  285. /** Function called after WA has finished loading
  286. * @namespace WAWebPlus.helper.init
  287. * @method initAfterLoading
  288. */
  289. wai.initAfterLoading = function (){
  290.  
  291.     //# Clear interval for checking whether WAWeb has loaded
  292.     clearInterval(wai.intvLoaded);
  293.  
  294.     //# Bind WAWebPlus run to mouse-clicks and to a 12 seconds interval
  295.     window.addEventListener("mouseup", waz.run);
  296.     wai.mainInterval = setInterval(waz.run, 12000);
  297.  
  298.     //# Start first WAWebPlus run
  299.     waz.run();
  300. };
  301.  
  302. // ===========================================================================
  303.  
  304. /** Inject css manipulations into page
  305. * @namespace WAWebPlus.helper.init.inject
  306. * @method css_man
  307. */
  308. wai.inject.css_man = function (){
  309.  
  310.     //# Create string for CSS manipulations
  311.     let csstr = "";
  312.  
  313.     //# Image roundness
  314.     csstr += ".avatar, .avatar-image, .avatar-overlay, .preview-image, .metadata-icon, .bubble-audio .preview { border-radius: " + wap.css_imgRoundness + " !important; } ";
  315.  
  316.     //# Custom color background topbar
  317.     if(wap.css_colorbarTop === "true"){
  318.         csstr += ".app-wrapper::after { background-color: " + wap.css_colorbarTopColor + " !important; } ";
  319.     }
  320.     else{
  321.         csstr += ".app-wrapper::after { display:none !important; } ";
  322.     }
  323.  
  324.     //# Wide text bubbles
  325.     if(wap.man_wideTextBubbles === "true"){
  326.         csstr += ".message-in, .message-out { max-width: 100% !important; } ";
  327.     }
  328.  
  329.     //# Chat background
  330.     if(wap.man_chatBackground === "true"){
  331.         if(wap.man_chatBackground_img === "true"){
  332.             csstr += ".pane-chat-msgs.pane-chat-body { background-image: url('" + wap.css_chatBackground_img + "') !important; background-size:cover !important; background-position:fixed !important; background-repeat: none; } ";
  333.         }
  334.         else{
  335.             csstr += ".pane-chat-msgs.pane-chat-body { background-color: " + wap.css_chatBackground_color + " !important; } ";
  336.         }
  337.     }
  338.  
  339.     //// TODO
  340.  
  341.     //# Create style-Element, apply style-string as content, append to page
  342.     let cssel = document.createElement("style");
  343.     cssel.innerHTML = csstr;
  344.     cssel.id = "WAWebPlus_css_mod";
  345.     document.body.appendChild(cssel);
  346. };
  347.  
  348. /** Inject css for GUI into page
  349. * @namespace WAWebPlus.helper.init.inject
  350. * @method css_gui
  351. */
  352. wai.inject.css_gui = function (){
  353.     //// TODO
  354. };
  355.  
  356. /** Inject html for gui into page
  357. * @namespace WAWebPlus.helper.init.inject
  358. * @method html_gui
  359. */
  360. wai.inject.html_gui = function (){
  361.     //// TODO
  362. };
  363.  
  364. // ===========================================================================
  365.  
  366. /** Compare two version strings
  367. * @namespace WAWebPlus.helper
  368. * @method compVersionStr
  369. * @param str left String to test
  370. * @param str right String to test left against
  371. * @return obj Object with comparison result
  372. */
  373. wah.compareVersionStr = function (left, right){
  374.  
  375.     // Adapted from https://stackoverflow.com/a/6832706/3144667
  376.     var nft = false;
  377.  
  378.     //# Check if same
  379.     if(left === right){
  380.         var res = 0;
  381.     }
  382.     //# Split at the dots
  383.     var left_comp = left.split(".");
  384.     var right_comp = right.split(".");
  385.  
  386.     //# Calculate minimum version string difference
  387.     var len = Math.min(left_comp.length, right_comp.length);
  388.  
  389.     //# Loop through parts of version string
  390.     for(var i = 0; i < len; i++){
  391.         if(parseInt(left_comp[i]) > parseInt(right_comp[i])){
  392.             var res = 1;
  393.             var nft = true;
  394.         }
  395.         if(parseInt(left_comp[i]) < parseInt(right_comp[i])){
  396.             var res = -1;
  397.             var nft = true;
  398.         }
  399.     }
  400.  
  401.     //# Check for length of ver string otherwise - longer is newer
  402.     if(!nft){
  403.         if(left_comp.length > right_comp.length){
  404.             var res = 1;
  405.         }
  406.         if(left_comp.length < right_comp.length){
  407.             var res = -1;
  408.         }
  409.     }
  410.  
  411.     //# Parse result to object
  412.     switch(res){
  413.         case 0:
  414.             var obj = { isOlder: false, isNewer: false, isSame: true, numeric:0 };
  415.             break;
  416.         case 1:
  417.             var obj = { isOlder: false, isNewer: true, isSame: false, numeric:1 };
  418.             break;
  419.         case -1:
  420.             var obj = { isOlder: true, isNewer: false, isSame: false, numeric:-1 };
  421.             break;
  422.         default:
  423.             var obj = { isOlder: false, isNewer: false, isSame: false, numeric:2 };
  424.             break;
  425.     }
  426.     return obj;
  427. };
  428.  
  429. /** Determine if startscreen is opened
  430. * @namespace WAWebPlus.helper
  431. * @method startScreenOpened
  432. * @return bool
  433. */
  434. wah.startScreenOpened = function (){
  435.  
  436.     //# Return state of existence of start screen
  437.     return !!document.querySelector("div.intro.pane-body");
  438. };
  439.  
  440. /** Determine if a chat is opened
  441. * @namespace WAWebPlus.helper
  442. * @method chatOpened
  443. * @return bool
  444. */
  445. wah.chatOpened = function (){
  446.  
  447.     //# Return state of existence of start screen
  448.     return !!document.querySelector("div.pane-chat-tile");
  449. };
  450.  
  451.  
  452.  
  453.  
  454. // ===========================================================================
  455.  
  456. /* Finally start everything on load */
  457. window.addEventListener("load", WAWebPlus.core.init);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement