diff --git a/assets/src/bundles/guided_tour/guided-tour-steps.yaml b/assets/src/bundles/guided_tour/guided-tour-steps.yaml index f3106275..73c01612 100644 --- a/assets/src/bundles/guided_tour/guided-tour-steps.yaml +++ b/assets/src/bundles/guided_tour/guided-tour-steps.yaml @@ -1,306 +1,310 @@ # Copyright (C) 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 homepage: - title: Welcome to the guided tour ! intro: | This guided tour will showcase Software Heritage web application - features in order to help you navigate into the archive - - - title: Homepage - intro: | - This is the entry point of Software Heritage web application, - let's see what we can do from here. + features in order to help you navigate into the archive.
+ Let's see what we can do from the homepage first. - element: .swh-search-box title: Search archived software origins intro: | An origin corresponds to a location from which a coherent set of source codes has been obtained, like a git repository, a directory containing tarballs, etc.

Software origins are identified by URLs (git clone URLs for instance).

- That form enables to search for terms in the full set of archived software + You can search for terms in the full set of archived software origin URLs. You will be redirected to a dedicated interface displaying search results. Clicking on an origin URL will then take you to the source code browsing interface. If you enter a complete archived origin URL, you will be immediately redirected to its source code browsing interface. - element: .swh-origin-save-link title: Save code now intro: | If you haven't found the software origin you were looking for, you can use the Save Code Now interface to submit a save request that will be immediately processed. - element: .swh-vault-link title: Downloads from the vault intro: | Show the list of downloads you requested from the Software Heritage Vault while browsing the archive.
Those downloads correspond to tarballs containing source directories archived by Software Heritage.
- That list of downloads is stored in your browser local storage so it + The list of downloads is stored in your browser local storage so it will be persistent across your visits. - element: .swh-help-link title: Launch guided tour - intro: Replay that guided tour. + intro: Replay the guided tour. - element: "#swh-login" title: Login or register intro: | Come and join our users community with a Software Heritage account. Click here and register in less than 30 seconds. When authenticated, you can benefit from extended features like a higher rate-limit quota for the Web API.

If you are already logged in, that link will take you to your user profile interface where you can generate bearer token for Web API authentication. - element: "#swh-web-api-link" title: Software Heritage Web API intro: | In the Software Heritage Web API documentation you will find the complete list of endpoints and how to use each one with a detailed example.
Please note that the Web API can also be queried from your web browser through a dedicated HTML interface displaying query results. - title: Browsing source code of an archived software origin intro: | Come on in, let's introduce the Web UI to browse the content of an archived software origin. browseOrigin: - title: Browse source code of an archived software origin intro: | You just arrived into the first view of the archived source code of an origin. The displayed source code files are taken from the most recent snapshot taken by Software Heritage. By default, the content of the HEAD branch is displayed. Continue your journey and dive deeper into the code and its development history. - element: "#swh-origin-url" title: Software origin URL intro: | - Here you can find the URL of the archived software origin.
+ You can find the URL of the archived software origin.
Following that link will always bring you back to the code in the HEAD branch as captured by the latest Software Heritage visit. position: bottom - element: "#swh-go-to-origin" title: Visit software origin intro: | - You can visit the software origin URL where source code was captured from - by following that link. + You can go directly to the place where source code was captured. position: bottom - element: "#swh-origin-visit" title: Software Heritage origin visit date intro: | - Here you can find the date when Software Heritage captured the source code of - that origin.
- Following that link will always bring you back to the code in the HEAD branch - as captured by that visit. + You can find the date when Software Heritage captured the source code of + that origin. position: bottom - element: "#swh-browse-code-nav-link" title: Browse source code intro: | - Here you can browse the source code of a software origin.
+ You can browse the source code of a software origin.
Clicking on the Code tab will always bring you back to the code in the HEAD branch for the currently selected Software Heritage visit. position: bottom - element: "#swh-browse-snapshot-branches-nav-link" title: Browse branches intro: | - Here you can browse the list of branches for a software origin.
+ You can browse the list of branches for a software origin.
Links are offered to browse the source code contained in each branch. position: bottom - element: "#swh-browse-snapshot-releases-nav-link" title: Browse releases intro: | - Here you can browse the list of releases for a software origin.
+ You can browse the list of releases for a software origin.
Links are offered to browse the source code contained in each release.
Please note that for git origins, only annotated tags are considered as releases. For non annotated git tags, you can browse them in the Branches tab. position: bottom - element: "#swh-browse-origin-visits-nav-link" title: Browse origin visits intro: | - Here you can find when Software Heritage captured the source code. + You can find when Software Heritage captured the source code. These visits are called snapshots and visualized in various ways: timeline, calendar and simple list. Like with a way-back machine, you can travel in time and see the code as it was when crawled by Software Heritage. position: bottom - element: "#swh-branches-releases-dd" title: Switch between branches and releases intro: | You can easily switch between different branches and releases using this dropdown. position: bottom - element: "#swh-breadcrumbs-container" title: Current navigation path intro: | You can see here the current path you are taking in the code, which will make it easier to navigate back. position: bottom - element: .swh-tr-link title: Browse revisions history intro: | Display the list of revisions (aka commits) for the current branch in various orderings. Links are offered to browse source code as it was in each revision. The list of files changes introduced in each revision can also be computed and the associated diffs displayed. position: bottom - element: .swh-vault-download title: Download source code in an archive intro: | You can request the creation of an archive in .tar.gz format that will contain the currently browsed directory. You can follow the archive creation progress and download it once done by visiting the Downloads page (link can be found in the left sidebar). position: bottom - element: "#swh-take-new-snashot" title: Request to save origin again intro: | If the archived software origin currently browsed is not synchronized with its upstream version (for instance when new commits have been issued), you can explicitly request Software Heritage to take a new snapshot of it. position: bottom - element: "#swh-tip-revision" title: Branch tip revision intro: | - Here you can see the latest revision (commit) archived by Software Heritage + You can see the latest revision (commit) archived by Software Heritage for the current branch. position: bottom - element: "#swhids-handle" title: Display SWHIDs of browsed objects intro: | When clicking on this handle, a tab will be displayed containing Software Heritage IDentifiers of currently browsed objects. position: left - element: "#swh-identifiers" title: Get SWHIDs of browsed objects intro: | - In that tab, you can get the SWHIDs of currently browsed objects. - Let's see what we can do from here. + The SWHID (Software Heritage Identifier), is an intrinsic identifier that is + computed uniquely from the software artifact itself.
+ All details about the syntax, semantics, interoperability and implementation can be + found in + the formal specification. position: left - element: "#swhid-object-types" title: Select archived object type intro: | Software Heritage computes identifiers for all archived objects whose type can be: Based on the current context, you can get the SWHID of each browsed object in a dedicated tab. position: left - element: .swh-badges title: Software Heritage badges intro: | - You can include Software Heritage badges in the README file of you code repository - to indicate its archival by Software Heritage.
- Clicking on a badge will show you how to do so depending on your README format. + You can include Software Heritage badges in the README file of you code repository + to indicate its archival by Software Heritage.
+ Clicking on a badge will show you how to do so depending on your README format. - element: .swhid title: Software Heritage IDentifier (SWHID) intro: | - Here you can find the SWHID of the selected object. + You can find the SWHID of the selected object. position: left - element: "#swhid-options" title: Add / remove qualifiers to SWHID intro: | - Toggle the adding of qualifiers to the SWHID which adds extra information regarding - the context the object has been found. + Toggle the adding of qualifiers to the SWHID which adds extra information regarding + the context the object has been found. position: bottom - element: "#swhid-copy-buttons" title: Copy SWHID for a given browsed object intro: | You can easily copy to clipboard a SWHID or its permalink using these dedicated buttons. position: bottom - title: Browsing a source code file intro: | - Special features are also offered when browsing a source code file.
- This is what we will see in the next part of that tour. + Special features are also offered when browsing a source code file.
+ This is what we will see in the next part of that tour. browseContent: - title: Browsing a source code file intro: | - You just arrived in the source code view of Software Heritage web application.
- Extra features are available in it compared to source directory view, let's make - a review of them. + You just arrived in the source code file view. Let's check a few extra features. - element: .swh-tr-link title: Download source code file intro: | You can download the raw bytes of the source code file and save it locally by using the "Save Page" feature of your browser. position: bottom - element: .chosen-container title: Select programming language intro: | If Software Heritage did not manage to automatically find a programming language for the browsed source code file or did not find the right one, you can explicitly set the language to highlight using this dropdown. position: bottom - element: .hljs-ln-numbers[data-line-number="11"] title: Highlight a source code line intro: | - Click on the line number to highlight the corresponding line of code.
+ Click on the line number to highlight the corresponding line of code.
When a line gets selected, it is automatically added in the SWHID qualifiers for the associated content object. It enables to easily browse back that specific line of code. position: bottom - element: .hljs-ln-numbers[data-line-number="17"] title: Highlight a range of source code lines, intro: | - Hold Shift key and click on the line number to highlight a range of source - code lines.
+ Hold Shift key and click on the line number to highlight a range of source + code lines.
When a range of lines get selected, it is automatically added in the SWHID qualifiers for the associated content object. It enables to easily browse back that specific code snippet. position: bottom - - title: End of guided tour + - element: .swhid + title: SWHID with lines qualifier + intro: | + As you can see, selecting lines of code updates the source file SWHID with + lines qualifier.
+ Browsing such qualified SWHID will immediately take you to the selected + code snippet. + position: left + + - title: Guided tour completed intro: | - Thank your for having followed that guided tour !
+ Thank your for following our guided tour !
You will be now redirected to the page you were browsing prior launching it. diff --git a/assets/src/bundles/guided_tour/index.js b/assets/src/bundles/guided_tour/index.js index 4c31a2e9..c2d08140 100644 --- a/assets/src/bundles/guided_tour/index.js +++ b/assets/src/bundles/guided_tour/index.js @@ -1,182 +1,192 @@ /** * Copyright (C) 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 */ import * as introJs from 'intro.js'; import 'intro.js/introjs.css'; import './swh-introjs.css'; import guidedTourSteps from './guided-tour-steps.yaml'; import {disableScrolling, enableScrolling} from 'utils/scrolling'; let guidedTour = []; let tour = null; let previousElement = null; // we use a origin available both in production and swh-web tests // environment to ease tour testing const originUrl = 'https://github.com/memononen/libtess2'; +function openSWHIDsTabBeforeNextStep() { + window.scrollTo(0, 0); + if (!$('#swh-identifiers').tabSlideOut('isOpen')) { + $('.introjs-helperLayer, .introjs-tooltipReferenceLayer').hide(); + $('#swh-identifiers').tabSlideOut('open'); + setTimeout(() => { + $('.introjs-helperLayer, .introjs-tooltipReferenceLayer').show(); + tour.nextStep(); + }, 500); + return false; + } + return true; +} + // init guided tour configuration when page loads in order // to hack on it in cypress tests $(() => { // tour is defined by an array of objects containing: // - URL of page to run a tour // - intro.js configuration with tour steps // - optional intro.js callback function for tour interactivity guidedTour = [ { url: Urls.swh_web_homepage(), introJsOptions: { disableInteraction: true, scrollToElement: false, steps: guidedTourSteps.homepage } }, { url: `${Urls.browse_origin_directory()}?origin_url=${originUrl}`, introJsOptions: { disableInteraction: true, scrollToElement: false, steps: guidedTourSteps.browseOrigin }, onBeforeChange: function(targetElement) { // open SWHIDs tab before its tour step if (targetElement && targetElement.id === 'swh-identifiers') { - if (!$('#swh-identifiers').tabSlideOut('isOpen')) { - $('.introjs-helperLayer, .introjs-tooltipReferenceLayer').hide(); - $('#swh-identifiers').tabSlideOut('open'); - setTimeout(() => { - $('.introjs-helperLayer, .introjs-tooltipReferenceLayer').show(); - tour.nextStep(); - }, 500); - return false; - } + return openSWHIDsTabBeforeNextStep(); } return true; } }, { url: `${Urls.browse_origin_content()}?origin_url=${originUrl}&path=Example/example.c`, introJsOptions: { steps: guidedTourSteps.browseContent }, onBeforeChange: function(targetElement) { const lineNumberStart = 11; const lineNumberEnd = 17; + if (targetElement && $(targetElement).hasClass('swhid')) { + return openSWHIDsTabBeforeNextStep(); // forbid move to next step until user clicks on line numbers - if (targetElement && targetElement.dataset.lineNumber === `${lineNumberEnd}`) { + } else if (targetElement && targetElement.dataset.lineNumber === `${lineNumberEnd}`) { const background = $(`.hljs-ln-numbers[data-line-number="${lineNumberStart}"]`).css('background-color'); const canGoNext = background !== 'rgba(0, 0, 0, 0)'; if (!canGoNext && $('#swh-next-step-disabled').length === 0) { $('.introjs-tooltiptext').append( `

You need to select the line number before proceeding to
next step.

`); } previousElement = targetElement; return canGoNext; } else if (previousElement && previousElement.dataset.lineNumber === `${lineNumberEnd}`) { let canGoNext = true; for (let i = lineNumberStart; i <= lineNumberEnd; ++i) { const background = $(`.hljs-ln-numbers[data-line-number="${i}"]`).css('background-color'); canGoNext = canGoNext && background !== 'rgba(0, 0, 0, 0)'; if (!canGoNext) { swh.webapp.resetHighlightedLines(); swh.webapp.scrollToLine(swh.webapp.highlightLine(lineNumberStart, true)); if ($('#swh-next-step-disabled').length === 0) { $('.introjs-tooltiptext').append( `

You need to select the line numbers range from ${lineNumberStart} to ${lineNumberEnd} before proceeding to next step.

`); } break; } } return canGoNext; } previousElement = targetElement; return true; } } ]; // init guided tour on page if guided_tour query parameter is present const searchParams = new URLSearchParams(window.location.search); if (searchParams && searchParams.has('guided_tour')) { initGuidedTour(parseInt(searchParams.get('guided_tour'))); } }); export function getGuidedTour() { return guidedTour; } export function guidedTourButtonClick(event) { event.preventDefault(); initGuidedTour(); } export function initGuidedTour(page = 0) { if (page >= guidedTour.length) { return; } const pageUrl = new URL(window.location.origin + guidedTour[page].url); const currentUrl = new URL(window.location.href); const guidedTourNext = currentUrl.searchParams.get('guided_tour_next'); currentUrl.searchParams.delete('guided_tour'); currentUrl.searchParams.delete('guided_tour_next'); const pageUrlStr = decodeURIComponent(pageUrl.toString()); const currentUrlStr = decodeURIComponent(currentUrl.toString()); if (currentUrlStr !== pageUrlStr) { // go to guided tour page URL if current one does not match pageUrl.searchParams.set('guided_tour', page); if (page === 0) { // user will be redirected to the page he was at the end of the tour pageUrl.searchParams.set('guided_tour_next', currentUrlStr); } window.location = decodeURIComponent(pageUrl.toString()); } else { // create intro.js guided tour and configure it tour = introJs().setOptions(guidedTour[page].introJsOptions); tour.setOptions({ 'exitOnOverlayClick': false, 'showBullets': false }); if (page < guidedTour.length - 1) { // if not on the last page of the tour, rename next button label // and schedule next page loading when clicking on it tour.setOption('doneLabel', 'Next page') .onexit(() => { // re-enable page scrolling when exiting tour enableScrolling(); }) .oncomplete(() => { const nextPageUrl = new URL(window.location.origin + guidedTour[page + 1].url); nextPageUrl.searchParams.set('guided_tour', page + 1); if (guidedTourNext) { nextPageUrl.searchParams.set('guided_tour_next', guidedTourNext); + } else if (page === 0) { + nextPageUrl.searchParams.set('guided_tour_next', currentUrlStr); } window.location.href = decodeURIComponent(nextPageUrl.toString()); }); } else { tour.oncomplete(() => { enableScrolling(); // re-enable page scrolling when tour is complete if (guidedTourNext) { window.location.href = guidedTourNext; } }); } if (guidedTour[page].hasOwnProperty('onBeforeChange')) { tour.onbeforechange(guidedTour[page].onBeforeChange); } setTimeout(() => { // run guided tour with a little delay to ensure every asynchronous operations // after page load have been executed disableScrolling(); // disable page scrolling with mouse or keyboard while tour runs. tour.start(); window.scrollTo(0, 0); }, 500); } };