Oilmonkey script – Digger Markdown format adapter knowledge points record

Script update log

Reference: Nuggets Markdown format adapter update log – Nuggets

Script address:

Updated on September 3, 2021 at 19:57:35

Reference: Nuggets Markdown format adapter

preface

For more information on why I wrote this script, see the following gag (or problem description) blog post I wrote:

Reference: Nuggets Markdown Editor Problem Description – Nuggets

My writing habits in my local Markdown editor (Typora) are:

  • with==xxx==To highlight text;
  • with<center></center>Center text;
  • As for the image center, it is automatically centered in Typora and I don’t need to worry about it, while in CSDN’s Markdown editor, it is added after the image#pic_centerCome to the middle.
  • Setting the color and size of the text and so on are all passed<font color="gray" size="2px"> </font>or**<font color="red" size="2px"> </font>**In the manner of;
  • Setting the key format is all through< < KBD > buttons/KBD > οΌ›

I’ve sorted out the support for certain Markdown syntax and HTML tags or attributes in Nuggets Markdown editor, CSDN Markdown editor, and Typora:

Markdown grammar,

HTML tag or attribute
function typora CSDN The Denver nuggets
==xxx== The highlighted text support support Does not support
<mark>xxx</mark> The highlighted text support support support
styleattribute Set the style support Does not support Does not support
<font color=gray size=2></font> Set the text

Size and color
support support Does not support
<center>xxx</center> Centered text support support Does not support
<div align="center">xxx</div> Centered by support support support
<div color="gray">xxx</div> Setting text Styles Does not support support support
<strong>xxx</strong> Bold text support support support
<strong color="red">xxx</strong> Bold text and

Set the color
Does not support support support
<span color="red">xxx</span> Set text color Does not support support support
<br> A newline support support support
<kbd>xxx</kbd> Setting key Styles support support Does not support
πŸ˜‚ :joy: Insert emoji support support Does not support

These are just a few of my common uses, and you can see that some are universal, but some don’t support all of them… In particular, the Nuggets don’t support the use of == XXX == to highlight the text, which bothers me a lot, because I see a lot of == in the article, which gives me the impression that the article was copied from somewhere in a hurry without having time to format it…

The bottom line is that the Nuggets Markdown editor does not support some of my common Markdown writing habits, so I wrote this adaptation script to change some of the local Markdown documents from my personal habits to the nuggets Markdown editing and parsing rules.

I really think the and


tags and the style attribute work well in Markdown, and I would love to see official support for these writing-friendly tags and attributes πŸ˜‚

Script function is relatively simple, but still spent a lot of time and energy, these days have been two or three. The regex matching rules may be lost in some documents until they are encountered. At present, the function of the script is quite enough,

I. Description of script functions

To be honest, these problems were caused by my writing habits in the local Markdown editor not being able to adapt to the Nuggets Markdown editor. There are some tricks that I think work well in the local Markdown editor (I mostly use Typora) or the CSDN Markdown editor. But it doesn’t work well in the Nuggets editor… This is very speechless, I only hope the nuggets can have a corresponding solution, after all, like my small script is not convenient enough.

1, the==xxx==Replace with<mark>xxx</mark>

The premise is that the imported Markdown document has == XXX ==. This is the second point in response to the above questions, such as:

== Text you want to highlight == Change to <mark> Text you want to highlight </mark>Copy the code

Updated on September 6, 2021 at 10:51:59

In fact, there was a problem when importing this article with script in the gold digger editor, there was no record at that time, now let’s fix it.

Normally, text wrapped in ‘is displayed as the original characters, not as some kind of syntax. But the script’s re doesn’t take this into account, so if you have == or


or! [](), the re will treat it as a qualified match, but we don’t really want the script to match and replace this part of the text.

The re should be modified to skip wrapped text, but I don’t have a solution yet… So be careful with scripts!

2, the<center>xxx</center>Replace with<div align="center">xxx</center>

The premise is that there is

in the imported Markdown document. This is the first point to address the above questions, such as:

<center> Text or element you want centered </center> becomes <div align="center"> Text or element you want centered </center>Copy the code

3, the! [](picture link)Replace with<div align="center"><img SRC =" image "></div>

If there is one in the imported Markdown document! [](image link). This is the first point to address the above questions, such as:

! <div align="center"><img SRC =" image "></div>Copy the code

[Updated: 01:01:37 on September 1, 2021]

You can also append the picture description to the bottom of the picture, with the format referring to [2].

! <div align="center">< /div> <div align="center" color="gray">Copy the code

4. (pseudo) Import local files

Click the corresponding script icon to select the local.md document, do the three things mentioned earlier, and then write the processed text to the clipboard. The user manually presses Ctrl + V to place the clipboard contents into the appropriate editor input box for the nuggets editor to parse.

5. Automatically fill in the title of the article

Automatically retrieves the first level 1 title in the imported Markdown document and fills in the article title input box.

Updated on September 3, 2021 at 02:45:31

There is a bug that appears to auto-fill the title, but it is still a problem. For details, see below.

Updated on September 3, 2021 at 19:04:05

It occurred to me that if there was no level 1 title in the document, I would be making the same error that I had encountered before with an empty match. Therefore, the existence judgment of the first-level title should be added. When there is no first-level title in the document, the first ten characters of the document should be taken as the title. If there is less than ten characters, the whole content should be taken as the title. .

6. Final effect demonstration

Script final effect demonstration


Two, knowledge points record

1. Regular expressions used in the script

The core functionality of this script relies on regular expressions. Here are a few of the re’s I used in the script:

demand regular
A. Matching consists of pairs= =Text of the package 1./==[^==]*==/g

2./ = = (? : (? ! (= =))) *==/g

3./ = =. *? ==/g(The one I finally adopted)
B. match by<center>xxx</center>Text of the package /<center>.*<\/center>/g
C. Match the Markdown image link! [] () /! \[.*\]\(.*\)/g
D. Match the level 1 title in the document# /#\s.*/g

1.1. Achieve non-greedy or minimum matching

In requirement [a], I initially used /==.*==/g, and found that some matches were not as expected, such as the following paragraph:

And the request interceptor callback == stored in 'interceptors.request' is loaded in pairs into the == header == of the 'chain' array (via the 'unshift()' method of the array object); The response interceptor callback == stored in 'interceptors.response' is pressed in pairs into the == tail of the == chain array (via the array object's 'push()' method).Copy the code

In this text, you should expect four matches: == pair ==, == header ==, == pair ==, == tail ==.

But the above re will only match one result: == pairs == into the == header of the chain array == (via the unshift() method of the array object); The response interceptor callback == stored in interceptors. Response is pressed in pairs into the == tail == of the chain array.

In other words, /==.*==/g will treat the first == of the pair == and the last == of the pair == and ignore the middle ==, which is obviously not what we want. /==[^==]*==/g The re means to find the text wrapped by == that can no longer contain ==. That would satisfy my need.

Then I came across a more general approach in a blog post:

Updated: August 29, 2021 at 21:37:33

Reference: Regular expression: does not contain certain words (super difficult regex, oh, oh)_ Xing Xiaoning -CSDN blog

So following the blogger’s thought, I wrote β‘‘/==(? : (? ! (= =))) *==/g, can also meet my needs.

I took a lot of detours here at first, and then came across a passage in the Regex tutorial in the Rookie tutorial:

Updated: September 1, 2021 at 14:36:46

Reference: the regular expression – grammar | novice tutorial

Rookie re tutorial – minimum match -QQ screenshot 20210902172007


So following this idea, I wrote β‘’/==.*? ==/g, I feel that this is the most directly logical way to meet my needs.

In addition, incidentally recommend the rookie tutorial online re tool, feel very good to use:

Reference: the regular expression online test tools | rookies

I spent a lot of energy on the regular part. After some exploration, I felt it was not easy… (Here is a memory of my sacrificed hair πŸ˜‚)

1.2. Regular expression constructors

There are two ways to create a regular expression: literals and constructors. Because I didn’t wrap the function at first, I just used the literal. When it comes to encapsulating functions, literals are not flexible enough. The RegExp() constructor is used. See the official documentation below for details:

Updated: September 1, 2021 at 22:39:47

Reference: the RegExp (regular expression) – JavaScript | MDN

I’ll mention just one pit I came across:

image-20210902174605536


For example, if I want to create a regular expression using the RegExp() constructor for image link matching, I pass in arguments like this:

let reg = '! \ \ \ \ \ \ [*] (. * \ \] '
let replacement = target.match(new RegExp(reg, 'g'));
Copy the code

1.3. Match the beginning and end of the re and the newline character

In requirement [d. match document level 1 title #], I start with the re /^#\s.*\n$/g to say that the matched text must begin with #, followed by a space, and must end with a newline character.

I thought it was reasonable, but it didn’t pass the test, and the result of my online re match in the rookie tool was not the same as the result of my re match in vscode. Finally, I put it into the code, and the reason is that the text cannot match the required text. In the middle of the night, I thought my script was about to be finished, so I got stuck here for an hour or so… People are falling asleep.

Later, I searched and checked, and found that there seems to be a problem with \n, ^ and $. In the end, after a few tweaks and tweaks, I managed to get the code to do what I wanted (although I didn’t quite understand why in the end… Again, Re is a big hole…) .

1.4 the re adds (concatenates) text to the original content of the match

This discovery had nothing to do with the script, but I found it interesting and useful, so I made a few notes here.

So let’s say I want to add 100 to each of the following items.

#chara 2,cgm_kt13
#chara 2,cgm_fd22
#chara 2,cgm_gy75
Copy the code

So just make the regular expression :(#chara 2,cgm_\w+). $1,100 = $1,100

Chara 2,cgm_kt13,100 #chara 2,cgm_fd22,100 #chara 2,cgm_gy75,100Copy the code

In regular expressions, groups are placed inside parentheses. The order in which the parentheses appear can be \1,\2… \ 9 (or $1, $2… $9) reference, the entire re is referenced with \0 or $0. Thus, the substitution \1 refers to what is matched in parentheses, followed by the character to be added.

< span style = “max-width: 100%; clear: both;

let selectedText = selectedText.replace(/(a)(b)(c)(d)(e)(f)(g)(h)(i)/g.$1- $2- $3- $4- $5- $6- $7');
Copy the code

β‘‘ Add the specified content to the beginning of the regular expression line:

Matching characters: ^(.+)$– matches any line beginning

Substitution character: A $1 — prefixes a character a to the result of the match above

β‘’ Add #pic_center to the image in CSDN to center the image. (This works by using Ctrl + G in CSDN editor)

Character: (. * \. PNG |. * \. JPG |. * \. GIF |. * \. Jpeg |. * \. Webp |. * \. SVG |. * \. BMP |. * \. Ico) – match all the image links

Replacement character: $1#pic_center – add the #pic_center suffix to all image links

// String to match! [1] plug-in effect (https://img-blog.csdnimg.cn/79f13197e56845a08c2e3e8536cece19.png) / / matching results! [1] plug-in effect (HTTP: / / https://img-blog.csdnimg.cn/79f13197e56845a08c2e3e8536cece19.png / / replace the result! [1] plug-in effect (https://img-blog.csdnimg.cn/79f13197e56845a08c2e3e8536cece19.png#pic_center)Copy the code

Updated: September 1, 2021 at 21:09:41

In regular expressions, how to add the original character and specific content after any matching character

2. Util.promisify () in node.js

Instead of testing the scripting functionality in the browser environment, I implemented and tested the functionality in the Node.js environment. Here, I use the node.js built-in file manipulation module FS to read and write documents related functions. The use of util.promisify() in Node.js encapsulates asynchronous operations related to reading and writing files.

Util is a built-in module in Node.js. Uti.promisify () wraps an error-first style callback into another function that returns a Promise value.

Description in official documentation:

Use functions that follow the common error-first callback style (that is, place (err, value) =>… Callback as the last argument) and returns a version that returns the promise.

Reference: util.promisify() utility

For example, readFile(path, (error, data) => {}) of fs module in Node.js is a typical error-first asynchronous operation. You can then wrap the readFile() function as a function that returns a Promise object by doing the following. The same goes for the writeFile() function.

const fs = require('fs');
const util = require('util');
const myReadFile = util.promisify(fs.readFile);
const myWriteFile = util.promisify(fs.writeFile);

myReadFile('./ test document.md ')
  .then(data= > {
    letcontent = data.toString(); .// Re processing logic
    // console.log(content);
    myWriteFile('./processed.md', content);
  }, error= > {
    console.warn(error);
  })
Copy the code

For more on promises, see the study notes I wrote earlier:

[Handwritten Promise; asynchronous programming; Promise API; exception penetration; chain calls; async and await] – Digging gold

3,Window.getselection () gets the text selected with the mouse

In fact, before I decided to use the local document reading scheme, I wanted to select a small part of the text in the editing area with the mouse, and then press the custom shortcut key, the selected text content can be replaced according to the rules. So we looked at Selection a little bit.

Updated on September 2, 2021 at 19:11:27

Reference: reference | MDN Selection – Web API interface

Window. GetSelection_xiaoxu

Get the selected text, copy the selected text _ wang Xiaomu’s blog -CSDN blog

Get the selected text – SegmentFault think no

Get the selected text, copy the selected text _ wang Xiaomu’s blog -CSDN blog

Reference: JS text operation copy copy and select text _ front-end view the world -CSDN blog

Reference: How do I get the CSDN community node where the selected text is located in javascript

However, I gave up this plan soon. After all, it was too time-consuming to find the text to be modified one by one.

4,File reading interface and file objects (Input tags and FileReader objects)

JavaScript provides a series of interfaces for browsers to read local files.

The tag is usually used when we want to read a file from the browser. Note that the type value is file. When we click the corresponding button, the browser will invoke a UI style consistent with our current operating system’s built-in file selection window to let the user select the corresponding local file. At the same time, the change event for the input tag will be triggered, and we can use event.target.files to get the list of selected files. The list is of type FileList. Each entry is a File object of type File.

We can also limit the type of file accepted by setting the ACCEPT attribute value of the input tag.

<input type="file" id="input" accept=".md, .txt, .docx">
Copy the code

Once we get the File object, we can manipulate the contents of the File we get through the FileReader object.

if (window.FileList && window.File && window.FileReader) {
  document.getElementById('input-file').addEventListener('change'.event= > {
    const file = event.target.files[0];
    const reader = new FileReader();
    reader.addEventListener('load'.event= > {
      // The event.target is the FileReader object we created
      letcontent = event.target.result; . });// reader.readAsDataURL(file);
    reader.readAsText(file);
  });
}
Copy the code

Below is the MDN document: FileReader – Web API interface reference | MDN descriptions of FileReader related API:

interface function
FileReader.result(read-only) The contents of the file. This property is valid only after the read operation is complete, and the format of the data depends on which method is used to initiate the read operation.
FileReader.readAsDataURL(file) Starts reading the specifiedBlobThe content of. Once that’s done,resultProperty will contain onedata:A Base64 string in URL format to represent the contents of the file being read.
FileReader.readAsText(file) Starts reading the specifiedBlobThe content of. Once that’s done,resultProperty will contain a string representing the contents of the file being read.

We are now ready to retrieve the specified document as a string.

Update: 01:06:11 on August 30, 2021

Reference: Read files in JavaScript

Reference: < input > : input (form input) elements – HTML (hypertext markup language (HTML) | MDN

Reference: in web application using the file – | MDN web API interface reference

Reference: reference | MDN FileReader – Web API interface

Reference: A deep exploration of the input type= “file” and its files object

Reference: JS learning – using JS to read local files _ Yin Shuo’s column -CSDN blog

Reference: File uploads can be triggered without using file type input

CSDN blog_input type=file [type=”file”

Reference: Front-end file upload principle _weixin_42600496 blog -CSDN blog

5,Customization of the input tag style

But the style of the native input tag isn’t pretty enough, so it needs to be dressed up. However, the style Settings available for the input tag are limited and still don’t meet my needs. So here’s how to do it.

The general idea is to assign a corresponding label label to the input label. Bind label to INPUT by setting the for attribute to be the same as the ID attribute.

<label for="file-input">label</label>
<input type="file" id="file-input"  style="display: none;"/>
Copy the code

Of course, you should also set display: None to the input tag for aesthetic purposes. This will only see the label label on the page, but when we click on the label label, it will trigger the event associated with the input label, which is equivalent to clicking on the input label. You can then style the label according to your needs.

Of course, you can override an element like div or IMG for the input tag and reduce its opacity to 0, but make sure that the tag’s level is higher than the element it overwrites (set the Z-index value). This ensures that clicking on the location triggers reading of the file. Its main ideas are: Wrap the input (position:absolute) in a div (position:relative) and hide the input. This changes the style. It is not really changing the style of the input. Instead, use the wrap style to cover up the input.

Updated: 02:01:33 on August 30, 2021

How to override the default style _ ingenious use of the label to implement the input file upload file custom style _weixin_39761645 blog -CSDN blog

How to give file type input tag, custom style – Shmily-HJT – blog garden

【 Front-End 】 Input file label custom upload style _ smart effort positive blog -CSDN blog

Reference: Web front-end custom input button style _LSY_U56 blog -CSDN blog _INPUT button style

Reference: custom input file upload style – huanzi- QCH – blog garden

Reference: CSS modify input type=”file” file default upload style _jo_an_na blog -CSDN blog

At first, I customized the style of the label according to the other icon styles in the toolbar, but there are always differences, although there are some details, I can still feel the difference, but I can’t help it, after all, there is no way to directly get all the styles of other buttons, and some of the styles are directly inherited. It’s hard to find layers…

Later, when I looked at the styles of the other buttons through the developer tools, I noticed that each button had three common class property values.

image-20210902222411352


After some experimentation, I found that simply adding class=” byte-tooln-icon “to the label tag generated by the script made the script button look exactly the same as the other buttons. After all the trouble I had to tweak the style, I ended up with a class property… Of course, this style needs to work with the SVG ICONS mentioned below to have the same effect.

6. Cursor: pointer and background-image do not function

< span style = “font-size: 12px! Important; color: RGB (74, 74, 74);”

β‘‘ Background-image can be used to set the background image of an element, and the target background can be set by url(). Supports local image file paths (absolute and relative paths) and network images, as well as Base64 format images.

attribute role
background-image Setting the background image
background-size Sets the size of the background image
background-color Sets the background color of the element
background-position Sets the starting position of the background image

Updated: September 2, 2021 at 21:05:03

Reference: cursor – CSS (cascading style sheets (CSS) | MDN

Reference: background – size – CSS (cascading style sheets (CSS) | MDN

Reference: CSS background-size property

Background-image resizing and positioning methods

A handy chart library from ByteDance can be used to download backgroundless images, copy the corresponding SVG or import it directly into your project.

Reference: ByteDance IconPark

7,Insert or create SVG

I started by setting the background image to make my import button look like the original UI. But because images still can’t dynamically change their background color to match the background color of the page, the script-generated buttons look awkward when the page is in dark mode. So I decided to replace the original image background with SVG so that the script button would blend in with the rest of the original button.

I started by copying the SVG code from the byte online icon library mentioned above, and pasting it directly into a local test web page showed up correctly, perfectly adapted to dark mode. But when I tried to insert the entire SVG code into the label tag via JavaScript, I found that the icon didn’t display.

importLabel.innerHTML = ` 
       
       
        
        
        
        
      `;
Copy the code

What I expected:

image-20210902213520828


In practice:

image-20210902214416068


The nested relationship does not display ICONS properly. After a bit of checking, I found that the

and tags in the SVG code copied from the online site are self-closing tags, but will automatically change into pairs of closed tags when testing local web pages. So I tried to change the copied SVG code from self-closing to closing tags in pairs and found that the icon was displayed successfully.

importLabel.innerHTML = ` 
       
       
        
        
        
        
      `;
Copy the code

I originally wanted to create a < SVG >
tag using document.createElement(), but it didn’t work. I later learned that SVG is based on XML and that creating tag nodes requires a namespace. CreateElementNS () is required to create SVG and PATH elements. So you need to change createElement() to createElementNS().

Since inserting SVG code directly inside the label was enough for me, I didn’t use JavaScript code specifically to create SVG.

Updated on September 2, 2021 at 22:00:35

Reference: Using JavaScript to create SVG tags _ MOOCs ape ask

How to create SVG with javascript

Lovollll – Lovollll – blogpark

Reference: XML DOM setAttributeNS() method

Reference: SVG path | novice tutorial

Implement tooltip

In the original Nuggets Markdown editor toolbar, there is a prompt effect when mouse over:

Tooltip effect in the Nuggets Markdown editor


For visual harmony, I think my script buttons should also have a prompt effect. So began the tooltip implementation.

For details, please see my other blog post:

Updated on September 3, 2021 at 18:43:50

Reference: Tooltip experience – Digging gold

9,Aria – XXXX properties

In the study of the above tooltip effect, I repeatedly observed how the tunneling tooltip was implemented, I found that every time the mouse moved to the button, the corresponding element will dynamically add an Aria-describedby attribute, and its value is with the increase of mouse times and present regular changes.

The Markdown editor tooltip effect


I wonder if nuggets’ tooltip implementation has anything to do with this property. So I tried writing the following test code:

<ul>
  <li aria-describedby="desc1">button</li>
</ul>
<p id="desc1">prompt</p>
<script type="text/javascript">
  const target = document.querySelector('[aria-describedby="desc1"]');
  const tip = document.getElementById('desc1');
  target.onmouseover = function () {
    tip.style.display = 'block';
  }
  target.onmouseleave = function () {
    tip.style.display = 'none';
  }
</script>
Copy the code

It looks like you can implement the tooltip effect, but it doesn’t feel like it works that way… I decided to find out what the aria-Describedby attribute was for. Then I found the following definition:

The property value is a string, which can be a whitespace delimited list of multiple ID property values.

This attribute defines interrelationships between elements that are not represented by the document structure. This attribute is intended to provide more information that a user might need through the tag. If more than one ID is specified, all elements are merged together to create a single description.

It might seem relevant, but why add such a property to implement tooltip? I’m a little confused. Since I later implemented Tooltip in other ways, I didn’t go any further. But the aria-xxxx property is something to be aware of.

Updated: August 30, 2021 at 21:18:43

Reference: ARIA – accessibility | MDN

Reference: Using the aria – describedby attribute – the org.eclipse.swt.accessibility | MDN

Reference: Accessibility development (iii) ARIA ARIA -*** attribute value _weixin_30510153 blog -CSDN blog

Reference: what does data-container=”body” mean? Net – longed for class

10. Encapsulation of several functions

10.1. Create DOM node objects

/ * * *@description: This function is used to create a <eleName k="attrs[k]">text</eleName> page element *@param {string} EleName Indicates the label type of the DOM element *@param {string} Text The internal text of the DOM element *@param {object} Attrs DOM element attribute configuration *@return {HTMLElement} Returns a DOM node */
function createEle(eleName, text, attrs) {
  let ele = document.createElement(eleName);
  // innerText which is 

text will be added here

ele.innerText = text; Attrs is of type map for (let k in attrs) { // Iterate over attrs and add the desired attributes to node ele ele.setAttribute(k, attrs[k]); } // returns the node return ele; } Copy the code

10.2. Intercepts a string between two specified strings

/ * * *@descriptionThis function is used to intercept the string * between the specified startStr and endStr substrings in the target string@param {string} Target Indicates the target character string *@param {string} StartStr Start substring *@param {string} EndStr end substring *@return {string} The truncated substring */
function getSubStr(target, startStr, endStr) {
  let startPos = target.indexOf(startStr) + startStr.length;
  let endPos;
  if (startStr === endStr) {
    endPos = target.lastIndexOf(endStr);
  } else {
    endPos = target.indexOf(endStr);
  }
  return target.substring(startPos, endPos);
}
Copy the code

10.3. Re replaces text

There are a few places in the script where the code to match and replace text with the re is repetitive, so I’ve wrapped it up a bit.

/ * * *@description: This function encapsulates the ability to replace relevant text in the original Markdown document *@param {string} Target Indicates the target text content to be processed@param {string} Reg regular expression *@param {string} Expected wrapperHead *@param {string} Expected wrapperTail *@param {string} StartStr The starting substring * when intercepting content@param {string} EndStr End substring * when intercepting content@return {string} Returns the processed document contents */
function replaceText(target, reg, wrapperHead, wrapperTail, startStr, endStr) {
  let replacement = target.match(new RegExp(reg, 'g'));
  // Check the existence of the match, otherwise an error will be reported
  if(! replacement) {return;
  }
  for (let i = 0; i < replacement.length; i++) {
    let content = getSubStr(replacement[i], startStr, endStr);
    let imgDescription = ' ';
    // Determine if the current match is a Markdown image, if so, append the image description
    if (reg === '! \ \ \ \ \ \ [*] (. * \ \] ') {
      imgDescription = `<div align="center" color="gray">${getSubStr(replacement[i], '['.'] ')}</div><br>`;
    }
    replacement[i] = wrapperHead + content + wrapperTail + imgDescription;
  }
  for (let i = 0; i < replacement.length; i++) {
    target = target.replace(new RegExp(reg), replacement[i]);
  }
  // [Update: 00:53:08, September 2, 2021] Be sure to return the result !!!!
  return target;
}
Copy the code

Update: 00:57:37 on September 1, 2021

While testing a document, the console suddenly reported the following error:

image-20210901005753231


Because some documents may not use matches, the result of the corresponding re will be null, and the length of the null value will be read with an error. So it’s important to make an existence judgment on the matches beforehand. That is, before the substitution we add this judgment:

if(! replacement) {return;
}
Copy the code

Updated: 02:50:45 on September 3, 2021

As I tried to test more documents, I noticed that one of them suddenly reported the following error:

image-20210903025300744


The reason is simple, because the first regular replacement in my script is for , and if there is no highlighted text in the document, it returns undefined on line 65, shown above. The target argument in replaceText() will be undefined when the next re is matched, so an error is reported. There are two changes:

/ / the first
let replacement = target.match(new RegExp(reg, 'g'));
if(! replacement) {returntarget; }...// Handle text logic
return target;
Copy the code
/ / the second
let replacement = target.match(new RegExp(reg, 'g'));
if (replacement) {
  ......	// Handle text logic
}
return target;
Copy the code

Function value passing and reference passing

When encapsulating [10.3] above, I did not initially return the processed result, resulting in the imported document content being completely unprocessed. After a step by step debugging observation on the console, I realized that I had made a stupid mistake: I didn’t understand the value passing and reference passing of functions.

When the content of the document I’m about to process (as a string) is passed to the function as an argument (the target argument above), inside the function you do see target change as expected, but once the function is finished, the result of the function’s processing just stays inside the function. So the content of the document is passed in as raw, and the end result is a piece of raw text written to the user’s clipboard.

So be sure to expose the processing result to the function via a return value, and arrange for an appropriate variable to receive it. That’s what makes the function work.

There are three ways in which a function can bring up a result:

  • The global variable
  • Function return value
  • Address parameter

12,JavaScript clipboard operations

The clipboard issue was addressed in my last script.

Reference: Copy title and address (myFirstScript)

Copy -title-and-location – copy-title-and-location

There are several frequently mentioned clipboard-related apis, objects, or JS libraries:

  • navigator.clipboard.writeText() 、navigator.clipboard.write() ε’Œ navigator.clipboard.readText() 、 navigator.clipboard.read()
  • document.execCommand('copy') ε’Œ document.execCommand('paste')
  • copyEvents,cutEvents,pasteThe event
  • event.clipboardDataThe objects andClipboardobject
  • clipboard-write(Write permission) andclipboard-read(Read permission)
  • clipboard.js
  • .

As for this script, it was mentioned in the function description [4] above that the file import function provided by the script is actually not “import” in the real sense, because the content after processing needs to be put into the editing area by pressing Ctrl + V. I wanted to grab the element where the cursor is in the edit area and write the text into the edit area using htmlElement.innertext (), but it wasn’t as simple as I thought. Since nuggets’ Markdown edit renders in real time based on user input, blocks of text are distributed in different


… If the script selects the so-called edit area via document.querySelector(), then it can only put text into a specific


, and there is no parsing effect…

image-20210903015336941


So, under compulsion, can only rely on Ctrl + V curve to save the country.

Updated: September 3, 2021 24:57:04

Reference: Clipboard operation Clipboard API tutorial – Ruan Yifeng’s weblog

Reference: reference | MDN Event – Web API interface

Reference: Element: paste | MDN events – Web API interface reference

Reference: JS: Copy content to clipboard (no plug-in, compatible with all browsers) _ small white one -CSDN blog _js Copy to clipboard

Js Copy text to paste board (clipboard.writetext ()) _β˜…γ€World Of Moshow Zheng Kai γ€‘β˜…-CSDN blog

Chrome 66 added asynchronous Clipboard API – Zhihu

Reference: JS to get clipboard content, JS control image paste. – SegmentFault think no

13,Triggers a custom event

Document. CreateEvent (eventType), event. InitEvent (” XXX “, false, true) and the document body. The dispatchEvent (event) may trigger a custom event.

Updated: 01:34:41 on September 3, 2021

Reference: JS automatic trigger events && custom events – simple book

Reference: Document. CreateEvent () – Web APIs | MDN

Html-how to create copy-paste event in JavaScript? – Stack Overflow

Update: 13:31:07, September 3, 2021

Programmatically trigger an “input” event without jQuery? – Stack Overflow

Reference: reference | MDN input – Web API interface

Reference: reference | MDN KeyboardEvent – Web API interface

Reference: KeyboardEvent. | MDN key – Web API interface reference

Updated on September 3, 2021 at 18:34:24

Fail to execute ‘dispathEvent’ on ‘EventTarget’ if dispatchEvent() is called directly from addEventListener() : S: The event is already being dispatched.】 I guess The code inside addEventListener() is executed once in The binding event. That means dispatchEvent() has already been called. When the event is triggered, dispatchEvent() will be called again, so there is an error, I use a timer package dispatchEvent() will not report an error, but the logic has changed, the principle of which is not studied at present.

14. Substr () and substring()

Substr () differs from substring() :

  • Str.substr (start [, length]) : returns a substring of the specified length starting at the specified position.

  • Str.substring (start, end) : Returns a substring at the specified position in the String object.

Updated: 02:49:35 On September 2, 2021

Reference: the JavaScript substr() method

Updated on September 2, 2021 at 19:37:06

Reference: js implementation intercepts or finds the string in the substring – icon_sunny – blog garden

Reference: Remove the specified string at the beginning and end of the string _pannijingling’s technical blog _51CTO blog

15,Simulated user input

In the above [Script function Description -5, auto-fill article title], a bug appears.

I thought I could simply set the input value to the level 1 title I got, but I was still too young…

If the user just lets the script auto-populate the title without making any changes to the content in the title input box, the online editor will issue the following warning when the user wants to post:

Image-20210903160537461 – The title cannot be empty


Why does the script warn me that the title cannot be empty when it has already populated the title field?

The console error message indicates that running the following code is an error:

image-20210903161327750


Search for title in the same JS code file and find that the content of the page TAB appears to be controlled by the following code:

image-20210903165622971


So I started looking at what happens when a user manually enters a title:

When the user manually enters the title


When the user tries to change the value of the input via a script, neither of the above changes — that is, the nuggets editor does not detect changes in the value of the input box. So I manually added an input event listener to the input field:

let titleInput = document.querySelector('#juejin-web-editor > div.edit-draft > div > header > input');
titleInput.addEventListener('input'.function () {
  console.log('The value is now ' + titleInput.value);
});
Copy the code

Thus, every time the user modifies the input value, the input event is triggered and the value of the current input box is printed on the console. When I manually entered the text in the article title input box, the console did output the relevant information as expected. But when I change the value in JavaScript code on the console, there is no output:

titleInput.value = 'change';
Copy the code
image-20210903164002363


It seemed that the user had to manually enter the title for this to work, so I started exploring how to simulate the events that the user had entered.

Updated: September 3, 2021 at 16:50:36

Reference: reference | MDN input – Web API interface

Programmatically trigger an “input” event without jQuery? – Stack Overflow

Reference: events: change, input, cut, copy, paste

Reference: Simulated user input _Areom personal blog -CSDN blog

Reference: How to use events to simulate complete user input _ MOOCs ape ask

[front-end] JS code simulation user keyboard and mouse input – Zhao Kang – blog park

Reference: JavaScript_js analog keyboard input – GisClub – Blog park

Reference: the oninput event | novice tutorial

I haven’t tried all of them, but somehow I don’t think they’ll work. I noticed that the Nuggets online editor sends a POST update request to the server every time a user enters something. I guess that’s why the Nuggets editor can save drafts in real time.

The general information of the request it sends is:

// General
Request URL: https://api.juejin.cn/content_api/v1/article_draft/update
Request Method: POST
Status Code: 200 
Remote Address: 124.225193.233.:443
Referrer Policy: no-referrer-when-downgrade
Copy the code

The format of the data it sends is:

// Request Payload
{
  "id":"7003406308921573389"."category_id":"6809637767543259144"."tag_ids": ["6809640507191328782"]."link_url":""."cover_image":""."is_gfw":0."title":"Test Title 2"."brief_content":"Test edit summary test...... Edit Digest Test edit digest test"."is_english":0."is_original":1."edit_type":10."html_content":"deprecated"."mark_content":""
}
Copy the code

Where “ID “:”7003406308921573389” is the unique identifier of the current draft, which is also the last paragraph in the current website:

https://juejin.cn/editor/drafts/7003406308921573389
Copy the code

What I’m interested in right now is the “title”:” Test title 2″ information, as you can see, this is the title OF the article I want. So I came up with a bold idea: could a script actively send a POST request to the server, and then carry the information we want to send to the server in the request body? I even went so far as to introduce Axios into the script to manually send POST requests, but it still didn’t work out the way I wanted. Error: must bind phone

{
  data: null
  err_msg: "must bind phone"
  err_no: 403
}
Copy the code

Here, I have no enthusiasm to explore further. It feels like it’s not worth the effort for such a small feature. So I came up with a compromise: Titleinput.value = XXX after each processing of the local document content, but always with a space after the title and titleinput.focus () to make the titleInput box focus, and then the user clicks the prompt. Delete the trailing space of the title, and then press Ctrl + V to paste content 】 in the editing area after the popover, you can directly press the Backspace key to delete the added space, many times the purpose of one action is to trigger the gold digging editor to automatically send update information to the server, and it is a curve saving the country of the crooked way…… No way, at present only this strength πŸ˜‚……

JS to achieve the use of POST to send requests – far hong – blog garden

How does TamperMonkey refer to Jquery+CSDN

Unexpectedly, this little feature kept me up until 2 or 3 in the morning. There seems to be a lot of room for improvement…

16. Whether the shear plate has capacity limitation

Towards the end, a question occurred to me: Does the clipboard have a capacity limit, and will I have a problem if I put a very long document on the clipboard? Baidu search didn’t seem to find the explanation I was looking for. I found a discussion about it on Google.

The Windows clipboard does not impose any other size limits. Unless you have a surprisingly small amount of virtual memory available (or you where trying to copy and paste the human genome), then it’s the fault of the programmers of the application.

To sum it up: Don’t worry about it… 😳

Updated on September 3, 2021 at 19:29:10

What is the Max amount of characters you can copy at once, and why is there a limit? : askscience

Windows-clipboard size limit-Stack Overflow

What is the maximum amount of text characters you can copy on a computer at once, and why is there a limit? – Quora

The reference

Regular expression

Updated: August 29, 2021 at 21:37:33

Reference: Regular expression: does not contain certain words (super difficult regex, oh, oh)_ Xing Xiaoning -CSDN blog

Updated: September 1, 2021 at 22:39:47

Reference: the RegExp (regular expression) – JavaScript | MDN

Reference: the regular expression online test tools | rookies

Updated: September 1, 2021 at 21:09:41

In regular expressions, how to add the original character and specific content after any matching character

Updated on September 2, 2021 at 19:16:31

Reference: VSCode find and replace regular expression escape character sorting – king – blog garden

Reference: Regular expressions match all kinds of special characters _ regular expressions _ Home of scripts

“Window. The Selection”

For details, please refer to the relevant content above: 2-3 (Press Ctrl to jump).

【JS read local files 】

For details, please refer to the relevant content above: 2-4 (Press Ctrl to jump).

Customize the style of the input tag

For details, please refer to the relevant content above: 2-5 (Press Ctrl to jump).

Insert or create SVG

For details, please refer to the relevant content above: 2-7 (Press Ctrl to jump).

【 ARIA-xxxx attribute 】

For details, please refer to the relevant content above: 2-9 (Press Ctrl to jump).

【JavaScript clipboard operation 】

For details, please refer to the relevant content above: 2-12 (Press Ctrl to jump).

【 Trigger custom events 】

For more information, see the related content above: 2-13 (Press Ctrl and click to jump).

[Simulated user operation]

For details, please refer to the relevant content above: 2-15 (Press Ctrl to jump).

[other]

Updated on August 29, 2021 at 21:52:19

Reference: String. The prototype. The replace () – JavaScript | MDN

Updated: 01:55:21 On August 30, 2021

Insert _DOM operation in front of the DOM to fill the pit (a) _ zhens blog -CSDN blog

Always-Learning-CSDN blog _ Get the first child of an element