From 8d6069d11ad6aaa76947d523521f39d4af6fc3c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20B=C3=B6sch-Plepelits?= Date: Wed, 3 Aug 2022 19:53:28 +0200 Subject: [PATCH] OpenStreetBrowserLoader: move loading to Repository, get rid of .getRepo() --- src/OpenStreetBrowserLoader.js | 83 +++++++--------------------------- src/Repository.js | 49 +++++++++++++++++++- 2 files changed, 64 insertions(+), 68 deletions(-) diff --git a/src/OpenStreetBrowserLoader.js b/src/OpenStreetBrowserLoader.js index dd937792..bc02949b 100644 --- a/src/OpenStreetBrowserLoader.js +++ b/src/OpenStreetBrowserLoader.js @@ -6,7 +6,6 @@ class OpenStreetBrowserLoader { constructor () { this.types = {} this.categories = {} - this.repoCache = {} this.repositories = {} this.templates = {} this._loadClash = {} // if a category is being loaded multiple times, collect callbacks @@ -78,79 +77,31 @@ class OpenStreetBrowserLoader { * @param string repo ID of the repository * @param [object] options Options. * @param {boolean} [options.force=false] Whether repository should be reloaded or not. - * @param function callback Callback which will be called with (err, repoData) + * @param function callback Callback which will be called with (err, repository) */ - getRepo (repo, options, callback) { - if (options.force) { - delete this.repoCache[repo] - } - - if (repo in this.repoCache) { - return callback.apply(this, this.repoCache[repo]) - } - - if (repo in this._loadClash) { - this._loadClash[repo].push(callback) - return - } + getRepository (id, options, callback) { + if (id in this.repositories) { + const repository = this.repositories[id] - this._loadClash[repo] = [ callback ] - - function reqListener (req) { - if (req.status !== 200) { - console.log('http error when loading repository', req) - this.repoCache[repo] = [ req.statusText, null ] - } else { - try { - let repoData = JSON.parse(req.responseText) - this.repositories[repo] = new Repository(repo, repoData) - this.repoCache[repo] = [ null, repoData ] - } catch (err) { - console.log('couldn\'t parse repository', req.responseText) - this.repoCache[repo] = [ 'couldn\t parse repository', null ] - } + if (repository.loadCallbacks) { + return repository.loadCallbacks.push((err) => callback(err, repository)) } - var todo = this._loadClash[repo] - delete this._loadClash[repo] + if (options.force) { + repository.clearCache() + return repository.load((err) => { + if (err) { return callback(err) } - todo.forEach(function (callback) { - callback.apply(this, this.repoCache[repo]) - }.bind(this)) - } - - var param = [] - if (repo) { - param.push('repo=' + encodeURIComponent(repo)) - } - param.push('lang=' + encodeURIComponent(ui_lang)) - param.push(config.categoriesRev) - param = param.length ? '?' + param.join('&') : '' - - var req = new XMLHttpRequest() - req.addEventListener('load', reqListener.bind(this, req)) - req.open('GET', 'repo.php' + param) - req.send() - } + options.force = false + callback(repository.err, repository) + }) + } - /** - * @param string repo ID of the repository - * @param [object] options Options. - * @param {boolean} [options.force=false] Whether repository should be reloaded or not. - * @param function callback Callback which will be called with (err, repository) - */ - getRepository (id, options, callback) { - if (id in this.repositories) { - return callback(null, this.repositories[id]) + return callback(repository.err, repository) } - this.getRepo(id, options, (err, repoData) => { - if (err) { - return callback(err) - } - - callback(null, this.repositories[id]) - }) + this.repositories[id] = new Repository(id) + this.repositories[id].load((err) => callback(err, this.repositories[id])) } /** diff --git a/src/Repository.js b/src/Repository.js index b819666d..bea94fa0 100644 --- a/src/Repository.js +++ b/src/Repository.js @@ -1,9 +1,54 @@ module.exports = class Repository { constructor (id, data) { this.id = id - this.data = data + this.isLoaded = false - this.lang = this.data.lang || {} + if (data) { + this.data = data + this.lang = this.data.lang || {} + this.loadCallbacks = null + } + } + + load (callback) { + if (this.loadCallbacks) { + return this.loadCallbacks.push(callback) + } + + this.loadCallbacks = [callback] + + var param = [] + + param.push('repo=' + encodeURIComponent(this.id)) + param.push('lang=' + encodeURIComponent(ui_lang)) + param.push(config.categoriesRev) + param = param.length ? '?' + param.join('&') : '' + + fetch('repo.php' + param) + .then(res => res.json()) + .then(data => { + this.data = data + this.lang = this.data.lang || {} + this.err = null + + global.setTimeout(() => { + const cbs = this.loadCallbacks + this.loadCallbacks = null + cbs.forEach(cb => cb(null)) + }, 0) + }) + .catch(err => { + this.err = err + global.setTimeout(() => { + const cbs = this.loadCallbacks + this.loadCallbacks = null + cbs.forEach(cb => cb(err)) + }, 0) + }) + } + + clearCache () { + this.data = null } getCategory (id, options, callback) {