From 5094fac68a7062d9958d45fb86ee28836eb37930 Mon Sep 17 00:00:00 2001 From: jaywcjlove <398188662@qq.com> Date: Thu, 29 Sep 2022 22:46:01 +0800 Subject: [PATCH] feat: add `http-status-code.md` cheatsheet. --- README.md | 1 + docs/http-status-code.md | 131 ++++++++++++++++++++++++ docs/javascript.md | 1 + docs/quickreference.md | 23 +++++ scripts/create.mjs | 44 ++------ scripts/style.css | 46 ++++++++- scripts/utils/childs.mjs | 18 ++++ scripts/utils/panelAddNumber.mjs | 18 ++++ scripts/{nodes => utils}/rehypeUrls.mjs | 0 scripts/utils/tooltips.mjs | 64 ++++++++++++ 10 files changed, 304 insertions(+), 42 deletions(-) create mode 100644 docs/http-status-code.md create mode 100644 scripts/utils/childs.mjs create mode 100644 scripts/utils/panelAddNumber.mjs rename scripts/{nodes => utils}/rehypeUrls.mjs (100%) create mode 100644 scripts/utils/tooltips.mjs diff --git a/README.md b/README.md index 27b3089..c19b765 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Quick Reference ## 其它 [Quick Reference](./docs/quickreference.md) +[HTTP 状态码](./docs/http-status-code.md) [HTML 字符实体](./docs/html-char.md) [Emoji](./docs/emoji.md) diff --git a/docs/http-status-code.md b/docs/http-status-code.md new file mode 100644 index 0000000..6eef3c2 --- /dev/null +++ b/docs/http-status-code.md @@ -0,0 +1,131 @@ +HTTP 状态码备忘清单 +=== + +HTTP 状态码备忘清单。 每个 HTTP 状态代码的快速参考。 + +HTTP 状态码 +--- + +### Means + +- [1xx: Informational](#1xx-information) _这意味着已收到请求并且该过程正在继续。_ +- [2xx: Success](#2xx-successful) _这意味着该操作已成功接收、理解和接受。_ +- [3xx: Redirection](#3xx-redirection) _这意味着必须采取进一步行动才能完成请求。_ +- [4xx: Client Error](#4xx-client-error) _这意味着请求包含不正确的语法或无法完成。_ +- [5xx: Server Error](#5xx-server-error) _这意味着服务器未能满足明显有效的请求。_ + +### 2xx. 成功的 + + +* [200: OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) _请求没问题。_ +* [201: Created](https://tools.ietf.org/html/rfc7231#section-6.3.2) _请求完成,并创建了一个新资源。_ +* [202: Accepted](https://tools.ietf.org/html/rfc7231#section-6.3.3) _接受请求进行处理,但处理未完成。_ +* [203: Non-Authoritative Information](https://tools.ietf.org/html/rfc7231#section-6.3.4) _实体标头中的信息来自本地或第三方副本,而不是来自原始服务器。_ +* [204: No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) _响应中给出了状态码和标头,但响应中没有实体主体。_ +* [205: Reset Content](https://tools.ietf.org/html/rfc7231#section-6.3.6) _浏览器应清除用于此事务的表单以获取其他输入。_ +* [206: Partial Content](https://tools.ietf.org/html/rfc7233#section-4.1) _服务器正在返回请求大小的部分数据。 用于响应指定 Range 标头的请求。 服务器必须使用 Content-Range 标头指定响应中包含的范围。_ + +### 4xx. 客户端错误 + + +* [400: Bad Request](https://tools.ietf.org/html/rfc7231#section-6.5.1) _服务器不理解该请求。_ +* [401: Unauthorized](https://tools.ietf.org/html/rfc7235#section-3.1) _请求的页面需要用户名和密码。_ +* [402: Payment Required](https://tools.ietf.org/html/rfc7231#section-6.5.2) _您还不能使用此代码。_ +* [403: Forbidden](https://tools.ietf.org/html/rfc7231#section-6.5.3) _禁止访问请求的页面。_ +* [404: Not Found](https://tools.ietf.org/html/rfc7231#section-6.5.4) _服务器找不到请求的页面。_ +* [405: Method Not Allowed](https://tools.ietf.org/html/rfc7231#section-6.5.5) _请求中指定的方法是不允许的。_ +* [406: Not Acceptable](https://tools.ietf.org/html/rfc7231#section-6.5.6) _服务器只能生成客户端不接受的响应。_ +* [407: Proxy Authentication Required](https://tools.ietf.org/html/rfc7235#section-3.2) _您必须先通过代理服务器进行身份验证,然后才能提供此请求。_ +* [408: Request Timeout](https://tools.ietf.org/html/rfc7231#section-6.5.7) _请求花费的时间比服务器准备等待的时间长。_ +* [409: Conflict](https://tools.ietf.org/html/rfc7231#section-6.5.8) _由于冲突,请求无法完成。_ +* [410: Gone](https://tools.ietf.org/html/rfc7231#section-6.5.9) _请求的页面不再可用。_ +* [411: Length Required](https://tools.ietf.org/html/rfc7231#section-6.5.10) _“Content-Length”未定义。 没有它,服务器将不会接受请求。_ +* [412: Precondition Failed](https://tools.ietf.org/html/rfc7232#section-4.2) _请求中给出的前提条件被服务器评估为 false。_ +* [413: Payload Too Large](https://tools.ietf.org/html/rfc7231#section-6.5.11) _服务器不会接受请求,因为请求实体太大。_ +* [414: URI Too Long](https://tools.ietf.org/html/rfc7231#section-6.5.12) _服务器不会接受请求,因为 url 太长。 当您将“发布”请求转换为具有长查询信息的“获取”请求时发生。_ +* [415: Unsupported Media Type](https://tools.ietf.org/html/rfc7231#section-6.5.13) _服务器不会接受请求,因为不支持媒体类型。_ +* [416: Range Not Satisfiable](https://tools.ietf.org/html/rfc7233#section-4.4) _请求的字节范围不可用且超出范围。_ +* [417: Expectation Failed](https://tools.ietf.org/html/rfc7231#section-6.5.14) _此服务器无法满足在 Expect 请求标头字段中给出的期望。_ +* [426: Upgrade Required](https://tools.ietf.org/html/rfc7231#section-6.5.15) _服务器拒绝使用当前协议执行请求,但在客户端升级到不同协议后可能愿意这样做。_ +* [451: Unavailable For Legal Reasons](https://datatracker.ietf.org/doc/html/rfc7725#section-3) _此状态代码表示服务器拒绝访问资源作为法律要求的结果。_ + +### 1xx. 信息 + +* [100: Continue](https://tools.ietf.org/html/rfc7231#section-6.2.1) _服务器只收到了请求的一部分,但只要没有被拒绝,客户端就应该继续请求。_ +* [101: Switching Protocols](https://tools.ietf.org/html/rfc7231#section-6.2.2) _服务器切换协议。_ +* [102: Processing](https://tools.ietf.org/html/rfc2518#section-10.1) _用于通知客户端服务器已接受完整请求但尚未完成的临时响应。_ + +### 3xx. 重定向 + +* [300: Multiple Choices](https://tools.ietf.org/html/rfc7231#section-6.4.1) _一个链接列表。 用户可以选择一个链接并转到该位置。 最多五个地址。_ +* [301: Moved Permanently](https://tools.ietf.org/html/rfc7231#section-6.4.2) _请求的页面已移至新的 url 。_ +* [302: Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) _请求的页面已临时移动到新的 url 。_ +* [303: See Other](https://tools.ietf.org/html/rfc7231#section-6.4.4) _请求的页面可以在不同的 url 下找到。_ +* [304: Not Modified](https://tools.ietf.org/html/rfc7232#section-4.1) _这是对 If-Modified-Since 或 If-None-Match 标头的响应代码,其中 URL 自指定日期以来未修改。_ +* [305: Use Proxy](https://tools.ietf.org/html/rfc7231#section-6.4.5) _请求的 URL 必须通过 Location 标头中提到的代理访问。_ +* [306: Unused](https://tools.ietf.org/html/rfc7231#section-6.4.6) _此代码在以前的版本中使用过。 它不再使用,但代码被保留。_ +* [307: Temporary Redirect](https://tools.ietf.org/html/rfc7231#section-6.4.7) _请求的页面已临时移动到新的 url。_ + +### 5xx. 服务器错误 + +* [500: Internal Server Error](https://tools.ietf.org/html/rfc7231#section-6.6.1) _请求未完成。 服务器遇到了意外情况_ +* [501: Not Implemented](https://tools.ietf.org/html/rfc7231#section-6.6.2) _请求未完成。 服务器不支持所需的功能_ +* [502: Bad Gateway](https://tools.ietf.org/html/rfc7231#section-6.6.3) _请求未完成。 服务器收到来自上游服务器的无效响应_ +* [503: Service Unavailable](https://tools.ietf.org/html/rfc7231#section-6.6.4) _请求未完成。 服务器暂时超载或停机_ +* [504: Gateway Timeout](https://tools.ietf.org/html/rfc7231#section-6.6.5) _网关已超时_ +* [505: HTTP Version Not Supported](https://tools.ietf.org/html/rfc7231#section-6.6.6) _服务器不支持“http 协议”版本_ + +### RESTful API + + :- | - +---- | ---- +`200` | 返回成功,GET,DELETE 请求成功。 +`204` | 无内容,POST 请求成功。 +`301` | 永久重定向。 +`302/307` | 临时重定向。 +`304` | 未修改,自上次请求以来。 +`331` | 用户名正确,需要密码。 +`332` | 需要登录帐户。 +`400` | 错误请求,缺少 API 请求的必需属性。 +`401` | 未授权,无效凭据进行身份验证将。 +`403` | 禁地,该请求不被允许。 +`404` | 未找到,无法访问资源 +`405` | 方法不允许,不支持该请求。 +`409` | 冲突,冲突资源已存在。 +`412` | 该请求被拒绝。 +`422` | 无法处理,无法处理该实体。 +`429` | 请求过多,用户超出了应用速率限制。 +`500` | 服务器错误,在处理请求时,服务器出现问题。 +`530` | 未登录。 + +### 5xx 永久性否定 + + + :- | - +---- | ---- +`500` | 语法错误,命令无法识别。这可能包括诸如命令行太长之类的错误。 +`501` | 在参数中有语法错误。 +`502` | 未执行命令。 +`503` | 错误的命令序列。 +`504` | 未执行该参数的命令。 +`530` | 未登录。 +`532` | 存储文件需要帐户。 +`550` | 未执行请求的操作。文件不可用(例如,未找到文件,没有访问权限)。 +`551` | 请求的操作异常终止:未知的页面类型。 +`552` | 请求的文件操作异常终止:超出存储分配(对于当前目录或数据集)。 +`553` | 未执行请求的操作。不允许的文件名。 + +永久性否定的完成答复,该命令不成功,错误是永久性的。如果客户端重试命令,将再次出现同样的错误。 + +另见 +---- + +- [常见 HTTP/FTP/WebSocket 错误代码大全](https://jaywcjlove.github.io/handbook/other/HTTP-status-codes.html) _(github.io)_ +- [HTTP 状态码列表](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) _(wikipedia.org)_ +- [FTP 状态码列表](https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes) _(wikipedia.org)_ +- [MDN CloseEvent](https://developer.mozilla.org/zh-CN/docs/Web/API/CloseEvent) _(mozilla.org)_ +- [HTTP 404](https://en.wikipedia.org/wiki/HTTP_404#Custom_error_pages) _(wikipedia.org)_ +- [List of FTP server return codes](https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes) _(wikipedia.org)_ +- [HTTP概述](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview) _(mozilla.org)_ +- [Help for HTTP error 403: “Forbidden”](http://www.getnetgoing.com/HTTP-403.html) _(getnetgoing.com)_ +- [实用的 RESTful API 最佳实践](https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api) _(vinaysahni.com)_ \ No newline at end of file diff --git a/docs/javascript.md b/docs/javascript.md index 4b79676..a2f867f 100644 --- a/docs/javascript.md +++ b/docs/javascript.md @@ -623,6 +623,7 @@ console.log(myArray[1]); // 200 | `pop` | | ✅ | | ✅ | | `unshift` | ✅ | | ✅ | | | `shift` | | ✅ | ✅ | | + ### 方法 .push() diff --git a/docs/quickreference.md b/docs/quickreference.md index fbf89cb..70bf2c8 100644 --- a/docs/quickreference.md +++ b/docs/quickreference.md @@ -123,6 +123,29 @@ function () {} 注释配置添加 `show-header` 类,放置在表格下面,表头将被展示出来。 +### Tooltips + +[鼠标移动到上面有提示](https://github.com/jaywcjlove/reference) _Tooltips 的提示内容_ + +添加注释配置 `` 添加一个 tooltips 提示。 + +### H3 部分(卡片)背景颜色 + + +```markdown +### H3 部分(卡片)背景颜色 + +``` + + +### 红色标题 + + +```markdown +### 红色标题 + +``` + 布局 --- diff --git a/scripts/create.mjs b/scripts/create.mjs index f8104b0..507de8b 100644 --- a/scripts/create.mjs +++ b/scripts/create.mjs @@ -1,45 +1,14 @@ import markdown from '@wcj/markdown-to-html'; import rehypeDocument from 'rehype-document'; import rehypeFormat from 'rehype-format'; -import { rehypeUrls } from './nodes/rehypeUrls.mjs'; +import remarkGemoji from 'remark-gemoji' import { htmlTagAddAttri } from './nodes/htmlTagAddAttri.mjs'; import { footer } from './nodes/footer.mjs'; import { header } from './nodes/header.mjs'; - -/** 标记 Number */ -function panelAddNumber(arr = [], result = []) { - let n = 0; - let level = -1; - while (n < arr.length) { - const toc = arr[n]; - const titleNum = Number(toc?.tagName?.replace(/^h/, '')); - if (titleNum && titleNum > -1) { - level = titleNum; - } - if (toc) { - result.push({ ...toc, number: level }) - } - n++; - } - return result -} - -function getChilds(data = [], level, result = []) { - for (let i = 1; i <= data.length; i++) { - const titleNum = Number(data[i]?.tagName?.replace(/^h/, '')); - if (titleNum && titleNum === level) break; - result.push(data[i]); - } - return result; -} -/** 获取 Heading 到下一个 Heading 之间的内容*/ -function getHeader(data = [], level, result = []) { - for (let i = 1; i <= data.length; i++) { - if (/^h\d$/.test(data[i]?.tagName) || data[i]?.number !== level) break; - result.push(data[i]); - } - return result; -} +import { rehypeUrls } from './utils/rehypeUrls.mjs'; +import { tooltips } from './utils/tooltips.mjs'; +import { panelAddNumber } from './utils/panelAddNumber.mjs'; +import { getChilds, getHeader } from './utils/childs.mjs'; /** Markdown 文档转成树形结构 */ export function getTocsTree(arr = [], result = []) { @@ -120,7 +89,7 @@ export function create(str = '', options = {}) { const subTitle = options.filename && !options.isHome ? `${options.filename} cheatsheet & `: '' const mdOptions = { hastNode: false, - remarkPlugins: [], + remarkPlugins: [remarkGemoji], rehypePlugins: [ rehypeFormat, [rehypeDocument, { @@ -133,6 +102,7 @@ export function create(str = '', options = {}) { }], ], rewrite: (node, index, parent) => { + tooltips(node, index, parent); htmlTagAddAttri(node, options); rehypeUrls(node); if (node.type === 'element' && node.tagName === 'body') { diff --git a/scripts/style.css b/scripts/style.css index 0876098..d7d41ba 100644 --- a/scripts/style.css +++ b/scripts/style.css @@ -62,10 +62,6 @@ table tr+tr { border-top: solid 1px #ececec94; border-color: rgb(51 65 85/0.5); } - -table td:first-child { - white-space: nowrap; -} table td, table th { padding: 9px 14px; text-align: left; @@ -322,6 +318,7 @@ a.text-grey { right: 0px; top: 0px; z-index: 10; + border-top-right-radius: 0.5rem; border-bottom-left-radius: 0.5rem; background-color: #228e6c; padding-left: 0.75rem; @@ -447,7 +444,6 @@ a.text-grey { position: relative; display: flex; flex-direction: column; - overflow: hidden; border-radius: 0.5rem; padding-top: 1.5rem; margin-bottom: 1rem; @@ -495,6 +491,46 @@ a.text-grey { .wrap-text { white-space: pre-wrap !important; overflow-wrap: break-word !important; + word-break: break-all; +} + +.tooltip { + position: relative; + display: inline-block; +} +.tooltip .tooltiptext { + display: none; + font-style: inherit; + position: absolute; + background-color: rgb(67 67 67 / 66%); + color: #fff; + padding: 0.5rem; + font-size: 12px; + opacity: 0; + border-radius: 0.5rem; + z-index: 1; + transition: opacity .6s; + line-height: 1.5; + + width: 220px; + bottom: 125%; + left: 50%; + margin-left: -110px; +} +.tooltip .tooltiptext::after { + content: ""; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: rgb(67 67 67 / 66%) transparent transparent transparent; +} +.tooltip:hover .tooltiptext { + visibility: visible; + display: inline-block; + opacity: 1; } [data-color-mode*='light'], [data-color-mode*='light'] body { diff --git a/scripts/utils/childs.mjs b/scripts/utils/childs.mjs new file mode 100644 index 0000000..f79f833 --- /dev/null +++ b/scripts/utils/childs.mjs @@ -0,0 +1,18 @@ + +export function getChilds(data = [], level, result = []) { + for (let i = 1; i <= data.length; i++) { + const titleNum = Number(data[i]?.tagName?.replace(/^h/, '')); + if (titleNum && titleNum === level) break; + result.push(data[i]); + } + return result; +} + +/** 获取 Heading 到下一个 Heading 之间的内容*/ +export function getHeader(data = [], level, result = []) { + for (let i = 1; i <= data.length; i++) { + if (/^h\d$/.test(data[i]?.tagName) || data[i]?.number !== level) break; + result.push(data[i]); + } + return result; +} diff --git a/scripts/utils/panelAddNumber.mjs b/scripts/utils/panelAddNumber.mjs new file mode 100644 index 0000000..7a781d2 --- /dev/null +++ b/scripts/utils/panelAddNumber.mjs @@ -0,0 +1,18 @@ + +/** 标记 Number */ +export function panelAddNumber(arr = [], result = []) { + let n = 0; + let level = -1; + while (n < arr.length) { + const toc = arr[n]; + const titleNum = Number(toc?.tagName?.replace(/^h/, '')); + if (titleNum && titleNum > -1) { + level = titleNum; + } + if (toc) { + result.push({ ...toc, number: level }) + } + n++; + } + return result +} \ No newline at end of file diff --git a/scripts/nodes/rehypeUrls.mjs b/scripts/utils/rehypeUrls.mjs similarity index 100% rename from scripts/nodes/rehypeUrls.mjs rename to scripts/utils/rehypeUrls.mjs diff --git a/scripts/utils/tooltips.mjs b/scripts/utils/tooltips.mjs new file mode 100644 index 0000000..ba832d6 --- /dev/null +++ b/scripts/utils/tooltips.mjs @@ -0,0 +1,64 @@ +/** + * 配置 tooltips 注释 + * + * ```markdown + * - [超链接有 tooltips 提示](#1xx-information) _Tooltips 展示内容_ + * ``` + * + * 上面示例:将 “Tooltips 展示内容” 放到 前一个 `` dom 节点作为子节点 + * + * - 注释配置的,前一个节点 A,A 的前一个节点 B + * - 如果 A 和 B 其中一个不存在 `tooltips` 将失效 + * - 设置 B 的类名称为 tooltips + */ +export function tooltips(node, index, parent) { + if (node.type === 'comment' && parent?.children.length > 2) { + const childs = parent?.children; + const result = []; + let recordPos = false; // 记录位置 + let tooltipNode = null; + for(let i = childs.length; i > -1; i--) { + const node = childs[i]; + // 记录 tooltip 的开始位置 + if (node?.type === 'comment' && node?.value === 'rehype:tooltips') { + recordPos = true; + continue + } + // 记录 tooltip 的 node + if (recordPos && !tooltipNode) { + if (node.type === 'comment' || (node.type === 'text' && !node?.value?.replace(/\s\n/g, ''))) { + recordPos = false; + } + if (recordPos && node.type === 'element') { + tooltipNode = node; + tooltipNode.properties['class'] = 'tooltiptext'; + delete tooltipNode.position; + continue + } + } + // 将 tooltip 节点,插入到下一个 element 节点的子节点中 + if (tooltipNode) { + if (node.type === 'comment' || (node.type === 'text' && !node?.value?.replace(/\s\n/g, ''))) { + recordPos = false; + tooltipNode = null + } + if (tooltipNode && node?.type === 'element') { + recordPos = false; + node.properties['class'] = 'tooltip'; + node.children.push(tooltipNode); + tooltipNode = null + } + } + if (!recordPos && node) { + result.push(node) + } + } + if (parent) { + parent.children = [...result.reverse()]; + } + } +} + +export function getPreviewNode() { + +} \ No newline at end of file