diff options
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/bg/background.html | 1 | ||||
| -rw-r--r-- | ext/bg/js/ankiweb.js | 180 | ||||
| -rw-r--r-- | ext/bg/js/options-form.js | 20 | ||||
| -rw-r--r-- | ext/bg/js/options.js | 6 | ||||
| -rw-r--r-- | ext/bg/js/yomichan.js | 3 | ||||
| -rw-r--r-- | ext/bg/options.html | 18 | ||||
| -rw-r--r-- | ext/manifest.json | 5 | 
7 files changed, 8 insertions, 225 deletions
| diff --git a/ext/bg/background.html b/ext/bg/background.html index 49fc6d0f..3ecfa3dc 100644 --- a/ext/bg/background.html +++ b/ext/bg/background.html @@ -4,7 +4,6 @@      <script src="../lib/handlebars.min.js"></script>      <script src="../lib/dexie.min.js"></script>      <script src="../lib/wanakana.min.js"></script> -    <script src="js/ankiweb.js"></script>      <script src="js/ankiconnect.js"></script>      <script src="js/ankinull.js"></script>      <script src="js/templates.js"></script> diff --git a/ext/bg/js/ankiweb.js b/ext/bg/js/ankiweb.js deleted file mode 100644 index 69a1b44d..00000000 --- a/ext/bg/js/ankiweb.js +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2016  Alex Yatskov <alex@foosoft.net> - * Author: Alex Yatskov <alex@foosoft.net> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -class AnkiWeb { -    constructor(username, password) { -        this.username = username; -        this.password = password; -        this.noteInfo = null; - -        chrome.webRequest.onBeforeSendHeaders.addListener( -            details => { -                details.requestHeaders.push({name: 'Origin', value: 'https://ankiweb.net'}); -                return {requestHeaders: details.requestHeaders}; -            }, -            {urls: ['https://ankiweb.net/*']}, -            ['blocking', 'requestHeaders'] -        ); -    } - -    addNote(note) { -        return this.retrieve().then(info => { -            const model = info.models.find(m => m.name === note.modelName); -            if (!model) { -                return Promise.reject('cannot add note model provided'); -            } - -            const fields = []; -            for (const field of model.fields) { -                fields.push(note.fields[field]); -            } - -            const data = { -                data: JSON.stringify([fields, note.tags.join(' ')]), -                mid: model.id, -                deck: note.deckName, -                csrf_token: info.token -            }; - -            return AnkiWeb.loadAccountPage('https://ankiweb.net/edit/save', data, this.username, this.password); -        }).then(response => response !== '0'); -    } - -    canAddNotes(notes) { -        return Promise.resolve(new Array(notes.length).fill(true)); -    } - -    getDeckNames() { -        return this.retrieve().then(info => info.deckNames); -    } - -    getModelNames() { -        return this.retrieve().then(info => info.models.map(m => m.name)); -    } - -    getModelFieldNames(modelName) { -        return this.retrieve().then(info => { -            const model = info.models.find(m => m.name === modelName); -            return model ? model.fields : []; -        }); -    } - -    retrieve() { -        if (this.noteInfo !== null) { -            return Promise.resolve(this.noteInfo); -        } - -        return AnkiWeb.scrape(this.username, this.password).then(({deckNames, models, token}) => { -            this.noteInfo = {deckNames, models, token}; -            return this.noteInfo; -        }); -    } - -    logout() { -        return AnkiWeb.loadPage('https://ankiweb.net/account/logout', null); -    } - -    static scrape(username, password) { -        return AnkiWeb.loadAccountPage('https://ankiweb.net/edit/', null, username, password).then(response => { -            const modelsMatch = /editor\.models = (.*}]);/.exec(response); -            if (modelsMatch === null) { -                return Promise.reject('failed to scrape model data'); -            } - -            const decksMatch = /editor\.decks = (.*}});/.exec(response); -            if (decksMatch === null) { -                return Promise.reject('failed to scrape deck data'); -            } - -            const tokenMatch = /editor\.csrf_token = \'(.*)\';/.exec(response); -            if (tokenMatch === null) { -                return Promise.reject('failed to acquire csrf_token'); -            } - -            const modelsJson = JSON.parse(modelsMatch[1]); -            const decksJson = JSON.parse(decksMatch[1]); -            const token = tokenMatch[1]; - -            const deckNames = Object.keys(decksJson).map(d => decksJson[d].name); -            const models = []; -            for (const modelJson of modelsJson) { -                models.push({ -                    name: modelJson.name, -                    id: modelJson.id, -                    fields: modelJson.flds.map(f => f.name) -                }); -            } - -            return {deckNames, models, token}; -        }); -    } - -    static login(username, password, token) { -        if (username.length === 0 || password.length === 0) { -            return Promise.reject('login credentials not specified'); -        } - -        const data = {username, password, csrf_token: token, submitted: 1}; -        return AnkiWeb.loadPage('https://ankiweb.net/account/login', data).then(response => { -            if (!response.includes('class="mitem"')) { -                return Promise.reject('failed to authenticate'); -            } -        }); -    } - -    static loadAccountPage(url, data, username, password) { -        return AnkiWeb.loadPage(url, data).then(response => { -            if (response.includes('name="password"')) { -                const tokenMatch = /name="csrf_token" value="(.*)"/.exec(response); -                if (tokenMatch === null) { -                    return Promise.reject('failed to acquire csrf_token'); -                } - -                return AnkiWeb.login(username, password, tokenMatch[1]).then(() => AnkiWeb.loadPage(url, data)); -            } else { -                return response; -            } -        }); -    } - -    static loadPage(url, data) { -        return new Promise((resolve, reject) => { -            let dataEnc = null; -            if (data) { -                const params = []; -                for (const key in data) { -                    params.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`); -                } - -                dataEnc = params.join('&'); -            } - -            const xhr = new XMLHttpRequest(); -            xhr.addEventListener('error', () => reject('failed to execute network request')); -            xhr.addEventListener('load', () => resolve(xhr.responseText)); -            if (dataEnc) { -                xhr.open('POST', url); -                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); -                xhr.send(dataEnc); -            } else { -                xhr.open('GET', url); -                xhr.send(); -            } -        }); -    } -} diff --git a/ext/bg/js/options-form.js b/ext/bg/js/options-form.js index ae13dbb1..8216f158 100644 --- a/ext/bg/js/options-form.js +++ b/ext/bg/js/options-form.js @@ -39,8 +39,6 @@ function getFormValues() {          optsNew.scanLength = parseInt($('#scan-length').val(), 10);          optsNew.ankiMethod = $('#anki-method').val(); -        optsNew.ankiUsername = $('#anki-username').val(); -        optsNew.ankiPassword = $('#anki-password').val();          optsNew.ankiCardTags = $('#anki-card-tags').val().split(/[,; ]+/);          optsNew.sentenceExtent = parseInt($('#sentence-extent').val(), 10);          optsNew.ankiTermDeck = $('#anki-term-deck').val(); @@ -67,13 +65,8 @@ function getFormValues() {  function updateVisibility(opts) {      switch (opts.ankiMethod) { -        case 'ankiweb': -            $('#anki-general').show(); -            $('.anki-login').show(); -            break;          case 'ankiconnect':              $('#anki-general').show(); -            $('.anki-login').hide();              break;          default:              $('#anki-general').hide(); @@ -102,8 +95,6 @@ $(document).ready(() => {          $('#scan-length').val(opts.scanLength);          $('#anki-method').val(opts.ankiMethod); -        $('#anki-username').val(opts.ankiUsername); -        $('#anki-password').val(opts.ankiPassword);          $('#anki-card-tags').val(opts.ankiCardTags.join(' '));          $('#sentence-extent').val(opts.sentenceExtent); @@ -430,16 +421,7 @@ function onOptionsChanged(e) {          return saveOptions(optsNew).then(() => {              yomichan().setOptions(optsNew);              updateVisibility(optsNew); - -            const loginChanged = -                optsNew.ankiUsername !== optsOld.ankiUsername || -                optsNew.ankiPassword !== optsOld.ankiPassword; - -            if (loginChanged && optsNew.ankiMethod === 'ankiweb') { -                showAnkiError(null); -                showAnkiSpinner(true); -                return anki().logout().then(() => populateAnkiDeckAndModel(optsNew)); -            } else if (loginChanged || optsNew.ankiMethod !== optsOld.ankiMethod) { +            if (optsNew.ankiMethod !== optsOld.ankiMethod) {                  showAnkiError(null);                  showAnkiSpinner(true);                  return populateAnkiDeckAndModel(optsNew); diff --git a/ext/bg/js/options.js b/ext/bg/js/options.js index 28448b96..f1fe0dac 100644 --- a/ext/bg/js/options.js +++ b/ext/bg/js/options.js @@ -31,8 +31,6 @@ function sanitizeOptions(options) {          dictionaries: {},          ankiMethod: 'disabled', -        ankiUsername: '', -        ankiPassword: '',          ankiCardTags: ['yomichan'],          sentenceExtent: 200, @@ -50,6 +48,10 @@ function sanitizeOptions(options) {          }      } +    if (options.ankiMethod === 'ankiweb') { +        options.ankiMethod = 'disabled'; +    } +      return options;  } diff --git a/ext/bg/js/yomichan.js b/ext/bg/js/yomichan.js index ef80f16c..12dd89ac 100644 --- a/ext/bg/js/yomichan.js +++ b/ext/bg/js/yomichan.js @@ -94,9 +94,6 @@ class Yomichan {          this.options = options;          switch (options.ankiMethod) { -            case 'ankiweb': -                this.anki = new AnkiWeb(options.ankiUsername, options.ankiPassword); -                break;              case 'ankiconnect':                  this.anki = new AnkiConnect();                  break; diff --git a/ext/bg/options.html b/ext/bg/options.html index 7ad5ea5c..0ef65abb 100644 --- a/ext/bg/options.html +++ b/ext/bg/options.html @@ -124,9 +124,8 @@                  <p class="help-block">                      Yomichan features automatic flashcard creation for <a href="http://ankisrs.net/">Anki</a>, a free application -                    designed to help you retain knowledge. While the <a href="https://foosoft.net/projects/anki-connect/">AnkiConnect</a> plugin -                    offers the best experience, it is also possible to create flashcards through <a href="https://ankiweb.net/">AnkiWeb</a>, -                    provided you already have an account. +                    designed to help you retain knowledge. This functionality requires prior installation of the +                    <a href="https://foosoft.net/projects/anki-connect/">AnkiConnect</a> plugin.                  </p>                  <div class="alert alert-danger" id="anki-error"> @@ -139,23 +138,10 @@                      <select class="form-control" id="anki-method">                          <option value="disabled">Disabled (no auto flashcard creation)</option>                          <option value="ankiconnect">AnkiConnect (requires the AnkiConnect plugin)</option> -                        <option value="ankiweb">AnkiWeb (requires an account on AnkiWeb)</option>                      </select>                  </div>                  <div id="anki-general"> -                    <div class="row"> -                        <div class="form-group anki-login col-xs-6"> -                            <label for="anki-username">Username</label> -                            <input type="text" id="anki-username" class="form-control anki-credential"> -                        </div> - -                        <div class="form-group anki-login col-xs-6"> -                            <label for="anki-password">Password</label> -                            <input type="password" id="anki-password" class="form-control anki-credential"> -                        </div> -                    </div> -                      <div class="form-group">                          <label for="anki-card-tags">Card tags (comma or space separated)</label>                          <input type="text" id="anki-card-tags" class="form-control"> diff --git a/ext/manifest.json b/ext/manifest.json index e1c1b7a9..09905cd8 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -1,7 +1,7 @@  {      "manifest_version": 2,      "name": "Yomichan", -    "version": "1.0.2", +    "version": "1.0.3",      "description": "Japanese dictionary with Anki integration",      "icons": {"16": "img/icon16.png", "48": "img/icon48.png", "128": "img/icon128.png"}, @@ -25,11 +25,8 @@          "page": "bg/options.html"      },      "permissions": [ -        "webRequest", -        "webRequestBlocking",          "file://*/*",          "http://127.0.0.1/*", -        "https://ankiweb.net/*",          "storage"      ],      "web_accessible_resources": [ |