Only fetch style JSON during installation.

JSON is 'cached' within the userstyleSearchResult object,
so the JSON is only fetched once during the life of the popup window.
This commit is contained in:
derv82 2017-12-09 00:25:47 -08:00
parent 40ab080070
commit 1c188f1f8d
2 changed files with 58 additions and 41 deletions

View File

@ -26,6 +26,7 @@ body.search-results-shown {
} }
.search-result, .search-result-empty { .search-result, .search-result-empty {
position: relative;
min-height: 170px; min-height: 170px;
padding: 5px; padding: 5px;
} }
@ -33,7 +34,9 @@ body.search-results-shown {
.search-result-empty { .search-result-empty {
position: relative; position: relative;
} }
.search-result-empty .lds-spinner {
.search-result .lds-spinner, .search-result-empty .lds-spinner {
opacity: 1;
top: 0; top: 0;
width: 150px; width: 150px;
height: 150px; height: 150px;

View File

@ -218,27 +218,13 @@
setTimeout(processNextResult, 0); // Keep processing setTimeout(processNextResult, 0); // Keep processing
} else { } else {
// Style not installed. // Style not installed.
Promise.all([ searchAPI.fetchStyle(nextResult.id) // for "style_settings" (customizations)
searchAPI.fetchStyleJson(nextResult.id), // for "sections" (applicable URLs) .then(userstyleObject => {
searchAPI.fetchStyle(nextResult.id), // for "style_settings" (customizations)
getActiveTab() // for comparing tab.url to sections.
]).then(([userstyleJson, userstyleObject, tab]) => {
// Extract applicable sections (i.e. styles that apply to the current site)
const applicableSections = BG.getApplicableSections({
style: userstyleJson,
matchUrl: tab.url,
stopOnFirst: true
});
if (applicableSections.length > 0) {
// Style is valid (can apply to this site).
nextResult.json = userstyleJson; // Store Style JSON for easy installing later.
// Store style settings for detecting customization later. // Store style settings for detecting customization later.
nextResult.style_settings = userstyleObject.style_settings; nextResult.style_settings = userstyleObject.style_settings;
processedResults.push(nextResult); processedResults.push(nextResult);
render(); render();
}
setTimeout(processNextResult, DELAY_AFTER_FETCHING_STYLES); // Keep processing setTimeout(processNextResult, DELAY_AFTER_FETCHING_STYLES); // Keep processing
}) })
.catch(reason => { .catch(reason => {
@ -426,23 +412,43 @@
if (event) { if (event) {
event.stopPropagation(); event.stopPropagation();
} }
const styleId = userstyleSearchResult.id;
const url = searchAPI.BASE_URL + '/styles/chrome/' + styleId + '.json'; // Spinner while installing
saveStyleSafe(userstyleSearchResult.json) entry.appendChild(
$create(
'.lds-spinner',
new Array(12).fill($create('div')).map(e => e.cloneNode()))
);
installButton.disabled = true;
// Fetch .JSON style
searchAPI.fetchStyleJson(userstyleSearchResult)
.then(userstyleJson => {
// Install style
saveStyleSafe(userstyleJson)
.then(savedStyle => { .then(savedStyle => {
// Success: Store installed styleId, mark as installed. // Success: Store installed styleId, mark as installed.
userstyleSearchResult.installed = true; userstyleSearchResult.installed = true;
userstyleSearchResult.installedStyleId = savedStyle.id; userstyleSearchResult.installedStyleId = savedStyle.id;
render(); // Hides install button, shows uninstall button. render(); // Hides install button, shows uninstall button.
$.remove('.lds-spinner', entry);
installButton.disabled = false;
});
}) })
.catch(reason => { .catch(reason => {
console.log('install:saveStyleSafe(', url, ') => [ERROR]: ', reason); const usoId = userstyleSearchResult.id;
alert('Error while downloading ' + url + '\nReason: ' + reason); console.log('install:saveStyleSafe(usoID:', usoId, ') => [ERROR]: ', reason);
alert('Error while downloading usoID:' + usoId + '\nReason: ' + reason);
$.remove('.lds-spinner', entry);
installButton.disabled = false;
}); });
return true; return true;
} }
}
} } // End of createSearchResultNode
} // End of searchResultsController
})(); })();
/** /**
@ -498,16 +504,24 @@ function searchUserstyles() {
/** /**
* Fetches the JSON style object from userstyles.org (containing code, sections, updateUrl, etc). * Fetches the JSON style object from userstyles.org (containing code, sections, updateUrl, etc).
* This is fetched from the /styles/chrome/ID.json endpoint. * Stores (caches) the JSON within the given usoSearchResult, to avoid unnecessary network usage.
* @param {number} userstylesId The internal "ID" for a style on userstyles.org * Style JSON is fetched from the /styles/chrome/{id}.json endpoint.
* @returns {Promise<Object>} The response as a JSON object. * @param {Object} usoSearchResult A search result object from userstyles.org
* @returns {Promise<Object>} Promises the response as a JSON object.
*/ */
function fetchStyleJson(userstylesId) { function fetchStyleJson(usoSearchResult) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const jsonUrl = BASE_URL + '/styles/chrome/' + userstylesId + '.json'; if (usoSearchResult.json) {
// JSON already downloaded & stored.
resolve(usoSearchResult.json);
}
const jsonUrl = BASE_URL + '/styles/chrome/' + usoSearchResult.id + '.json';
download(jsonUrl) download(jsonUrl)
.then(responseText => { .then(responseText => {
resolve(tryJSONparse(responseText)); // Store JSON within the search result, so we don't have to download again.
usoSearchResult.json = tryJSONparse(responseText);
resolve(usoSearchResult.json);
}) })
.catch(reject); .catch(reject);
}); });