您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
The CodinGame web-chat without CodinGame.
当前为
// ==UserScript== // @name CGChat // @namespace BlaiseEbuth // @match https://www.codingame.com/* // @grant none // @version 1.3.0 // @author BlaiseEbuth // @description The CodinGame web-chat without CodinGame. // @icon https://i.imgur.com/E39sADi.png // ==/UserScript== /* CGChat is an externalization as a standalone window of the CodinGame's web chat. Copyright (C) 2020 BlaiseEbuth This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ 'use strict'; // Be strict ! // A map to store the clicked links. var openedLinks = {}; // A function that set "CGChat" as window's title. function setTitle() { // The window's title is defined by the page's <title> tag. var title = document.getElementsByTagName("title"); if(title.length == 1) // If the page is loaded. { // We change the title. title[0].innerHTML = "CGChat"; } } // A function that clean the connexion page. function signin() { // Select all elements that are not related to the connexion process: var nav = document.getElementById("navigation"); // The navigation bar. var cookies = document.getElementsByClassName("cg-cookies-banner"); // The cookies notification. var footer = document.getElementsByClassName("cg-login-form_footer"); // The login form footer that allow to create a new account. // Hide all of this uselles stuff. if(nav != null)nav.style.display = "none"; if(cookies.length == 1)cookies[0].style.display = "none"; if(footer.length == 1)footer[0].style.display = "none"; } // A function that adapt the height of the textarea depending on its content. function adjustMessageBox() { // We get the textarea. var messBox = document.getElementById("chat-input"); // We compute the height difference between the textarea and its content. var heightDiff = messBox.scrollHeight - messBox.clientHeight; // If there is a difference: if(heightDiff > 0) { // We get the CSS height value of the textarea. var messBoxStyle = window.getComputedStyle(messBox); var messBoxHeight = messBoxStyle.getPropertyValue("height"); var intHeight = parseInt(messBoxHeight.substr(0, messBoxHeight.length - 2)); // If this height is lesser than 150px (the max height we allow): if(intHeight < 150) { // We get the absolute bottom position of the messages zone. var messWrap = document.getElementsByClassName("messages-wrap")[0]; var messWrapStyle = window.getComputedStyle(messWrap); var messWrapBot = messWrapStyle.getPropertyValue("bottom"); // We compute the new height of the textarea and the one of the chat footer which contain it. var newHeight = intHeight + heightDiff + 10; var newBottom = parseInt(messWrapBot.substr(0, messWrapBot.length - 2)) + heightDiff + 10; // We adjust the size and the position of the elements. messWrap.style.bottom = newBottom.toString() + "px"; document.getElementsByClassName("footer")[0].style.height = newBottom.toString() + "px"; document.getElementsByClassName("send-form")[0].style.height = newHeight.toString() + "px"; messBox.style.height = newHeight.toString() + "px"; // We get the messages container. var messView = document.getElementById("messages"); // And we set the scroll bar to the end. messView.scrollTop = messView.scrollHeight; } } // If the textarea is empty: if(messBox.value == "") { // We reset all the values to the defaults. document.getElementsByClassName("messages-wrap")[0].style.bottom = "125px"; document.getElementsByClassName("footer")[0].style.height = "125px"; document.getElementsByClassName("send-form")[0].style.height = "45px"; messBox.style.height = "45px"; } } // The function that manage all the chat-related actions. function chat() { // If we are in the application and jquerry is not loaded yet. if(window.isNwjs && document.getElementById("jquery") == null) { // We get the page's <head> element. var head = document.getElementsByTagName("head"); if(head.length == 1) // If head is defined. { // We create a <script> element. var jquery = document.createElement("script"); // With the "jquerry" id. jquery.id = "jquery"; jquery.type = "text/javascript"; jquery.src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"; // And we add it to the page's <head>. head[0].appendChild(jquery); } } // We select the navigation bar and the site's content. var leftCol = document.getElementsByClassName("left-column"); var nav = document.getElementById("navigation"); // If they exist we delete them. if(leftCol.length == 1)leftCol[0].style.display = "none"; if(nav != null)nav.style.display = "none"; // We select the chat's containers. var wrapper = document.getElementsByClassName("chat-wrapper"); var chat = document.getElementById("chat"); // If they exist, we make them occupy the full window. if(wrapper.length == 1)wrapper[0].style.cssText = "width:100% !important"; if(chat != null)chat.style.cssText = "display:flex !important"; // We check if the chat is minimized. var small = document.getElementsByClassName("small-chat"); // If yes, we maximize it. if(small.length == 1)small[0].click(); // We select the chat itself. var chatClass = document.getElementsByClassName("chat"); // And some of its elements which need to be removed: var discord = document.getElementsByTagName("cg-discord-disclaimer"); // The discord disclaimer. var hideWrapper = document.getElementsByClassName("hide-wrapper"); // The "Hide/Show" button. var help = document.getElementsByClassName("help-center"); // The help center. // We make the chat occupy 100% of its container. if(chatClass.length == 1)chatClass[0].style.width = "100%"; // And we delete the useless stuff. if(discord.length == 1)discord[0].style.display = "none"; if(hideWrapper.length == 1)hideWrapper[0].style.display = "none"; if(help.length == 1)help[0].style.display = "none"; // We get the settings popup. var settings = document.getElementsByClassName("settings-popup"); if(settings.length == 1) // If it exist. { for(var i = 0; i < 3; i++) { // We delete the 3 first elements to only keep the theme settings. settings[0].children[i].style.display = "none"; } } // If the refresh button does not exist yet. if(document.getElementById("refreshButton") == null) { // We create it. var refreshButton = document.createElement("span"); refreshButton.id = "refreshButton"; refreshButton.style.cssText = "display : inline-block;\ width : 15px;\ height : 15px;\ margin-left : 8px;\ background-image : url('https://i.imgur.com/rDqWLLQ.png');\ background-size : contain;"; // As well as a wrapper, for display purposes. var buttonWrapper = document.createElement("span"); buttonWrapper.classList.add("button-wrapper"); buttonWrapper.setAttribute("onClick", "window.location.reload(true)"); buttonWrapper.title = "Reload"; // We get the chat's settings bar. var settingsBar = document.getElementsByClassName("settings-bar"); // And we add the button and its wrapper to it. buttonWrapper.appendChild(refreshButton); settingsBar[0].appendChild(buttonWrapper); } // We get the messages container. var messages = document.getElementById("messages"); if(messages != null) // If it is defined. { // We make the messages occupy 100% of their container. messages.style.width = "100%"; if(window.isNwjs) // If in the application. { // We select all the links in the messages. var links = messages.getElementsByTagName("a"); if(links.length > 0) // If there's at least one link. { // We set a click event on each of those links. $('a[target=_blank]').on('click', function() { // If the link is not in the openedLinks map. if(!(this.href in openedLinks)) { // We open it in a browser. require('nw.gui').Shell.openExternal(this.href); // And we add the URL in the map with a value of 100. openedLinks[this.href] = 100; } return false; }); } } } adjustMessageBox(); } // The main() function. var main = function() { // If we don't know if we are in the application or the browser extension. if(window.isNwjs == null) { try { // We call a NWJS specific knack and if it is defined we set the 'isNwjs' variable to true. window.isNwjs = (typeof require('nw.gui') !== "undefined"); } catch(e) { // If not, we set the 'isNwjs' variable to false; window.isNwjs = false; } } setTitle(); // Change the window's title. for(var l in openedLinks) // For each URL in the map. { openedLinks[l]--; // We decrease its countdown. if(openedLinks[l] == 0) // If the countdown reach 0. { // We delete the URL from the map. delete openedLinks[l]; } } // Get the current URI. var path = window.location.pathname; if(path == "/start") // If not logged in. { // Go to the connexion page. window.location.replace("/signin"); } else if(path == "/signin") // If on the connexion page. { // Call the signin() function. signin(); } else // In other cases. { // Lets chat ! chat(); } } // Repeat the main() function every 100ms. setInterval(main, 100);