Commit 8fb677c7 authored by Karl Hasselbring's avatar Karl Hasselbring

Merge mit MetaGer-Redesign

parents cd063cec 2f08d504
...@@ -14,12 +14,12 @@ langfiles.zip ...@@ -14,12 +14,12 @@ langfiles.zip
/public/js/lib.js /public/js/lib.js
/public/js/scriptStartPage.js /public/js/scriptStartPage.js
/public/js/scriptResultPage.js /public/js/scriptResultPage.js
/public/js/focus-creator.js
/public/js/searchbar.js /public/js/searchbar.js
/public/js/utility.js /public/js/utility.js
/public/css/beitritt.css /public/css/beitritt.css
/public/css/themes/default.css /public/css/themes/default.css
/public/css/utility.css /public/css/utility.css
/public/js/utility.js
**/*.map **/*.map
/.buildpath /.buildpath
......
$(function () {
setFocusCreatorActionListeners();
loadInitialCustomFocuses();
loadInitialSelectedFocus();
focusChanged();
});
/**
* Sets all action listeners for this page
*/
function setFocusCreatorActionListeners () {
$('.focusCheckbox').click(checkboxCheckListener);
$('#addFocusBtn').click(() => showFocusCreateDialog(''));
$('#editFocusBtn').click(editCurrentFocus);
$('.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 $('#foki > div.active').attr('id');
}
/**
* Shows an edit dialog for the current selected focus
*/
function editCurrentFocus () {
var currentFocus = getCurrentFocus();
if (currentFocus !== undefined) {
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);
var customFocus = $('<div id="' + id + '"><a href="#" target="_self">' + name + '</a><a class="edit-focus" data-id="' + id + '" href="#"><i class="fa fa-wrench"></i></div>');
$(customFocus).find('.edit-focus').click(function () {
showFocusEditDialog($(this).attr('data-id'));
});
$('#foki .search-option-frame').before(customFocus);
}
/**
* 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 (typeof(currentFocus) !== 'undefined') {
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);
var url = '/meta/meta.ger3?eingabe=x&focus=';
// clearCustomSearch()
for (var key in focus) {
if (key.startsWith('engine_') && focus[key] == 'on') {
addSumaToCustomSearch(key);
}
}
}
function getFocusInUrl () {
var url = window.location;
var focReg = /focus=(focus_\w+)/.exec(url);
if (focReg && focReg[1]) {
return focReg[1];
}
}
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);
}
$(function () {
loadLocalStorage();
});
/**
* Loads the user theme and stored settings from local storage
*/
function loadLocalStorage () {
if (localStorage) {
setSettings();
}
}
function setSettings () {
var acceptedParams = ['autocomplete', 'key', 'lang', 'newtab', 'sprueche'];
for (var key in localStorage) {
var value = localStorage.getItem(key);
var accepted = false;
for (var i in acceptedParams) {
if (key === 'param_' + acceptedParams[i]) {
accepted = true;
}
}
if (accepted) {
key = key.substring(6);
// Check for existing hidden fields for this key
var existing = $('.search-hidden input[name="' + key + '"]');
if (existing.length === 0) {
// if none exist, create a new one
$('.search-hidden').append('<input type="hidden" name="' + key + '" value="' + value + '">');
}
}
}
// Change the request method to the given parameter
var requestMethod = localStorage.getItem('request');
if (requestMethod !== null && (requestMethod === 'GET' || requestMethod === 'POST')) {
$('#searchForm').attr('method', requestMethod);
}
}
\ No newline at end of file
...@@ -57,8 +57,8 @@ Results.prototype.sortResults = function () { ...@@ -57,8 +57,8 @@ Results.prototype.sortResults = function () {
break; break;
case 'alphabetical': // by hostname case 'alphabetical': // by hostname
this.results.sort(function (a, b) { this.results.sort(function (a, b) {
if (b.hostname > a.hostname) return -1; if (b.hosterName > a.hosterName) return -1;
if (b.hostname < a.hostname) return 1; if (b.hosterName < a.hosterName) return 1;
return 0; return 0;
}); });
break; break;
...@@ -78,7 +78,7 @@ Results.prototype.loadAllResults = function () { ...@@ -78,7 +78,7 @@ Results.prototype.loadAllResults = function () {
// Remove the prefix // Remove the prefix
key = key.substr(this.prefix.length); key = key.substr(this.prefix.length);
// Create the result for this key by loading it from localstorage // Create the result for this key by loading it from localstorage
var tmpResult = new Result(undefined, undefined, undefined, undefined, undefined, undefined, key); var tmpResult = new Result(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, key);
// Add the result to the list of results // Add the result to the list of results
this.results.push(tmpResult); this.results.push(tmpResult);
} }
...@@ -117,7 +117,7 @@ Results.prototype.updateResultPageInterface = function () { ...@@ -117,7 +117,7 @@ Results.prototype.updateResultPageInterface = function () {
// If there is no savedFoki element yet, create it // If there is no savedFoki element yet, create it
var tabPanel = $('\ var tabPanel = $('\
<div id="savedFoki">\ <div id="savedFoki">\
<h1>Gespeicherte Ergebnisse</h1>\ <h1>' + t('result-saver.title') + '</h1>\
</div>\ </div>\
'); ');
$('#additions-container').append(tabPanel); $('#additions-container').append(tabPanel);
...@@ -141,19 +141,20 @@ Results.prototype.addToContainer = function (container) { ...@@ -141,19 +141,20 @@ Results.prototype.addToContainer = function (container) {
var options = $('\ var options = $('\
<div id="saver-options">\ <div id="saver-options">\
<div class="saver-option saver-option-filter">\ <div class="saver-option saver-option-filter">\
<input class="form-control" type="text" placeholder="&#xf0b0 Filtern">\ <input class="form-control" type="text" placeholder="&#xf0b0 ' + t('result-saver.filter') + '">\
</div>\ </div>\
<div class="saver-option saver-option-sort">\ <div class="saver-option saver-option-sort">\
<select class="form-control" style="font-family: FontAwesome, sans-serif;">\ <select class="form-control" style="font-family: FontAwesome, sans-serif;">\
<option value="chronological" style="font-family: FontAwesome, sans-serif;">&#xf017 Chronologisch</option>\ <option value="chronological" style="font-family: FontAwesome, sans-serif;">&#xf017 ' + t('result-saver.sort.chronological') + '</option>\
<option value="rank" style="font-family: FontAwesome, sans-serif;">&#xf162 MetaGer-Ranking</option>\ <option value="rank" style="font-family: FontAwesome, sans-serif;">&#xf162 ' + t('result-saver.sort.ranking') + '</option>\
<option value="alphabetical" style="font-family: FontAwesome, sans-serif;">&#xf15d Alphabetisch (Hostname)</option>\ <option value="alphabetical" style="font-family: FontAwesome, sans-serif;">&#xf15d ' + t('result-saver.sort.alphabetical') + '</option>\
</select>\ </select>\
</div>\ </div>\
<div class="saver-option saver-option-delete">\ <div class="saver-option saver-option-delete">\
<button class="btn btn-danger btn-md" id="saver-options-delete-btn">\ <button class="btn btn-danger btn-md" id="saver-options-delete-btn">\
<i class="fa fa-trash-o" aria-hidden="true"></i>\ <i class="fa fa-trash-o" aria-hidden="true"></i>\
<span class="hidden-xs">Ergebnisse</span> löschen</button>\ ' + t('result-saver.deleteAll') + '\
</button>\
</div>\ </div>\
</div>\ </div>\
'); ');
...@@ -217,13 +218,13 @@ Results.prototype.addToContainer = function (container) { ...@@ -217,13 +218,13 @@ Results.prototype.addToContainer = function (container) {
* @param {int} rank The rank of this result * @param {int} rank The rank of this result
* @param {int} hash The hash value for this result * @param {int} hash The hash value for this result
*/ */
function Result (title, link, anzeigeLink, description, anonym, index, hash) { function Result (title, link, hosterName, hosterLink, anzeigeLink, description, anonym, index, hash) {
// Set prefix for localstorage // Set prefix for localstorage
this.prefix = 'result_'; this.prefix = 'result_';
if (hash === null || hash === undefined) { if (hash === null || hash === undefined) {
// Calculate the hash value of this result // Calculate the hash value of this result
hash = MD5(title + link + anzeigeLink + description + anonym); hash = MD5(title + link + hosterName + hosterLink + anzeigeLink + description + anonym);
} }
this.hash = hash; this.hash = hash;
...@@ -233,16 +234,14 @@ function Result (title, link, anzeigeLink, description, anonym, index, hash) { ...@@ -233,16 +234,14 @@ function Result (title, link, anzeigeLink, description, anonym, index, hash) {
// Save all important data // Save all important data
this.title = title; this.title = title;
this.link = link; this.link = link;
this.hosterName = hosterName;
this.hosterLink = hosterLink;
this.anzeigeLink = anzeigeLink; this.anzeigeLink = anzeigeLink;
this.description = description; this.description = description;
this.anonym = anonym; this.anonym = anonym;
this.index = index; this.index = index;
this.rank = index; this.rank = index;
this.added = new Date().getTime(); this.added = new Date().getTime();
// 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 // Save this result to localstorage
this.save(); this.save();
...@@ -257,25 +256,24 @@ Result.prototype.load = function () { ...@@ -257,25 +256,24 @@ Result.prototype.load = function () {
if (!localStorage) return false; if (!localStorage) return false;
// Try to load from local storage // Try to load from local storage
var result = localStorage.getItem(this.prefix + this.hash); var encoded = localStorage.getItem(this.prefix + this.hash);
if (result === null) return false; if (encoded === null) return false;
// Decode the base64 result into a normal string, then json // Decode the base64 result into a normal string, then json
result = b64DecodeUnicode(result); var decoded = b64DecodeUnicode(encoded);
result = JSON.parse(result); var result = JSON.parse(decoded);
// Load all important data // Load all important data
this.title = result.title; this.title = result.title;
this.link = result.link; this.link = result.link;
this.anzeigeLink = result.anzeigeLink; this.anzeigeLink = result.anzeigeLink;
this.gefVon = result.gefVon; this.hosterName = result.hosterName;
this.hoster = result.hoster; this.hosterLink = result.hosterLink;
this.anonym = result.anonym; this.anonym = result.anonym;
this.description = result.description; this.description = result.description;
this.added = result.added; this.added = result.added;
this.index = -result.index; this.index = -result.index;
this.rank = result.rank; this.rank = result.rank;
this.hostname = result.hostname;
return true; return true;
}; };
...@@ -291,14 +289,13 @@ Result.prototype.save = function () { ...@@ -291,14 +289,13 @@ Result.prototype.save = function () {
title: this.title, title: this.title,
link: this.link, link: this.link,
anzeigeLink: this.anzeigeLink, anzeigeLink: this.anzeigeLink,
gefVon: this.gefVon, hosterName: this.hosterName,
hoster: this.hoster, hosterLink: this.hosterLink,
anonym: this.anonym, anonym: this.anonym,
description: this.description, description: this.description,
added: this.added, added: this.added,
index: this.index, index: this.index,
rank: this.rank, rank: this.rank
hostname: this.hostname
}; };
// Encode the result object into a string, then into base64 // Encode the result object into a string, then into base64
...@@ -356,31 +353,36 @@ Result.prototype.toHtml = function () { ...@@ -356,31 +353,36 @@ Result.prototype.toHtml = function () {
// Create the saved-result element // Create the saved-result element
var result = $('\ var result = $('\
<div class="saved-result result" data-count="' + this.index + '">\ <div class="saved-result result" data-count="' + this.index + '">\
<div class="saved-result-remover remover" title="Ergebnis aus dem Speicher löschen">\