SurferSEO Lines to Paragraph

Combines lines separated by newlines into a single paragraph.

  1. // ==UserScript==
  2. // @name SurferSEO Lines to Paragraph
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description Combines lines separated by newlines into a single paragraph.
  6. // @match https://app.surferseo.com/drafts/*
  7. // @grant none
  8. // @author mhshan
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. 'use strict';
  14.  
  15. // Function to combine lines into a single paragraph
  16. function combineLinesToParagraph(text) {
  17. return text
  18. .split(/\n+/) // Split text by newlines
  19. .map(line => line.trim()) // Trim spaces from each line
  20. .filter(line => line.length > 0) // Remove empty lines
  21. .join(' '); // Combine lines into one paragraph with spaces
  22. }
  23.  
  24. // Add a button to combine lines into a paragraph
  25. const combineButton = document.createElement('button');
  26. combineButton.innerText = 'Lines to Paragraph';
  27. combineButton.style.position = 'fixed';
  28. combineButton.style.top = '250px';
  29. combineButton.style.left = '60px';
  30. combineButton.style.padding = '10px 15px';
  31. combineButton.style.fontSize = '14px';
  32. combineButton.style.backgroundColor = '#000000';
  33. combineButton.style.color = 'white';
  34. combineButton.style.border = 'none';
  35. combineButton.style.borderRadius = '5px';
  36. combineButton.style.cursor = 'pointer';
  37. combineButton.style.transition = 'transform 0.3s ease, background-color 0.3s ease';
  38. combineButton.style.zIndex = '1000';
  39. document.body.appendChild(combineButton);
  40.  
  41. // Hover animation for the button
  42. combineButton.addEventListener('mouseover', () => {
  43. combineButton.style.transform = 'scale(1.1)';
  44. combineButton.style.backgroundColor = '#3ccf4e';
  45. });
  46.  
  47. combineButton.addEventListener('mouseout', () => {
  48. combineButton.style.transform = 'scale(1)';
  49. combineButton.style.backgroundColor = '#000000';
  50. });
  51.  
  52. // Display "Combined!" confirmation message with animation
  53. const combinedMessage = document.createElement('div');
  54. combinedMessage.innerText = 'Combined!';
  55. combinedMessage.style.position = 'fixed';
  56. combinedMessage.style.top = '100px';
  57. combinedMessage.style.left = '60px';
  58. combinedMessage.style.padding = '5px 10px';
  59. combinedMessage.style.backgroundColor = '#4CAF50';
  60. combinedMessage.style.color = 'white';
  61. combinedMessage.style.fontSize = '14px';
  62. combinedMessage.style.borderRadius = '5px';
  63. combinedMessage.style.zIndex = '1000';
  64. combinedMessage.style.opacity = '0'; // Initially hidden
  65. combinedMessage.style.transition = 'opacity 0.5s ease';
  66. document.body.appendChild(combinedMessage);
  67.  
  68. // Event listener for the button
  69. combineButton.addEventListener('click', () => {
  70. const selectedText = window.getSelection().toString();
  71. if (selectedText) {
  72. const combinedText = combineLinesToParagraph(selectedText);
  73.  
  74. // Replace selected text with combined text in place
  75. document.execCommand('insertText', false, combinedText);
  76.  
  77. // Show "Combined!" message with fade-in/out animation
  78. combinedMessage.style.opacity = '1'; // Fade in
  79. setTimeout(() => {
  80. combinedMessage.style.opacity = '0'; // Fade out after 1 second
  81. }, 1000);
  82. } else {
  83. // If no text is selected, show message
  84. combinedMessage.innerText = 'Please select text to combine!';
  85. combinedMessage.style.opacity = '1';
  86. setTimeout(() => {
  87. combinedMessage.style.opacity = '0';
  88. combinedMessage.innerText = 'Combined!';
  89. }, 1000);
  90. }
  91. });
  92. })();