Passer au contenu principal

Lister les nouveautés de GitLab-CE

Entrer les lignes suivantes dans la console Javascript du navigateur

{
  const version = document.querySelector('h1').textContent;
  const wishesSections = ['top-feature', 'primary-features', 'secondary-features'];
  const availableData = '[data-original-title="Available in GitLab self-managed Free"]'
  const notAvailable = '[data-original-title="Not available in GitLab self-managed Free"]'
  const [topFeatures, primaryFeatures, secondaryFeatures] = Array.from(document.querySelectorAll('.content > section')).filter(el => wishesSections.includes(el.id));
  
  const nestedElement = (el, overload, linkEl = 'previousElementSibling') => {
    const paths = overload.split(".");
    let result = el.parentNode.parentNode.parentNode;
    const doc = result.parentNode.lastElementChild.firstElementChild.firstElementChild.href;
    const docLink = doc ? `[_(doc)_](${doc})` : '';
    for (path of paths) {
      result = result[path];
    }
    const link = result[linkEl];
    return [`- [${result.textContent}](${link.href}) ${docLink}`];
  };
  
  const hideElements = (el, overload, linkEl = false) => {
    const paths = overload.split(".");
    let result = el.parentNode.parentNode.parentNode;
    for (path of paths) {
      result = result[path];
    }
    if (linkEl) {
      result.previousElementSibling.style.display="none";
    };
    result.style.display="none";
  };
  
  Array.from(topFeatures.querySelectorAll(notAvailable)).forEach(el => hideElements(el, 'parentNode'));
  
  Array.from(primaryFeatures.querySelectorAll(notAvailable)).forEach(el => hideElements(el, 'parentNode.parentNode', true));
  
  Array.from(secondaryFeatures.querySelectorAll(notAvailable)).forEach(el => hideElements(el, 'parentNode'));
  
  const primaryAvailable = Array.from(primaryFeatures.querySelectorAll(availableData)).map(el => nestedElement(el, 'parentNode.parentNode.previousElementSibling.firstElementChild.lastElementChild'));
  
  const secondaryAvailable = Array.from(secondaryFeatures.querySelectorAll(availableData)).map(el => nestedElement(el, 'previousElementSibling.lastElementChild'));
  
  const finalResult = [].concat(version,primaryAvailable,secondaryAvailable).join('\n');
 
  console.log(finalResult);

  const copyButton = document.createElement("button");
  const defaultOpacity = "0.4"
  copyButton.style.position = "fixed";
  copyButton.style.margin = "20px";
  copyButton.style.bottom = "0";
  copyButton.style.zIndex = "10"
  copyButton.style.backgroundColor = "teal";
  copyButton.style.color = "wheat";
  copyButton.style.fontSize = "1.5em";
  copyButton.style.fontWeight = "bold";
  copyButton.style.borderRadius = "10px";
  copyButton.style.transition = "all 0.4s 0.1s ease-in"
  copyButton.style.opacity = defaultOpacity;
  copyButton.onmouseover = function() {
    this.style.opacity = "1";
    this.style.boxShadow = "black -3px 2px 6px";
    this.style.transform = "translate(3px, -2px)";
  };
  copyButton.onmouseleave = function() {
    this.style.opacity = defaultOpacity;
    this.style.boxShadow = "unset";
    this.style.transform = "translate(-3px, 2px)";
  };
  copyButton.innerHTML = "Copier la liste<br><em>Community Edition</em>";
  document.body.insertBefore(copyButton, document.body.firstChild);
  const copyFunction = () => {
    navigator.clipboard.writeText(finalResult).then(() => {
      console.log("Données copiées dans le presse-papier.");
    }, (e) => {
      console.error("Les données ne sont pas copiées…");
    });
    document.execCommand("copy");
  }
  copyButton.addEventListener("click", copyFunction)
}

Version Bookmarklet

Pour une utilisation régulière, il faut ajouter un marque-page, puis remplacer l'URL par le code suivant :

javascript: const version = document.querySelector("h1").textContent; const wishesSections = [ "top-feature", "primary-features", "secondary-features", ]; const availableData = '[data-original-title="Available in GitLab self-managed Free"]'; const notAvailable = '[data-original-title="Not available in GitLab self-managed Free"]'; const [topFeatures, primaryFeatures, secondaryFeatures] = Array.from( document.querySelectorAll(".content > section") ).filter((el) => wishesSections.includes(el.id)); const nestedElement = (el, overload, linkEl = "previousElementSibling") => { const paths = overload.split("."); let result = el.parentNode.parentNode.parentNode; const doc = result.parentNode.lastElementChild.firstElementChild.firstElementChild.href; const docLink = doc ? `[_(doc)_](${doc})` : ""; for (path of paths) { result = result[path]; } const link = result[linkEl]; return [`- [${result.textContent}](${link.href}) ${docLink}`]; }; const hideElements = (el, overload, linkEl = false) => { const paths = overload.split("."); let result = el.parentNode.parentNode.parentNode; for (path of paths) { result = result[path]; } if (linkEl) {result.previousElementSibling.style.display = "none"}; result.style.display = "none"; }; Array.from(topFeatures.querySelectorAll(notAvailable)).forEach((el) => hideElements(el, "parentNode") ); Array.from(primaryFeatures.querySelectorAll(notAvailable)).forEach((el) => hideElements(el, "parentNode.parentNode", true) ); Array.from(secondaryFeatures.querySelectorAll(notAvailable)).forEach((el) => hideElements(el, "parentNode") ); const primaryAvailable = Array.from( primaryFeatures.querySelectorAll(availableData) ).map((el) => nestedElement( el, "parentNode.parentNode.previousElementSibling.firstElementChild.lastElementChild" ) ); const secondaryAvailable = Array.from( secondaryFeatures.querySelectorAll(availableData) ).map((el) => nestedElement(el, "previousElementSibling.lastElementChild")); const finalResult = [] .concat(version, primaryAvailable, secondaryAvailable) .join("\n"); console.log(finalResult); const copyButton = document.createElement("button"); const defaultOpacity = "0.4"; copyButton.style.position = "fixed"; copyButton.style.margin = "20px"; copyButton.style.bottom = "0"; copyButton.style.zIndex = "10"; copyButton.style.backgroundColor = "teal"; copyButton.style.color = "wheat"; copyButton.style.fontSize = "1.5em"; copyButton.style.fontWeight = "bold"; copyButton.style.borderRadius = "10px"; copyButton.style.transition = "all 0.4s 0.1s ease-in"; copyButton.style.opacity = defaultOpacity; copyButton.onmouseover = function () { this.style.opacity = "1"; this.style.boxShadow = "black -3px 2px 6px"; this.style.transform = "translate(3px, -2px)"; }; copyButton.onmouseleave = function () { this.style.opacity = defaultOpacity; this.style.boxShadow = "unset"; this.style.transform = "translate(-3px, 2px)"; }; copyButton.innerHTML = "Copier la liste<br><em>Community Edition</em>"; document.body.insertBefore(copyButton, document.body.firstChild); const copyFunction = () => { navigator.clipboard.writeText(finalResult).then( () => { console.log("Donn%C3%A9es copi%C3%A9es dans le presse-papier."); }, (e) => { console.error("Les donn%C3%A9es ne sont pas copi%C3%A9es%E2%80%A6", e); } ); document.execCommand("copy"); }; copyButton.addEventListener("click", copyFunction);

Ensuite, le fait de cliquer que le marque-page activera le script.

Résultat

Exemple avec la page GitLab 16.0 released.

Les éléments ne correspondant pas à Self-Managed Free sont masqués sur la page.

Un bouton apparaît permettant de copier la liste suivante dans le presse-papier :

GitLab 16.0 Release