From 5ee7bb9ec28b9bbfc72cb703ac9a01f5af5ee7d9 Mon Sep 17 00:00:00 2001 From: Ian Coleman Date: Thu, 20 Oct 2016 16:42:15 +1100 Subject: [PATCH] Multiple language functionality added --- src/index.html | 3 + src/js/index.js | 157 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 145 insertions(+), 15 deletions(-) diff --git a/src/index.html b/src/index.html index fc3a6d1..56d73e6 100644 --- a/src/index.html +++ b/src/index.html @@ -40,6 +40,9 @@ box-shadow: inset 0 1px 1px rgba(0,0,0,.0); -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.0); } + .phrase { + word-break: keep-all; + } .strength { /* override mobile width from bootstrap */ width: auto!important; diff --git a/src/js/index.js b/src/js/index.js index 69f5eab..c5f6c11 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -1,6 +1,8 @@ (function() { - var mnemonic = new Mnemonic("english"); + // mnemonics is populated as required by getLanguage + var mnemonics = { "english": new Mnemonic("english") }; + var mnemonic = mnemonics["english"]; var seed = null var bip32RootKey = null; var bip32ExtendedKey = null; @@ -44,6 +46,7 @@ DOM.indexToggle = $(".index-toggle"); DOM.addressToggle = $(".address-toggle"); DOM.privateKeyToggle = $(".private-key-toggle"); + DOM.languages = $(".languages a"); function init() { // Events @@ -63,6 +66,7 @@ DOM.indexToggle.on("click", toggleIndexes); DOM.addressToggle.on("click", toggleAddresses); DOM.privateKeyToggle.on("click", togglePrivateKeys); + DOM.languages.on("click", languageChanged); disableForms(); hidePending(); hideValidationError(); @@ -94,6 +98,7 @@ function phraseChanged() { showPending(); hideValidationError(); + setMnemonicLanguage(); // Get the mnemonic phrase var phrase = DOM.phrase.val(); var errorText = findPhraseErrors(phrase); @@ -163,6 +168,7 @@ clearDisplay(); showPending(); setTimeout(function() { + setMnemonicLanguage(); var phrase = generateRandomPhrase(); if (!phrase) { return; @@ -171,6 +177,20 @@ }, 50); } + function languageChanged() { + setTimeout(function() { + setMnemonicLanguage(); + if (DOM.phrase.val().length > 0) { + var newPhrase = convertPhraseToNewLanguage(); + DOM.phrase.val(newPhrase); + phraseChanged(); + } + else { + DOM.generate.trigger("click"); + } + }, 50); + } + function toggleIndexes() { showIndex = !showIndex; $("td.index span").toggleClass("invisible"); @@ -246,26 +266,19 @@ // TODO make this right // Preprocess the words phrase = mnemonic.normalizeString(phrase); - var parts = phrase.split(" "); - var proper = []; - for (var i=0; i 0) { - // TODO check that lowercasing is always valid to do - proper.push(part.toLowerCase()); - } - } - var properPhrase = proper.join(' '); + var words = phraseToWordArray(phrase); // Check each word - for (var i=0; i 0) { + var words = phraseToWordArray(phrase); + var languageMatches = {}; + for (l in WORDLISTS) { + // Track how many words match in this language + languageMatches[l] = 0; + for (var i=0; i -1; + if (wordInLanguage) { + languageMatches[l]++; + } + } + // Find languages with most word matches. + // This is made difficult due to commonalities between Chinese + // simplified vs traditional. + var mostMatches = 0; + var mostMatchedLanguages = []; + for (var l in languageMatches) { + var numMatches = languageMatches[l]; + if (numMatches > mostMatches) { + mostMatches = numMatches; + mostMatchedLanguages = [l]; + } + else if (numMatches == mostMatches) { + mostMatchedLanguages.push(l); + } + } + } + if (mostMatchedLanguages.length > 0) { + // Use first language and warn if multiple detected + language = mostMatchedLanguages[0]; + if (mostMatchedLanguages.length > 1) { + console.warn("Multiple possible languages"); + console.warn(mostMatchedLanguages); + } + } + } + return language; + } + + function getLanguageFromUrl() { + return window.location.hash.substring(1); + } + + function setMnemonicLanguage() { + var language = getLanguage(); + // Load the bip39 mnemonic generator for this language if required + if (!(language in mnemonics)) { + mnemonics[language] = new Mnemonic(language); + } + mnemonic = mnemonics[language]; + } + + function convertPhraseToNewLanguage() { + var oldLanguage = getLanguageFromPhrase(); + var newLanguage = getLanguageFromUrl(); + var oldPhrase = DOM.phrase.val(); + var oldWords = phraseToWordArray(oldPhrase); + var newWords = []; + for (var i=0; i 0) { + noBlanks.push(word); + } + } + return noBlanks; + } + + // TODO look at jsbip39 - mnemonic.joinWords + function wordArrayToPhrase(words) { + var phrase = words.join(" "); + var language = getLanguageFromPhrase(phrase); + if (language == "japanese") { + phrase = words.join("\u3000"); + } + return phrase; + } + var networks = [ { name: "Bitcoin", -- 2.41.0