Memrise Preview Word

Allows to Preview one specific Word

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

You will need to install an extension such as Tampermonkey to install this script.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==UserScript==
// @name           Memrise Preview Word
// @description    Allows to Preview one specific Word
// @match          http://*.memrise.com/course/*
// @match          https://*.memrise.com/course/*
// @match          http://*.memrise.com/community/course/*
// @match          https://*.memrise.com/community/course/*
// @match          http://*.memrise.com/aprender/*
// @match          https://*.memrise.com/aprender/*
// @run-at         document-end
// @version        2.2
// @grant          none
// @namespace      https://greasyfork.org/users/213706
// ==/UserScript==

if(typeof unsafeWindow == "undefined") {
  unsafeWindow = window;
}

// Inside a level: add links to preview
if(typeof unsafeWindow.MEMRISE != "undefined") {
  if(document.body.classList.contains('level-view')) {
    window.addEventListener('load', onLoadCourse, false);
  }
  function onLoadCourse() {
    var path = window.location.pathname;

    // Retrieve course id and level index from URL
    var m = path.match('/course/([0-9]+)/[^/]+/([0-9]*)');
    if(!m) {
      console.error('Could not extract course and level in URL');
      return;
    }
    var idCourse = m[1],
      	idxLevel = m[2] || 1;

    // Display link in black when not hovering
    const css = document.createElement('style');
    css.textContent = `
    .col_a a {
      color: inherit;
    }
    .col_a a:hover {
      color:#0c618f
    }`;
    document.head.appendChild(css);

    var url_preview = '/aprender/preview?course_id=' + idCourse + '&level_index=' + idxLevel + '&';
    // var url_preview = window.location.pathname + 'garden/preview/?';

    // Add links to column a
    document.body.querySelectorAll('.col_a').forEach(function(node){
      var a  = document.createElement('a'),
          id = node.parentNode.getAttribute('data-learnable-id');

      node.appendChild(a);
      a.setAttribute('href', url_preview + 'learnable_id=' + id);
      a.appendChild(node.firstElementChild);
    });
  }

// Preview a specific word with learning app V1
} else if(window.location.search.startsWith('?learnable_id=')) {
  if (unsafeWindow.$) {
    interceptJqueryAjax();
  }
  window.addEventListener('load', onLoadPreviewV1, false);

  // Change close preview link (toward level instead of home)
  function onLoadPreviewV1() {
    var url_course = window.location.pathname.replace("/garden/preview/", "/"),
        exit       = document.querySelector('a.session-exit');

    if(exit) {
      exit.setAttribute('href', url_course);
      exit.addEventListener('click', function(){
        window.onbeforeunload = null;
        window.location.href  = this.getAttribute('href');
      });
    }
  }

  // Intercept AJAX response for V1 learning session
  function interceptJqueryAjax() {
    function main() {

      var _oldAjax = $.ajax;
      $.ajax = function(options) {

        if(options.url == "/ajax/session/") {
          var _oldSuccess = options.success;

          _oldSuccess && $.extend(options, {
            success: function(data) {
              var learnable_id = window.location.search.substr(14);

              // Replace list of words with list of a single word
              if(typeof data.screens[learnable_id] != "undefined") {
                data.boxes = [{
                  learnable_id: learnable_id,
                  template: "presentation"
                }];
                data.session.num_items = 1;
              }
              _oldSuccess(data);
            }
          });
        }
        return _oldAjax(options);
      };
    }

    // Inject JS directly in page to prevent limitations of access
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.appendChild(document.createTextNode('('+ main +')();'));
    document.body.appendChild(script);
  }

// Preview a specific word with learning app V2
} else if(window.location.pathname == '/aprender/preview' && (new URLSearchParams(window.location.search)).get('learnable_id')) {
  if (window.fetch && unsafeWindow.Promise) {
    interceptFetch();
  }

  // V2 learning session
  function interceptFetch() {
    function main() {

      // Override native fetch
      const overrideFetch = function() {
        var p = _oldAjax.apply(this, arguments);

        if (p.__proto__ == Promise.prototype && typeof interceptedResponse != 'undefined') {
          var url = arguments[0];

          if (url && url.endsWith("/preview/")) {
            return p.then((response) => {
              return interceptedResponse(response);
            });
          }
        }
        return p;
      }
      const _oldAjax = window.fetch;
      if (!_oldAjax.proxiedFetch) {
        overrideFetch.proxiedFetch = true;

        window.fetch = overrideFetch;
      }

      // Override the json() function
      function interceptedResponse(response) {
        console.log('intercept.response', response);
        var _oldFn = response.json;
        if(!_oldFn) {
          return response;
        }
        response.json = function() {
          var p = _oldFn.apply(this, arguments);
          if (p.__proto__ == Promise.prototype && typeof interceptedJson != 'undefined') {
            return p.then((data) => {
              return interceptedJson(data);
            });
          }
          return p;
        }
        return response;
      }

      // Attempt to update the decoded data
      function interceptedJson(data) {
        console.log('intercept.json', data);
        try {
          updateData(data)
        } catch(e) {
          console.error(e);
        }
        return data;
      }

      function updateData(data) {
        console.log('updateData', data);

        var LEARNABLE_ID = (new URLSearchParams(window.location.search)).get('learnable_id');
        if(!('learnables' in data) || !LEARNABLE_ID) {
          return;
        }
        var learnable = data.learnables && data.learnables.find(x => x.id == LEARNABLE_ID);
        Object.assign(data, {
          learnables: learnable ? [learnable] : [],
        });
      }
    }

    // Inject JS directly in page to prevent limitations of access
    var script = document.createElement('script');
    script.setAttribute("type", "application/javascript");
    script.appendChild(document.createTextNode('('+ main +')();'));
    document.body.appendChild(script);
  }
}