@cherry-markdown/cherry-markdown-dev 0.9.0-dev.202504110650.834443a → 0.9.0-dev.202504160300.d23d141
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/addons/advance/cherry-table-echarts-plugin.js +1 -1
- package/dist/addons/cherry-code-block-mermaid-plugin.js +1 -1
- package/dist/cherry-markdown.core.common.js +1 -1
- package/dist/cherry-markdown.core.js +1 -1
- package/dist/cherry-markdown.engine.core.common.js +1 -1
- package/dist/cherry-markdown.engine.core.esm.js +1 -1
- package/dist/cherry-markdown.engine.core.js +1 -1
- package/dist/cherry-markdown.esm.js +1 -1
- package/dist/cherry-markdown.js +1 -1
- package/dist/cherry-markdown.min.js +1 -1
- package/dist/fonts/ch-icon.eot +0 -0
- package/dist/fonts/ch-icon.ttf +0 -0
- package/dist/fonts/ch-icon.woff +0 -0
- package/dist/fonts/ch-icon.woff2 +0 -0
- package/package.json +1 -3
- package/src/Cherry.config.js +0 -634
- package/src/Cherry.js +0 -1104
- package/src/CherryStatic.js +0 -70
- package/src/Editor.js +0 -748
- package/src/Engine.js +0 -402
- package/src/Event.js +0 -140
- package/src/Factory.js +0 -180
- package/src/Logger.js +0 -31
- package/src/Previewer.js +0 -1192
- package/src/Sanitizer.js +0 -4
- package/src/Sanitizer.node.js +0 -7
- package/src/UrlCache.js +0 -98
- package/src/addons/advance/cherry-table-echarts-plugin.js +0 -170
- package/src/addons/cherry-code-block-mermaid-plugin.js +0 -158
- package/src/addons/cherry-code-block-plantuml-plugin.js +0 -106
- package/src/core/HookCenter.js +0 -297
- package/src/core/HooksConfig.js +0 -105
- package/src/core/ParagraphBase.js +0 -332
- package/src/core/SentenceBase.js +0 -65
- package/src/core/SyntaxBase.js +0 -194
- package/src/core/hooks/AutoLink.js +0 -232
- package/src/core/hooks/BackgroundColor.js +0 -46
- package/src/core/hooks/Blockquote.js +0 -70
- package/src/core/hooks/Br.js +0 -85
- package/src/core/hooks/CodeBlock.js +0 -456
- package/src/core/hooks/Color.js +0 -46
- package/src/core/hooks/CommentReference.js +0 -96
- package/src/core/hooks/Detail.js +0 -108
- package/src/core/hooks/Emoji.config.js +0 -1825
- package/src/core/hooks/Emoji.js +0 -119
- package/src/core/hooks/Emphasis.js +0 -113
- package/src/core/hooks/Footnote.js +0 -125
- package/src/core/hooks/FrontMatter.js +0 -51
- package/src/core/hooks/Header.js +0 -234
- package/src/core/hooks/HighLight.js +0 -37
- package/src/core/hooks/Hr.js +0 -52
- package/src/core/hooks/HtmlBlock.js +0 -199
- package/src/core/hooks/Image.js +0 -174
- package/src/core/hooks/InlineCode.js +0 -48
- package/src/core/hooks/InlineMath.js +0 -108
- package/src/core/hooks/Link.js +0 -160
- package/src/core/hooks/List.js +0 -264
- package/src/core/hooks/MathBlock.js +0 -104
- package/src/core/hooks/Panel.js +0 -145
- package/src/core/hooks/Paragraph.js +0 -84
- package/src/core/hooks/Ruby.js +0 -34
- package/src/core/hooks/Size.js +0 -51
- package/src/core/hooks/Strikethrough.js +0 -54
- package/src/core/hooks/Sub.js +0 -47
- package/src/core/hooks/SuggestList.js +0 -333
- package/src/core/hooks/Suggester.js +0 -707
- package/src/core/hooks/Sup.js +0 -47
- package/src/core/hooks/Table.js +0 -275
- package/src/core/hooks/Toc.js +0 -292
- package/src/core/hooks/Transfer.js +0 -47
- package/src/core/hooks/Underline.js +0 -37
- package/src/index.core.js +0 -29
- package/src/index.engine.core.js +0 -68
- package/src/index.engine.js +0 -28
- package/src/index.js +0 -32
- package/src/libs/mermaidAPI.8.4.8.js +0 -1
- package/src/libs/mermaidAPI.8.5.2.js +0 -42
- package/src/libs/rawdeflate.js +0 -1663
- package/src/locales/en_US.js +0 -139
- package/src/locales/index.js +0 -25
- package/src/locales/ru_RU.js +0 -139
- package/src/locales/zh_CN.js +0 -142
- package/src/sass/base.scss +0 -26
- package/src/sass/bubble_formula.scss +0 -166
- package/src/sass/ch-icon.scss +0 -118
- package/src/sass/cherry.scss +0 -1116
- package/src/sass/components/bubble.scss +0 -173
- package/src/sass/components/shortcut_key_config.scss +0 -108
- package/src/sass/formula_utils_bubble.scss +0 -82
- package/src/sass/icon_template.scss +0 -24
- package/src/sass/icons/uEA03-list.svg +0 -19
- package/src/sass/icons/uEA04-check.svg +0 -14
- package/src/sass/icons/uEA09-square.svg +0 -10
- package/src/sass/icons/uEA0A-bold.svg +0 -20
- package/src/sass/icons/uEA0B-code.svg +0 -18
- package/src/sass/icons/uEA0C-color.svg +0 -13
- package/src/sass/icons/uEA0D-header.svg +0 -8
- package/src/sass/icons/uEA0E-image.svg +0 -15
- package/src/sass/icons/uEA0F-italic.svg +0 -8
- package/src/sass/icons/uEA10-link.svg +0 -16
- package/src/sass/icons/uEA11-ol.svg +0 -21
- package/src/sass/icons/uEA12-size.svg +0 -11
- package/src/sass/icons/uEA13-strike.svg +0 -16
- package/src/sass/icons/uEA14-table.svg +0 -12
- package/src/sass/icons/uEA15-ul.svg +0 -17
- package/src/sass/icons/uEA16-underline.svg +0 -13
- package/src/sass/icons/uEA17-word.svg +0 -16
- package/src/sass/icons/uEA18-blockquote.svg +0 -11
- package/src/sass/icons/uEA19-font.svg +0 -10
- package/src/sass/icons/uEA1F-insertClass.svg +0 -39
- package/src/sass/icons/uEA20-insertFlow.svg +0 -8
- package/src/sass/icons/uEA21-insertFormula.svg +0 -23
- package/src/sass/icons/uEA22-insertGantt.svg +0 -13
- package/src/sass/icons/uEA23-insertGraph.svg +0 -13
- package/src/sass/icons/uEA24-insertPie.svg +0 -19
- package/src/sass/icons/uEA25-insertSeq.svg +0 -20
- package/src/sass/icons/uEA26-insertState.svg +0 -35
- package/src/sass/icons/uEA27-line.svg +0 -11
- package/src/sass/icons/uEA28-preview.svg +0 -18
- package/src/sass/icons/uEA29-previewClose.svg +0 -24
- package/src/sass/icons/uEA2A-toc.svg +0 -24
- package/src/sass/icons/uEA2D-sub.svg +0 -15
- package/src/sass/icons/uEA2E-sup.svg +0 -15
- package/src/sass/icons/uEA2F-h1.svg +0 -16
- package/src/sass/icons/uEA30-h2.svg +0 -20
- package/src/sass/icons/uEA31-h3.svg +0 -23
- package/src/sass/icons/uEA32-h4.svg +0 -16
- package/src/sass/icons/uEA33-h5.svg +0 -20
- package/src/sass/icons/uEA34-h6.svg +0 -17
- package/src/sass/icons/uEA35-video.svg +0 -20
- package/src/sass/icons/uEA36-insert.svg +0 -25
- package/src/sass/icons/uEA37-little_table.svg +0 -30
- package/src/sass/icons/uEA38-pdf.svg +0 -27
- package/src/sass/icons/uEA39-checklist.svg +0 -22
- package/src/sass/icons/uEA40-close.svg +0 -12
- package/src/sass/icons/uEA41-fullscreen.svg +0 -81
- package/src/sass/icons/uEA42-minscreen.svg +0 -77
- package/src/sass/icons/uEA43-insertChart.svg +0 -23
- package/src/sass/icons/uEA44-question.svg +0 -25
- package/src/sass/icons/uEA45-settings.svg +0 -32
- package/src/sass/icons/uEA46-ok.svg +0 -7
- package/src/sass/icons/uEA47-br.svg +0 -22
- package/src/sass/icons/uEA48-normal.svg +0 -15
- package/src/sass/icons/uEA49-undo.svg +0 -19
- package/src/sass/icons/uEA50-redo.svg +0 -21
- package/src/sass/icons/uEA51-copy.svg +0 -6
- package/src/sass/icons/uEA52-phone.svg +0 -5
- package/src/sass/icons/uEA53-cherry-table-delete.svg +0 -17
- package/src/sass/icons/uEA54-cherry-table-insert-bottom.svg +0 -16
- package/src/sass/icons/uEA55-cherry-table-insert-left.svg +0 -15
- package/src/sass/icons/uEA56-cherry-table-insert-right.svg +0 -16
- package/src/sass/icons/uEA57-cherry-table-insert-top.svg +0 -16
- package/src/sass/icons/uEA58-sort-s.svg +0 -13
- package/src/sass/icons/uEA59-pinyin.svg +0 -1
- package/src/sass/icons/uEA5A-create.svg +0 -24
- package/src/sass/icons/uEA5B-download.svg +0 -34
- package/src/sass/icons/uEA5C-edit.svg +0 -3
- package/src/sass/icons/uEA5D-export.svg +0 -53
- package/src/sass/icons/uEA5E-folder-open.svg +0 -3
- package/src/sass/icons/uEA5F-folder.svg +0 -3
- package/src/sass/icons/uEA60-help.svg +0 -5
- package/src/sass/icons/uEA61-pen-fill.svg +0 -13
- package/src/sass/icons/uEA62-pen.svg +0 -3
- package/src/sass/icons/uEA64-tips.svg +0 -5
- package/src/sass/icons/uEA65-warn.svg +0 -5
- package/src/sass/icons/uEA66-mistake.svg +0 -4
- package/src/sass/icons/uEA67-success.svg +0 -4
- package/src/sass/icons/uEA68-danger.svg +0 -4
- package/src/sass/icons/uEA69-info.svg +0 -5
- package/src/sass/icons/uEA6A-primary.svg +0 -5
- package/src/sass/icons/uEA6B-warning.svg +0 -5
- package/src/sass/icons/uEA6C-justify.svg +0 -19
- package/src/sass/icons/uEA6D-justifyCenter.svg +0 -19
- package/src/sass/icons/uEA6E-justifyLeft.svg +0 -19
- package/src/sass/icons/uEA6F-justifyRight.svg +0 -19
- package/src/sass/icons/uEA70-chevronsLeft.svg +0 -1
- package/src/sass/icons/uEA71-chevronsRight.svg +0 -1
- package/src/sass/icons/uEA72-trendingUp.svg +0 -1
- package/src/sass/icons/uEA74-codeBlock.svg +0 -1
- package/src/sass/icons/uEA75-expand.svg +0 -3
- package/src/sass/icons/uEA76-unExpand.svg +0 -3
- package/src/sass/icons/uEA77-swap-vert.svg +0 -1
- package/src/sass/icons/uEA78-swap.svg +0 -1
- package/src/sass/icons/uEA79-keyboard.svg +0 -1
- package/src/sass/icons/uEA7A-command.svg +0 -1
- package/src/sass/icons/uEA7B-search.svg +0 -1
- package/src/sass/index.scss +0 -3
- package/src/sass/markdown.scss +0 -668
- package/src/sass/markdown_pure.scss +0 -9
- package/src/sass/prettyprint/prettyprint.scss +0 -118
- package/src/sass/previewer.scss +0 -179
- package/src/sass/print.scss +0 -13
- package/src/sass/prism/coy.scss +0 -220
- package/src/sass/prism/dark.scss +0 -132
- package/src/sass/prism/default.scss +0 -143
- package/src/sass/prism/funky.scss +0 -133
- package/src/sass/prism/okaidia.scss +0 -126
- package/src/sass/prism/one-dark.scss +0 -440
- package/src/sass/prism/one-light.scss +0 -428
- package/src/sass/prism/solarized-light.scss +0 -153
- package/src/sass/prism/tomorrow-night.scss +0 -125
- package/src/sass/prism/twilight.scss +0 -202
- package/src/sass/prism/vs-dark.scss +0 -275
- package/src/sass/prism/vs-light.scss +0 -168
- package/src/sass/themes/blue.scss +0 -411
- package/src/sass/themes/dark.scss +0 -517
- package/src/sass/themes/default.scss +0 -255
- package/src/sass/themes/green.scss +0 -395
- package/src/sass/themes/light.scss +0 -368
- package/src/sass/themes/red.scss +0 -397
- package/src/sass/themes/violet.scss +0 -410
- package/src/sass/variable.scss +0 -84
- package/src/toolbars/Bubble.js +0 -234
- package/src/toolbars/BubbleFormula.js +0 -298
- package/src/toolbars/BubbleTable.js +0 -147
- package/src/toolbars/FloatMenu.js +0 -131
- package/src/toolbars/HiddenToolbar.js +0 -36
- package/src/toolbars/HookCenter.js +0 -231
- package/src/toolbars/MenuBase.js +0 -569
- package/src/toolbars/PreviewerBubble.js +0 -608
- package/src/toolbars/ShortcutKeyConfigPanel.js +0 -345
- package/src/toolbars/Sidebar.js +0 -36
- package/src/toolbars/Toc.js +0 -242
- package/src/toolbars/Toolbar.js +0 -449
- package/src/toolbars/ToolbarRight.js +0 -37
- package/src/toolbars/hooks/Audio.js +0 -79
- package/src/toolbars/hooks/BarTable.js +0 -41
- package/src/toolbars/hooks/Bold.js +0 -73
- package/src/toolbars/hooks/Br.js +0 -34
- package/src/toolbars/hooks/ChangeLocale.js +0 -62
- package/src/toolbars/hooks/ChatGpt.js +0 -182
- package/src/toolbars/hooks/CheckList.js +0 -41
- package/src/toolbars/hooks/Code.js +0 -49
- package/src/toolbars/hooks/CodeTheme.js +0 -66
- package/src/toolbars/hooks/Color.js +0 -298
- package/src/toolbars/hooks/Copy.js +0 -141
- package/src/toolbars/hooks/Detail.js +0 -69
- package/src/toolbars/hooks/DrawIo.js +0 -57
- package/src/toolbars/hooks/Export.js +0 -49
- package/src/toolbars/hooks/File.js +0 -79
- package/src/toolbars/hooks/Formula.js +0 -69
- package/src/toolbars/hooks/FullScreen.js +0 -50
- package/src/toolbars/hooks/Graph.js +0 -263
- package/src/toolbars/hooks/H1.js +0 -71
- package/src/toolbars/hooks/H2.js +0 -71
- package/src/toolbars/hooks/H3.js +0 -71
- package/src/toolbars/hooks/Header.js +0 -118
- package/src/toolbars/hooks/Hr.js +0 -35
- package/src/toolbars/hooks/Image.js +0 -91
- package/src/toolbars/hooks/InlineCode.js +0 -53
- package/src/toolbars/hooks/Insert.js +0 -193
- package/src/toolbars/hooks/Italic.js +0 -72
- package/src/toolbars/hooks/Justify.js +0 -49
- package/src/toolbars/hooks/LineTable.js +0 -41
- package/src/toolbars/hooks/Link.js +0 -49
- package/src/toolbars/hooks/List.js +0 -55
- package/src/toolbars/hooks/MobilePreview.js +0 -44
- package/src/toolbars/hooks/Ol.js +0 -41
- package/src/toolbars/hooks/Panel.js +0 -140
- package/src/toolbars/hooks/Pdf.js +0 -78
- package/src/toolbars/hooks/Publish.js +0 -123
- package/src/toolbars/hooks/QuickTable.js +0 -43
- package/src/toolbars/hooks/Quote.js +0 -45
- package/src/toolbars/hooks/Redo.js +0 -33
- package/src/toolbars/hooks/Ruby.js +0 -59
- package/src/toolbars/hooks/Search.js +0 -53
- package/src/toolbars/hooks/Settings.js +0 -220
- package/src/toolbars/hooks/ShortcutKey.js +0 -62
- package/src/toolbars/hooks/Size.js +0 -118
- package/src/toolbars/hooks/Split.js +0 -37
- package/src/toolbars/hooks/Strikethrough.js +0 -71
- package/src/toolbars/hooks/Sub.js +0 -58
- package/src/toolbars/hooks/Sup.js +0 -58
- package/src/toolbars/hooks/SwitchModel.js +0 -56
- package/src/toolbars/hooks/Table.js +0 -56
- package/src/toolbars/hooks/Theme.js +0 -62
- package/src/toolbars/hooks/Toc.js +0 -35
- package/src/toolbars/hooks/TogglePreview.js +0 -91
- package/src/toolbars/hooks/Ul.js +0 -41
- package/src/toolbars/hooks/Underline.js +0 -68
- package/src/toolbars/hooks/Undo.js +0 -30
- package/src/toolbars/hooks/Video.js +0 -79
- package/src/toolbars/hooks/Word.js +0 -78
- package/src/toolbars/hooks/WordCount.js +0 -106
- package/src/utils/autoindent.js +0 -58
- package/src/utils/cm-search-replace.js +0 -794
- package/src/utils/code-preview-language-setting.js +0 -180
- package/src/utils/codeBlockContentHandler.js +0 -400
- package/src/utils/config.js +0 -174
- package/src/utils/copy.js +0 -55
- package/src/utils/dialog.js +0 -214
- package/src/utils/dom.js +0 -163
- package/src/utils/downloadUtil.js +0 -23
- package/src/utils/env.js +0 -22
- package/src/utils/error.js +0 -61
- package/src/utils/event.js +0 -38
- package/src/utils/export.js +0 -166
- package/src/utils/file.js +0 -164
- package/src/utils/formulaUtilsHandler.js +0 -232
- package/src/utils/htmlparser.js +0 -976
- package/src/utils/image.js +0 -99
- package/src/utils/imgSizeHandler.js +0 -279
- package/src/utils/lazyLoadImg.js +0 -327
- package/src/utils/lineFeed.js +0 -49
- package/src/utils/listContentHandler.js +0 -227
- package/src/utils/lookbehind-replace.js +0 -81
- package/src/utils/mathjax.js +0 -89
- package/src/utils/myersDiff.js +0 -211
- package/src/utils/pasteHelper.js +0 -253
- package/src/utils/platformTransform.js +0 -71
- package/src/utils/recount-pos.js +0 -59
- package/src/utils/regexp.js +0 -295
- package/src/utils/sanitize.js +0 -477
- package/src/utils/selection.js +0 -50
- package/src/utils/shortcutKey.js +0 -291
- package/src/utils/svgUtils.js +0 -96
- package/src/utils/tableContentHandler.js +0 -876
- package/test/core/CommonMark.spec.ts +0 -62
- package/test/core/hooks/AutoLink.spec.ts +0 -28
- package/test/core/hooks/List.spec.ts +0 -79
- package/test/core/hooks/__snapshots__/List.spec.ts.snap +0 -11
- package/test/example.md +0 -778
- package/test/node.js +0 -10
- package/test/suites/commonmark.spec.json +0 -5218
- package/test/tsconfig.test.json +0 -6
- package/test/utils/regexp.spec.ts +0 -28
package/src/utils/image.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (C) 2021 THL A29 Limited, a Tencent company.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const imgAltHelper = {
|
|
18
|
-
/**
|
|
19
|
-
* 提取alt部分的扩展属性
|
|
20
|
-
* @param {string} alt 图片引用中的alt部分
|
|
21
|
-
* @returns
|
|
22
|
-
*/
|
|
23
|
-
processExtendAttributesInAlt(alt) {
|
|
24
|
-
const attrRegex = /#([0-9]+(px|em|pt|pc|in|mm|cm|ex|%)|auto)/g;
|
|
25
|
-
const info = alt.match(attrRegex);
|
|
26
|
-
if (!info) {
|
|
27
|
-
return '';
|
|
28
|
-
}
|
|
29
|
-
let extendAttrs = '';
|
|
30
|
-
const [width, height] = info;
|
|
31
|
-
if (width) {
|
|
32
|
-
extendAttrs = ` width="${width.replace(/[ #]*/g, '')}"`;
|
|
33
|
-
}
|
|
34
|
-
if (height) {
|
|
35
|
-
extendAttrs += ` height="${height.replace(/[ #]*/g, '')}"`;
|
|
36
|
-
}
|
|
37
|
-
return extendAttrs;
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 提取alt部分的扩展样式
|
|
42
|
-
* @param {string} alt 图片引用中的alt部分
|
|
43
|
-
* @returns {{extendStyles:string, extendClasses:string}}
|
|
44
|
-
*/
|
|
45
|
-
processExtendStyleInAlt(alt) {
|
|
46
|
-
let extendStyles = imgAltHelper.$getAlignment(alt);
|
|
47
|
-
let extendClasses = '';
|
|
48
|
-
const info = alt.match(/#(border|shadow|radius|B|S|R)/g);
|
|
49
|
-
if (info) {
|
|
50
|
-
for (let i = 0; i < info.length; i++) {
|
|
51
|
-
switch (info[i]) {
|
|
52
|
-
case '#border':
|
|
53
|
-
case '#B':
|
|
54
|
-
extendStyles += 'border:1px solid #888888;padding: 2px;box-sizing: border-box;';
|
|
55
|
-
extendClasses += ' cherry-img-border';
|
|
56
|
-
break;
|
|
57
|
-
case '#shadow':
|
|
58
|
-
case '#S':
|
|
59
|
-
extendStyles += 'box-shadow:0 2px 15px -5px rgb(0 0 0 / 50%);';
|
|
60
|
-
extendClasses += ' cherry-img-shadow';
|
|
61
|
-
break;
|
|
62
|
-
case '#radius':
|
|
63
|
-
case '#R':
|
|
64
|
-
extendStyles += 'border-radius: 15px;';
|
|
65
|
-
extendClasses += ' cherry-img-radius';
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return { extendStyles, extendClasses };
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* 从alt中提取对齐方式信息
|
|
75
|
-
* @param {string} alt
|
|
76
|
-
* @returns {string}
|
|
77
|
-
*/
|
|
78
|
-
$getAlignment(alt) {
|
|
79
|
-
const styleRegex = /#(center|right|left|float-right|float-left)/i;
|
|
80
|
-
const info = alt.match(styleRegex);
|
|
81
|
-
if (!info) {
|
|
82
|
-
return '';
|
|
83
|
-
}
|
|
84
|
-
const [, alignment] = info;
|
|
85
|
-
switch (alignment) {
|
|
86
|
-
case 'center':
|
|
87
|
-
return 'transform:translateX(-50%);margin-left:50%;display:block;';
|
|
88
|
-
case 'right':
|
|
89
|
-
return 'transform:translateX(-100%);margin-left:100%;margin-right:-100%;display:block;';
|
|
90
|
-
case 'left':
|
|
91
|
-
return 'transform:translateX(0);margin-left:0;display:block;';
|
|
92
|
-
case 'float-right':
|
|
93
|
-
return 'float:right;transform:translateX(0);margin-left:0;display:block;';
|
|
94
|
-
case 'float-left':
|
|
95
|
-
return 'float:left;transform:translateX(0);margin-left:0;display:block;';
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
export default imgAltHelper;
|
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (C) 2021 THL A29 Limited, a Tencent company.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
|
-
* 用于在图片四周画出调整图片尺寸的边框
|
|
18
|
-
*/
|
|
19
|
-
const imgSizeHandler = {
|
|
20
|
-
mouseResize: {},
|
|
21
|
-
getImgPosition() {
|
|
22
|
-
const position = this.img.getBoundingClientRect();
|
|
23
|
-
const editorPosition = this.previewerDom.parentNode.getBoundingClientRect();
|
|
24
|
-
const padding = parseFloat(this.img.style.padding) || 0;
|
|
25
|
-
return {
|
|
26
|
-
bottom: position.bottom - editorPosition.bottom,
|
|
27
|
-
top: position.top - editorPosition.top + padding * 1.5,
|
|
28
|
-
height: position.height,
|
|
29
|
-
width: position.width,
|
|
30
|
-
right: position.right - editorPosition.right,
|
|
31
|
-
left: position.left - editorPosition.left + padding * 1.5,
|
|
32
|
-
x: position.x - editorPosition.x,
|
|
33
|
-
y: position.y - editorPosition.y,
|
|
34
|
-
};
|
|
35
|
-
},
|
|
36
|
-
initBubbleButtons() {
|
|
37
|
-
const position = this.getImgPosition();
|
|
38
|
-
return {
|
|
39
|
-
points: {
|
|
40
|
-
arr: [
|
|
41
|
-
'leftTop',
|
|
42
|
-
'leftBottom',
|
|
43
|
-
'rightTop',
|
|
44
|
-
'rightBottom',
|
|
45
|
-
'leftMiddle',
|
|
46
|
-
'middleBottom',
|
|
47
|
-
'middleTop',
|
|
48
|
-
'rightMiddle',
|
|
49
|
-
],
|
|
50
|
-
arrInfo: {
|
|
51
|
-
leftTop: { name: '20', left: 0, top: 0 },
|
|
52
|
-
leftBottom: { name: '00', left: 0, top: 0 },
|
|
53
|
-
rightTop: { name: '22', left: 0, top: 0 },
|
|
54
|
-
rightBottom: { name: '02', left: 0, top: 0 },
|
|
55
|
-
leftMiddle: { name: '10', left: 0, top: 0 },
|
|
56
|
-
middleBottom: { name: '01', left: 0, top: 0 },
|
|
57
|
-
middleTop: { name: '21', left: 0, top: 0 },
|
|
58
|
-
rightMiddle: { name: '12', left: 0, top: 0 },
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
imgSrc: this.img.src,
|
|
62
|
-
style: {
|
|
63
|
-
width: this.img.width,
|
|
64
|
-
height: this.img.height,
|
|
65
|
-
left: position.left - 1,
|
|
66
|
-
top: position.top - 1,
|
|
67
|
-
marginTop: 0,
|
|
68
|
-
marginLeft: 0,
|
|
69
|
-
},
|
|
70
|
-
scrollTop: this.previewerDom.scrollTop,
|
|
71
|
-
position,
|
|
72
|
-
};
|
|
73
|
-
},
|
|
74
|
-
showBubble(img, container, previewerDom) {
|
|
75
|
-
if (this.$isResizing()) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
this.img = img;
|
|
79
|
-
this.previewerDom = previewerDom;
|
|
80
|
-
this.container = container;
|
|
81
|
-
this.buts = this.initBubbleButtons();
|
|
82
|
-
this.drawBubbleButs();
|
|
83
|
-
},
|
|
84
|
-
emit(type, event = {}) {
|
|
85
|
-
switch (type) {
|
|
86
|
-
case 'mousedown':
|
|
87
|
-
return this.resizeBegin(event);
|
|
88
|
-
case 'mouseup':
|
|
89
|
-
return this.resizeStop(event);
|
|
90
|
-
case 'mousemove':
|
|
91
|
-
return this.resizeWorking(event);
|
|
92
|
-
case 'scroll':
|
|
93
|
-
return this.dealScroll(event);
|
|
94
|
-
case 'remove':
|
|
95
|
-
return this.remove();
|
|
96
|
-
case 'previewUpdate':
|
|
97
|
-
return this.previewUpdate(event);
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
previewUpdate(callback) {
|
|
101
|
-
if (this.$isResizing()) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
this.remove();
|
|
105
|
-
callback();
|
|
106
|
-
},
|
|
107
|
-
drawBubbleButs() {
|
|
108
|
-
if (this.butsLayout) {
|
|
109
|
-
return this.updateBubbleButs();
|
|
110
|
-
}
|
|
111
|
-
this.butsLayout = this.container;
|
|
112
|
-
this.butsImg = document.createElement('div');
|
|
113
|
-
this.butsImg.className = 'cherry-previewer-img-size-handler__background';
|
|
114
|
-
this.butsImg.style.backgroundImage = `url(${this.buts.imgSrc})`;
|
|
115
|
-
this.butsLayout.appendChild(this.butsImg);
|
|
116
|
-
|
|
117
|
-
this.butsPoints = {};
|
|
118
|
-
Object.keys(this.buts.points.arr).forEach((index) => {
|
|
119
|
-
const name = this.buts.points.arr[index];
|
|
120
|
-
const tmp = document.createElement('div');
|
|
121
|
-
tmp.className = [
|
|
122
|
-
'cherry-previewer-img-size-handler__points',
|
|
123
|
-
`cherry-previewer-img-size-handler__points-${name}`,
|
|
124
|
-
].join(' ');
|
|
125
|
-
tmp.dataset.name = name;
|
|
126
|
-
this.butsLayout.appendChild(tmp);
|
|
127
|
-
this.butsPoints[`pints-${name}`] = tmp;
|
|
128
|
-
});
|
|
129
|
-
return this.updateBubbleButs();
|
|
130
|
-
},
|
|
131
|
-
remove() {
|
|
132
|
-
this.butsLayout = false;
|
|
133
|
-
},
|
|
134
|
-
updateBubbleButs() {
|
|
135
|
-
this.$updatePointsInfo();
|
|
136
|
-
Object.keys(this.buts.style).forEach((name) => {
|
|
137
|
-
this.butsLayout.style[name] = `${this.buts.style[name]}px`;
|
|
138
|
-
});
|
|
139
|
-
Object.keys(this.buts.points.arr).forEach((index) => {
|
|
140
|
-
const name = this.buts.points.arr[index];
|
|
141
|
-
this.butsPoints[`pints-${name}`].style.top = `${this.buts.points.arrInfo[name].top}px`;
|
|
142
|
-
this.butsPoints[`pints-${name}`].style.left = `${this.buts.points.arrInfo[name].left}px`;
|
|
143
|
-
});
|
|
144
|
-
},
|
|
145
|
-
$updatePointsInfo() {
|
|
146
|
-
const pointLeft = this.buts.style.width;
|
|
147
|
-
const pointTop = this.buts.style.height;
|
|
148
|
-
const newPointsInfo = this.$getPointsInfo(pointLeft, pointTop);
|
|
149
|
-
Object.keys(this.buts.points.arr).forEach((index) => {
|
|
150
|
-
const name = this.buts.points.arr[index];
|
|
151
|
-
if (this.buts.points.arrInfo[name].left !== newPointsInfo[name].left) {
|
|
152
|
-
this.buts.points.arrInfo[name].left = newPointsInfo[name].left;
|
|
153
|
-
}
|
|
154
|
-
if (this.buts.points.arrInfo[name].top !== newPointsInfo[name].top) {
|
|
155
|
-
this.buts.points.arrInfo[name].top = newPointsInfo[name].top;
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
},
|
|
159
|
-
$getPointsInfo(left, top) {
|
|
160
|
-
return {
|
|
161
|
-
leftTop: { left: 0, top: 0 },
|
|
162
|
-
leftBottom: { left: 0, top },
|
|
163
|
-
rightTop: { left, top: 0 },
|
|
164
|
-
rightBottom: { left, top },
|
|
165
|
-
leftMiddle: { left: 0, top: top / 2 },
|
|
166
|
-
middleBottom: { left: left / 2, top },
|
|
167
|
-
middleTop: { left: left / 2, top: 0 },
|
|
168
|
-
rightMiddle: { left, top: top / 2 },
|
|
169
|
-
};
|
|
170
|
-
},
|
|
171
|
-
$isResizing() {
|
|
172
|
-
return this.mouseResize.resize;
|
|
173
|
-
},
|
|
174
|
-
dealScroll(event) {
|
|
175
|
-
const position = this.getImgPosition();
|
|
176
|
-
if (this.butsLayout.style.marginTop !== position.top - this.buts.position.top) {
|
|
177
|
-
this.butsLayout.style.marginTop = `${position.top - this.buts.position.top}px`;
|
|
178
|
-
this.buts.style.marginTop = `${position.top - this.buts.position.top}px`;
|
|
179
|
-
}
|
|
180
|
-
if (this.butsLayout.style.marginLeft !== position.left - this.buts.position.left) {
|
|
181
|
-
this.butsLayout.style.marginLeft = `${position.left - this.buts.position.left}px`;
|
|
182
|
-
this.buts.style.marginLeft = `${position.left - this.buts.position.left}px`;
|
|
183
|
-
}
|
|
184
|
-
},
|
|
185
|
-
initMouse() {
|
|
186
|
-
return { left: 0, top: 0, resize: false, name: '' };
|
|
187
|
-
},
|
|
188
|
-
resizeBegin(event) {
|
|
189
|
-
const point = event.target;
|
|
190
|
-
if (!point.classList.contains('cherry-previewer-img-size-handler__points')) {
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
this.mouseResize.left = event.clientX;
|
|
194
|
-
this.mouseResize.top = event.clientY;
|
|
195
|
-
this.mouseResize.resize = true;
|
|
196
|
-
this.mouseResize.name = point.getAttribute('data-name');
|
|
197
|
-
this.previewerDom.classList.add('doing-resize-img');
|
|
198
|
-
},
|
|
199
|
-
resizeStop(event, buts, editor, menu) {
|
|
200
|
-
if (!this.$isResizing()) {
|
|
201
|
-
return false;
|
|
202
|
-
}
|
|
203
|
-
this.img.style.width = `${this.buts.style.width}px`;
|
|
204
|
-
this.img.style.height = `${this.buts.style.height}px`;
|
|
205
|
-
this.buts.style.marginTop = 0;
|
|
206
|
-
this.buts.style.marginLeft = 0;
|
|
207
|
-
this.updateBubbleButs();
|
|
208
|
-
this.mouseResize.resize = false;
|
|
209
|
-
this.previewerDom.classList.remove('doing-resize-img');
|
|
210
|
-
this.change();
|
|
211
|
-
},
|
|
212
|
-
resizeWorking(event, buts) {
|
|
213
|
-
if (!this.$isResizing()) {
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
const changeX = event.clientX - this.mouseResize.left;
|
|
217
|
-
const changeY = event.clientY - this.mouseResize.top;
|
|
218
|
-
let change = {};
|
|
219
|
-
switch (this.mouseResize.name) {
|
|
220
|
-
case 'leftTop':
|
|
221
|
-
case 'leftBottom':
|
|
222
|
-
case 'leftMiddle':
|
|
223
|
-
change = this.$getChange(changeX, changeY, 'x');
|
|
224
|
-
this.buts.style.width = this.buts.position.width - change.changeX;
|
|
225
|
-
if (this.mouseResize.name !== 'leftMiddle') {
|
|
226
|
-
this.buts.style.height = this.buts.position.height - change.changeY;
|
|
227
|
-
}
|
|
228
|
-
break;
|
|
229
|
-
case 'rightTop':
|
|
230
|
-
case 'rightBottom':
|
|
231
|
-
case 'rightMiddle':
|
|
232
|
-
change = this.$getChange(changeX, changeY, 'x');
|
|
233
|
-
this.buts.style.width = this.buts.position.width + change.changeX;
|
|
234
|
-
if (this.mouseResize.name !== 'rightMiddle') {
|
|
235
|
-
this.buts.style.height = this.buts.position.height + change.changeY;
|
|
236
|
-
}
|
|
237
|
-
break;
|
|
238
|
-
case 'middleTop':
|
|
239
|
-
change = this.$getChange(changeX, changeY, 'y');
|
|
240
|
-
this.buts.style.height = this.buts.position.height - change.changeY;
|
|
241
|
-
break;
|
|
242
|
-
case 'middleBottom':
|
|
243
|
-
change = this.$getChange(changeX, changeY, 'y');
|
|
244
|
-
this.buts.style.height = this.buts.position.height + change.changeY;
|
|
245
|
-
break;
|
|
246
|
-
}
|
|
247
|
-
this.updateBubbleButs();
|
|
248
|
-
this.change();
|
|
249
|
-
},
|
|
250
|
-
change() {
|
|
251
|
-
this.emitChange(this.img, { width: this.buts.style.width, height: this.buts.style.height });
|
|
252
|
-
},
|
|
253
|
-
bindChange(func) {
|
|
254
|
-
this.emitChange = func;
|
|
255
|
-
},
|
|
256
|
-
/**
|
|
257
|
-
* 根据宽(x)或高(y)来进行等比例缩放
|
|
258
|
-
* @param {number} x 宽度
|
|
259
|
-
* @param {number} y 高度
|
|
260
|
-
* @param {string} type 类型,以宽/高为基准做等比例缩放
|
|
261
|
-
* @returns
|
|
262
|
-
*/
|
|
263
|
-
$getChange(x, y, type) {
|
|
264
|
-
const ret = { changeX: 0, changeY: 0 };
|
|
265
|
-
switch (type) {
|
|
266
|
-
case 'y':
|
|
267
|
-
ret.changeY = y;
|
|
268
|
-
ret.changeX = (y * this.buts.position.width) / this.buts.position.height;
|
|
269
|
-
break;
|
|
270
|
-
default:
|
|
271
|
-
ret.changeX = x;
|
|
272
|
-
ret.changeY = (x * this.buts.position.height) / this.buts.position.width;
|
|
273
|
-
break;
|
|
274
|
-
}
|
|
275
|
-
return ret;
|
|
276
|
-
},
|
|
277
|
-
};
|
|
278
|
-
|
|
279
|
-
export default imgSizeHandler;
|
package/src/utils/lazyLoadImg.js
DELETED
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (C) 2021 THL A29 Limited, a Tencent company.
|
|
3
|
-
*
|
|
4
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
* you may not use this file except in compliance with the License.
|
|
6
|
-
* You may obtain a copy of the License at
|
|
7
|
-
*
|
|
8
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
*
|
|
10
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
* See the License for the specific language governing permissions and
|
|
14
|
-
* limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 懒加载图片
|
|
19
|
-
*
|
|
20
|
-
* - 只缓存图片的src的原因
|
|
21
|
-
* - 1、因为浏览器的图片缓存机制,相同的src第二次请求时,会浏览器会直接返回缓存的图片
|
|
22
|
-
* - 2、编辑状态时预览区域dom结构不稳定,并不能准确的缓存到img dom对象
|
|
23
|
-
*
|
|
24
|
-
* - 当浏览器**禁用**了图片缓存时,本机制效果有限
|
|
25
|
-
* - 依然还是可以实现懒加载的效果
|
|
26
|
-
* - 但是会把图片请求次数翻倍
|
|
27
|
-
*/
|
|
28
|
-
export default class LazyLoadImg {
|
|
29
|
-
options = {
|
|
30
|
-
// 加载图片时如果需要展示loading图,则配置loading图的地址
|
|
31
|
-
loadingImgPath: '',
|
|
32
|
-
// 同一时间最多有几个图片请求,最大同时加载6张图片
|
|
33
|
-
maxNumPerTime: 2,
|
|
34
|
-
// 不进行懒加载处理的图片数量,如果为0,即所有图片都进行懒加载处理, 如果设置为-1,则所有图片都不进行懒加载处理
|
|
35
|
-
noLoadImgNum: 5,
|
|
36
|
-
// 首次自动加载几张图片(不论图片是否滚动到视野内),autoLoadImgNum = -1 表示会自动加载完所有图片
|
|
37
|
-
autoLoadImgNum: 5,
|
|
38
|
-
// 针对加载失败的图片 或 beforeLoadOneImgCallback 返回false 的图片,最多尝试加载几次,为了防止死循环,最多5次。以图片的src为纬度统计重试次数
|
|
39
|
-
maxTryTimesPerSrc: 2,
|
|
40
|
-
// 加载一张图片之前的回调函数,函数return false 会终止加载操作
|
|
41
|
-
beforeLoadOneImgCallback: (img) => {},
|
|
42
|
-
// 加载一张图片失败之后的回调函数
|
|
43
|
-
failLoadOneImgCallback: (img) => {},
|
|
44
|
-
// 加载一张图片之后的回调函数,如果图片加载失败,则不会回调该函数
|
|
45
|
-
afterLoadOneImgCallback: (img) => {},
|
|
46
|
-
// 加载完所有图片后调用的回调函数,只表示某一个时刻所有图片都加在完时的回调,如果预览区域又有了新图片,当新图片加载完后还会产生这个回调
|
|
47
|
-
afterLoadAllImgCallback: () => {},
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
constructor(options, previewer) {
|
|
51
|
-
Object.assign(this.options, options);
|
|
52
|
-
this.previewer = previewer;
|
|
53
|
-
// 记录已经加载过的图片src
|
|
54
|
-
this.srcLoadedList = [];
|
|
55
|
-
// 记录加载失败的图片src,key是src,value是失败次数
|
|
56
|
-
this.srcFailLoadedList = {};
|
|
57
|
-
// 记录正在加载的图片src
|
|
58
|
-
this.srcLoadingList = [];
|
|
59
|
-
// 记录所有懒加载的图片src
|
|
60
|
-
this.srcList = [];
|
|
61
|
-
// 记录当前时刻有多少图片正在加载
|
|
62
|
-
this.loadingImgNum = 0;
|
|
63
|
-
// 记录上次加载完所有图片的个数
|
|
64
|
-
this.lastLoadAllNum = 0;
|
|
65
|
-
this.previewerDom = this.previewer.getDomContainer();
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* 判断图片的src是否加载过
|
|
70
|
-
* @param {String} src
|
|
71
|
-
* @return {Boolean}
|
|
72
|
-
*/
|
|
73
|
-
isLoaded(src) {
|
|
74
|
-
return this.srcLoadedList.includes(src);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* 判断图片是否正在加载
|
|
79
|
-
* @param {String} src
|
|
80
|
-
* @return {Boolean}
|
|
81
|
-
*/
|
|
82
|
-
isLoading(src) {
|
|
83
|
-
return this.srcLoadingList.includes(src);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 加载失败时,把src加入到失败队列中,并记录失败次数
|
|
88
|
-
* @param {*} src
|
|
89
|
-
*/
|
|
90
|
-
loadFailed(src) {
|
|
91
|
-
this.srcFailLoadedList[src] = this.srcFailLoadedList[src] ? this.srcFailLoadedList[src] + 1 : 1;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* 判断图片失败次数是否超过最大次数
|
|
96
|
-
* @param {*} src
|
|
97
|
-
* @return {Boolean}
|
|
98
|
-
*/
|
|
99
|
-
isFailLoadedMax(src) {
|
|
100
|
-
return this.srcFailLoadedList[src] && this.srcFailLoadedList[src] > this.options.maxTryTimesPerSrc;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* 判断当前时刻所有图片是否都完成过加载
|
|
105
|
-
* 当出现新图片后,完成加载后,当前函数还是会再次触发加载完的回调函数(afterLoadAllImgCallback)
|
|
106
|
-
* 该函数并不是实时返回的,最大有1s的延时
|
|
107
|
-
*/
|
|
108
|
-
isLoadedAllDone() {
|
|
109
|
-
const imgs = this.previewerDom.querySelectorAll('img[data-src]');
|
|
110
|
-
const allLoadedNum = this.srcLoadedList.length;
|
|
111
|
-
// const dataSrcRemain = allLoadNum - this.srcLoadedList.length;
|
|
112
|
-
if (imgs.length <= 0 && this.lastLoadAllNum < allLoadedNum) {
|
|
113
|
-
this.lastLoadAllNum = allLoadedNum;
|
|
114
|
-
this.options.afterLoadAllImgCallback();
|
|
115
|
-
return true;
|
|
116
|
-
}
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* 当向下滚动时,提前100px加载图片
|
|
122
|
-
* 当向上滚动时,不提前加载图片,一定要图片完全进入可视区域(top > 0)再加载图片,否则当锚点定位时,会由于上面的图片加载出现定位不准的情况
|
|
123
|
-
*
|
|
124
|
-
*/
|
|
125
|
-
loadOneImg() {
|
|
126
|
-
const imgs = this.previewerDom.querySelectorAll('img[data-src]');
|
|
127
|
-
const { height, top } = this.previewerDom.getBoundingClientRect();
|
|
128
|
-
const previewerHeight = height + top + 100; // 冗余一定高度用于提前加载
|
|
129
|
-
const windowsHeight = window?.innerHeight ?? 0 + 100; // 浏览器的视口高度
|
|
130
|
-
const maxHeight = Math.min(previewerHeight, windowsHeight); // 目标视区高度一定是小于浏览器视口高度的,也一定是小于预览区高度的
|
|
131
|
-
const minHeight = top - 30; // 计算顶部高度时,需要预加载一行高
|
|
132
|
-
const { autoLoadImgNum } = this.options;
|
|
133
|
-
for (let i = 0; i < imgs.length; i++) {
|
|
134
|
-
const img = imgs[i];
|
|
135
|
-
const position = img.getBoundingClientRect();
|
|
136
|
-
// 判断是否在视区内
|
|
137
|
-
const testPosition = position.top >= minHeight && position.top <= maxHeight;
|
|
138
|
-
// 判断是否需要自动加载
|
|
139
|
-
const testAutoLoad = this.srcList.length < autoLoadImgNum;
|
|
140
|
-
if (!testPosition && !testAutoLoad) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
let originSrc = img.getAttribute('data-src');
|
|
144
|
-
if (!originSrc) {
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
if (this.isLoaded(originSrc) || this.isFailLoadedMax(originSrc)) {
|
|
148
|
-
// 如果已经加载过相同的图片,或者已经超过失败最大重试次数,则直接加载
|
|
149
|
-
img.setAttribute('src', originSrc);
|
|
150
|
-
img.removeAttribute('data-src');
|
|
151
|
-
}
|
|
152
|
-
// 如果当前src正在加载,则忽略这个src,继续找下个符合条件的src
|
|
153
|
-
if (this.isLoading(originSrc)) {
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
// 超过最大并发量时停止加载
|
|
157
|
-
if (this.loadingImgNum >= this.options.maxNumPerTime) {
|
|
158
|
-
return false;
|
|
159
|
-
}
|
|
160
|
-
const test = this.options.beforeLoadOneImgCallback(img);
|
|
161
|
-
if (typeof test === 'undefined' || test) {
|
|
162
|
-
originSrc = img.getAttribute('data-src') ?? originSrc;
|
|
163
|
-
} else {
|
|
164
|
-
this.loadFailed(originSrc);
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
this.loadingImgNum += 1;
|
|
168
|
-
this.srcList.push(originSrc);
|
|
169
|
-
this.srcLoadingList.push(originSrc);
|
|
170
|
-
this.tryLoadOneImg(
|
|
171
|
-
originSrc,
|
|
172
|
-
() => {
|
|
173
|
-
img.setAttribute('src', originSrc);
|
|
174
|
-
img.removeAttribute('data-src');
|
|
175
|
-
this.srcLoadedList.push(originSrc);
|
|
176
|
-
this.loadingImgNum -= 1;
|
|
177
|
-
this.srcLoadingList.splice(this.srcLoadingList.indexOf(originSrc), 1);
|
|
178
|
-
this.options.afterLoadOneImgCallback(img);
|
|
179
|
-
this.loadOneImg();
|
|
180
|
-
},
|
|
181
|
-
() => {
|
|
182
|
-
this.loadFailed(originSrc);
|
|
183
|
-
this.loadingImgNum -= 1;
|
|
184
|
-
this.srcLoadingList.splice(this.srcLoadingList.indexOf(originSrc), 1);
|
|
185
|
-
this.options.failLoadOneImgCallback(img);
|
|
186
|
-
this.loadOneImg();
|
|
187
|
-
},
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* 尝试加载src
|
|
195
|
-
* @param {String} src
|
|
196
|
-
*/
|
|
197
|
-
tryLoadOneImg(src, successCallback, failCallback) {
|
|
198
|
-
const img = document.createElement('img');
|
|
199
|
-
img.onload = () => {
|
|
200
|
-
successCallback();
|
|
201
|
-
img.remove();
|
|
202
|
-
};
|
|
203
|
-
img.onerror = () => {
|
|
204
|
-
failCallback();
|
|
205
|
-
img.remove();
|
|
206
|
-
};
|
|
207
|
-
img.setAttribute('src', src);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* 开始进行懒加载
|
|
212
|
-
*
|
|
213
|
-
* **关于实现方式的思考**
|
|
214
|
-
* 实现图片懒加载一般有三种方式:
|
|
215
|
-
* 1、监听滚动事件,滚动到视野内的图片开始加载
|
|
216
|
-
* 2、定时检测当前视窗内是否有图片需要加载
|
|
217
|
-
* 3、当前一张图片加载完成后,自动加载下一张图片
|
|
218
|
-
*
|
|
219
|
-
* 方式1监听滚动事件的弊端:
|
|
220
|
-
* 1、需要限频率
|
|
221
|
-
* 2、不能实现自动加载所有图片的功能(autoLoadImgNum = -1)
|
|
222
|
-
* 3、如果业务方对预览区域做了个性化加工,有可能导致监听不到滚动事件
|
|
223
|
-
* 4、在自动滚动到锚点的场景,会在页面滚动时加载图片,图片的加载会导致锚点上方的元素高度发生变化,最终导致锚点定位失败
|
|
224
|
-
* (所以在这个场景下,需要特殊处理图片加载的时机,但并不好判断是否锚点引发的滚动)
|
|
225
|
-
* 5、浏览器尺寸发生变化或者浏览器缩放比例发生变化的场景(当然还有横屏竖屏切换、系统分辨率改变等)不好监听和响应
|
|
226
|
-
*
|
|
227
|
-
* 方式2轮询的弊端:
|
|
228
|
-
* 1、需要额外的逻辑来控制并发
|
|
229
|
-
* 2、消耗计算资源,所以需要尽量优化单次计算量,并尽量避免在轮询里进行大范围dom操作
|
|
230
|
-
* 3、两次图片加载中间可能有最大轮询间隔的空闲时间浪费
|
|
231
|
-
*
|
|
232
|
-
* 方式3依次加载的弊端:
|
|
233
|
-
* 1、没办法实现滚动到视野内再加载图片
|
|
234
|
-
*
|
|
235
|
-
* 综合考虑决定用方式2(轮询)+方式3(依次加载)的组合方式,并且每次只做一次dom写操作
|
|
236
|
-
* 轮询带来的性能开销就让受摩尔定律加持的硬件和每月都会更新版本的浏览器们愁去吧
|
|
237
|
-
*/
|
|
238
|
-
doLazyLoad() {
|
|
239
|
-
// 防止重复调用
|
|
240
|
-
if (this.isRunning) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
this.isRunning = true;
|
|
244
|
-
const { maxNumPerTime } = this.options;
|
|
245
|
-
const polling = () => {
|
|
246
|
-
// 保证至少有一次自动加载
|
|
247
|
-
this.loadOneImg();
|
|
248
|
-
for (let i = 1; i < maxNumPerTime; i++) {
|
|
249
|
-
this.loadOneImg();
|
|
250
|
-
}
|
|
251
|
-
setTimeout(polling, 200);
|
|
252
|
-
};
|
|
253
|
-
polling();
|
|
254
|
-
// setTimeout(polling, 200);
|
|
255
|
-
setInterval(() => {
|
|
256
|
-
this.isLoadedAllDone();
|
|
257
|
-
}, 1000);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* 把图片里的data-src替换为src
|
|
262
|
-
* @param {*} content
|
|
263
|
-
* @returns {String}
|
|
264
|
-
*/
|
|
265
|
-
changeDataSrc2Src(content) {
|
|
266
|
-
return content.replace(/<img ([^>]*?)data-src="([^"]+)"([^>]*?)>/g, (match, m1, src, m3) => {
|
|
267
|
-
return `<img ${this.$removeSrc(m1)} src="${src}" ${this.$removeSrc(m3)}>`.replace(/ {2,}/g, ' ');
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* 把已经加载的图片里的data-src替换为src
|
|
273
|
-
* @param {*} content
|
|
274
|
-
* @returns {String}
|
|
275
|
-
*/
|
|
276
|
-
changeLoadedDataSrc2Src(content) {
|
|
277
|
-
return content.replace(/<img ([^>]*?)data-src="([^"]+)"([^>]*?)>/g, (match, m1, src, m3) => {
|
|
278
|
-
if (!this.isLoaded(src)) {
|
|
279
|
-
return match;
|
|
280
|
-
}
|
|
281
|
-
return `<img ${this.$removeSrc(m1)} src="${src}" ${this.$removeSrc(m3)}>`.replace(/ {2,}/g, ' ');
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* 移除图片的src属性
|
|
287
|
-
* @param {String} img
|
|
288
|
-
* @returns {String}
|
|
289
|
-
*/
|
|
290
|
-
$removeSrc(img) {
|
|
291
|
-
return ` ${img}`.replace(/^(.*?) src=".*?"(.*?$)/, '$1$2');
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* 把图片里的src替换为data-src,如果src已经加载过,则不替换
|
|
296
|
-
* @param {String} content
|
|
297
|
-
* @param {Boolean} focus 强制替换
|
|
298
|
-
* @returns {String}
|
|
299
|
-
*/
|
|
300
|
-
changeSrc2DataSrc(content, focus = false) {
|
|
301
|
-
const { loadingImgPath } = this.options;
|
|
302
|
-
const { noLoadImgNum } = this.options;
|
|
303
|
-
let currentNoLoadImgNum = 0;
|
|
304
|
-
return content.replace(/<img ([^>]*?)src="([^"]+)"([^>]*?)>/g, (match, m1, src, m3) => {
|
|
305
|
-
// 如果已经替换过data-src了,或者没有src属性,或者关闭了懒加载功能,则不替换
|
|
306
|
-
if (/data-src="/.test(match) || !/ src="/.test(match) || noLoadImgNum < 0) {
|
|
307
|
-
return match;
|
|
308
|
-
}
|
|
309
|
-
if (focus === false) {
|
|
310
|
-
// 前noLoadImgNum张图片不替换
|
|
311
|
-
if (currentNoLoadImgNum < noLoadImgNum) {
|
|
312
|
-
currentNoLoadImgNum += 1;
|
|
313
|
-
return match;
|
|
314
|
-
}
|
|
315
|
-
// 如果src已经加载过,则不替换
|
|
316
|
-
if (this.isLoaded(src)) {
|
|
317
|
-
return match;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
// 如果配置了loadingImgPath,则替换src为loadingImgPath
|
|
321
|
-
if (loadingImgPath) {
|
|
322
|
-
return `<img ${m1}src="${loadingImgPath}" data-src="${src}"${m3}>`;
|
|
323
|
-
}
|
|
324
|
-
return `<img ${m1}data-src="${src}"${m3}>`;
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
}
|