Skip to main content
5 of 7
Update script to version 1.3: SE changed where the `title` was in the Active information. Handle localized sites.

Sidebar Question Stats - Put question stats back in the sidebar

##Screenshot

enter image description here

##About

A recent change moved question stats (ask date, view count, and active date) from the sidebar to under the question title. Like others, you may find this distracting, because the information is only occasionally useful, yet its new position results in it being the second thing you read on every page.

This userscript runs on any SE site, and restores the question stats back to their prior position in the sidebar, removing them from just below the title.

This is intended for desktop users. The position change was probably made to make it easier for those with narrow screens to see the stats. Should work on any browser that supports userscripts and ES6, including Chrome and FF.

For compatibility with Roomba Forecaster and with any other older userscripts that depended on the old location of question stats in the sidebar, make sure this userscript runs before they do, so that the #qinfo table it creates can be found by the other userscripts.

###Code

// ==UserScript==
// @name             Stack Sidebar Question Stats
// @author           CertainPerformance
// @description      Puts question stats in the sidebar, rather than at the top of the page
// @version          1.3
// @include          /https://(?:[^/]+\.)?(?:(?:stackoverflow|serverfault|superuser|stackexchange|askubuntu|stackapps)\.com|mathoverflow\.net)/questions/\d+/
// @run-at           document-start
// @grant            none
// ==/UserScript==

/* For compatibility with Roomba Forecaster
 * and with any other older userscripts that depended on the old location of question stats in the sidebar
 * Make sure this userscript runs before they do, so that the #qinfo table it creates can be found by the other userscripts
 * https://www.mturkcrowd.com/threads/how-to-change-execution-order-of-userscripts-and-customize-excluded-pages.152/
 */

if (document.readyState === 'loading') {
  window.addEventListener('DOMContentLoaded', moveQuestionStats);
} else {
  moveQuestionStats();
}

function moveQuestionStats() {
  //Localization:
  const localizationSubstitutions = Object.entries({
    active: [
        'Active', //English
        'Ativa', //pt.stackoverflow.com
        'Activa', //es.stackoverflow.com
        'Последняя активность', //ru.stackoverflow.com & rus.stackexchange.com
        'アクティブ', //ja.stackoverflow.com
    ],
    asked: [
        'Asked', //English
        'Perguntada', //pt.stackoverflow.com
        'Formulada', //es.stackoverflow.com
        'Вопрос задан', //ru.stackoverflow.com & rus.stackexchange.com
        '質問日', //ja.stackoverflow.com
    ],
    viewed: [
        'Viewed', //English
        'Vista', //pt.stackoverflow.com
        //'Vista', //es.stackoverflow.com
        'Просмотрен', //ru.stackoverflow.com & rus.stackexchange.com
        '閲覧数', //ja.stackoverflow.com
    ],
  });
  const topQuestionStatsContainer = document.querySelector('#question-header + div.grid');
  const statusCells = {};
  for (const cell of topQuestionStatsContainer.querySelectorAll('#question-header + div.grid > .grid--cell')) {
      const type = (localizationSubstitutions.find(([key, listToMatch]) => {
        const text = cell.textContent;
        return listToMatch.some((match) => text.indexOf(match) > -1);
      }) || [])[0];
      if (type) {
          statusCells[type] = cell;
      }
  }

  const askedCell = statusCells.asked;
  const askedCellLabel = askedCell.querySelector('span.fc-light').textContent.trim();
  const possibleActiveCell = statusCells.active;
  const viewedCell = statusCells.viewed;
  const viewedCellLabel = viewedCell.querySelector('span.fc-light').textContent.trim();
  const askedTitle = askedCell.title;
  const askedTimeHTML = askedCell.children[1].outerHTML;
  const viewCountTextContent = viewedCell.lastChild.textContent;

  // This element also acts as the horizontal separator between the title and the question body;
  // clear, but do not remove
  topQuestionStatsContainer.textContent = '';

  const sidebar = document.querySelector('#sidebar');
  const newSideQuestionStatsContainer = document.createElement('div');
  sidebar.insertAdjacentElement('afterbegin', newSideQuestionStatsContainer);
  newSideQuestionStatsContainer.className = 'module question-stats';
  newSideQuestionStatsContainer.innerHTML = `
  <table id="qinfo">
    <tbody>
      <tr>
        <td>
          <p class="label-key">${askedCellLabel}</p>
        </td>
        <td style="padding-left: 10px">
          <p class="label-key" title="${askedTitle}">
            <b>
              ${askedTimeHTML}
            </b>
          </p>
        </td>
      </tr>
      <tr>
        <td>
          <p class="label-key">${viewedCellLabel}</p>
        </td>
        <td style="padding-left: 10px">
          <p class="label-key">
            <b>${viewCountTextContent}</b>
          </p>
        </td>
      </tr>
      ${(() => {
        if (!possibleActiveCell) {
          return '';
        }
        const activeLink = possibleActiveCell.querySelector('a');
        const activeTitle = activeLink.title;
        const activeTextContent = activeLink.textContent;
        return `
        <tr>
          <td>
            <p class="label-key">${possibleActiveCell.querySelector('span.fc-light').textContent.trim()}</p>
          </td>
          <td style="padding-left: 10px">
            <p class="label-key">
              <b>
                <a href="?lastactivity" class="lastactivity-link" title="${activeTitle}">${activeTextContent}</a>
              </b>
            </p>
          </td>
        </tr>`
        })()
      }
    </tbody>
  </table>
  `;
}