diff --git a/public/js/searchbar.js b/public/js/searchbar.js index cc23c099bea2ac52b3c476ab84eed76d9237354c..7dc53ee6d89bb3609567b823d0f0e93cdf8d5b45 100644 --- a/public/js/searchbar.js +++ b/public/js/searchbar.js @@ -421,383 +421,4 @@ function setCheckedForAllWithName (name, checked) { $('.focusCheckbox[name=' + name + ']').prop('checked', checked); } -$(function () { - setFocusCreatorActionListeners(); - loadInitialCustomFocuses(); - loadInitialSelectedFocus(); - focusChanged(); -}); - -/** - * Sets all action listeners for this page - */ -function setFocusCreatorActionListeners () { - $('.focusCheckbox').click(checkboxCheckListener); - $('#addFocusBtn').click(() => showFocusCreateDialog('')); - $('#editFocusBtn').click(editCurrentFocus); - $('#toggleOptBtn').click(toggleOptionsDialog); - $('.save-focus-btn').click(saveFocus); - $('.delete-focus-btn').click(deleteFocus); - $('#focus-select').change(focusChanged); - // Save Focus on clicking enter while in the focus name input - $('#focus-name').keyup(function (event) { - if (event.keyCode == 13) { - saveFocus(); - } - }); - $('#create-focus-modal').on('shown.bs.modal', function () { - $('#focus-name').focus(); - }); -} -/** - * Loads all the custom focuses stored in local storage - */ -function loadInitialCustomFocuses () { - for (var key in localStorage) { - if (key.startsWith('focus_')) { - var focus = loadFocusById(key); - addFocus(focus.name); - } - } -} - -function loadInitialSelectedFocus () { - setFocus(getFocusInUrl()); -} - -/** - * Shows the focus create dialog - * If an id is given it will try to load a focus for the given id - */ -function showFocusCreateDialog (id) { - if (id === undefined) { - id = ''; - } - document.getElementById('original-id').value = id; - $('#create-focus-modal').modal('show'); - var storedFocus = loadFocusById(id); - var focus = {}; - // Try to load a focus for the given id - $('#focus-name').val(''); - uncheckAll(); - if (storedFocus !== null) { - try { - focus = JSON.parse(localStorage.getItem(id)); - $('#focus-name').val(focus.name); - for (var key in focus) { - if (key.startsWith('engine_')) { - $('.focusCheckbox[name=' + key + ']').prop('checked', true); - } - } - } catch (ex) { - console.error(ex); - } - } - toggleDeleteButton(); -} - -/** - * Shows the focus create dialog for a given id - */ -function showFocusEditDialog (id) { - showFocusCreateDialog(id); -} - -function getCurrentFocus () { - return document.getElementById('focus-select').value; -} - -/** - * Shows an edit dialog for the current selected focus - */ -function editCurrentFocus () { - var currentFocus = getCurrentFocus(); - showFocusEditDialog(currentFocus); -} - -/** - * Shows/Hides the delete button if (no) checkboxes are selected - */ -function toggleDeleteButton () { - if (atLeastOneChecked()) { - $('.delete-focus-btn').show(); - } else { - $('.delete-focus-btn').hide(); - } -} - -/** - * Save the current Focus - * Listens for save button - */ -function saveFocus () { - /* Vorprüfungen */ - // Falls keine Suchmaschine ausgewählt wurde - if (!atLeastOneChecked()) { - switch (document.documentElement.lang) { - case 'en': - alert('Please select at least 1 search engine.'); - break; - case 'es': - alert('Por favor, seleccione al menos un motor de búsqueda.'); - break; - default: - alert('Bitte mindestens 1 Suchmaschine auswählen.'); - break; - } - return; - } - // Falls der Name zu kurz ist oder ungültige Zeichen enthält - var name = document.getElementById('focus-name').value; - if (!isValidName(name)) { - switch (document.documentElement.lang) { - case 'en': - alert('No characters other than a-z, A-Z, 0-9, ä, ö, ü, ß, -, _ allowed, at least 1 character'); - break; - case 'es': - alert('Por favor, introduzca un nombre válido'); - break; - default: - alert('Bitte gültigen Namen eingeben:\n* Keine Sonderzeichen\n* Mindestens 1 Buchstabe\n'); - break; - } - return; - } - // Liest die original-id des aktuellen fokus-dialogs (gesetzt wenn man einen Fokus bearbeitet) - var oldId = document.getElementById('original-id').value; - var id = getIdFromName(name); - var overwrite = true; - // Wenn bereits ein Fokus mit dem Namen existiert, man diesen aber nicht editiert sondern gerade einen Neuen erstellt - if (alreadyInUse(name) && oldId !== id) { - // Fragt den Nutzer ob er den Fokus überschreiben möchte - if (!confirm('Name bereits genutzt\nüberschreiben?')) { - // Falls nicht wird das Speichern abgebrochen - return; - } - // Ansonsten wird der andere Fokus gelöscht - deleteFocusById(id); - } - /* Fokus speichern */ - var focus = {}; - // Ausgewählte Suchmaschinen lesen und zu Fokus hinzufügen - $('input[type=checkbox]:checked').each(function (el) { - focus[$(this).attr('name')] = $(this).val(); - }); - - // Name setzen - focus['name'] = name; - // Alte Version des Fokus löschen (aus localStorage und von der Webseite, falls eine existiert) - if (oldId !== '') { - localStorage.removeItem(oldId); - removeFocusById(oldId); - } - // Neue Version des Fokus hinzufügen (zu localStorage und der Webseite) - localStorage.setItem(id, JSON.stringify(focus)); - addFocus(name); - setFocus(id); - // Fokus-Formular verbergen - $('#create-focus-modal').modal('hide'); -} - -/** - * Delete current Focus - * Listens for delete button - */ -function deleteFocusById (id) { - localStorage.removeItem(id); - removeFocusById(id); - $('#focus-select').change(); -} - -/** - * Delete current Focus - * Listens for delete button - */ -function deleteFocus () { - var oldId = document.getElementById('original-id').value; - deleteFocusById(oldId); - $('#create-focus-modal').modal('hide'); - $('#focus-select').change(); -} - -/** - * Is the name valid (in terms of characters)? - */ -function isValidName (name) { - // no Characters other then a-z, A-Z, 0-9, ä, ö, ü, ß, -, _ allowed - // at least 1 character - return /^[a-zA-Z0-9äöüß\-_ ]+$/.test(name); -} - -/** - * Is at least one focus selected? - */ -function atLeastOneChecked () { - return $('.focusCheckbox:checked').length > 0; -} - -/** - * Is there already a focus with this name? - */ -function alreadyInUse (name) { - return localStorage.hasOwnProperty(getIdFromName(name)); -} - -/** - * Adds an option to the focus selector - */ -function addFocus (name) { - var id = getIdFromName(name); - $('#focus-select').append('<option value="' + id + '" style="font-family: FontAwesome, sans-serif;"> ' + name + '</option>'); -} - -/** - * Remove the focuses html-elements - */ -function removeFocus (name) { - removeFocusById(getIdFromName(name)); -} - -/** - * Remove the focuses html-elements - */ -function removeFocusById (id) { - if (id == '') { - return; - } - $('#focus-select option[value="' + id + '"]').remove(); -} - -/** - * Turns a name into an id - * Converts special characters and spaces - */ -function getIdFromName (name) { - name = name.toLowerCase(); - name = name.split(' ').join('_'); - name = name.split('ä').join('ae'); - name = name.split('ö').join('oe'); - name = name.split('ü').join('ue'); - return 'focus_' + name; -} - -/** - * Loads the focus object for the given id from local storage - */ -function loadFocusById (id) { - return JSON.parse(localStorage.getItem(id)); -} - -/** - * Unchecks all focuses from the focus creator dialog - */ -function uncheckAll () { - $('.focusCheckbox').prop('checked', false); -} - -/** - * Sets the selected focus to default - */ -function setFocusToDefault () { - setFocus(DEFAULT_FOCUS); -} - -/** - * Sets the selected focus - * @param {String} focusID The id of the focus, without # - */ -function setFocus (focusID) { - $('#focus-select option[value="' + focusID + '"]').prop('selected', true); - $('#focus-select').change(); -} - -function focusChanged () { - var selectedFocus = getCurrentFocus(); - if (focusIsEditable(selectedFocus)) { - enableEditFocusBtn(); - } else { - disableEditFocusBtn(); - } - loadFocusForSearch(selectedFocus); -} - -function focusIsEditable (focus) { - if (focus.startsWith('focus_')) { - return true; - } else { - return false; - } -} - -function enableEditFocusBtn () { - $('#editFocusBtn').removeClass('disabled').click(editCurrentFocus); -} - -function disableEditFocusBtn () { - $('#editFocusBtn').addClass('disabled').off('click'); -} - -function loadFocusForSearch (focus) { - var focus = loadFocusById(focus); - clearCustomSearch(); - for (var key in focus) { - if (key.startsWith('engine_') && focus[key] == 'on') { - addSumaToCustomSearch(key); - } - } -} - -function clearCustomSearch () { - $('.search-custom-hidden').empty(); -} - -function addSumaToCustomSearch (sumaId) { - $('.search-custom-hidden').append('<input type="hidden" name="' + sumaId + '" value="on">'); -} - -function getFocusInUrl () { - var url = window.location; - var focReg = /focus=(focus_\w+)/.exec(url); - if (focReg && focReg[1]) { - return focReg[1]; - } -} - -function toggleOptionsDialog () { - var btnMode = $('#toggleOptBtn').attr('data-mode'); - if (btnMode == 'o') { - openOptionsDialog(); - } else { - closeOptionsDialog(); - } -} - -function openOptionsDialog () { - $('#toggleOptBtn').html('<i class="fa fa-chevron-up" aria-hidden="true"></i>'); - $('#toggleOptBtn').attr('data-mode', 'c'); - $('.search-option-frame').removeClass('hide'); -} - -function closeOptionsDialog () { - $('#toggleOptBtn').html('<i class="fa fa-chevron-down" aria-hidden="true"></i>'); - $('#toggleOptBtn').attr('data-mode', 'o'); - $('.search-option-frame').addClass('hide'); -} - -function checkboxCheckListener (event) { - toggleDeleteButton(); - var elem = event.target; - if (elem.name) { - if (elem.checked) { - setCheckedForAllWithName(elem.name, true); - } else { - setCheckedForAllWithName(elem.name, false); - } - } -} - -function setCheckedForAllWithName (name, checked) { - $('.focusCheckbox[name=' + name + ']').prop('checked', checked); -} - //# sourceMappingURL=searchbar.js.map diff --git a/resources/assets/js/result-saver.js b/resources/assets/js/result-saver.js index 8ef1dac127f6581475d3b9226d1b6656c10905df..9f9669d2ae06136adcc5ff5dd460b0ca254df3e9 100644 --- a/resources/assets/js/result-saver.js +++ b/resources/assets/js/result-saver.js @@ -1,36 +1,40 @@ /** - * Global Results type element + * All results are stored in the global object 'results' */ -RESULTS_GLOBAL = null; +results = new Results(); -/** - * Returns the global results object, - * creates it if necessary - * @returns {Results} The global results object - */ -function results() { - if (!RESULTS_GLOBAL) { - RESULTS_GLOBAL = new Results(); - } - return RESULTS_GLOBAL; -} +$(document).ready(function () { + // Add all saved results + results.loadAllResults(); + // Sort all results + results.sortResults(); + // Update the visualization + results.updateResultPageInterface(); +}); /** * Load all saved results and sort them * @param {String} sort The type of sorting function to call for these results */ -function Results () { //TODO remove sort +function Results () { if (!localStorage) return; this.prefix = 'result_'; this.sort = 'chronological'; this.results = []; - this.loadAllResults(); - this.length = this.results.length; - this.sortResults(); - - results = this; } +/** + * Adds a result to the list of results + * @param {Result} result The result to add + */ +Results.prototype.addResult = function (result) { + if (this.results.every(function (val) { + return val.hash !== result.hash; + })) { + this.results.push(result); + } +}; + /** * Sorts all results according to the sort-type given with this.sort */ @@ -51,7 +55,7 @@ Results.prototype.sortResults = function () { return 0; }); break; - case 'alphabetical': + case 'alphabetical': // by hostname this.results.sort(function (a, b) { if (b.hostname > a.hostname) return -1; if (b.hostname < a.hostname) return 1; @@ -75,8 +79,6 @@ Results.prototype.loadAllResults = function () { key = key.substr(this.prefix.length); // Create the result for this key by loading it from localstorage var tmpResult = new Result(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, key); - // Give the result an unique index - tmpResult.setIndex(i); // Add the result to the list of results this.results.push(tmpResult); } @@ -87,6 +89,7 @@ Results.prototype.loadAllResults = function () { * Delete all results from localstorage */ Results.prototype.deleteAllResults = function () { + this.results = []; var keys = []; // Save all keys starting with the prefix used for saved results into the keys array for (var i = 0; i < localStorage.length; i++) { @@ -160,35 +163,43 @@ Results.prototype.addToContainer = function (container) { // Add the saver-options element to the given container $(container).append(options); - // When the sorting select value is changed, - // Sort all results with the selected sorting function and update their appearance - $(options).find('select').change(function () { - results().sortResults($(this).val()).updateResultPageInterface(); - }); - - // 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(); - }); - + /* ~~~ 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 () { // Get the entered filter var search = $(this).val(); // Hide all results that do not contain the entered filter - $('#savedFoki saved-result-content').each(function (index, value) { + $('#savedFoki .saved-result-content').each(function (index, value) { + // check for filter in all of the elements html-content var html = $(this).html(); if (html.toLowerCase().indexOf(search.toLowerCase()) === -1) { - $(value).addClass('hidden'); + // hide entire result block + $(value).parent().addClass('hidden'); }else { - $(value).removeClass('hidden'); + // show entire result block + $(value).parent().removeClass('hidden'); } }); }); + /* ~~~ 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(); + }); + + /* ~~~ 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(); + }); + // Append all results available $.each(this.results, function (index, result) { $(container).append(result.toHtml()); @@ -207,18 +218,19 @@ Results.prototype.addToContainer = function (container) { * @param {int} rank The rank of this result * @param {int} hash The hash value for this result */ -function Result (title, link, anzeigeLink, gefVon, hoster, anonym, description, rank, hash) { +function Result (title, link, anzeigeLink, gefVon, hoster, anonym, description, index, hash) { // Set prefix for localstorage this.prefix = 'result_'; - if (hash !== null && hash !== undefined) { - // If a hash is given, the result for this hash is loaded from localstorage - this.hash = hash; - this.load(); - } else { - // If no hash is given, calculate it - this.hash = MD5(title + link + anzeigeLink + gefVon + hoster + anonym + description); + if (hash === null || hash === undefined) { + // Calculate the hash value of this result + hash = MD5(title + link + anzeigeLink + gefVon + hoster + anonym + description); + } + this.hash = hash; + + // Try to load the result, if there was none create it + if (!this.load()) { // Save all important data this.title = title; this.link = link; @@ -227,11 +239,13 @@ function Result (title, link, anzeigeLink, gefVon, hoster, anonym, description, this.hoster = hoster; this.anonym = anonym; this.description = description; - this.rank = rank; + this.index = index; + this.rank = index; this.added = new Date().getTime(); - var parser = document.createElement('a'); - parser.href = this.anzeigeLink; - this.hostname = parser.hostname; + // read the hostname from the displayed link + // matches everything from after a 'www' to the locality ending ('de', 'com', etc.) + var matches = /(?:www\.)*((?:[\w\-]+\.)+\w{2,3})(?:$|[/?])/.exec(this.anzeigeLink); + this.hostname = matches[1]; // Save this result to localstorage this.save(); @@ -262,6 +276,7 @@ Result.prototype.load = function () { this.anonym = result.anonym; this.description = result.description; this.added = result.added; + this.index = -result.index; this.rank = result.rank; this.hostname = result.hostname; @@ -284,6 +299,7 @@ Result.prototype.save = function () { anonym: this.anonym, description: this.description, added: this.added, + index: this.index, rank: this.rank, hostname: this.hostname }; @@ -328,7 +344,11 @@ Result.prototype.setIndex = function (index) { */ Result.prototype.remove = function () { localStorage.removeItem(this.prefix + this.hash); - new Results().updateResultPageInterface(); + var hash = this.hash; + results.results.splice(results.results.findIndex(function (result) { + return result.hash === hash; + }), 1); + results.updateResultPageInterface(); }; /** @@ -350,7 +370,7 @@ Result.prototype.toHtml = function () { </h2>\ <div class="result-header">\ <div class="result-link">\ - <a href="' + this.link + '" target="_blank" data-hoster="' + this.hoster + '" data-count="' + this.index + '" rel="noopener">\ + <a href="' + this.link + '" target="_blank" data-hoster="' + this.hoster + '" rel="noopener">\ ' + this.anzeigeLink + '\ </a>\ </div>\ @@ -385,21 +405,29 @@ function resultSaver (index) { var original = $('.result[data-count=' + index + ']'); // Read the necessary data from the result html - var title = $('.result[data-count=' + index + '] .result-title a').html(); - var link = $('.result[data-count=' + index + '] .result-title a').attr('href'); - var anzeigeLink = $('.result[data-count=' + index + '] .result-link a').html(); - var gefVon = $('.result[data-count=' + index + '] .result-hoster a').html(); - var hoster = $('.result[data-count=' + index + '] .result-hoster a').attr('href'); - var anonym = $('.result[data-count=' + index + '] .result-proxy').attr('href'); - var description = $('.result[data-count=' + index + '] .result-description').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 anzeigeLink = $('.result[data-count=' + index + '] .result-link a').html().trim(); + var gefVon = $('.result[data-count=' + index + '] .result-hoster a').html().trim(); + var hoster = $('.result[data-count=' + index + '] .result-hoster a').attr('href').trim(); + var anonym = $('.result[data-count=' + index + '] .result-proxy a').attr('href').trim(); + var description = $('.result[data-count=' + index + '] .result-description').html().trim(); // Create the result object - var result = new Result(title, link, anzeigeLink, gefVon, hoster, anonym, description, index, undefined); + var result = new Result(title, link, anzeigeLink, gefVon, hoster, anonym, description, index, null); + + // Add new result to results + results.addResult(result); + + // Sort results + results.sortResults(); // Update the saved results - results().updateResultPageInterface(); + results.updateResultPageInterface(); // Animate the result transfer to the saved results var transferTarget = $('.saved-result[data-count=' + index + ']'); - $(original).transfer({to: transferTarget, duration: 1000}); + if (original.length > 0 && transferTarget.length > 0) { + $(original).transfer({to: transferTarget, duration: 1000}); + } } diff --git a/resources/assets/js/scriptResultPage.js b/resources/assets/js/scriptResultPage.js index 2d0147eb3759d5ffc3a63faa3d6c968922edc8b4..5e7aabff7d88e087bfc55ced202aacd7225f638b 100644 --- a/resources/assets/js/scriptResultPage.js +++ b/resources/assets/js/scriptResultPage.js @@ -4,7 +4,6 @@ $(document).ready(function () { var custom = $('#foki > li.active').hasClass('custom-focus-tab-selector'); getDocumentReadyForUse(focus, custom); botProtection(); - new Results().updateResultPageInterface(); // Adds the saved Results if they are present if (document.location.href.indexOf('focus=container') !== -1) { $($('#foki > li#savedFokiTabSelector').get(0)).find('>a').tab('show'); }