diff --git a/app/Models/Key.php b/app/Models/Key.php index 7748e1046cfc1de1fa3842435556a12c5bb2cf94..4dbc633abbe121595fb3a63f3028b969300d5c65 100644 --- a/app/Models/Key.php +++ b/app/Models/Key.php @@ -2,19 +2,23 @@ namespace App\Models; +use Illuminate\Support\Facades\Redis; +use Request; + class Key { public $key; public $status; # valid key = true, invalid key = false, unidentified key = null - private $keyserver = "https://key.metager.de/"; + //private $keyserver = "https://key.metager.de/"; + private $keyserver = "https://dev.key.metager.de/"; public function __construct($key, $status = null) { $this->key = $key; $this->status = $status; - if (getenv("APP_ENV") !== "production") { + /*if (getenv("APP_ENV") !== "production") { $this->keyserver = "https://dev.key.metager.de/"; - } + }*/ } # always returns true or false @@ -22,6 +26,29 @@ class Key { if ($this->key !== '' && $this->status === null) { $this->updateStatus(); + if(empty($this->status)){ + // The user provided an invalid key which we will log to fail2ban + $fail2banEnabled = config("metager.metager.fail2ban_enabled"); + if(empty($fail2banEnabled) || !$fail2banEnabled || !env("fail2banurl", false) || !env("fail2banuser") || !env("fail2banpassword")){ + return false; + } + + // Submit fetch job to worker + $mission = [ + "resulthash" => "captcha", + "url" => env("fail2banurl") . "/mgkeytry/", + "useragent" => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0", + "username" => env("fail2banuser"), + "password" => env("fail2banpassword"), + "headers" => [ + "ip" => Request::ip() + ], + "cacheDuration" => 0, + "name" => "Captcha", + ]; + $mission = json_encode($mission); + Redis::rpush(\App\MetaGer::FETCHQUEUE_KEY, $mission); + } } if ($this->status === null || $this->status === false) { return false; @@ -33,10 +60,23 @@ class Key public function updateStatus() { + $authKey = base64_encode(env("KEY_USER", "test") . ':' . env("KEY_PASSWORD", "test")); + + $opts = array( + 'http' => array( + 'method' => 'GET', + 'header' => 'Authorization: Basic ' . $authKey , + ), + ); + $context = stream_context_create($opts); + try { - $link = $this->keyserver . urlencode($this->key) . "/request-permission/api-access"; - $result = json_decode(file_get_contents($link)); - if ($result->{'api-access'} == true) { + $link = $this->keyserver . "v2/key/". urlencode($this->key); + $result = json_decode(file_get_contents($link, false, $context)); + if ($result->{'apiAccess'} == 'unlimited') { + $this->status = true; + return true; + } else if ($result->{'apiAccess'} == 'normal' && $result->{'adFreeSearches'} > 0){ $this->status = true; return true; } else { @@ -50,13 +90,17 @@ class Key public function requestPermission() { + $authKey = base64_encode(env("KEY_USER", "test") . ':' . env("KEY_PASSWORD", "test")); $postdata = http_build_query(array( 'dummy' => 0, )); $opts = array( 'http' => array( 'method' => 'POST', - 'header' => 'Content-type: application/x-www-form-urlencoded', + 'header' => [ + 'Content-type: application/x-www-form-urlencoded', + 'Authorization: Basic ' . $authKey + ], 'content' => $postdata, ), ); @@ -64,9 +108,9 @@ class Key $context = stream_context_create($opts); try { - $link = $this->keyserver . urlencode($this->key) . "/request-permission/api-access"; + $link = $this->keyserver . "v2/key/". urlencode($this->key) . "/request-permission"; $result = json_decode(file_get_contents($link, false, $context)); - if ($result->{'api-access'} == true) { + if ($result->{'apiAccess'} == true) { return true; } else { $this->status = false; diff --git a/resources/js/donation.js b/resources/js/donation.js index f6ad022a560959d2701fc652228fed19b748d187..9c649d0b1913578c145a6627ba5f7dd1e2e824eb 100644 --- a/resources/js/donation.js +++ b/resources/js/donation.js @@ -1,7 +1,9 @@ -$(document).ready(function () { - $(".amount-custom").click(function () { - setTimeout(function () { - $("#custom-amount").focus(); - }, 100) +document.addEventListener("DOMContentLoaded", (event) => { + document.querySelectorAll(".amount-custom").forEach(element => { + element.onclick = (e) => { + setTimeout(() => { + document.querySelector("#custom-amount").focus(); + }, 100); + } }); }); \ No newline at end of file diff --git a/resources/js/keyboardNavigation.js b/resources/js/keyboardNavigation.js index 70c2e476eb0e51f27fb449f984e11f0a98c0f1c0..d22490402f42c65e3f321094030b552d479f6367 100644 --- a/resources/js/keyboardNavigation.js +++ b/resources/js/keyboardNavigation.js @@ -2,27 +2,27 @@ * Flag ctrlInfo is used for initial display of the navigation box */ var ctrlInfo = false; - -$(document).ready(function () { +document.addEventListener("DOMContentLoaded", (event) => { // Add entry point for tabbing to the first result - $('.result, .ad').first().attr("id", "results-entry"); + document.querySelectorAll('.result, .ad')[0].setAttribute("id", "results-entry"); // Initially focus the searchbar }); /** * Simulate a click on enter keypress when focused on labels */ -$('label').on('keydown', function (e) { - if (e.keyCode == '13') { - $(this).click(); - $('a', this) +document.querySelectorAll('label').forEach((element) => { + element.onkeydown = (e) => { + if (e.keyCode == '13') { + e.srcElement.click(); + } } }); /** * Handles tab keypress and escape keypress */ -$(document).on('keydown', function (e) { +document.onkeydown = (e) => { e = e || window.event; // On first tab keypress there is special behaviour and the ctrlInfo flag is set if (!ctrlInfo && e.keyCode == '9') { @@ -32,14 +32,15 @@ $(document).on('keydown', function (e) { } else if (e.keyCode == '27') { escKeyPressed(); } -}); +}; + /** * Shows the navigation box and focuses the first <a> tag */ function focusNavBox() { - $('#keyboard-nav-info').show(); - $('#keyboard-nav-info a').first().focus(); + document.querySelector("#keyboard-nav-info").style.display = "inherit"; + document.querySelectorAll("#keyboard-nav-info a")[0].focus(); } /** @@ -47,34 +48,36 @@ function focusNavBox() { */ function escKeyPressed() { focusNavBox(); - $('input[type="checkbox"]').removeAttr('checked'); + document.querySelectorAll('input[type="checkbox"]').forEach((element) => { + element.checked = false; + }); } /** * Focuses the first <a> tag of the first result */ function focusResults() { - $('#results-entry .result-title a').focus(); + document.querySelector('#results-entry .result-title a').focus(); } /** * Focuses the first <a> tag of the focus options */ function focusFoki() { - $('#foki a').first().focus(); + document.querySelector("#foki a").focus(); } /** * Focuses the search settings */ function focusSettings() { - $('#settings a').focus(); + document.querySelector('#settings a').focus(); } /** * Focuses the first <tag> of the sidebar */ function focusNavigation() { - $('#sidebarToggle').prop('checked', true); - $('.sidebar-list a').first().focus(); + document.querySelector("#sidebarToggle").checked = true; + document.querySelector(".sidebar-list a").focus(); } \ No newline at end of file diff --git a/resources/js/result-saver.js b/resources/js/result-saver.js index 7776f026fbf06928a7df376f786fad53002b1e4d..07703da5c63afe4c347808ff673692a14cd53169 100644 --- a/resources/js/result-saver.js +++ b/resources/js/result-saver.js @@ -1,16 +1,33 @@ +if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) { + // Yes, there's really no need for `Object.defineProperty` here + NodeList.prototype.forEach = Array.prototype.forEach; +} + /** * All results are stored in the global object 'results' - */ + */ results = new Results(); -$(document).ready(function () { +document.addEventListener("DOMContentLoaded", (event) => { + if(document.readyState == 'complete'){ + initResultSaver(); + }else{ + document.addEventListener("readystatechange", e => { + if (document.readyState === 'complete') { + initResultSaver(); + } + }); + } +}); + +function initResultSaver() { // Add all saved results results.loadAllResults(); // Sort all results results.sortResults(); // Update the visualization results.updateResultPageInterface(); -}); +} /** * Load all saved results and sort them @@ -99,7 +116,7 @@ Results.prototype.deleteAllResults = function () { } } // Remove all keys saved in the keys array from localstorage - $.each(keys, function (index, value) { + keys.forEach(value => { localStorage.removeItem(value); }); }; @@ -110,22 +127,25 @@ Results.prototype.deleteAllResults = function () { Results.prototype.updateResultPageInterface = function () { if (this.results.length === 0) { // If there are no saved-results left, remove the savedFoki element - $('#savedFoki').remove(); + document.querySelectorAll('#savedFoki').forEach(element => { + element.remove(); + }); return; } - if ($('#savedFoki').length === 0) { + if (document.querySelector('#savedFoki') == null || document.querySelector('#savedFoki').length === 0) { // If there is no savedFoki element yet, create it - var tabPanel = $('\ - <div id="savedFoki">\ - <h1>' + t('result-saver.title') + '</h1>\ - </div>\ - '); - $('#additions-container').prepend(tabPanel); + var template = document.createElement("div"); + template.innerHTML = '<div id="savedFoki">\ + <h1>' + t('result-saver.title') + '</h1>\ + </div>'; + var tabPanel = template.firstChild; + document.querySelector('#additions-container').prepend(tabPanel); } else { // If there already is a savedFoki element, get it - $('#savedFoki').html(''); - var tabPanel = $('#savedFoki'); + var tabPanel = document.querySelector("#savedFoki"); + tabPanel.innerHTML = ""; } + // Add the full savedFoki element to the tabPanel this.addToContainer(tabPanel); }; @@ -138,49 +158,50 @@ Results.prototype.updateResultPageInterface = function () { Results.prototype.addToContainer = function (container) { // Create the saver-options element, which is a bar containing // options for filtering, sorting and deleting all results - var options = $('\ - <div id="saver-options">\ - <div class="saver-option saver-option-filter">\ - <input style="font-family: \'Font Awesome 5 Free\', sans-serif;" class="form-control" type="text" placeholder=" ' + t('result-saver.filter') + '">\ - </div>\ - <div class="saver-option saver-option-sort">\ - <select class="form-control" style="font-family: \'Font Awesome 5 Free\', sans-serif;">\ - <option value="chronological" style="font-family: \'Font Awesome 5 Free\', sans-serif;"> ' + t('result-saver.sort.chronological') + '</option>\ - <option value="rank" style="font-family: \'Font Awesome 5 Free\', sans-serif;"> ' + t('result-saver.sort.ranking') + '</option>\ - <option value="alphabetical" style="font-family: \'Font Awesome 5 Free\', sans-serif;"> ' + t('result-saver.sort.alphabetical') + '</option>\ - </select>\ - </div>\ - <div class="saver-option saver-option-delete">\ - <button class="btn btn-danger btn-md" id="saver-options-delete-btn">\ - <i class="fa fa-trash-o" aria-hidden="true"></i>\ - ' + t('result-saver.deleteAll') + '\ - </button>\ - </div>\ + var template = document.createElement("div"); + + template.innerHTML = '<div id="saver-options">\ + <div class="saver-option saver-option-filter">\ + <input style="font-family: \'Font Awesome 5 Free\', sans-serif;" class="form-control" type="text" placeholder=" ' + t('result-saver.filter') + '">\ + </div>\ + <div class="saver-option saver-option-sort">\ + <select class="form-control" style="font-family: \'Font Awesome 5 Free\', sans-serif;">\ + <option value="chronological" style="font-family: \'Font Awesome 5 Free\', sans-serif;"> ' + t('result-saver.sort.chronological') + '</option>\ + <option value="rank" style="font-family: \'Font Awesome 5 Free\', sans-serif;"> ' + t('result-saver.sort.ranking') + '</option>\ + <option value="alphabetical" style="font-family: \'Font Awesome 5 Free\', sans-serif;"> ' + t('result-saver.sort.alphabetical') + '</option>\ + </select>\ + </div>\ + <div class="saver-option saver-option-delete">\ + <button class="btn btn-danger btn-md" id="saver-options-delete-btn">\ + <i class="fa fa-trash-o" aria-hidden="true"></i>\ + ' + t('result-saver.deleteAll') + '\ + </button>\ </div>\ - '); + </div>'; + var options = template.firstChild; // Set the initial value for the sorting select, based on this.sort - $(options).find('select').val(this.sort); + options.querySelector("select").value = this.sort; // Add the saver-options element to the given container - $(container).append(options); + container.append(options); /* ~~~ Filter ~~~ */ // When the user is done typing into the filter input field, // Filter all results, only showing ones that contain the filer - $(options).find('input').keyup(function () { + options.querySelectorAll("input").forEach(element => { // Get the entered filter - var search = $(this).val(); + var search = element.value; // Hide all results that do not contain the entered filter - $('#savedFoki .saved-result-content').each(function (index, value) { + document.querySelectorAll('#savedFoki .saved-result-content').forEach(value => { // check for filter in all of the elements html-content - var html = $(this).html(); + var html = value.innerHTML; if (html.toLowerCase().indexOf(search.toLowerCase()) === -1) { // hide entire result block - $(value).parent().addClass('hidden'); + value.parentNode.classList.add('hidden'); } else { // show entire result block - $(value).parent().removeClass('hidden'); + value.parentNode.classList.remove("hidden"); } }); }); @@ -188,23 +209,27 @@ Results.prototype.addToContainer = function (container) { /* ~~~ Sort ~~~ */ // When the sorting select value is changed, // Sort all results with the selected sorting function and update their appearance - $(options).find('select').change(function () { - var sort = $(this).val(); - results.sort = sort; - results.sortResults(sort).updateResultPageInterface(); + options.querySelectorAll("select").forEach(element => { + element.onchange = (e) => { + var sort = element.value; + results.sort = sort; + results.sortResults(sort).updateResultPageInterface(); + }; }); /* ~~~ Delete ~~~ */ // When the delete button is clicked, // Delete all results and update their appearance - $(options).find('#saver-options-delete-btn').click(function (event) { - results.deleteAllResults(); - results.updateResultPageInterface(); + options.querySelectorAll('#saver-options-delete-btn').forEach(element => { + element.onclick = (e) => { + results.deleteAllResults(); + results.updateResultPageInterface(); + } }); // Append all results available - $.each(this.results, function (index, result) { - $(container).append(result.toHtml()); + this.results.forEach(result => { + container.append(result.toHtml()); }); }; @@ -272,7 +297,7 @@ Result.prototype.load = function () { this.anonym = result.anonym; this.description = result.description; this.added = result.added; - this.index = -result.index; + this.index = result.index; this.rank = result.rank; return true; @@ -351,46 +376,51 @@ Result.prototype.remove = function () { */ Result.prototype.toHtml = function () { // Create the saved-result element - var result = $('\ - <div class="saved-result result" data-count="' + this.index + '">\ - <div class="saved-result-remover remover" title="' + t('result-saver.delete') + '">\ - <i class="fa fa-trash"></i>\ - </div>\ - <div class="saved-result-content">\ - <div class="result-header">\ - <div class="result-headline">\ - <h2 class="result-title">\ - <a href="' + this.link + '" target="_blank" data-count="1" rel="noopener">\ - ' + this.title + '\ - </a>\ - </h2>\ - <a class="result-hoster" href="' + this.hosterLink + '" target="_blank" data-count="1" rel="noopener">\ - ' + this.hosterName + '\ + var template = document.createElement("div"); + template.innerHTML = '<div class="saved-result result" data-count="' + this.index + '">\ + <div class="saved-result-remover remover" title="' + t('result-saver.delete') + '">\ + <i class="fa fa-trash"></i>\ + </div>\ + <div class="saved-result-content">\ + <div class="result-header">\ + <div class="result-headline">\ + <h2 class="result-title">\ + <a href="' + this.link + '" target="_blank" data-count="1" rel="noopener">\ + ' + this.title + '\ </a>\ - </div>\ - <a class="result-link" href="' + this.link + '" target="_blank" rel="noopener">\ - ' + this.anzeigeLink + '\ - </a>\ - <div class="result-body">\ - <div class="description">' + this.description + '</div>\ - </div>\ - <div class="result-footer">\ - <a class="result-open" href="' + this.link + '" target="_self" rel="noopener">\ - ' + t('result-saver.save.this') + '\ - </a>\ - <a class="result-open" href="' + this.link + '" target="_blank" rel="noopener">\ - ' + t('result-saver.save.newtab') + '\ - </a>\ - <a class="result-open-proxy" onmouseover="$(this).popover(\'show\');" onmouseout="$(this).popover(\'hide\');" data-toggle="popover" data-placement="auto right" data-container="body" data-content="Der Link wird anonymisiert geöffnet. Ihre Daten werden nicht zum Zielserver übertragen. Möglicherweise funktionieren manche Webseiten nicht wie gewohnt." href="' + this.anonym + '" target="_blank" rel="noopener" data-original-title="" title="">\ - ' + t('result-saver.save.anonymous') + '\ + </h2>\ + <a class="result-hoster" href="' + this.hosterLink + '" target="_blank" data-count="1" rel="noopener">\ + ' + this.hosterName + '\ </a>\ </div>\ + <a class="result-link" href="' + this.link + '" target="_blank" rel="noopener">\ + ' + this.anzeigeLink + '\ + </a>\ + <div class="result-body">\ + <div class="description">' + this.description + '</div>\ + </div>\ + <div class="result-footer">\ + <a class="result-open" href="' + this.link + '" target="_self" rel="noopener">\ + ' + t('result-saver.save.this') + '\ + </a>\ + <a class="result-open" href="' + this.link + '" target="_blank" rel="noopener">\ + ' + t('result-saver.save.newtab') + '\ + </a>\ + <a class="result-open-proxy" href="' + this.anonym + '" target="_blank" rel="noopener" title="Der Link wird anonymisiert geöffnet. Ihre Daten werden nicht zum Zielserver übertragen. Möglicherweise funktionieren manche Webseiten nicht wie gewohnt.">\ + ' + t('result-saver.save.anonymous') + '\ + </a>\ </div>\ - </div>'); + </div>\ + </div>'; + + var result = template.firstChild; // Add a click listener to the remover, that removes the result on click - $(result).find('.remover').click({ caller: this }, function (event) { - event.data.caller.remove(); + var caller = this; + result.querySelectorAll(".remover").forEach(element => { + element.onclick = (e) => { + caller.remove(); + }; }); return result; @@ -402,17 +432,17 @@ Result.prototype.toHtml = function () { */ function resultSaver(index) { // Remember the original result element - var original = $('.result[data-count=' + index + ']'); + var original = document.querySelector('.result[data-count="' + index + '"]'); // Read the necessary data from the result html - var title = $('.result[data-count=' + index + '] .result-title a').html().trim(); - var link = $('.result[data-count=' + index + '] .result-title a').attr('href').trim(); - var hosterName = $('.result[data-count=' + index + '] .result-hoster').html().trim(); - var hosterLink = $('.result[data-count=' + index + '] .result-hoster').attr('href'); - hosterLink = hosterLink?hosterLink.trim():"#"; - var anzeigeLink = $('.result[data-count=' + index + '] .result-link').html().trim(); - var description = $('.result[data-count=' + index + '] .result-description').html().trim(); - var anonym = $('.result[data-count=' + index + '] .result-open-proxy').attr('href').trim(); + var title = document.querySelector('.result[data-count="' + index + '"] .result-title a').innerHTML.trim(); + var link = document.querySelector('.result[data-count="' + index + '"] .result-title a').href.trim(); + var hosterName = document.querySelector('.result[data-count="' + index + '"] .result-subheadline > a').title.trim(); + var hosterLink = document.querySelector('.result[data-count="' + index + '"] .result-hoster').href; + hosterLink = hosterLink ? hosterLink.trim() : "#"; + var anzeigeLink = document.querySelector('.result[data-count="' + index + '"] .result-link').innerHTML.trim(); + var description = document.querySelector('.result[data-count="' + index + '"] .result-description').innerHTML.trim(); + var anonym = document.querySelector('.result[data-count="' + index + '"] .result-open-proxy').href.trim(); // Create the result object var result = new Result(title, link, hosterName, hosterLink, anzeigeLink, description, anonym, index, null); @@ -427,8 +457,8 @@ function resultSaver(index) { results.updateResultPageInterface(); // Animate the result transfer to the saved results - var transferTarget = $('.saved-result[data-count=' + index + ']'); - if (original.length > 0 && transferTarget.length > 0) { - $(original).transfer({ to: transferTarget, duration: 1000 }); - } + // var transferTarget = $('.saved-result[data-count=' + index + ']'); + // if (original.length > 0 && transferTarget.length > 0) { + // $(original).transfer({ to: transferTarget, duration: 1000 }); + // } } diff --git a/resources/js/scriptResultPage.js b/resources/js/scriptResultPage.js index 82d24b3f85beeed5c31f4d4d37ef0954579b27ec..5ec468e5f142a632307a279e0c037b75781871d9 100644 --- a/resources/js/scriptResultPage.js +++ b/resources/js/scriptResultPage.js @@ -1,65 +1,84 @@ -$(document).ready(function () { +document.addEventListener("DOMContentLoaded", (event) => { + if(document.readyState == 'complete'){ + initialize(); + }else{ + document.addEventListener("readystatechange", e => { + if (document.readyState == 'complete') { + initialize(); + } + }); + } +}); + +function initialize(){ botProtection(); enableFormResetter(); loadMoreResults(); -}); +} + + +let link, newtab, top; function botProtection() { - $('.result').find('a').click(function (e) { - var link = $(this).attr('href'); - var newtab = false; - var top = false; - if ($(this).attr('target') == '_blank' || e.ctrlKey || e.metaKey) { - newtab = true; - } else if ($(this).attr('target') == "_top") { - top = true; - } + document.querySelectorAll(".result a").forEach((element) => { + element.onclick = e => { + link = element.href; + newtab = false; + top = false; + if (element.target == '_blank' || e.ctrlKey || e.metaKey) { + newtab = true; + } else if (element.target == "_top") { + top = true; + } - $.ajax({ - url: '/img/cat.jpg', - type: 'post', - data: { - mm: $('meta[name=mm]').attr('content') - }, - timeout: 2000 - }) - .always(function () { - if (!newtab) { - if (top) { - window.top.location.href = link; - } else { - document.location.href = link; + fetch("/img/cat.png", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + body: "mm=" + document.querySelector('meta[name="mm"]').content + }) + .then(response => { + if (!newtab) { + if (top) { + window.top.location.href = link; + } else { + document.location.href = link; + } } - } - }); - return newtab; + }); + return newtab; + }; }); } function enableFormResetter() { - var deleteButton = $("#search-delete-btn"); + var deleteButton = document.querySelector("#search-delete-btn"); var timeout = null; - $(deleteButton).click(function () { + + deleteButton.onclick = (e) => { if (timeout != null) { clearTimeout(timeout); timeout = null; } - $("input[name=eingabe]").val(""); - $("input[name=eingabe]").focus(); - }); - $("input[name=eingabe]").focusin(function () { - $(deleteButton).css("display", "initial"); + document.querySelector("input[name=\"eingabe\"]").value = ""; + document.querySelector("input[name=\"eingabe\"]").focus(); + }; + + document.querySelector("input[name=\"eingabe\"]").addEventListener("focusin", (e) => { + deleteButton.style.display = "initial"; }); - $("input[name=eingabe]").focusout(function () { + + document.querySelector("input[name=\"eingabe\"]").addEventListener("focusout", (e) => { timeout = window.setTimeout(function () { - $(deleteButton).css("display", "none"); + deleteButton.style.display = "none"; timeout = null; }, 500); }); } function loadMoreResults() { - var searchKey = $("meta[name=searchkey]").attr("content"); + var searchKey = document.querySelector("meta[name=searchkey]").content var updateUrl = document.location.href; updateUrl += "&loadMore=loader_" + searchKey + "&script=yes"; @@ -75,61 +94,80 @@ function loadMoreResults() { clearInterval(resultLoader); } currentlyLoading = true; - $.getJSON(updateUrl, function (data) { - // Check if we can clear the interval (once every searchengine has answered) - if (!data || data.finished) { - clearInterval(resultLoader); - } - // If there are new results we can add them - if (typeof data.newResults != "undefined") { - for (var key in data.newResults) { - var value = data.newResults[key]; - - // If there are more results than the given index we will prepend otherwise we will append the result - if (!data.imagesearch) { - var results = $(".result:not(.ad)"); - if (key == 0) { - if ($(".result.ad").length > 0) { - $(value).insertAfter($($(".result.ad")[$(".result.ad").length - 1])); - } else { - $("#results").prepend(value); - } - } else if (typeof results[key] != "undefined") { - $(value).insertBefore($(results[key])); - } else if (typeof results[key - 1] != "undefined") { - $(value).insertAfter($(results[key - 1])); - } - } else { - var results = $(".image-container > .image"); - if (key == 0) { - $(".image-container").prepend(value); - } else if (typeof results[key] != "undefined") { - $(value).insertBefore($(results[key])); - } else if (typeof results[key - 1] != "undefined") { - $(value).insertAfter($(results[key - 1])); + fetch(updateUrl) + .then(response => response.json()) + .then(data => { + // Check if we can clear the interval (once every searchengine has answered) + if (!data || data.finished) { + clearInterval(resultLoader); + } + + if (typeof data.changedResults != "undefined") { + for (var key in data.changedResults) { + var value = data.changedResults[key]; + // If there are more results than the given index we will prepend otherwise we will append the result + if (!data.imagesearch) { + var results = document.querySelectorAll(".result:not(.ad)"); + var replacement = document.createElement("div"); + replacement.innerHTML = value.trim(); + results[key].parentNode.replaceChild(replacement.firstChild, results[key]); + } else { + var results = document.querySelectorAll(".image-container > .image"); + var replacement = document.createElement("div"); + replacement.innerHTML = value.trim(); + results[key].parentNode.replaceChild(replacement.firstChild, results[key]); } } + botProtection(); } - if ($(".no-results-error").length > 0 && ($(".image-container > .image").length > 0) || $(".result:not(.ad)").length > 0) { - $(".no-results-error").remove(); - if ($(".alert.alert-danger > ul").children().length == 0) { - $(".alert.alert-danger").remove(); + + // If there are new results we can add them + if (typeof data.newResults != "undefined") { + for (var key in data.newResults) { + var value = data.newResults[key]; + + // If there are more results than the given index we will prepend otherwise we will append the result + if (!data.imagesearch) { + var resultContainer = document.querySelector("#results"); + var results = document.querySelectorAll(".result:not(.ad)"); + var replacement = document.createElement("div"); + replacement.innerHTML = value.trim(); + if (key == 0) { + resultContainer.insertBefore(replacement.firstChild, results[0]); + } else if (typeof results[key] != "undefined") { + resultContainer.insertBefore(replacement.firstChild, results[key]); + } else if (typeof results[key - 1] != "undefined") { + resultContainer.append(replacement.firstChild); + } + } else { + var resultContainer = document.querySelector("#results"); + var results = document.querySelectorAll(".image-container > .image"); + var replacement = document.createElement("div"); + replacement.innerHTML = value.trim(); + if (key == 0) { + resultContainer.insertBefore(replacement.firstChild, results[0]); + } else if (typeof results[key] != "undefined") { + resultContainer.insertBefore(replacement.firstChild, results[key]); + } else if (typeof results[key - 1] != "undefined") { + resultContainer.append(replacement.firstChild); + } + } } - } - } - if (typeof data.changedResults != "undefined") { - for (var key in data.changedResults) { - var value = data.changedResults[key]; - // If there are more results than the given index we will prepend otherwise we will append the result - if (!data.imagesearch) { - $($(".result:not(.ad)")[key]).replaceWith($(value)); - } else { - $($(".image-container > .image")[key]).replaceWith($(value)); + botProtection(); + if (document.querySelectorAll(".no-results-error").length > 0 && (document.querySelectorAll(".image-container > .image").length > 0) || document.querySelectorAll(".result:not(.ad)").length > 0) { + document.querySelectorAll(".no-results-error").forEach(element => { + element.remove(); + }); + if (document.querySelector(".alert.alert-danger > ul") != null && document.querySelector(".alert.alert-danger > ul").children().length == 0) { + document.querySelectorAll(".alert.alert-danger").forEach(element => { + element.remove(); + }); + } } } - } - currentlyLoading = false; - }); + + currentlyLoading = false; + }); } }, 1000); } diff --git a/resources/js/scriptSettings.js b/resources/js/scriptSettings.js index 1c62f16c510d42f1a1467a94df4076b4de2e2356..14af01e836c143bf41c150486c8e5ec2f0c8b9b6 100644 --- a/resources/js/scriptSettings.js +++ b/resources/js/scriptSettings.js @@ -1,6 +1,7 @@ -$(document).ready(function () { - $("#filter-form, #setting-form").find("button[type=submit]").css("display", "none"); - $("#filter-form, #setting-form").find("select").on("change", function () { - $(this).closest('form').submit(); +document.addEventListener("DOMContentLoaded", (event) => { + document.querySelectorAll("#setting-form select").forEach((element) => { + element.onchange = (e) => { + e.srcElement.form.submit(); + }; }); }); \ No newline at end of file diff --git a/resources/js/translations.js b/resources/js/translations.js index 1d6ce9a98d6929f976c4e91d3f6d555ca5627e09..97058ffd885a45a142ec71ec461e6192b7aba1af 100644 --- a/resources/js/translations.js +++ b/resources/js/translations.js @@ -22,8 +22,8 @@ var translations = { 'result-saver.save.this': 'ÖFFNEN', 'result-saver.save.newtab': 'IN NEUEM TAB', 'result-saver.save.anonymous': 'ANONYM ÖFFNEN', - 'close-dropdowns' : 'Alle zuklappen', - 'open-dropdowns' : 'Alle aufklappen' + 'close-dropdowns': 'Alle zuklappen', + 'open-dropdowns': 'Alle aufklappen' }, 'en': { @@ -42,20 +42,20 @@ var translations = { 'result-saver.save.this': 'OPEN', 'result-saver.save.newtab': 'IN NEW TAB', 'result-saver.save.anonymous': 'OPEN ANONYMOUSLY', - 'close-dropdowns' : 'Collapse all', - 'open-dropdowns' : 'Expand all' + 'close-dropdowns': 'Collapse all', + 'open-dropdowns': 'Expand all' }, 'es': { 'select-engine': 'Por favor, seleccione al menos un motor de búsqueda.', 'select-valid-name': 'Por favor, introduzca un nombre válido constituido por letras y números.', 'confirm-overwrite-name': 'Nombre ya ha sido elegido.\n¿Substituirlo?', - // 'saved-settings': '', - // 'generated-plugin': '' - // 'result-saver.sort.chronological': 'Chronologisch', - // 'result-saver.sort.ranking': 'MetaGer-Ranking', - // 'result-saver.sort.alphabetical': 'Alphabetisch (Hostname)', - // 'result-saver.delete': 'Ergebnis aus dem Speicher löschen', + // 'saved-settings': '', + // 'generated-plugin': '' + // 'result-saver.sort.chronological': 'Chronologisch', + // 'result-saver.sort.ranking': 'MetaGer-Ranking', + // 'result-saver.sort.alphabetical': 'Alphabetisch (Hostname)', + // 'result-saver.delete': 'Ergebnis aus dem Speicher löschen', } }; @@ -65,9 +65,9 @@ var translations = { * @param {string} key Zu übersetzender Schlüssel * @param {string} lang Zu verwendende Sprache */ -function t (key, lang) { +function t(key, lang) { if (arguments.length == 1) { - var lang = $('html').attr('lang'); + var lang = document.querySelector("html").getAttribute("lang"); return t(key, lang); } else if (arguments.length == 2 && translations[lang] && translations[lang][key]) { return translations[lang][key]; diff --git a/resources/js/utility.js b/resources/js/utility.js index 4a94950271def55a3b887de3b0bfaee2a4a4dbd9..0b01f3ad738d6755ff6902543d5ba8bf636ef0c0 100644 --- a/resources/js/utility.js +++ b/resources/js/utility.js @@ -1,4 +1,4 @@ -$(document).ready(function () { - $('.js-only').removeClass('js-only'); - $('.no-js').addClass('hide'); +document.addEventListener("DOMContentLoaded", (event) => { + document.querySelectorAll(".js-only").forEach(el => el.classList.remove("js-only")); + document.querySelectorAll(".no-js").forEach(el => el.classList.add("hide")); }); \ No newline at end of file diff --git a/resources/js/widgets.js b/resources/js/widgets.js index 9ae0330a22afd644dd4e3033956981e240f12a34..3a060292e888eaf631d22db9756dde8c9268ce89 100644 --- a/resources/js/widgets.js +++ b/resources/js/widgets.js @@ -1,19 +1,22 @@ -function copyCode () { - $('#codesnippet').select(); +function copyCode() { + document.querySelector("#codesnippet").select(); try { var successful = document.execCommand('copy'); if (successful) { - $('#copyButton').removeClass('btn-default'); - $('#copyButton').addClass('btn-success'); + document.querySelector("#copyButton").classList.remove("btn-default"); + document.querySelector("#copyButton").classList.add("btn-success"); } else { - $('#copyButton').removeClass('btn-default'); - $('#copyButton').addClass('btn-danger'); + document.querySelector("#copyButton").classList.remove("btn-default"); + document.querySelector("#copyButton").classList.add("btn-danger"); } } catch (err) { - $('#copyButton').removeClass('btn-default'); - $('#copyButton').addClass('btn-danger'); + document.querySelector("#copyButton").classList.remove("btn-default"); + document.querySelector("#copyButton").classList.add("btn-danger"); } } window.onload = function () { - $('#copyButton').bind('click', copyCode); + let copyButton = document.querySelector("#copyButton"); + if (copyButton != null) { + copyButton.onclick = copyCode; + } }; diff --git a/resources/less/utility.less b/resources/less/utility.less index bc6208bc2bbc82fc3f0eccba3eed75b5c809944f..e7989b70c5081a95e2f78fb3f8fdd12d02135dd0 100644 --- a/resources/less/utility.less +++ b/resources/less/utility.less @@ -4,6 +4,10 @@ display: none !important; } +.hide { + display: none !important; +} + /* Zweck: Beim klick auf den .dropdown-opener soll der .dropdown-content angezeigt werden. * Verwendung: <a class="dropdown-opener" href="javascript:void(0);">...</a> * <div class="dropdown-content">...</div> diff --git a/resources/views/layouts/resultpage/verificationHeader.blade.php b/resources/views/layouts/resultpage/verificationHeader.blade.php index 85ba8d9a022cd048806aad020b94289184f01ad0..cbd8651ec9c0d7d15107321d6082463a22271682 100644 --- a/resources/views/layouts/resultpage/verificationHeader.blade.php +++ b/resources/views/layouts/resultpage/verificationHeader.blade.php @@ -2,5 +2,5 @@ <html lang="{!! trans('staticPages.meta.language') !!}"> <head> <meta charset="UTF-8"> - <link rel="stylesheet" href="/index.css?id={{ $key }}" beforeLoad="console.log('test');"> + <link rel="stylesheet" href="/index.css?id={{ $key }}"> <script src="/index.js?id={{ $key }}"></script> diff --git a/resources/views/settings/index.blade.php b/resources/views/settings/index.blade.php index cf82c1a47a4619958344af022f4033467e81dbcd..f7546d11ed4806aaaef0b5621d426b088fd1d017 100644 --- a/resources/views/settings/index.blade.php +++ b/resources/views/settings/index.blade.php @@ -153,7 +153,7 @@ </select> </div> @endif - <button type="submit" class="btn btn-default">@lang('settings.save')</button> + <button type="submit" class="btn btn-default no-js">@lang('settings.save')</button> </form> </div> <div class="card-light" id="actions"> diff --git a/resources/views/widget/sitesearch.blade.php b/resources/views/widget/sitesearch.blade.php index 57a5ccaa9ef242363834ee58af87a70b5b7dc659..0685b949251aa0de86d8b8ae873bbf3afa5eda81 100644 --- a/resources/views/widget/sitesearch.blade.php +++ b/resources/views/widget/sitesearch.blade.php @@ -20,7 +20,7 @@ {!! $template !!} </div> <div class="card-medium"> - <h2>{{ trans('sitesearch.generated.5') }} <button id="copyButton" class="btn btn-default" type="button"><i class="fa fa-paperclip" aria-hidden="true"></i> {{ trans('websearch.head.copy') }}</button></h2> + <h2>{{ trans('sitesearch.generated.5') }} <button id="copyButton" class="btn btn-default js-only" type="button"><i class="fa fa-paperclip" aria-hidden="true"></i> {{ trans('websearch.head.copy') }}</button></h2> <textarea id="codesnippet" readonly style="width:100%;height:500px"> {!! $template !!} </textarea> diff --git a/routes/web.php b/routes/web.php index befbe815ccad9acdecd554972f7f833ac4451c19..d8f4b4a17f2634684379d5841d33401d2f163628 100644 --- a/routes/web.php +++ b/routes/web.php @@ -224,7 +224,7 @@ Route::group( Route::match(['get', 'post'], 'meta/meta.ger3', 'MetaGerSearch@search')->middleware('browserverification', 'humanverification', 'useragentmaster')->name("resultpage"); Route::get('meta/loadMore', 'MetaGerSearch@loadMore'); - Route::post('img/cat.jpg', 'HumanVerification@remove'); + Route::post('img/cat.png', 'HumanVerification@remove'); Route::get('verify/metager/{id}/{uid}', ['as' => 'captcha', 'uses' => 'HumanVerification@captcha']); Route::get('r/metager/{mm}/{pw}/{url}', ['as' => 'humanverification', 'uses' => 'HumanVerification@removeGet']); Route::post('img/dog.jpg', 'HumanVerification@whitelist'); @@ -242,7 +242,7 @@ Route::group( $redis->expire($key, 30); }); - return response("", 200)->header("Content-Type", "application/js"); + return response("", 200)->header("Content-Type", "application/javascript"); }); Route::get('meta/picture', 'Pictureproxy@get'); diff --git a/webpack.mix.js b/webpack.mix.js index 5e4be685345876ffc0c3d04825d6a20f864e6a85..00fcc2ea56374a93c95da3978c6f590043c08057 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -58,9 +58,6 @@ mix // js .babel( [ - "resources/js/lib/jquery.js", - "resources/js/lib/jquery-ui.min.js", - "resources/js/lib/bootstrap.js", "resources/js/lib/md5.js" ], "public/js/lib.js"