Monthly Archives: Marzec 2018

jQuery – Zaznaczanie tekstu na stronie (podkreślanie)

Dostałem tydzień temu informację że w systemie jaki tworzę nagle zaczął się źle zaznaczać filtrowany tekst w tabelach. A mianowicie zamiast zaznaczać się tylko tekst, który jest wyszukiwany zaczął się zaznaczać tekst niemalże do końca linii. Najdziwniejsze w tej historii jest to że w ciągu tygodnia nie robiłem żadnej aktualizacji systemu, która mogłaby taki błąd wprowadzić. Może coś w przeglądarkach wprowadzono o czym nie wiem?? Może. Ale znalazłem kod, który realizuje to zadanie idealnie:

/*
 * jQuery Highlight plugin
 *
 * Based on highlight v3 by Johann Burkard
 * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
 *
 * Code a little bit refactored and cleaned (in my humble opinion).
 * Most important changes:
 *  - has an option to highlight only entire words (wordsOnly - false by default),
 *  - has an option to be case sensitive (caseSensitive - false by default)
 *  - highlight element tag and class names can be specified in options
 *
 * Usage:
 *   // wrap every occurrance of text 'lorem' in content
 *   // with <span class='highlight'> (default options)
 *   $('#content').highlight('lorem');
 *
 *   // search for and highlight more terms at once
 *   // so you can save some time on traversing DOM
 *   $('#content').highlight(['lorem', 'ipsum']);
 *   $('#content').highlight('lorem ipsum');
 *
 *   // search only for entire word 'lorem'
 *   $('#content').highlight('lorem', { wordsOnly: true });
 *
 *   // don't ignore case during search of term 'lorem'
 *   $('#content').highlight('lorem', { caseSensitive: true });
 *
 *   // wrap every occurrance of term 'ipsum' in content
 *   // with <em class='important'>
 *   $('#content').highlight('ipsum', { element: 'em', className: 'important' });
 *
 *   // remove default highlight
 *   $('#content').unhighlight();
 *
 *   // remove custom highlight
 *   $('#content').unhighlight({ element: 'em', className: 'important' });
 *
 *
 * Copyright (c) 2009 Bartek Szopka
 *
 * Licensed under MIT license.
 *
 */

jQuery.extend({
    highlight: function (node, re, nodeName, className) {
        if (node.nodeType === 3) {
            var match = node.data.match(re);
            if (match) {
                var highlight = document.createElement(nodeName || 'span');
                highlight.className = className || 'highlight';
                var wordNode = node.splitText(match.index);
                wordNode.splitText(match[0].length);
                var wordClone = wordNode.cloneNode(true);
                highlight.appendChild(wordClone);
                wordNode.parentNode.replaceChild(highlight, wordNode);
                return 1; //skip added node in parent
            }
        } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
                !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
                !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
            for (var i = 0; i < node.childNodes.length; i++) {
                i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
            }
        }
        return 0;
    }
});

jQuery.fn.unhighlight = function (options) {
    var settings = { className: 'highlight', element: 'span' };
    jQuery.extend(settings, options);

    return this.find(settings.element + "." + settings.className).each(function () {
        var parent = this.parentNode;
        parent.replaceChild(this.firstChild, this);
        parent.normalize();
    }).end();
};

jQuery.fn.highlight = function (words, options) {
    var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
    jQuery.extend(settings, options);

    if (words.constructor === String) {
        words = [words];
    }
    words = jQuery.grep(words, function(word, i){
      return word != '';
    });
    words = jQuery.map(words, function(word, i) {
      return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
    });
    if (words.length == 0) { return this; };

    var flag = settings.caseSensitive ? "" : "i";
    var pattern = "(" + words.join("|") + ")";
    if (settings.wordsOnly) {
        pattern = "\\b" + pattern + "\\b";
    }
    var re = new RegExp(pattern, flag);

    return this.each(function () {
        jQuery.highlight(this, re, settings.element, settings.className);
    });
};

Łatwa i darmowa synchronizacja danych między komputerami

Lubię posiadać kopię zapasowe swoich danych w wielu miejscach, żeby w przypadku awarii dysku czy też jakiś zdarzeń losowych nie mieć problemu z odzyskiwaniem danych. Dlatego dotychczas używałem chmur plikowych takich jak Dropbox czy OneDrive. Jednak powyżej jakieś ilości składowanych danych w chmurze, trzeba zacząć za takie składowanie danych płacić. Dodatkowy problem, który uważam że jest dość ważny, to to że nie mamy pewności gdzie znajdują się dane i czy ktoś nieuprawniony nie ma do nich dostępu.

Dlatego zacząłem szukać jakiegoś rozwiązania, które miałoby na celu zminimalizować ryzyko utraty danych, działałoby i synchronizowałoby moje dane tylko na moich komputerach i byłoby względnie tanie a najlepiej darmowe.

Takim rozwiązaniem jest Syncthing, który jest multiplatformową aplikacją do wymiany danych między urządzeniami. Nie wymaga kupna serwera, czy zewnętrznego stałego adresu IP i jest całkowicie darmowe.

W moim przypadku akurat to oprogramowanie jest uruchomione na serwerze 24h/7, ale nie jest to konieczne. Wystarczy włączyć komputery, które mają się synchronizować.

Muszę przyznać, że byłem bardzo zaskoczony ilością funkcji zawartych w tym programie. Okazało się, że jest możliwość tak jak w Dropboxie tworzyć historię zmian plików, udostępniać udział tylko do odczytu (co jest bardzo ważne w przypadku gdy nie chcemy żeby ktoś miał możliwość nadpisania pliku), czy też synchronizować dane z komórki.

W celu udostępnienia udziału kolejnemu komputerowi wystarczy wygenerować specjalny kod, który po przesłaniu w formie tekstowej lub QR może zostać synchronizowany na innym komputerze, ale dopiero po akceptacji na komputerze udostępniającym dane.

Oczywiście nie warto 100 procentowo ufać żadnemu oprogramowaniu, dlatego też zalecam jednak wrażliwe dane synchronizować po uprzednim spakowaniu archiwizatorem z odpowiednio trudnym hasłem.