Greasy Fork is available in English.

c3subtitles

autocompletion for c3subtitles!

// ==UserScript==
// @name         c3subtitles
// @namespace    http://tampermonkey.net/
// @version      2.1
// @description  autocompletion for c3subtitles!
// @author       http://github.com/zestyping
// @match        https://live.c3subtitles.de/write/*
// @grant        none
// ==/UserScript==

(function() {
    var timesTyped = {};
    var completions = {};
    var isCompleted = {};
    var caseSensitiveCompletion = true;

    var addCompletion = function(word) {
        if (!caseSensitiveCompletion) word = word.toLowerCase();
        if (word.length >= 5) {
            for (var i = word.length - 1; i >= 2; i--) {
                var prefix = word.substring(0, i);
                var rest = word.substring(i);
                completions[prefix] = rest;
                if (isCompleted[prefix]) break;
            }
            isCompleted[word] = true;
        }
    };

    // grep -v '[A-Z]' < 999-common-words.txt | sort | grep ... | sed -e 's/\(...\)\(.*\)/\1\2 \1/' | uniq -c -f 1 | grep '^ *1 ' | grep -o '[a-z][a-z][a-z][a-z][a-z]*' > autocomplete-words.txt
    var enAutocompleteWords = [
        'able', 'across', 'adjective', 'afraid', 'after', 'agreed', 'ahead',
        'almost', 'already', 'also', 'although', 'always', 'angle', 'animal',
        'another', 'answer', 'around', 'arrived', 'away', 'baby', 'back',
        'ball', 'bank', 'base', 'been', 'before', 'behind', 'being', 'bill',
        'birds', 'black', 'blue', 'body', 'bones', 'book', 'born', 'branches',
        'break', 'burning', 'business', 'call', 'came', 'case', 'cells',
        'certain', 'check', 'choose', 'church', 'circle', 'city', 'class',
        'climbed', 'coast', 'copy', 'cost', 'cotton', 'covered', 'cows',
        'create', 'cried', 'current', 'dance', 'dark', 'deep', 'developed',
        'dictionary', 'died', 'doctor', 'dollars', 'door', 'down', 'dress',
        'drive', 'drop', 'during', 'each', 'edge', 'effect', 'eggs', 'eight',
        'either', 'else', 'energy', 'engine', 'enjoy', 'enough', 'especially',
        'exercise', 'fall', 'fast', 'father', 'fear', 'field', 'filled',
        'fish', 'five', 'flat', 'follow', 'fraction', 'friends', 'fruit',
        'full', 'game', 'garden', 'gave', 'general', 'girl', 'give', 'glass',
        'gold', 'gone', 'good', 'government', 'grass', 'guess', 'hair', 'halt',
        'hand', 'hard', 'have', 'high', 'hill', 'home', 'hope', 'horse',
        'huge', 'human', 'idea', 'important', 'information', 'iron', 'island',
        'joined', 'jumped', 'just', 'keep', 'kept', 'killed', 'knew', 'lady',
        'lake', 'large', 'last', 'later', 'laughed', 'left', 'legs', 'length',
        'less', 'level', 'light', 'like', 'line', 'little', 'live', 'located',
        'long', 'look', 'lost', 'loud', 'love', 'machine', 'made', 'main',
        'major', 'make', 'meet', 'melody', 'members', 'middle', 'might',
        'miss', 'modern', 'molecules', 'moment', 'moon', 'most', 'mother',
        'much', 'name', 'near', 'necessary', 'need', 'never', 'next', 'night',
        'nose', 'noun', 'object', 'observe', 'ocean', 'often', 'once', 'only',
        'open', 'opposite', 'order', 'other', 'over', 'oxygen', 'page',
        'paper', 'pattern', 'people', 'phrase', 'piece', 'please', 'plural',
        'poem', 'point', 'pole', 'poor', 'pounds', 'power', 'practice',
        'printed', 'pulled', 'pushed', 'questions', 'race', 'radio', 'rather',
        'region', 'return', 'rhythm', 'rich', 'ride', 'right', 'ring', 'rise',
        'river', 'road', 'rock', 'rolled', 'rope', 'rose', 'round', 'rule',
        'safe', 'same', 'sand', 'save', 'scale', 'school', 'score', 'sell',
        'separate', 'serve', 'ship', 'side', 'silent', 'sister', 'size',
        'skin', 'slowly', 'small', 'smell', 'smiled', 'snow', 'soft', 'soil',
        'soon', 'space', 'spot', 'square', 'such', 'suddenly', 'suffix',
        'swim', 'syllables', 'symbols', 'system', 'table', 'tail', 'take',
        'tell', 'temperature', 'terms', 'test', 'thus', 'tied', 'time', 'tiny',
        'today', 'together', 'told', 'tone', 'total', 'touch', 'tree',
        'trouble', 'tube', 'turn', 'type', 'uncle', 'unit', 'until', 'upon',
        'usually', 'various', 'view', 'village', 'visit', 'voice', 'vowel',
        'wait', 'want', 'waves', 'week', 'weight', 'well', 'went', 'were',
        'what', 'wide', 'wife', 'wire', 'wish', 'wood', 'yard', 'year',
        'yellow',

    // grep -v '[A-Z]' < 3000-common-words.txt | sort | grep ... | sed -e 's/\(...\)\(.*\)/\1\2 \1/' | uniq -c -f 1 | grep '^ *1 ' | grep -o '[a-z][a-z][a-z][a-z][a-z]*' > autocomplete-words-2.txt
        'abandon', 'ability', 'able', 'abroad', 'abuse', 'academic', 'acid',
        'acknowledge', 'acquire', 'across', 'adapt', 'adequate', 'adult',
        'afraid', 'aggressive', 'ahead', 'album', 'alcohol', 'alive', 'almost',
        'already', 'also', 'always', 'amazing', 'ancient', 'animal', 'another',
        'answer', 'anticipate', 'anxiety', 'architect', 'area', 'arise',
        'around', 'aside', 'asleep', 'aspect', 'atmosphere', 'audience',
        'available', 'average', 'avoid', 'awful', 'baby', 'bake', 'beer',
        'before', 'being', 'beyond', 'bike', 'bind', 'biological', 'blind',
        'blue', 'body', 'boss', 'boundary', 'bowl', 'brush', 'buck', 'budget',
        'bullet', 'bunch', 'cake', 'cause', 'ceiling', 'church', 'cigarette',
        'code', 'coffee', 'cognitive', 'cost', 'cotton', 'crucial', 'cycle',
        'daily', 'damage', 'daughter', 'degree', 'deny', 'derive', 'dialogue',
        'dimension', 'door', 'dozen', 'drop', 'drug', 'during', 'dust', 'duty',
        'mail', 'each', 'eager', 'edge', 'eight', 'either', 'elderly',
        'embrace', 'emission', 'enable', 'enforcement', 'enhance', 'enjoy',
        'ensure', 'episode', 'error', 'escape', 'especially', 'evidence',
        'fabric', 'fade', 'fault', 'federal', 'fellow', 'female', 'fence',
        'fiber', 'fiction', 'field', 'five', 'flight', 'focus', 'fuel',
        'future', 'gain', 'game', 'gang', 'gaze', 'gear', 'gesture', 'ghost',
        'giant', 'goal', 'good', 'hair', 'have', 'heel', 'height', 'hide',
        'hill', 'hire', 'hope', 'huge', 'hurt', 'husband', 'hypothesis',
        'ignore', 'ingredient', 'injury', 'inquiry', 'iron', 'island', 'issue',
        'item', 'jacket', 'jail', 'joke', 'juice', 'jump', 'junior', 'jury',
        'keep', 'kick', 'kiss', 'kitchen', 'knee', 'knife', 'lack', 'lady',
        'lake', 'last', 'left', 'lemon', 'length', 'level', 'license', 'light',
        'loud', 'machine', 'magazine', 'mechanism', 'middle', 'might', 'much',
        'multiple', 'murder', 'mutual', 'myth', 'naked', 'name', 'need',
        'next', 'nice', 'night', 'nine', 'nobody', 'noise', 'nomination',
        'nose', 'novel', 'nuclear', 'nurse', 'obligation', 'obtain', 'ocean',
        'often', 'okay', 'once', 'ongoing', 'onion', 'onto', 'opinion',
        'option', 'orange', 'ought', 'page', 'paper', 'pause', 'peer',
        'penalty', 'people', 'pepper', 'phase', 'phenomenon', 'philosophy',
        'phrase', 'piano', 'pipe', 'pitch', 'plot', 'plus', 'pocket', 'point',
        'poverty', 'pull', 'punishment', 'push', 'question', 'quote',
        'reinforce', 'reject', 'rhythm', 'rifle', 'right', 'ring', 'river',
        'road', 'rock', 'romantic', 'rope', 'rose', 'rule', 'rural', 'rush',
        'sacred', 'sake', 'sauce', 'segment', 'seize', 'separate', 'sequence',
        'session', 'shrug', 'shut', 'sick', 'side', 'sister', 'size', 'slave',
        'sleep', 'smell', 'smile', 'snap', 'snow', 'called', 'soil', 'soon',
        'sophisticated', 'space', 'split', 'style', 'system', 'tactic', 'tail',
        'take', 'tank', 'target', 'text', 'thus', 'ticket', 'tight', 'time',
        'tiny', 'tissue', 'title', 'tobacco', 'today', 'together', 'toss',
        'tube', 'tunnel', 'turn', 'ugly', 'unable', 'uncle', 'unfortunately',
        'unknown', 'until', 'unusual', 'upon', 'upper', 'urban', 'urge',
        'utility', 'vacation', 'vast', 'vegetable', 'vehicle', 'venture',
        'vessel', 'veteran', 'video', 'village', 'vital', 'voice',
        'vulnerable', 'wage', 'wait', 'wake', 'wave', 'wedding', 'wife',
        'wipe', 'wire', 'woman', 'wrap', 'wrong', 'yard', 'yield', 'zone',

    // from https://en.wikipedia.org/wiki/Most_common_words_in_English
        'time', 'person', 'year', 'way', 'day', 'thing', 'man', 'world',
        'life', 'hand', 'part', 'child', 'eye', 'woman', 'place', 'work',
        'week', 'case', 'point', 'government', 'company', 'number', 'group',
        'problem', 'fact', 'be', 'have', 'do', 'say', 'get', 'make', 'go',
        'know', 'take', 'see', 'come', 'think', 'look', 'want', 'give', 'use',
        'find', 'tell', 'ask', 'work', 'seem', 'feel', 'try', 'leave', 'call',
        'good', 'new', 'first', 'last', 'long', 'great', 'little', 'own',
        'other', 'old', 'right', 'big', 'high', 'different', 'small', 'large',
        'next', 'early', 'young', 'important', 'few', 'public', 'bad', 'same',
        'able', 'to', 'of', 'in', 'for', 'on', 'with', 'at', 'by', 'from',
        'up', 'about', 'into', 'over', 'after', 'beneath', 'under', 'above',
        'the', 'and', 'a', 'that', 'I', 'it', 'not', 'he', 'as', 'you', 'this',
        'but', 'his', 'they', 'her', 'she', 'or', 'an', 'will', 'my', 'one',
        'all', 'would', 'there', 'their',

    // hand-picked words: software
        'application', 'server', 'network', 'Ethernet',
        'architecture', 'request', 'protocol', 'abstract', 'virtual',
        'container', 'virtualization', 'operating', 'system', 'instruction',
        'building', 'build', 'continuous', 'integration', 'interface',
        'module', 'assembly', 'package', 'deploy', 'deployment', 'service',
        'optimize', 'optimization', 'understand', 'testing', 'compiler',
        'latency' ,'performance', 'incremental', 'throughput', 'capacity',
        'database', 'infrastructure',
        'Internet', 'telecommunications', 'provider', 'platform',

    // hand-picked words: computer security
        'computer', 'software', 'hardware', 'exploit', 'vulnerability',
        'firmware', 'malware', 'attack', 'intrusion', 'protection', 'detection',
        'embedded', 'device', 'peripheral', 'implementation', 'implement',
        'disclosure', 'publication', 'research', 'announce', 'announcement',
        'communicate', 'communication', 'community', 'communities',
        'anonymous', 'pseudonymous', 'identification', 'password', 'privacy',
        'public key', 'private key', 'encryption', 'decryption', 'integrity',
        'encryption key', 'decryption key', 'symmetric encryption', 'intercept',
        'man-in-the-middle', 'obfuscation', 'steganography', 'security',
        'anonymity', 'authentication', 'authorization', 'insecure',

    // hand-picked words: society
        'national', 'international', 'political', 'economic', 'organization',
        'activist', 'defense', 'testimony', 'justice', 'injustice',
        'jurisdiction', 'observation', 'indictment', 'prosecution',
        'participant', 'volunteer', 'connect', 'remember', 'individual',
        'newspaper', 'broadcast',
        'Chaos Communication', 'Communication Congress', 'Congress',
        'United States', 'Germany', 'Europe', 'Canada',

    // hand-picked words: science
        'accelerate', 'problem', 'solution', 'science',
        'hypothesis', 'experiment',
        'expensive', 'penalty', 'advantage', 'disadvantage',

    // hand-picked words: space
        'colonization', 'species', 'technology', 'challenge',
        'humanity', 'solar system', 'planet', 'exoplanet',
        'satellite', 'telescope', 'future', 'planetary', 'rocket',
        'Earth', 'Mars', 'colony', 'asteroid', 'space shuttle', 'shuttle',
        'interstellar', 'expansion', 'cosmos', 'reasonable', 'conditions',
        'atmosphere', 'agriculture', 'civilization', 'settlement',
        'residential', 'supply chain', 'transport',

    // hand-picked words: other
        'something', 'everything', 'anything',
        'someone', 'everyone', 'anyone',
        'somebody', 'everybody', 'anybody',
        'somewhere', 'everywhere', 'anywhere',
        'overwhelm', 'overwhelmed', 'overwhelming',
        'dangerous', 'significant', 'remarkable', 'critical', 'devastating',
        'massive', 'widespread', 'profound', 'phenomenon', 'probably',
        'probability', 'statistical', 'user interface', 'unlimited',
        'insignificant', 'underestimate'
    ];

    var deAutocompleteWords = [
        'abbauen', 'ablehnen', 'abwarten', 'afrikanischen', 'aggressiv',
        'agieren', 'ahnen', 'ankommt', 'anlegen', 'anmelden', 'annehmen',
        'anpassen', 'anwesend', 'asiatischen', 'auch', 'bald', 'basiert',
        'bequem', 'birgt', 'blutigen', 'brutal', 'buchen', 'dabei', 'dachte',
        'dadurch', 'dagegen', 'decken', 'detaillierte', 'diplomatischen',
        'doch', 'donnerstags', 'dotierten', 'drucken', 'dumm', 'effektiv',
        'egal', 'ehrlich', 'energisch', 'erbracht', 'ereignete', 'erprobt',
        'essen', 'ethnischen', 'etliche', 'euch', 'europaweit', 'eventuell',
        'exakt', 'fahren', 'flexibel', 'flog', 'froh', 'gearbeitet', 'gilt',
        'grundlegende', 'hast', 'hoch', 'http', 'hundert', 'ignoriert',
        'immer', 'wieder', 'inhaltlich', 'inklusive', 'inmitten', 'inwieweit',
        'inzwischen', 'irischen', 'isoliert', 'jeher', 'just', 'kaputt',
        'kirchlichen', 'klug', 'krank', 'laden', 'lediglich', 'lenken',
        'lesen', 'leuchtet', 'live', 'logische', 'lohnt', 'lustig', 'mahnte',
        'maximal', 'messen', 'mich', 'mochte', 'momentan', 'nach',
        'nachzudenken', 'nein', 'nicht', 'nicht', 'einmal', 'nicht', 'nichts',
        'nichts', 'nimmt', 'nirgendwo', 'nominiert', 'null', 'obwohl', 'oder',
        'olympischen', 'online', 'paar', 'packen', 'peinlich', 'plus', 'quer',
        'raten', 'raus', 'renommierten', 'retten', 'rutschte', 'sachlich',
        'satt', 'signalisiert', 'skeptisch', 'sobald', 'soeben', 'genannten',
        'somit', 'soviel', 'systematisch', 'tanzen', 'telefonisch', 'testen',
        'toll', 'bereinstimmungen', 'inärdatei', 'tandardeingabe',
        'umliegenden', 'unerwartet', 'unheimlich', 'unklar', 'unter',
        'anderem', 'vage', 'vehement', 'allem', 'weder', 'winzigen', 'wobei',
        'wodurch', 'womit', 'wonach', 'wovon', 'wozu', 'wuchs', 'zudem',
        'zukommen', 'anderen', 'einen', 'zuordnen',

        'Computer', 'Software', 'Hardware', 'Exploit', 'Sicherheitslücke',
        'Firmware', 'Attacke', 'Veröffentlichung', 'Device', 'Gerät',
        'Malware', 'Forschung', 'Nachweis', 'bekanntgeben', 'veröffentlichen',
        'implementieren', 'ankündigen', 'Community', 'Chaos', 'Communities',
        'Nation', 'Staat', 'Überwachung', 'Privatsphäre', 'international',
        'politisch', 'Politik', 'Wirtschaft', 'Organisation', 'Gemeinschaft',
        'staatlich', 'Freiheit', 'Angst', 'Aktivist', 'Aktivismus', 'Abwehr',
        'Cyber', 'Justiz', 'Gericht', 'Prozess', 'Defense', 'Gerechtigkeit',
        'Ungerechtigkeit', 'Zeuge', 'Aussage', 'Gutachten', 'Beobachtung',
        'beobachten', 'Verfahren', 'Chaos Communication',
        'Communication Congress', 'Congress', 'Anwendung', 'Application',
        'Server', 'Client', 'Netzwerk', 'Ethernet', 'Architektur', 'Request',
        'Protokoll', 'abstrakt', 'virtuell', 'Virtualisierung',
        'Operating System', 'Betriebssystem', 'Container', 'Einführung',
        'Handbuch', 'bauen', 'kompilieren', 'kontinuierlich', 'Integration',
        'Continuous Integration', 'Modul', 'Assembly', 'Assembler',
        'Packet', 'deploy',
        'Cloud', 'Wolke', 'beschleunigen', 'Hypothese', 'Lösung',
        'Wissenschaft', 'Chemie', 'Rechnen', 'Rechner', 'Experiment',
        'Infrastruktur', 'Datenbank', 'Optimierung', 'Optimieren',
        'optimieren', 'experimentieren', 'verstehen', 'Verständnis', 'Testen',
        'Unit Tests', 'Kompiler', 'kompilieren', 'Latenz', 'Durchsatz',
        'Performanz', 'zuwachsend', 'wachsend', 'Kapazität', 'teuer',
        'Penalty', 'Strafe', 'Vorteil', 'Nachteil', 'Teilnehmer',
        'Freiwilliger', 'verbinden', 'Verbindung', 'erinnern', 'Gedenken',
        'irgendjemand', 'irgendwer', 'irgendwas', 'jede', 'Internet',
        'Provider', 'Telekommunikationsprovider', 'Platform', 'anonym',
        'Passwort', 'Authentifizierung', 'authentifizieren', 'Pseudonym',
        'Passwort', 'Amerika', 'Deutschland', 'Platform', 'Europa', 'Kanada',
        'Frankreich', 'Private Key', 'Public Key', 'Verschlüsselung',
        'verschlüsslen', 'Entschlüsselung', 'entschlüsseln', 'Integrität',
        'symmetrisch', 'Intercept', 'Man-in-the-Middle', 'Sicherheit',
        'Verschleierung', 'Obfuscation', 'Sicherheit', 'Anonymität',
        'kritisch'
    ];

    var resetDictionary = function (initialWords) {
        completions = {};
        isCompleted = {};
        for (var i = initialWords.length - 1; i >= 0; i--) {
            addCompletion(initialWords[i]);
        }
    };

    var initialWordSets = {
        'en': enAutocompleteWords,
        'de': deAutocompleteWords
    };

    resetDictionary(initialWordSets['en']);

    window.setTimeout(function() {
        document.body.style.lineHeight = '1.5';
        var pendingArea = document.querySelector('div[style="display: flex; flex-direction: column-reverse;"]');
        pendingArea.style.padding = '2em 0 0 0';
        pendingArea.style.opacity = '0.6';
        pendingArea.style.fontStyle = 'italic';

        var field = document.querySelector('input');
        field.style.fontFamily = 'Roboto';
        field.style.fontSize = '16px';

        var parent = field.parentElement;
        parent.style.position = 'relative';

        var hint = document.createElement('span');
        hint.style.fontSize = '16px';
        hint.style.position = 'absolute';
        hint.style.left = field.offsetLeft + 'px';
        hint.style.bottom = '2px';
        hint.style.height = field.offsetHeight + 'px';
        hint.style.right = '0px';
        hint.style.color = '#2c2';
        hint.style.pointerEvents = 'none';
        hint.style.textAlign = 'right';
        hint.innerText = 'use TAB to autocomplete\xa0\xa0';
        parent.appendChild(hint);

        var measure = document.createElement('span');
        measure.style.position = 'absolute';
        measure.style.opacity = '0';
        measure.style.fontSize = '16px';
        parent.appendChild(measure);

        var buttonBox = document.createElement('div');
        buttonBox.style.position = 'absolute';
        buttonBox.style.top = '2px';
        buttonBox.style.right = '6px';
        buttonBox.style.zIndex = '9999';
        buttonBox.style.fontFamily = 'Roboto';
        buttonBox.style.fontSize = '12px';
        buttonBox.innerText = 'Reset autocompletions to:\xa0';
        document.body.appendChild(buttonBox);

        var isCaseSensitive = {
            'en': true,
            'de': false
        };
        var addResetButton = function(lang) {
            var reset = document.createElement('button');
            reset.innerText = lang;
            reset.addEventListener('click', function() {
                caseSensitiveCompletion = isCaseSensitive[lang];
                resetDictionary(initialWordSets[lang]);
            });
            buttonBox.appendChild(reset);
        };
        addResetButton('en');
        addResetButton('de');

        function measureWidth(text) {
            measure.innerText = text;
            return measure.offsetWidth;
        }

        var inputEvent = new Event('input', { bubbles: true });
        var lastWord = '';
        var lastTwoWords = '';

        var handleKeyDown = function(keyEvent) {
            if (keyEvent.keyCode === 9) {
                keyEvent.preventDefault();  // don't move focus
            }
        };
        var handleKeyUp = function(keyEvent) {
            var keyCode = keyEvent.keyCode;
            if (keyCode === 32 || keyCode === 13) {
                var word = lastWord.replace(/[^a-zA-Z0-9\xc0-\xff]*$/, '');  // ignore trailing punctuation
                timesTyped[word] = (timesTyped[word] || 0) + 1;
                if (timesTyped[word] >= 2) {
                    addCompletion(word);
                }
                if (lastTwoWords) {
                    var twoWords = lastTwoWords.replace(/[^a-zA-Z0-9\xc0-\xff]*$/, '');  // ignore trailing punctuation
                    timesTyped[twoWords] = (timesTyped[twoWords] || 0) + 1;
                    if (timesTyped[twoWords] >= 2) {
                        addCompletion(twoWords);
                    }
                }
            }

            lastWord = field.value.replace(/.* /, '');
            if (!caseSensitiveCompletion) lastWord = lastWord.toLowerCase();
            var twoWordMatch = field.value.match(/\S\S\S+ \S\S\S+$/);
            lastTwoWords = twoWordMatch ? twoWordMatch[0] : null;
            completion = completions[lastWord];
            if (keyCode === 9 && completion) {  // tab
                field.value += completion;
                field.dispatchEvent(inputEvent);  // make React notice the new text
                lastWord = field.value.replace(/.* /, '');  // maybe complete a longer word
                if (!caseSensitiveCompletion) lastWord = lastWord.toLowerCase();
                completion = completions[lastWord];
            }
            hint.innerText = completion || '';
            if (completion) {
                hint.style.left = (4 + measureWidth(field.value)) + 'px';
                hint.style.textAlign = 'left';
            }
        };
        document.addEventListener('keydown', handleKeyDown);
        document.addEventListener('keyup', handleKeyUp);
    }, 2000);
})();