[Deprecated] Kanka Backup to Local Storage

Copies the editor’s content to local storage before saving to allow recovery if something is lost in transit.

  1. // ==UserScript==
  2. // @name [Deprecated] Kanka Backup to Local Storage
  3. // @namespace http://tampermonkey.net/
  4. // @version 2
  5. // @description Copies the editor’s content to local storage before saving to allow recovery if something is lost in transit.
  6. // @author Salvatos
  7. // @license MIT
  8. // @match https://app.kanka.io/*
  9. // @icon https://www.google.com/s2/favicons?domain=kanka.io
  10. // @run-at document-end
  11. // ==/UserScript==
  12.  
  13. // Wait for Summernote to initialize
  14. $('#entry').on('summernote.init', function() {
  15. // Find the current entity’s ID (NOTE: DOES NOT WORK FOR NEW ENTITIES (/create))
  16. const entryType = window.location.href.match(/posts/) ? "post" : "entry";
  17. let entityID = "";
  18. if (entryType == "entry") {
  19. entityID = window.location.href.match(/w\/([\w\d])+\/[a-z]+\/(\d+)/) ? window.location.href.match(/w\/([\w\d])+\/[a-z]+\/(\d+)/)[1] : "new";
  20. }
  21. if (entryType == "post") {
  22. entityID = window.location.href.match(/posts\/(\d+)/) ? window.location.href.match(/posts\/(\d+)/)[1] : "new";
  23. }
  24.  
  25. if (entityID != "new") {
  26. var recoveryButton = `
  27. <button type="button" id="recoveryButton" class="note-btn btn btn-default btn-sm" tabindex="-1" title="Recover previous state" aria-label="Recover previous state" data-original-title="Recover previous state">
  28. <i class="fa-solid fa-clock-rotate-left"></i>
  29. </button>
  30. `;
  31. document.getElementsByClassName('note-toolbar')[0].insertAdjacentHTML("beforeend", recoveryButton);
  32.  
  33. // Grab our button instance
  34. recoveryButton = document.getElementById('recoveryButton');
  35.  
  36. // Add click event to button (copy saved content to clipboard)
  37. recoveryButton.addEventListener('click', ()=>{
  38. let savedState = "";
  39. if (entryType == "entry") {
  40. savedState = JSON.parse( localStorage.getItem('kanka-recovery-entity-'+entityID) );
  41. }
  42. if (entryType == "post") {
  43. savedState = JSON.parse( localStorage.getItem('kanka-recovery-post-'+entityID) );
  44. }
  45.  
  46. if (savedState && savedState.length > 0) {
  47. // Copy code to clipboard (no IE support)
  48. navigator.clipboard.writeText(savedState).then(function() {
  49. alert("Saved state copied to clipboard");
  50. }, function() {
  51. alert("Failed to access the clipboard");
  52. });
  53. }
  54. else {
  55. alert("No saved state found for the current " + entryType + ".");
  56. }
  57. });
  58. }
  59.  
  60. // Add event to save button(s)
  61. document.getElementById('form-submit-main').addEventListener('click', ()=>{
  62. var editorValue = "";
  63. // Code editor
  64. if ($('#entry + div').hasClass('codeview')) {
  65. editorValue = $('#entry + div').find('.note-codable').val();
  66. }
  67. // Visual editor
  68. else {
  69. editorValue = $('#entry').val();
  70. }
  71.  
  72. if (entryType == "entry") {
  73. localStorage.setItem('kanka-recovery-entity-'+entityID, JSON.stringify(editorValue));
  74. }
  75. if (entryType == "post") {
  76. localStorage.setItem('kanka-recovery-post-'+entityID, JSON.stringify(editorValue));
  77. }
  78. });
  79.  
  80. });