diff --git a/assets/src/bundles/admin/origin-save.js b/assets/src/bundles/admin/origin-save.js --- a/assets/src/bundles/admin/origin-save.js +++ b/assets/src/bundles/admin/origin-save.js @@ -222,7 +222,7 @@ $('body').on('click', e => { if ($(e.target).parents('.popover').length > 0) { - event.stopPropagation(); + e.stopPropagation(); } else if ($(e.target).parents('.swh-save-request-info').length === 0) { $('.swh-save-request-info').popover('dispose'); } @@ -231,78 +231,72 @@ }); } -export function addAuthorizedOriginUrl() { - let originUrl = $('#swh-authorized-url-prefix').val(); - let addOriginUrl = Urls.admin_origin_save_add_authorized_url(originUrl); - csrfPost(addOriginUrl) - .then(handleFetchError) - .then(() => { - authorizedOriginTable.row.add({'url': originUrl}).draw(); - $('.swh-add-authorized-origin-status').html( - htmlAlert('success', 'The origin url prefix has been successfully added in the authorized list.', true) - ); - }) - .catch(response => { - $('.swh-add-authorized-origin-status').html( - htmlAlert('warning', 'The provided origin url prefix is already registered in the authorized list.', true) - ); - }); +export async function addAuthorizedOriginUrl() { + const originUrl = $('#swh-authorized-url-prefix').val(); + const addOriginUrl = Urls.admin_origin_save_add_authorized_url(originUrl); + try { + const response = await csrfPost(addOriginUrl); + handleFetchError(response); + authorizedOriginTable.row.add({'url': originUrl}).draw(); + $('.swh-add-authorized-origin-status').html( + htmlAlert('success', 'The origin url prefix has been successfully added in the authorized list.', true) + ); + } catch (_) { + $('.swh-add-authorized-origin-status').html( + htmlAlert('warning', 'The provided origin url prefix is already registered in the authorized list.', true) + ); + } } -export function removeAuthorizedOriginUrl() { - let originUrl = $('#swh-authorized-origin-urls tr.selected').text(); +export async function removeAuthorizedOriginUrl() { + const originUrl = $('#swh-authorized-origin-urls tr.selected').text(); if (originUrl) { - let removeOriginUrl = Urls.admin_origin_save_remove_authorized_url(originUrl); - csrfPost(removeOriginUrl) - .then(handleFetchError) - .then(() => { - authorizedOriginTable.row('.selected').remove().draw(); - }) - .catch(() => {}); + const removeOriginUrl = Urls.admin_origin_save_remove_authorized_url(originUrl); + try { + const response = await csrfPost(removeOriginUrl); + handleFetchError(response); + authorizedOriginTable.row('.selected').remove().draw(); + } catch (_) {} } } -export function addUnauthorizedOriginUrl() { - let originUrl = $('#swh-unauthorized-url-prefix').val(); - let addOriginUrl = Urls.admin_origin_save_add_unauthorized_url(originUrl); - csrfPost(addOriginUrl) - .then(handleFetchError) - .then(() => { - unauthorizedOriginTable.row.add({'url': originUrl}).draw(); - $('.swh-add-unauthorized-origin-status').html( - htmlAlert('success', 'The origin url prefix has been successfully added in the unauthorized list.', true) - ); - }) - .catch(() => { - $('.swh-add-unauthorized-origin-status').html( - htmlAlert('warning', 'The provided origin url prefix is already registered in the unauthorized list.', true) - ); - }); +export async function addUnauthorizedOriginUrl() { + const originUrl = $('#swh-unauthorized-url-prefix').val(); + const addOriginUrl = Urls.admin_origin_save_add_unauthorized_url(originUrl); + try { + const response = await csrfPost(addOriginUrl); + handleFetchError(response); + unauthorizedOriginTable.row.add({'url': originUrl}).draw(); + $('.swh-add-unauthorized-origin-status').html( + htmlAlert('success', 'The origin url prefix has been successfully added in the unauthorized list.', true) + ); + } catch (_) { + $('.swh-add-unauthorized-origin-status').html( + htmlAlert('warning', 'The provided origin url prefix is already registered in the unauthorized list.', true) + ); + } } -export function removeUnauthorizedOriginUrl() { - let originUrl = $('#swh-unauthorized-origin-urls tr.selected').text(); +export async function removeUnauthorizedOriginUrl() { + const originUrl = $('#swh-unauthorized-origin-urls tr.selected').text(); if (originUrl) { - let removeOriginUrl = Urls.admin_origin_save_remove_unauthorized_url(originUrl); - csrfPost(removeOriginUrl) - .then(handleFetchError) - .then(() => { - unauthorizedOriginTable.row('.selected').remove().draw(); - }) - .catch(() => {}); + const removeOriginUrl = Urls.admin_origin_save_remove_unauthorized_url(originUrl); + try { + const response = await csrfPost(removeOriginUrl); + handleFetchError(response); + unauthorizedOriginTable.row('.selected').remove().draw(); + } catch (_) {}; } } export function acceptOriginSaveRequest() { - let selectedRow = pendingSaveRequestsTable.row('.selected'); + const selectedRow = pendingSaveRequestsTable.row('.selected'); if (selectedRow.length) { - let acceptOriginSaveRequestCallback = () => { - let rowData = selectedRow.data(); - let acceptSaveRequestUrl = Urls.admin_origin_save_request_accept(rowData['visit_type'], rowData['origin_url']); - csrfPost(acceptSaveRequestUrl) - .then(() => { - pendingSaveRequestsTable.ajax.reload(null, false); - }); + const acceptOriginSaveRequestCallback = async() => { + const rowData = selectedRow.data(); + const acceptSaveRequestUrl = Urls.admin_origin_save_request_accept(rowData['visit_type'], rowData['origin_url']); + await csrfPost(acceptSaveRequestUrl); + pendingSaveRequestsTable.ajax.reload(null, false); }; swh.webapp.showModalConfirm( @@ -313,15 +307,13 @@ } export function rejectOriginSaveRequest() { - let selectedRow = pendingSaveRequestsTable.row('.selected'); + const selectedRow = pendingSaveRequestsTable.row('.selected'); if (selectedRow.length) { - let rejectOriginSaveRequestCallback = () => { - let rowData = selectedRow.data(); - let rejectSaveRequestUrl = Urls.admin_origin_save_request_reject(rowData['visit_type'], rowData['origin_url']); - csrfPost(rejectSaveRequestUrl) - .then(() => { - pendingSaveRequestsTable.ajax.reload(null, false); - }); + let rejectOriginSaveRequestCallback = async() => { + const rowData = selectedRow.data(); + const rejectSaveRequestUrl = Urls.admin_origin_save_request_reject(rowData['visit_type'], rowData['origin_url']); + await csrfPost(rejectSaveRequestUrl); + pendingSaveRequestsTable.ajax.reload(null, false); }; swh.webapp.showModalConfirm( @@ -335,12 +327,10 @@ let selectedRow = requestTable.row('.selected'); if (selectedRow.length) { let requestId = selectedRow.data()['id']; - let removeOriginSaveRequestCallback = () => { - let removeSaveRequestUrl = Urls.admin_origin_save_request_remove(requestId); - csrfPost(removeSaveRequestUrl) - .then(() => { - requestTable.ajax.reload(null, false); - }); + let removeOriginSaveRequestCallback = async() => { + const removeSaveRequestUrl = Urls.admin_origin_save_request_remove(requestId); + await csrfPost(removeSaveRequestUrl); + requestTable.ajax.reload(null, false); }; swh.webapp.showModalConfirm( diff --git a/assets/src/bundles/auth/index.js b/assets/src/bundles/auth/index.js --- a/assets/src/bundles/auth/index.js +++ b/assets/src/bundles/auth/index.js @@ -36,45 +36,42 @@ window.location = Urls.oidc_generate_bearer_token(); } -function displayToken(tokenId) { +async function displayToken(tokenId) { const postData = { token_id: tokenId }; - csrfPost(Urls.oidc_get_bearer_token(), {}, JSON.stringify(postData)) - .then(handleFetchError) - .then(response => response.text()) - .then(token => { - const tokenHtml = - `

Below is your token.

-
${token}
`; - swh.webapp.showModalHtml('Display bearer token', tokenHtml); - }) - .catch(response => { - response.text().then(responseText => { - let errorMsg = 'Internal server error.'; - if (response.status === 400) { - errorMsg = responseText; - } - swh.webapp.showModalHtml('Display bearer token', errorMessage(errorMsg)); - }); - }); + try { + const response = await csrfPost(Urls.oidc_get_bearer_token(), {}, JSON.stringify(postData)); + handleFetchError(response); + const token = await response.text(); + const tokenHtml = + `

Below is your token.

+
${token}
`; + swh.webapp.showModalHtml('Display bearer token', tokenHtml); + } catch (response) { + const responseText = await response.text(); + let errorMsg = 'Internal server error.'; + if (response.status === 400) { + errorMsg = responseText; + } + swh.webapp.showModalHtml('Display bearer token', errorMessage(errorMsg)); + } } -function revokeTokens(tokenIds) { +async function revokeTokens(tokenIds) { const postData = { token_ids: tokenIds }; - csrfPost(Urls.oidc_revoke_bearer_tokens(), {}, JSON.stringify(postData)) - .then(handleFetchError) - .then(() => { - disableSubmitButton(); - $('#swh-token-form-message').html( - successMessage(`Bearer token${tokenIds.length > 1 ? 's' : ''} successfully revoked.`)); - apiTokensTable.draw(); - }) - .catch(() => { - $('#swh-token-form-message').html(errorMessage('Internal server error.')); - }); + try { + const response = await csrfPost(Urls.oidc_revoke_bearer_tokens(), {}, JSON.stringify(postData)); + handleFetchError(response); + disableSubmitButton(); + $('#swh-token-form-message').html( + successMessage(`Bearer token${tokenIds.length > 1 ? 's' : ''} successfully revoked.`)); + apiTokensTable.draw(); + } catch (_) { + $('#swh-token-form-message').html(errorMessage('Internal server error.')); + } } function revokeToken(tokenId) { diff --git a/assets/src/bundles/browse/origin-search.js b/assets/src/bundles/browse/origin-search.js --- a/assets/src/bundles/browse/origin-search.js +++ b/assets/src/bundles/browse/origin-search.js @@ -28,12 +28,13 @@ $('#origin-search-results tbody tr').remove(); } -function populateOriginSearchResultsTable(origins) { +async function populateOriginSearchResultsTable(origins) { if (origins.length > 0) { $('#swh-origin-search-results').show(); $('#swh-no-result').hide(); clearOriginSearchResultsTable(); let table = $('#origin-search-results tbody'); + let promises = []; for (let [i, origin] of origins.entries()) { let browseUrl = `${Urls.browse_origin()}?origin_url=${encodeURIComponent(origin.url)}`; let tableRow = @@ -54,32 +55,27 @@ // get async latest visit snapshot and update visit status icon let latestSnapshotUrl = Urls.api_1_origin_visit_latest(origin.url); latestSnapshotUrl += '?require_snapshot=true'; - fetch(latestSnapshotUrl) - .then(response => { - if (response.status === 404) { - throw new Error(); - } - return response.json(); - }) - .then(data => { - if (data.type) { - $(`#visit-type-origin-${i}`).html(data.type); - $(`#visit-status-origin-${i}`).html( - 'Archived'); - } else { - throw new Error(); - } - }) - .catch(() => { - $(`#visit-type-origin-${i}`).html('unknown'); - $(`#visit-status-origin-${i}`).html( - 'Pending archival'); - if ($('#swh-filter-empty-visits').prop('checked')) { - $(`#origin-${i}`).remove(); - } - }); + promises.push(fetch(latestSnapshotUrl)); + } + const responses = await Promise.all(promises); + const responsesData = await Promise.all(responses.map(r => r.json())); + for (let i = 0; i < responses.length; ++i) { + const response = responses[i]; + const data = responsesData[i]; + if (response.status !== 404 && data.type) { + $(`#visit-type-origin-${i}`).html(data.type); + $(`#visit-status-origin-${i}`).html( + 'Archived'); + } else { + $(`#visit-type-origin-${i}`).html('unknown'); + $(`#visit-status-origin-${i}`).html( + 'Pending archival'); + if ($('#swh-filter-empty-visits').prop('checked')) { + $(`#origin-${i}`).remove(); + } + } } fixTableRowsStyle(); } else { @@ -127,67 +123,60 @@ searchOrigins(searchUrl); } -function searchOrigins(searchUrl) { +async function searchOrigins(searchUrl) { clearOriginSearchResultsTable(); $('.swh-loading').addClass('show'); - let response = fetch(searchUrl) - .then(handleFetchError) - .then(resp => { - response = resp; - return response.json(); - }) - .then(data => { - // Save link to the current results page - linkCurrent = searchUrl; - // Save link to the next results page. - linkNext = null; - if (response.headers.has('Link')) { - let parsedLink = parseLinkHeader(response.headers.get('Link')); - if (parsedLink !== undefined) { - linkNext = parsedLink; - } + try { + const response = await fetch(searchUrl); + handleFetchError(response); + const data = await response.json(); + // Save link to the current results page + linkCurrent = searchUrl; + // Save link to the next results page. + linkNext = null; + if (response.headers.has('Link')) { + let parsedLink = parseLinkHeader(response.headers.get('Link')); + if (parsedLink !== undefined) { + linkNext = parsedLink; } - // prevLinks is updated by the caller, which is the one to know if - // we're going forward or backward in the pages. + } + // prevLinks is updated by the caller, which is the one to know if + // we're going forward or backward in the pages. - $('.swh-loading').removeClass('show'); - populateOriginSearchResultsTable(data); - }) - .catch(response => { - $('.swh-loading').removeClass('show'); - inSearch = false; - $('#swh-origin-search-results').hide(); - $('#swh-no-result').text(`Error ${response.status}: ${response.statusText}`); - $('#swh-no-result').show(); - }); + $('.swh-loading').removeClass('show'); + populateOriginSearchResultsTable(data); + } catch (response) { + $('.swh-loading').removeClass('show'); + inSearch = false; + $('#swh-origin-search-results').hide(); + $('#swh-no-result').text(`Error ${response.status}: ${response.statusText}`); + $('#swh-no-result').show(); + } } -function doSearch() { +async function doSearch() { $('#swh-no-result').hide(); - let searchQueryText = $('#swh-origins-url-patterns').val(); + const searchQueryText = $('#swh-origins-url-patterns').val(); inSearch = true; if (searchQueryText.startsWith('swh:')) { - // searchQueryText may be a PID so sending search queries to PID resolve endpoint - let resolveSWHIDUrl = Urls.api_1_resolve_swhid(searchQueryText); - fetch(resolveSWHIDUrl) - .then(handleFetchError) - .then(response => response.json()) - .then(data => { - // SWHID has been successfully resolved, - // so redirect to browse page - window.location = data.browse_url; - }) - .catch(response => { - // display a useful error message if the input - // looks like a SWHID - response.json().then(data => { - $('#swh-origin-search-results').hide(); - $('.swh-search-pagination').hide(); - $('#swh-no-result').text(data.reason); - $('#swh-no-result').show(); - }); - - }); + try { + // searchQueryText may be a PID so sending search queries to PID resolve endpoint + const resolveSWHIDUrl = Urls.api_1_resolve_swhid(searchQueryText); + const response = await fetch(resolveSWHIDUrl); + handleFetchError(response); + const data = await response.json(); + // SWHID has been successfully resolved, + // so redirect to browse page + window.location = data.browse_url; + } catch (response) { + // display a useful error message if the input + // looks like a SWHID + const data = await response.json(); + $('#swh-origin-search-results').hide(); + $('.swh-search-pagination').hide(); + $('#swh-no-result').text(data.reason); + $('#swh-no-result').show(); + }; } else { // otherwise, proceed with origins search $('#swh-origin-search-results').show(); diff --git a/assets/src/bundles/revision/diff-utils.js b/assets/src/bundles/revision/diff-utils.js --- a/assets/src/bundles/revision/diff-utils.js +++ b/assets/src/bundles/revision/diff-utils.js @@ -315,7 +315,7 @@ } // to compute diff and process it for display -export function computeDiff(diffUrl, diffId) { +export async function computeDiff(diffUrl, diffId) { // force diff computation ? let force = diffUrl.indexOf('force=true') !== -1; @@ -341,214 +341,214 @@ $(`#${diffId}-highlightjs`).css('display', 'none'); // request diff computation and process it - fetch(diffUrl) - .then(response => response.json()) - .then(data => { - // increment number of computed diffs - ++nbDiffsComputed; - // toggle the 'Compute all diffs' button if all diffs have been computed - if (nbDiffsComputed === changes.length) { - $('#swh-compute-all-diffs').addClass('active'); - } + const response = await fetch(diffUrl); + const data = await response.json(); + + // increment number of computed diffs + ++nbDiffsComputed; + // toggle the 'Compute all diffs' button if all diffs have been computed + if (nbDiffsComputed === changes.length) { + $('#swh-compute-all-diffs').addClass('active'); + } - // Large diff (> threshold) are not automatically computed, - // add a button to force its computation - if (data.diff_str.indexOf('Large diff') === 0) { - $(`#${diffId}`)[0].innerHTML = data.diff_str + + // Large diff (> threshold) are not automatically computed, + // add a button to force its computation + if (data.diff_str.indexOf('Large diff') === 0) { + $(`#${diffId}`)[0].innerHTML = data.diff_str + `
'; - setDiffVisible(diffId); - } else if (data.diff_str.indexOf('@@') !== 0) { - $(`#${diffId}`).text(data.diff_str); - setDiffVisible(diffId); - } else { + setDiffVisible(diffId); + } else if (data.diff_str.indexOf('@@') !== 0) { + $(`#${diffId}`).text(data.diff_str); + setDiffVisible(diffId); + } else { - // prepare code highlighting - $(`.${diffId}`).removeClass('nohighlight'); - $(`.${diffId}`).addClass(data.language); + // prepare code highlighting + $(`.${diffId}`).removeClass('nohighlight'); + $(`.${diffId}`).addClass(data.language); - // set unified diff text - $(`#${diffId}`).text(data.diff_str); + // set unified diff text + $(`#${diffId}`).text(data.diff_str); - // code highlighting for unified diff - $(`#${diffId}`).each((i, elt) => { - hljs.highlightElement(elt); - hljs.lineNumbersElementSync(elt); - }); + // code highlighting for unified diff + $(`#${diffId}`).each((i, elt) => { + hljs.highlightElement(elt); + hljs.lineNumbersElementSync(elt); + }); - // process unified diff lines in order to generate side-by-side diffs text - // but also compute line numbers for unified and side-by-side diffs - let baseFromLine = ''; - let baseToLine = ''; - let fromToLines = []; - let fromLines = []; - let toLines = []; - let maxNumberChars = 0; - let diffFromStr = ''; - let diffToStr = ''; - let linesOffset = 0; - - $(`#${diffId} .hljs-ln-numbers`).each((i, lnElt) => { - let lnText = lnElt.nextSibling.innerText; - let linesInfo = parseDiffHunkRangeIfAny(lnText); - let fromLine = ''; - let toLine = ''; - // parsed lines info from the diff output - if (linesInfo) { - baseFromLine = linesInfo[0]; - baseToLine = linesInfo[1]; - linesOffset = 0; - diffFromStr += (lnText + '\n'); - diffToStr += (lnText + '\n'); - fromLines.push(''); + // process unified diff lines in order to generate side-by-side diffs text + // but also compute line numbers for unified and side-by-side diffs + let baseFromLine = ''; + let baseToLine = ''; + let fromToLines = []; + let fromLines = []; + let toLines = []; + let maxNumberChars = 0; + let diffFromStr = ''; + let diffToStr = ''; + let linesOffset = 0; + + $(`#${diffId} .hljs-ln-numbers`).each((i, lnElt) => { + let lnText = lnElt.nextSibling.innerText; + let linesInfo = parseDiffHunkRangeIfAny(lnText); + let fromLine = ''; + let toLine = ''; + // parsed lines info from the diff output + if (linesInfo) { + baseFromLine = linesInfo[0]; + baseToLine = linesInfo[1]; + linesOffset = 0; + diffFromStr += (lnText + '\n'); + diffToStr += (lnText + '\n'); + fromLines.push(''); + toLines.push(''); + // line removed in the from file + } else if (lnText.length > 0 && lnText[0] === '-') { + baseFromLine = baseFromLine + 1; + fromLine = baseFromLine.toString(); + fromLines.push(fromLine); + ++nbDeletions; + diffFromStr += (lnText + '\n'); + ++linesOffset; + // line added in the to file + } else if (lnText.length > 0 && lnText[0] === '+') { + baseToLine = baseToLine + 1; + toLine = baseToLine.toString(); + toLines.push(toLine); + ++nbAdditions; + diffToStr += (lnText + '\n'); + --linesOffset; + // line present in both files + } else { + baseFromLine = baseFromLine + 1; + baseToLine = baseToLine + 1; + fromLine = baseFromLine.toString(); + toLine = baseToLine.toString(); + for (let j = 0; j < Math.abs(linesOffset); ++j) { + if (linesOffset > 0) { + diffToStr += '\n'; toLines.push(''); - // line removed in the from file - } else if (lnText.length > 0 && lnText[0] === '-') { - baseFromLine = baseFromLine + 1; - fromLine = baseFromLine.toString(); - fromLines.push(fromLine); - ++nbDeletions; - diffFromStr += (lnText + '\n'); - ++linesOffset; - // line added in the to file - } else if (lnText.length > 0 && lnText[0] === '+') { - baseToLine = baseToLine + 1; - toLine = baseToLine.toString(); - toLines.push(toLine); - ++nbAdditions; - diffToStr += (lnText + '\n'); - --linesOffset; - // line present in both files } else { - baseFromLine = baseFromLine + 1; - baseToLine = baseToLine + 1; - fromLine = baseFromLine.toString(); - toLine = baseToLine.toString(); - for (let j = 0; j < Math.abs(linesOffset); ++j) { - if (linesOffset > 0) { - diffToStr += '\n'; - toLines.push(''); - } else { - diffFromStr += '\n'; - fromLines.push(''); - } - } - linesOffset = 0; - diffFromStr += (lnText + '\n'); - diffToStr += (lnText + '\n'); - toLines.push(toLine); - fromLines.push(fromLine); - } - if (!baseFromLine) { - fromLine = ''; - } - if (!baseToLine) { - toLine = ''; + diffFromStr += '\n'; + fromLines.push(''); } - fromToLines[i] = [fromLine, toLine]; - maxNumberChars = Math.max(maxNumberChars, fromLine.length); - maxNumberChars = Math.max(maxNumberChars, toLine.length); - }); + } + linesOffset = 0; + diffFromStr += (lnText + '\n'); + diffToStr += (lnText + '\n'); + toLines.push(toLine); + fromLines.push(fromLine); + } + if (!baseFromLine) { + fromLine = ''; + } + if (!baseToLine) { + toLine = ''; + } + fromToLines[i] = [fromLine, toLine]; + maxNumberChars = Math.max(maxNumberChars, fromLine.length); + maxNumberChars = Math.max(maxNumberChars, toLine.length); + }); - diffMaxNumberChars[diffId] = maxNumberChars; + diffMaxNumberChars[diffId] = maxNumberChars; - // set side-by-side diffs text - $(`#${diffId}-from`).text(diffFromStr); - $(`#${diffId}-to`).text(diffToStr); + // set side-by-side diffs text + $(`#${diffId}-from`).text(diffFromStr); + $(`#${diffId}-to`).text(diffToStr); - // code highlighting for side-by-side diffs - $(`#${diffId}-from, #${diffId}-to`).each((i, elt) => { - hljs.highlightElement(elt); - hljs.lineNumbersElementSync(elt); - }); + // code highlighting for side-by-side diffs + $(`#${diffId}-from, #${diffId}-to`).each((i, elt) => { + hljs.highlightElement(elt); + hljs.lineNumbersElementSync(elt); + }); - // diff highlighting for added/removed lines on top of code highlighting - $(`.${diffId} .hljs-ln-numbers`).each((i, lnElt) => { - let lnText = lnElt.nextSibling.innerText; - if (lnText.startsWith('@@')) { - $(lnElt).parent().addClass('swh-diff-lines-info'); - let linesInfoText = $(lnElt).parent().find('.hljs-ln-code .hljs-ln-line').text(); - $(lnElt).parent().find('.hljs-ln-code .hljs-ln-line').children().remove(); - $(lnElt).parent().find('.hljs-ln-code .hljs-ln-line').text(''); - $(lnElt).parent().find('.hljs-ln-code .hljs-ln-line').append(`${linesInfoText}`); - } else if (lnText.length > 0 && lnText[0] === '-') { - $(lnElt).parent().addClass('swh-diff-removed-line'); - } else if (lnText.length > 0 && lnText[0] === '+') { - $(lnElt).parent().addClass('swh-diff-added-line'); - } - }); + // diff highlighting for added/removed lines on top of code highlighting + $(`.${diffId} .hljs-ln-numbers`).each((i, lnElt) => { + let lnText = lnElt.nextSibling.innerText; + if (lnText.startsWith('@@')) { + $(lnElt).parent().addClass('swh-diff-lines-info'); + let linesInfoText = $(lnElt).parent().find('.hljs-ln-code .hljs-ln-line').text(); + $(lnElt).parent().find('.hljs-ln-code .hljs-ln-line').children().remove(); + $(lnElt).parent().find('.hljs-ln-code .hljs-ln-line').text(''); + $(lnElt).parent().find('.hljs-ln-code .hljs-ln-line').append(`${linesInfoText}`); + } else if (lnText.length > 0 && lnText[0] === '-') { + $(lnElt).parent().addClass('swh-diff-removed-line'); + } else if (lnText.length > 0 && lnText[0] === '+') { + $(lnElt).parent().addClass('swh-diff-added-line'); + } + }); - // set line numbers for unified diff - $(`#${diffId} .hljs-ln-numbers`).each((i, lnElt) => { - const lineNumbers = formatDiffLineNumbers(diffId, fromToLines[i][0], fromToLines[i][1]); - setLineNumbers(lnElt, lineNumbers); - }); + // set line numbers for unified diff + $(`#${diffId} .hljs-ln-numbers`).each((i, lnElt) => { + const lineNumbers = formatDiffLineNumbers(diffId, fromToLines[i][0], fromToLines[i][1]); + setLineNumbers(lnElt, lineNumbers); + }); - // set line numbers for the from side-by-side diff - $(`#${diffId}-from .hljs-ln-numbers`).each((i, lnElt) => { - setLineNumbers(lnElt, fromLines[i]); - }); + // set line numbers for the from side-by-side diff + $(`#${diffId}-from .hljs-ln-numbers`).each((i, lnElt) => { + setLineNumbers(lnElt, fromLines[i]); + }); - // set line numbers for the to side-by-side diff - $(`#${diffId}-to .hljs-ln-numbers`).each((i, lnElt) => { - setLineNumbers(lnElt, toLines[i]); - }); + // set line numbers for the to side-by-side diff + $(`#${diffId}-to .hljs-ln-numbers`).each((i, lnElt) => { + setLineNumbers(lnElt, toLines[i]); + }); - // last processing: - // - remove the '+' and '-' at the beginning of the diff lines - // from code highlighting - // - add the "no new line at end of file marker" if needed - $(`.${diffId} .hljs-ln-code`).each((i, lnElt) => { - if (lnElt.firstChild) { - if (lnElt.firstChild.nodeName !== '#text') { - let lineText = lnElt.firstChild.innerHTML; - if (lineText[0] === '-' || lineText[0] === '+') { - lnElt.firstChild.innerHTML = lineText.substr(1); - let newTextNode = document.createTextNode(lineText[0]); - $(lnElt).prepend(newTextNode); - } - } - $(lnElt).contents().filter((i, elt) => { - return elt.nodeType === 3; // Node.TEXT_NODE - }).each((i, textNode) => { - let swhNoNewLineMarker = '[swh-no-nl-marker]'; - if (textNode.textContent.indexOf(swhNoNewLineMarker) !== -1) { - textNode.textContent = textNode.textContent.replace(swhNoNewLineMarker, ''); - $(lnElt).append($(noNewLineMarker)); - } - }); + // last processing: + // - remove the '+' and '-' at the beginning of the diff lines + // from code highlighting + // - add the "no new line at end of file marker" if needed + $(`.${diffId} .hljs-ln-code`).each((i, lnElt) => { + if (lnElt.firstChild) { + if (lnElt.firstChild.nodeName !== '#text') { + let lineText = lnElt.firstChild.innerHTML; + if (lineText[0] === '-' || lineText[0] === '+') { + lnElt.firstChild.innerHTML = lineText.substr(1); + let newTextNode = document.createTextNode(lineText[0]); + $(lnElt).prepend(newTextNode); + } + } + $(lnElt).contents().filter((i, elt) => { + return elt.nodeType === 3; // Node.TEXT_NODE + }).each((i, textNode) => { + let swhNoNewLineMarker = '[swh-no-nl-marker]'; + if (textNode.textContent.indexOf(swhNoNewLineMarker) !== -1) { + textNode.textContent = textNode.textContent.replace(swhNoNewLineMarker, ''); + $(lnElt).append($(noNewLineMarker)); } }); + } + }); - // hide the diff mode switch button in case of not generated diffs - if (data.diff_str.indexOf('Diffs are not generated for non textual content') !== 0) { - $(`#diff_${diffId} .diff-styles`).css('visibility', 'visible'); - } + // hide the diff mode switch button in case of not generated diffs + if (data.diff_str.indexOf('Diffs are not generated for non textual content') !== 0) { + $(`#diff_${diffId} .diff-styles`).css('visibility', 'visible'); + } - setDiffVisible(diffId); + setDiffVisible(diffId); - // highlight diff lines if provided in URL fragment - if (selectedDiffLinesInfo && + // highlight diff lines if provided in URL fragment + if (selectedDiffLinesInfo && selectedDiffLinesInfo.diffPanelId.indexOf(diffId) !== -1) { - if (!selectedDiffLinesInfo.unified) { - showSplitDiff(diffId); - } - const firstHighlightedLine = highlightDiffLines( - diffId, selectedDiffLinesInfo.startLines, - selectedDiffLinesInfo.endLines, selectedDiffLinesInfo.unified); - - $('html, body').animate( - { - scrollTop: firstHighlightedLine.offset().top - 50 - }, - { - duration: 500 - } - ); - } + if (!selectedDiffLinesInfo.unified) { + showSplitDiff(diffId); } - }); + const firstHighlightedLine = highlightDiffLines( + diffId, selectedDiffLinesInfo.startLines, + selectedDiffLinesInfo.endLines, selectedDiffLinesInfo.unified); + + $('html, body').animate( + { + scrollTop: firstHighlightedLine.offset().top - 50 + }, + { + duration: 500 + } + ); + } + } + } function setDiffVisible(diffId) { @@ -664,7 +664,7 @@ await import(/* webpackChunkName: "highlightjs" */ 'utils/highlightjs'); // callback when the 'Changes' tab is activated - $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', e => { + $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', async e => { currentTabName = e.currentTarget.text.trim(); if (currentTabName === 'Changes') { window.location.hash = changesUrlFragment; @@ -677,43 +677,42 @@ // request computation of revision file changes list // when navigating to the 'Changes' tab and add diff panels // to the DOM when receiving the result - fetch(diffRevisionUrl) - .then(response => response.json()) - .then(data => { - changes = data.changes; - nbChangedFiles = data.total_nb_changes; - let changedFilesText = `${nbChangedFiles} changed file`; - if (nbChangedFiles !== 1) { - changedFilesText += 's'; - } - $('#swh-revision-changed-files').text(changedFilesText); - $('#swh-total-nb-diffs').text(changes.length); - $('#swh-revision-changes-list pre')[0].innerHTML = data.changes_msg; - - $('#swh-revision-changes-loading').css('display', 'none'); - $('#swh-revision-changes-list pre').css('display', 'block'); - $('#swh-compute-all-diffs').css('visibility', 'visible'); - $('#swh-revision-changes-list').removeClass('in'); - - if (nbChangedFiles > changes.length) { - $('#swh-too-large-revision-diff').css('display', 'block'); - $('#swh-nb-loaded-diffs').text(changes.length); - } + const response = await fetch(diffRevisionUrl); + const data = await response.json(); + + changes = data.changes; + nbChangedFiles = data.total_nb_changes; + let changedFilesText = `${nbChangedFiles} changed file`; + if (nbChangedFiles !== 1) { + changedFilesText += 's'; + } + $('#swh-revision-changed-files').text(changedFilesText); + $('#swh-total-nb-diffs').text(changes.length); + $('#swh-revision-changes-list pre')[0].innerHTML = data.changes_msg; + + $('#swh-revision-changes-loading').css('display', 'none'); + $('#swh-revision-changes-list pre').css('display', 'block'); + $('#swh-compute-all-diffs').css('visibility', 'visible'); + $('#swh-revision-changes-list').removeClass('in'); + + if (nbChangedFiles > changes.length) { + $('#swh-too-large-revision-diff').css('display', 'block'); + $('#swh-nb-loaded-diffs').text(changes.length); + } - for (let i = 0; i < changes.length; ++i) { - let diffData = changes[i]; - diffsUrls[diffData.id] = diffData.diff_url; - $('#swh-revision-diffs').append(genDiffPanel(diffData)); - } + for (let i = 0; i < changes.length; ++i) { + let diffData = changes[i]; + diffsUrls[diffData.id] = diffData.diff_url; + $('#swh-revision-diffs').append(genDiffPanel(diffData)); + } - setupWaypoints(); - computeVisibleDiffs(); + setupWaypoints(); + computeVisibleDiffs(); - if (selectedDiffLinesInfo) { - scrollToDiffPanel(selectedDiffLinesInfo.diffPanelId, false); - } + if (selectedDiffLinesInfo) { + scrollToDiffPanel(selectedDiffLinesInfo.diffPanelId, false); + } - }); } else if (currentTabName === 'Files') { removeUrlFragment(); $('#readme-panel').css('display', 'block'); diff --git a/assets/src/bundles/save/index.js b/assets/src/bundles/save/index.js --- a/assets/src/bundles/save/index.js +++ b/assets/src/bundles/save/index.js @@ -11,7 +11,7 @@ let saveRequestsTable; -function originSaveRequest( +async function originSaveRequest( originType, originUrl, extraData, acceptedCallback, pendingCallback, errorCallback ) { @@ -27,23 +27,21 @@ }; }; - csrfPost(addSaveOriginRequestUrl, headers, body) - .then(handleFetchError) - .then(response => response.json()) - .then(data => { - $('.swh-processing-save-request').css('display', 'none'); - if (data.save_request_status === 'accepted') { - acceptedCallback(); - } else { - pendingCallback(); - } - }) - .catch(response => { - $('.swh-processing-save-request').css('display', 'none'); - response.json().then(errorData => { - errorCallback(response.status, errorData); - }); - }); + try { + const response = await csrfPost(addSaveOriginRequestUrl, headers, body); + handleFetchError(response); + const data = await response.json(); + $('.swh-processing-save-request').css('display', 'none'); + if (data.save_request_status === 'accepted') { + acceptedCallback(); + } else { + pendingCallback(); + } + } catch (response) { + $('.swh-processing-save-request').css('display', 'none'); + const errorData = await response.json(); + errorCallback(response.status, errorData); + }; } function addArtifactVersionAutofillHandler(formId) { @@ -116,19 +114,18 @@ export function initOriginSave() { - $(document).ready(() => { + $(document).ready(async() => { $.fn.dataTable.ext.errMode = 'none'; - fetch(Urls.origin_save_types_list()) - .then(response => response.json()) - .then(data => { - for (let originType of data) { - $('#swh-input-visit-type').append(``); - } - // set git as the default value as before - $('#swh-input-visit-type').val('git'); - }); + const response = await fetch(Urls.origin_save_types_list()); + const data = await response.json(); + + for (let originType of data) { + $('#swh-input-visit-type').append(``); + } + // set git as the default value as before + $('#swh-input-visit-type').val('git'); saveRequestsTable = $('#swh-origin-save-requests') .on('error.dt', (e, settings, techNote, message) => { @@ -464,7 +461,7 @@ return value === null ? null : mapFormatPerTypeFn[type](value); } -export function displaySaveRequestInfo(event, saveRequestId) { +export async function displaySaveRequestInfo(event, saveRequestId) { event.stopPropagation(); const saveRequestTaskInfoUrl = Urls.origin_save_task_info(saveRequestId); // close popover when clicking again on the info icon @@ -499,50 +496,49 @@ }); $(event.target).popover('show'); - fetch(saveRequestTaskInfoUrl) - .then(response => response.json()) - .then(saveRequestTaskInfo => { - let content; - if ($.isEmptyObject(saveRequestTaskInfo)) { - content = 'Not available'; - } else { - let saveRequestInfo = []; - const taskData = { - 'Type': ['raw', 'type'], - 'Visit status': ['raw', 'visit_status'], - 'Arguments': ['json', 'arguments'], - 'Id': ['raw', 'id'], - 'Backend id': ['raw', 'backend_id'], - 'Scheduling date': ['date', 'scheduled'], - 'Start date': ['date', 'started'], - 'Completion date': ['date', 'ended'], - 'Duration': ['duration', 'duration'], - 'Runner': ['raw', 'worker'], - 'Log': ['raw', 'message'] - }; - for (const [title, [type, property]] of Object.entries(taskData)) { - if (saveRequestTaskInfo.hasOwnProperty(property)) { - saveRequestInfo.push({ - key: title, - value: formatValuePerType(type, saveRequestTaskInfo[property]) - }); - } - } - content = ''; - for (let info of saveRequestInfo) { - content += + const response = await fetch(saveRequestTaskInfoUrl); + const saveRequestTaskInfo = await response.json(); + + let content; + if ($.isEmptyObject(saveRequestTaskInfo)) { + content = 'Not available'; + } else { + let saveRequestInfo = []; + const taskData = { + 'Type': ['raw', 'type'], + 'Visit status': ['raw', 'visit_status'], + 'Arguments': ['json', 'arguments'], + 'Id': ['raw', 'id'], + 'Backend id': ['raw', 'backend_id'], + 'Scheduling date': ['date', 'scheduled'], + 'Start date': ['date', 'started'], + 'Completion date': ['date', 'ended'], + 'Duration': ['duration', 'duration'], + 'Runner': ['raw', 'worker'], + 'Log': ['raw', 'message'] + }; + for (const [title, [type, property]] of Object.entries(taskData)) { + if (saveRequestTaskInfo.hasOwnProperty(property)) { + saveRequestInfo.push({ + key: title, + value: formatValuePerType(type, saveRequestTaskInfo[property]) + }); + } + } + content = '
'; + for (let info of saveRequestInfo) { + content += ``; - } - content += '
'; - } - $('.swh-popover').html(content); - $(event.target).popover('update'); - }); + } + content += ''; + } + $('.swh-popover').html(content); + $(event.target).popover('update'); } export function fillSaveRequestFormAndScroll(visitType, originUrl) { diff --git a/assets/src/bundles/vault/vault-create-tasks.js b/assets/src/bundles/vault/vault-create-tasks.js --- a/assets/src/bundles/vault/vault-create-tasks.js +++ b/assets/src/bundles/vault/vault-create-tasks.js @@ -14,7 +14,7 @@ 'z-index': '100000' }; -export function vaultRequest(objectType, objectId) { +export async function vaultRequest(objectType, objectId) { let vaultUrl; if (objectType === 'directory') { vaultUrl = Urls.api_1_vault_cook_directory(objectId); @@ -22,32 +22,31 @@ vaultUrl = Urls.api_1_vault_cook_revision_gitfast(objectId); } // check if object has already been cooked - fetch(vaultUrl) - .then(response => response.json()) - .then(data => { - // object needs to be cooked - if (data.exception === 'NotFoundExc' || data.status === 'failed') { - // if last cooking has failed, remove previous task info from localStorage - // in order to force the recooking of the object - swh.vault.removeCookingTaskInfo([objectId]); - $(`#vault-cook-${objectType}-modal`).modal('show'); - // object has been cooked and should be in the vault cache, - // it will be asked to cook it again if it is not - } else if (data.status === 'done') { - $(`#vault-fetch-${objectType}-modal`).modal('show'); - } else { - const cookingServiceDownAlert = + const response = await fetch(vaultUrl); + const data = await response.json(); + + // object needs to be cooked + if (data.exception === 'NotFoundExc' || data.status === 'failed') { + // if last cooking has failed, remove previous task info from localStorage + // in order to force the recooking of the object + swh.vault.removeCookingTaskInfo([objectId]); + $(`#vault-cook-${objectType}-modal`).modal('show'); + // object has been cooked and should be in the vault cache, + // it will be asked to cook it again if it is not + } else if (data.status === 'done') { + $(`#vault-fetch-${objectType}-modal`).modal('show'); + } else { + const cookingServiceDownAlert = $(htmlAlert('danger', 'Archive cooking service is currently experiencing issues.
' + 'Please try again later.', true)); - cookingServiceDownAlert.css(alertStyle); - $('body').append(cookingServiceDownAlert); - } - }); + cookingServiceDownAlert.css(alertStyle); + $('body').append(cookingServiceDownAlert); + } } -function addVaultCookingTask(cookingTask) { +async function addVaultCookingTask(cookingTask) { const swhidsContext = swh.webapp.getSwhIdsContext(); cookingTask.origin = swhidsContext[cookingTask.object_type].context.origin; @@ -75,32 +74,31 @@ cookingUrl += '?email=' + cookingTask.email; } - csrfPost(cookingUrl) - .then(handleFetchError) - .then(() => { - vaultCookingTasks.push(cookingTask); - localStorage.setItem('swh-vault-cooking-tasks', JSON.stringify(vaultCookingTasks)); - $('#vault-cook-directory-modal').modal('hide'); - $('#vault-cook-revision-modal').modal('hide'); - const cookingTaskCreatedAlert = + try { + const response = await csrfPost(cookingUrl); + handleFetchError(response); + vaultCookingTasks.push(cookingTask); + localStorage.setItem('swh-vault-cooking-tasks', JSON.stringify(vaultCookingTasks)); + $('#vault-cook-directory-modal').modal('hide'); + $('#vault-cook-revision-modal').modal('hide'); + const cookingTaskCreatedAlert = $(htmlAlert('success', 'Archive cooking request successfully submitted.
' + `Go to the Downloads page ` + 'to get the download link once it is ready.', true)); - cookingTaskCreatedAlert.css(alertStyle); - $('body').append(cookingTaskCreatedAlert); - }) - .catch(() => { - $('#vault-cook-directory-modal').modal('hide'); - $('#vault-cook-revision-modal').modal('hide'); - const cookingTaskFailedAlert = + cookingTaskCreatedAlert.css(alertStyle); + $('body').append(cookingTaskCreatedAlert); + } catch (_) { + $('#vault-cook-directory-modal').modal('hide'); + $('#vault-cook-revision-modal').modal('hide'); + const cookingTaskFailedAlert = $(htmlAlert('danger', 'Archive cooking request submission failed.', true)); - cookingTaskFailedAlert.css(alertStyle); - $('body').append(cookingTaskFailedAlert); - }); + cookingTaskFailedAlert.css(alertStyle); + $('body').append(cookingTaskFailedAlert); + } } } @@ -125,14 +123,12 @@ } } -export function fetchDirectoryArchive(directoryId) { +export async function fetchDirectoryArchive(directoryId) { $('#vault-fetch-directory-modal').modal('hide'); const vaultUrl = Urls.api_1_vault_cook_directory(directoryId); - fetch(vaultUrl) - .then(response => response.json()) - .then(data => { - swh.vault.fetchCookedObject(data.fetch_url); - }); + const response = await fetch(vaultUrl); + const data = await response.json(); + swh.vault.fetchCookedObject(data.fetch_url); } export function cookRevisionArchive(revisionId) { @@ -150,12 +146,10 @@ } } -export function fetchRevisionArchive(revisionId) { +export async function fetchRevisionArchive(revisionId) { $('#vault-fetch-directory-modal').modal('hide'); const vaultUrl = Urls.api_1_vault_cook_revision_gitfast(revisionId); - fetch(vaultUrl) - .then(response => response.json()) - .then(data => { - swh.vault.fetchCookedObject(data.fetch_url); - }); + const response = await fetch(vaultUrl); + const data = await response.json(); + swh.vault.fetchCookedObject(data.fetch_url); } diff --git a/assets/src/bundles/vault/vault-ui.js b/assets/src/bundles/vault/vault-ui.js --- a/assets/src/bundles/vault/vault-ui.js +++ b/assets/src/bundles/vault/vault-ui.js @@ -41,33 +41,32 @@ let recookTask; // called when the user wants to download a cooked archive -export function fetchCookedObject(fetchUrl) { +export async function fetchCookedObject(fetchUrl) { recookTask = null; // first, check if the link is still available from the vault - fetch(fetchUrl) - .then(response => { - // link is still alive, proceed to download - if (response.ok) { - $('#vault-fetch-iframe').attr('src', fetchUrl); - // link is dead - } else { - // get the associated cooking task - let vaultCookingTasks = JSON.parse(localStorage.getItem('swh-vault-cooking-tasks')); - for (let i = 0; i < vaultCookingTasks.length; ++i) { - if (vaultCookingTasks[i].fetch_url === fetchUrl) { - recookTask = vaultCookingTasks[i]; - break; - } - } - // display a modal asking the user if he wants to recook the archive - $('#vault-recook-object-modal').modal('show'); + const response = await fetch(fetchUrl); + + // link is still alive, proceed to download + if (response.ok) { + $('#vault-fetch-iframe').attr('src', fetchUrl); + // link is dead + } else { + // get the associated cooking task + let vaultCookingTasks = JSON.parse(localStorage.getItem('swh-vault-cooking-tasks')); + for (let i = 0; i < vaultCookingTasks.length; ++i) { + if (vaultCookingTasks[i].fetch_url === fetchUrl) { + recookTask = vaultCookingTasks[i]; + break; } - }); + } + // display a modal asking the user if he wants to recook the archive + $('#vault-recook-object-modal').modal('show'); + } } // called when the user wants to recook an archive // for which the download link is not available anymore -export function recookObject() { +export async function recookObject() { if (recookTask) { // stop cooking tasks status polling clearTimeout(checkVaultId); @@ -81,35 +80,35 @@ if (recookTask.email) { cookingUrl += '?email=' + recookTask.email; } + try { // request archive cooking - csrfPost(cookingUrl) - .then(handleFetchError) - .then(() => { - // update task status - recookTask.status = 'new'; - let vaultCookingTasks = JSON.parse(localStorage.getItem('swh-vault-cooking-tasks')); - for (let i = 0; i < vaultCookingTasks.length; ++i) { - if (vaultCookingTasks[i].object_id === recookTask.object_id) { - vaultCookingTasks[i] = recookTask; - break; - } + const response = await csrfPost(cookingUrl); + handleFetchError(response); + + // update task status + recookTask.status = 'new'; + let vaultCookingTasks = JSON.parse(localStorage.getItem('swh-vault-cooking-tasks')); + for (let i = 0; i < vaultCookingTasks.length; ++i) { + if (vaultCookingTasks[i].object_id === recookTask.object_id) { + vaultCookingTasks[i] = recookTask; + break; } - // save updated tasks to local storage - localStorage.setItem('swh-vault-cooking-tasks', JSON.stringify(vaultCookingTasks)); - // restart cooking tasks status polling - checkVaultCookingTasks(); - // hide recook archive modal - $('#vault-recook-object-modal').modal('hide'); - }) + } + // save updated tasks to local storage + localStorage.setItem('swh-vault-cooking-tasks', JSON.stringify(vaultCookingTasks)); + // restart cooking tasks status polling + checkVaultCookingTasks(); + // hide recook archive modal + $('#vault-recook-object-modal').modal('hide'); + } catch (_) { // something went wrong - .catch(() => { - checkVaultCookingTasks(); - $('#vault-recook-object-modal').modal('hide'); - }); + checkVaultCookingTasks(); + $('#vault-recook-object-modal').modal('hide'); + } } } -function checkVaultCookingTasks() { +async function checkVaultCookingTasks() { let vaultCookingTasks = JSON.parse(localStorage.getItem('swh-vault-cooking-tasks')); if (!vaultCookingTasks || vaultCookingTasks.length === 0) { $('.swh-vault-table tbody tr').remove(); @@ -140,62 +139,63 @@ $(row).remove(); } }); - Promise.all(cookingTaskRequests) - .then(handleFetchErrors) - .then(responses => Promise.all(responses.map(r => r.json()))) - .then(cookingTasks => { - let table = $('#vault-cooking-tasks tbody'); - for (let i = 0; i < cookingTasks.length; ++i) { - let cookingTask = tasks[cookingTasks[i].obj_id]; - cookingTask.status = cookingTasks[i].status; - cookingTask.fetch_url = cookingTasks[i].fetch_url; - cookingTask.progress_message = cookingTasks[i].progress_message; - } - for (let i = 0; i < vaultCookingTasks.length; ++i) { - let cookingTask = vaultCookingTasks[i]; - let rowTask = $(`#vault-task-${cookingTask.object_id}`); - - if (!rowTask.length) { - - let browseUrl = cookingTask.browse_url; - if (!browseUrl) { - if (cookingTask.object_type === 'directory') { - browseUrl = Urls.browse_directory(cookingTask.object_id); - } else { - browseUrl = Urls.browse_revision(cookingTask.object_id); - } + try { + const responses = await Promise.all(cookingTaskRequests); + handleFetchErrors(responses); + const cookingTasks = await Promise.all(responses.map(r => r.json())); + + let table = $('#vault-cooking-tasks tbody'); + for (let i = 0; i < cookingTasks.length; ++i) { + let cookingTask = tasks[cookingTasks[i].obj_id]; + cookingTask.status = cookingTasks[i].status; + cookingTask.fetch_url = cookingTasks[i].fetch_url; + cookingTask.progress_message = cookingTasks[i].progress_message; + } + for (let i = 0; i < vaultCookingTasks.length; ++i) { + let cookingTask = vaultCookingTasks[i]; + let rowTask = $(`#vault-task-${cookingTask.object_id}`); + + if (!rowTask.length) { + + let browseUrl = cookingTask.browse_url; + if (!browseUrl) { + if (cookingTask.object_type === 'directory') { + browseUrl = Urls.browse_directory(cookingTask.object_id); + } else { + browseUrl = Urls.browse_revision(cookingTask.object_id); } + } - let progressBar = $.parseHTML(progress)[0]; - let progressBarContent = $(progressBar).find('.progress-bar'); - updateProgressBar(progressBarContent, cookingTask); - table.prepend(vaultTableRowTemplate({ - browseUrl: browseUrl, - cookingTask: cookingTask, - progressBar: progressBar, - Urls: Urls, - swh: swh - })); - } else { - let progressBar = rowTask.find('.progress-bar'); - updateProgressBar(progressBar, cookingTask); - let downloadLink = rowTask.find('.vault-dl-link'); - if (cookingTask.status === 'done') { - downloadLink[0].innerHTML = + let progressBar = $.parseHTML(progress)[0]; + let progressBarContent = $(progressBar).find('.progress-bar'); + updateProgressBar(progressBarContent, cookingTask); + table.prepend(vaultTableRowTemplate({ + browseUrl: browseUrl, + cookingTask: cookingTask, + progressBar: progressBar, + Urls: Urls, + swh: swh + })); + } else { + let progressBar = rowTask.find('.progress-bar'); + updateProgressBar(progressBar, cookingTask); + let downloadLink = rowTask.find('.vault-dl-link'); + if (cookingTask.status === 'done') { + downloadLink[0].innerHTML = ''; - } else { - downloadLink[0].innerHTML = ''; - } + } else { + downloadLink[0].innerHTML = ''; } } - localStorage.setItem('swh-vault-cooking-tasks', JSON.stringify(vaultCookingTasks)); - checkVaultId = setTimeout(checkVaultCookingTasks, pollingInterval); - }) - .catch(error => { - console.log('Error when fetching vault cooking tasks:', error); - }); + } + localStorage.setItem('swh-vault-cooking-tasks', JSON.stringify(vaultCookingTasks)); + checkVaultId = setTimeout(checkVaultCookingTasks, pollingInterval); + + } catch (error) { + console.log('Error when fetching vault cooking tasks:', error); + } } export function removeCookingTaskInfo(tasksToRemove) { diff --git a/assets/src/bundles/webapp/notebook-rendering.js b/assets/src/bundles/webapp/notebook-rendering.js --- a/assets/src/bundles/webapp/notebook-rendering.js +++ b/assets/src/bundles/webapp/notebook-rendering.js @@ -120,18 +120,17 @@ nb.highlighter = highlightCode; nb.ansi = renderAnsi; - fetch(nbJsonUrl) - .then(response => response.json()) - .then(nbJson => { - // parse the notebook - let notebook = nb.parse(nbJson); - // render it to HTML and apply XSS filtering - let rendered = swh.webapp.filterXSS(notebook.render()); - // insert rendered notebook in the DOM - $(domElt).append(rendered); - // set light red background color for stderr output cells - $('pre.nb-stderr').parent().css('background', '#fdd'); - // load MathJax library for math typesetting - swh.webapp.typesetMath(); - }); + const response = await fetch(nbJsonUrl); + const nbJson = await response.json(); + + // parse the notebook + let notebook = nb.parse(nbJson); + // render it to HTML and apply XSS filtering + let rendered = swh.webapp.filterXSS(notebook.render()); + // insert rendered notebook in the DOM + $(domElt).append(rendered); + // set light red background color for stderr output cells + $('pre.nb-stderr').parent().css('background', '#fdd'); + // load MathJax library for math typesetting + swh.webapp.typesetMath(); } diff --git a/assets/src/bundles/webapp/pdf-rendering.js b/assets/src/bundles/webapp/pdf-rendering.js --- a/assets/src/bundles/webapp/pdf-rendering.js +++ b/assets/src/bundles/webapp/pdf-rendering.js @@ -20,34 +20,33 @@ let ctx = canvas.getContext('2d'); // Get page info from document, resize canvas accordingly, and render page. - function renderPage(num) { + async function renderPage(num) { pageRendering = true; // Using promise to fetch the page - pdfDoc.getPage(num).then(page => { - let divWidth = $('.swh-content').width(); - let scale = Math.min(defaultScale, divWidth / page.getViewport({scale: 1.0}).width); - - let viewport = page.getViewport({scale: scale}); - canvas.width = viewport.width; - canvas.height = viewport.height; - - // Render PDF page into canvas context - let renderContext = { - canvasContext: ctx, - viewport: viewport - }; - let renderTask = page.render(renderContext); - - // Wait for rendering to finish - renderTask.promise.then(() => { - pageRendering = false; - if (pageNumPending !== null) { - // New page rendering is pending - renderPage(pageNumPending); - pageNumPending = null; - } - }); - }); + const page = await pdfDoc.getPage(num); + + let divWidth = $('.swh-content').width(); + let scale = Math.min(defaultScale, divWidth / page.getViewport({scale: 1.0}).width); + + let viewport = page.getViewport({scale: scale}); + canvas.width = viewport.width; + canvas.height = viewport.height; + + // Render PDF page into canvas context + const renderContext = { + canvasContext: ctx, + viewport: viewport + }; + + // Wait for rendering to finish + await page.render(renderContext); + + pageRendering = false; + if (pageNumPending !== null) { + // New page rendering is pending + renderPage(pageNumPending); + pageNumPending = null; + } // Update page counters $('#pdf-page-num').text(num); @@ -85,19 +84,19 @@ pdfjs.GlobalWorkerOptions.workerSrc = staticAsset('js/pdf.worker.min.js'); - $(document).ready(() => { + $(document).ready(async() => { $('#pdf-prev').click(onPrevPage); $('#pdf-next').click(onNextPage); - let loadingTask = pdfjs.getDocument(pdfUrl); - loadingTask.promise.then(pdf => { + try { + const pdf = await pdfjs.getDocument(pdfUrl).promise; pdfDoc = pdf; $('#pdf-page-count').text(pdfDoc.numPages); // Initial/first page rendering renderPage(pageNum); - }, function(reason) { + } catch (reason) { // PDF loading error console.error(reason); - }); + } // Render PDF on resize $(window).on('resize', function() { diff --git a/assets/src/bundles/webapp/readme-rendering.js b/assets/src/bundles/webapp/readme-rendering.js --- a/assets/src/bundles/webapp/readme-rendering.js +++ b/assets/src/bundles/webapp/readme-rendering.js @@ -1,5 +1,5 @@ /** - * Copyright (C) 2018-2019 The Software Heritage developers + * Copyright (C) 2018-2021 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information @@ -47,21 +47,21 @@ }]; } - $(document).ready(() => { + $(document).ready(async() => { let converter = new showdown.Converter({ tables: true, extensions: [showdownHighlight] }); - fetch(markdownDocUrl) - .then(handleFetchError) - .then(response => response.text()) - .then(data => { - $(domElt).addClass('swh-showdown'); - $(domElt).html(swh.webapp.filterXSS(converter.makeHtml(data))); - }) - .catch(() => { - $(domElt).text('Readme bytes are not available'); - }); + + try { + const response = await fetch(markdownDocUrl); + handleFetchError(response); + const data = await response.text(); + $(domElt).addClass('swh-showdown'); + $(domElt).html(swh.webapp.filterXSS(converter.makeHtml(data))); + } catch (_) { + $(domElt).text('Readme bytes are not available'); + } }); } @@ -83,41 +83,36 @@ } export function renderOrg(domElt, orgDocUrl) { - - $(document).ready(() => { - fetch(orgDocUrl) - .then(handleFetchError) - .then(response => response.text()) - .then(data => { - renderOrgData(domElt, data); - }) - .catch(() => { - $(domElt).text('Readme bytes are not available'); - }); + $(document).ready(async() => { + try { + const response = await fetch(orgDocUrl); + handleFetchError(response); + const data = await response.text(); + renderOrgData(domElt, data); + } catch (_) { + $(domElt).text('Readme bytes are not available'); + } }); - } export function renderTxt(domElt, txtDocUrl) { - - $(document).ready(() => { - fetch(txtDocUrl) - .then(handleFetchError) - .then(response => response.text()) - .then(data => { - let orgMode = '-*- mode: org -*-'; - if (data.indexOf(orgMode) !== -1) { - renderOrgData(domElt, data.replace(orgMode, '')); - } else { - $(domElt).addClass('swh-readme-txt'); - $(domElt) + $(document).ready(async() => { + try { + const response = await fetch(txtDocUrl); + handleFetchError(response); + const data = await response.text(); + + let orgMode = '-*- mode: org -*-'; + if (data.indexOf(orgMode) !== -1) { + renderOrgData(domElt, data.replace(orgMode, '')); + } else { + $(domElt).addClass('swh-readme-txt'); + $(domElt) .html('') .append($('
').text(data));
-        }
-      })
-      .catch(() => {
-        $(domElt).text('Readme bytes are not available');
-      });
+      }
+    } catch (_) {
+      $(domElt).text('Readme bytes are not available');
+    }
   });
-
 }
diff --git a/assets/src/bundles/webapp/status-widget.js b/assets/src/bundles/webapp/status-widget.js
--- a/assets/src/bundles/webapp/status-widget.js
+++ b/assets/src/bundles/webapp/status-widget.js
@@ -17,34 +17,34 @@
 };
 
 export function initStatusWidget(statusDataURL) {
-  $('.swh-current-status-indicator').ready(() => {
+  $('.swh-current-status-indicator').ready(async() => {
     let maxStatusCode = '';
     let maxStatusDescription = '';
     let sc = '';
     let sd = '';
-    fetch(statusDataURL)
-      .then(resp => resp.json())
-      .then(data => {
-        for (let s of data.result.status) {
-          sc = s.status_code;
-          sd = s.status;
-          if (maxStatusCode < sc) {
-            maxStatusCode = sc;
-            maxStatusDescription = sd;
-          }
-        }
-        if (maxStatusCode === '') {
-          $('.swh-current-status').remove();
-          return;
+    try {
+      const response = await fetch(statusDataURL);
+      const data = await response.json();
+
+      for (let s of data.result.status) {
+        sc = s.status_code;
+        sd = s.status;
+        if (maxStatusCode < sc) {
+          maxStatusCode = sc;
+          maxStatusDescription = sd;
         }
-        $('.swh-current-status-indicator').removeClass('green');
-        $('.swh-current-status-indicator').addClass(statusCodeColor[maxStatusCode]);
-        $('#swh-current-status-description').text(maxStatusDescription);
-      })
-      .catch(e => {
-        console.log(e);
+      }
+      if (maxStatusCode === '') {
         $('.swh-current-status').remove();
-      });
+        return;
+      }
+      $('.swh-current-status-indicator').removeClass('green');
+      $('.swh-current-status-indicator').addClass(statusCodeColor[maxStatusCode]);
+      $('#swh-current-status-description').text(maxStatusDescription);
 
+    } catch (e) {
+      console.log(e);
+      $('.swh-current-status').remove();
+    }
   });
 }
diff --git a/assets/src/bundles/webapp/webapp-utils.js b/assets/src/bundles/webapp/webapp-utils.js
--- a/assets/src/bundles/webapp/webapp-utils.js
+++ b/assets/src/bundles/webapp/webapp-utils.js
@@ -200,37 +200,36 @@
 }
 
 export function initHomePage() {
-  $(document).ready(() => {
+  $(document).ready(async() => {
     $('.swh-coverage-list').iFrameResize({heightCalculationMethod: 'taggedElement'});
-    fetch(Urls.stat_counters())
-      .then(response => response.json())
-      .then(data => {
-        if (data.stat_counters && !$.isEmptyObject(data.stat_counters)) {
-          for (let objectType of ['content', 'revision', 'origin', 'directory', 'person', 'release']) {
-            const count = data.stat_counters[objectType];
-            if (count !== undefined) {
-              $(`#swh-${objectType}-count`).html(count.toLocaleString());
-            } else {
-              $(`#swh-${objectType}-count`).closest('.swh-counter-container').hide();
-            }
-          }
+    const response = await fetch(Urls.stat_counters());
+    const data = await response.json();
+
+    if (data.stat_counters && !$.isEmptyObject(data.stat_counters)) {
+      for (let objectType of ['content', 'revision', 'origin', 'directory', 'person', 'release']) {
+        const count = data.stat_counters[objectType];
+        if (count !== undefined) {
+          $(`#swh-${objectType}-count`).html(count.toLocaleString());
         } else {
-          $('.swh-counter').html('0');
+          $(`#swh-${objectType}-count`).closest('.swh-counter-container').hide();
         }
-        if (data.stat_counters_history && !$.isEmptyObject(data.stat_counters_history)) {
-          for (let objectType of ['content', 'revision', 'origin']) {
-            const history = data.stat_counters_history[objectType];
-            if (history) {
-              swh.webapp.drawHistoryCounterGraph(`#swh-${objectType}-count-history`, history);
-            } else {
-              $(`#swh-${objectType}-count-history`).hide();
-            }
-
-          }
+      }
+    } else {
+      $('.swh-counter').html('0');
+    }
+    if (data.stat_counters_history && !$.isEmptyObject(data.stat_counters_history)) {
+      for (let objectType of ['content', 'revision', 'origin']) {
+        const history = data.stat_counters_history[objectType];
+        if (history) {
+          swh.webapp.drawHistoryCounterGraph(`#swh-${objectType}-count-history`, history);
         } else {
-          $('.swh-counter-history').hide();
+          $(`#swh-${objectType}-count-history`).hide();
         }
-      });
+
+      }
+    } else {
+      $('.swh-counter-history').hide();
+    }
   });
   initPage('home');
 }