123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677 |
- // 小程序富文本插件 https://github.com/jin-yufeng/Parser
- "use strict";
- function _classCallCheck(t, i) {
- if (!(t instanceof i))
- throw new TypeError("Cannot call a class as a function");
- }
- var _createClass = (function () {
- function t(t, i) {
- for (var s = 0; s < i.length; s++) {
- var e = i[s];
- (e.enumerable = e.enumerable || !1),
- (e.configurable = !0),
- "value" in e && (e.writable = !0),
- Object.defineProperty(t, e.key, e);
- }
- }
- return function (i, s, e) {
- return s && t(i.prototype, s), e && t(i, e), i;
- };
- })(),
- cfg = require("./config.js"),
- blankChar = cfg.blankChar,
- CssHandler = require("./CssHandler.js"),
- screenWidth = wx.getSystemInfoSync().screenWidth;
- try {
- var emoji = require("./emoji.js.js.js");
- } catch (t) {}
- var MpHtmlParser = (function () {
- function t(i) {
- var s = this,
- e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {};
- _classCallCheck(this, t),
- (this.getName = function (t) {
- return s.xml ? t : t.toLowerCase();
- }),
- (this.isClose = function () {
- return (
- ">" == s.data[s.i] || ("/" == s.data[s.i] && ">" == s.data[s.i + 1])
- );
- }),
- (this.section = function () {
- return s.data.substring(s.start, s.i);
- }),
- (this.parent = function () {
- return s.STACK[s.STACK.length - 1];
- }),
- (this.siblings = function () {
- return s.STACK.length ? s.parent().children : s.DOM;
- }),
- (this.attrs = {}),
- (this.compress = e.compress),
- (this.CssHandler = new CssHandler(e.tagStyle, screenWidth)),
- (this.data = i),
- (this.domain = e.domain),
- (this.DOM = []),
- (this.i = this.start = this.audioNum = this.imgNum = this.videoNum = 0),
- (this.protocol =
- this.domain && this.domain.includes("://")
- ? this.domain.split("://")[0]
- : "http"),
- (this.state = this.Text),
- (this.STACK = []),
- (this.useAnchor = e.useAnchor),
- (this.xml = e.xml);
- }
- return (
- _createClass(t, [
- {
- key: "parse",
- value: function () {
- emoji && (this.data = emoji.parseEmoji(this.data));
- for (var t; (t = this.data[this.i]); this.i++) this.state(t);
- for (this.state == this.Text && this.setText(); this.STACK.length; )
- this.popNode(this.STACK.pop());
- return (
- this.DOM.length &&
- ((this.DOM[0].PoweredBy = "Parser"),
- this.title && (this.DOM[0].title = this.title)),
- this.DOM
- );
- },
- },
- {
- key: "setAttr",
- value: function () {
- var t = this.getName(this.attrName);
- for (
- cfg.trustAttrs[t] &&
- (this.attrVal
- ? (this.attrs[t] =
- "src" == t
- ? this.getUrl(this.attrVal.replace(/&/g, "&"))
- : this.attrVal)
- : cfg.boolAttrs[t] && (this.attrs[t] = "T")),
- this.attrVal = "";
- blankChar[this.data[this.i]];
- )
- this.i++;
- this.isClose()
- ? this.setNode()
- : ((this.start = this.i), (this.state = this.AttrName));
- },
- },
- {
- key: "setText",
- value: function () {
- var t,
- i = this.section();
- if (i)
- if (
- ((i =
- (cfg.onText &&
- cfg.onText(i, function () {
- return (t = !0);
- })) ||
- i),
- t)
- ) {
- this.data =
- this.data.substr(0, this.start) + i + this.data.substr(this.i);
- var s = this.start + i.length;
- for (this.i = this.start; this.i < s; this.i++)
- this.state(this.data[this.i]);
- } else {
- if (!this.pre) {
- for (var e, a = [], r = i.length; (e = i[--r]); )
- (!blankChar[e] || (!blankChar[a[0]] && (e = " "))) &&
- a.unshift(e);
- if (" " == (i = a.join(""))) return;
- }
- for (var h, n, l = -1, o = this.siblings(); ; ) {
- if (-1 == (l = i.indexOf("&", l + 1))) break;
- if (-1 == (h = i.indexOf(";", l + 2))) break;
- "#" == i[l + 1]
- ? ((n = parseInt(
- ("x" == i[l + 2] ? "0" : "") + i.substring(l + 2, h)
- )),
- isNaN(n) ||
- (i =
- i.substr(0, l) +
- String.fromCharCode(n) +
- i.substr(h + 1)))
- : ((n = i.substring(l + 1, h)),
- "nbsp" == n
- ? (i = i.substr(0, l) + " " + i.substr(h + 1))
- : "lt" != n &&
- "gt" != n &&
- "amp" != n &&
- "ensp" != n &&
- "emsp" != n &&
- "quot" != n &&
- "apos" != n &&
- (l && o.push({ type: "text", text: i.substr(0, l) }),
- o.push({ type: "text", text: "&" + n + ";", en: 1 }),
- (i = i.substr(h + 1)),
- (l = -1)));
- }
- i && o.push({ type: "text", text: i });
- }
- },
- },
- {
- key: "setNode",
- value: function () {
- var t = { name: this.getName(this.tagName), attrs: this.attrs },
- i =
- cfg.selfClosingTags[t.name] ||
- (this.xml && "/" == this.data[this.i]);
- if (((this.attrs = {}), cfg.ignoreTags[t.name]))
- if (i)
- if ("source" == t.name) {
- var s = this.parent(),
- e = t.attrs;
- if (s && e.src)
- if ("video" == s.name || "audio" == s.name)
- s.attrs.source.push(e.src);
- else {
- var a,
- r = e.media;
- "picture" == s.name &&
- !s.attrs.src &&
- (!r ||
- (r.includes("px") &&
- ((-1 != (a = r.indexOf("min-width")) &&
- -1 != (a = r.indexOf(":", a + 8)) &&
- screenWidth > parseInt(r.substr(a + 1))) ||
- (-1 != (a = r.indexOf("max-width")) &&
- -1 != (a = r.indexOf(":", a + 8)) &&
- screenWidth < parseInt(r.substr(a + 1)))))) &&
- (s.attrs.src = e.src);
- }
- } else
- "base" != t.name || this.domain || (this.domain = t.attrs.href);
- else this.remove(t);
- else
- this.matchAttr(t),
- i
- ? (cfg.filter && 0 == cfg.filter(t, this)) ||
- this.siblings().push(t)
- : ((t.children = []),
- "pre" == t.name &&
- cfg.highlight &&
- (this.remove(t), (this.pre = t.pre = !0)),
- this.siblings().push(t),
- this.STACK.push(t));
- "/" == this.data[this.i] && this.i++,
- (this.start = this.i + 1),
- (this.state = this.Text);
- },
- },
- {
- key: "remove",
- value: function (t) {
- for (var i = t.name, s = this.i; ; ) {
- if (-1 == (this.i = this.data.indexOf("</", this.i + 1)))
- return void (this.i =
- "pre" == i || "svg" == i ? s : this.data.length);
- for (
- this.start = this.i += 2;
- !blankChar[this.data[this.i]] && !this.isClose();
- )
- this.i++;
- if (this.getName(this.section()) == i) {
- if ("pre" == i)
- return (
- (this.data =
- this.data.substr(0, s + 1) +
- cfg.highlight(
- this.data.substring(s + 1, this.i - 5),
- t.attrs
- ) +
- this.data.substr(this.i - 5)),
- (this.i = s)
- );
- if (
- ("style" == i
- ? this.CssHandler.getStyle(
- this.data.substring(s + 1, this.i - 7)
- )
- : "title" == i &&
- (this.title = this.data.substring(s + 1, this.i - 7)),
- -1 == (this.i = this.data.indexOf(">", this.i)) &&
- (this.i = this.data.length),
- "svg" == i)
- ) {
- var e = this.data.substring(s, this.i + 1);
- t.attrs.xmlns ||
- (e = ' xmlns="http://www.w3.org/2000/svg"' + e);
- for (var a = s; "<" != this.data[s]; ) s--;
- e = this.data.substring(s, a) + e;
- var r = this.parent();
- "100%" == t.attrs.width &&
- r &&
- (r.attrs.style || "").includes("inline") &&
- (r.attrs.style =
- "width:300px;max-width:100%;" + r.attrs.style),
- this.siblings().push({
- name: "img",
- attrs: {
- src: "data:image/svg+xml;utf8," + e.replace(/#/g, "%23"),
- },
- svg: 1,
- });
- }
- return;
- }
- }
- },
- },
- {
- key: "matchAttr",
- value: function (t) {
- var i = t.attrs,
- s = this.CssHandler.match(t.name, i, t) + (i.style || ""),
- e = {};
- switch (
- (i.id &&
- (1 & this.compress
- ? (i.id = void 0)
- : this.useAnchor && this.bubble()),
- 2 & this.compress && i.class && (i.class = void 0),
- t.name)
- ) {
- case "a":
- case "ad":
- this.bubble();
- break;
- case "font":
- if (
- (i.color && ((e.color = i.color), (i.color = void 0)),
- i.face && ((e["font-family"] = i.face), (i.face = void 0)),
- i.size)
- ) {
- var a = parseInt(i.size);
- a < 1 ? (a = 1) : a > 7 && (a = 7);
- var r = [
- "xx-small",
- "x-small",
- "small",
- "medium",
- "large",
- "x-large",
- "xx-large",
- ];
- (e["font-size"] = r[a - 1]), (i.size = void 0);
- }
- break;
- case "video":
- case "audio":
- i.id
- ? this[t.name + "Num"]++
- : (i.id = t.name + ++this[t.name + "Num"]),
- "video" == t.name && this.videoNum > 3 && (t.lazyLoad = 1),
- (i.source = []),
- i.src && i.source.push(i.src),
- i.controls ||
- i.autoplay ||
- console.warn(
- "存在没有 controls 属性的 " +
- t.name +
- " 标签,可能导致无法播放",
- t
- ),
- this.bubble();
- break;
- case "td":
- case "th":
- if (i.colspan || i.rowspan)
- for (var h, n = this.STACK.length; (h = this.STACK[--n]); )
- if ("table" == h.name) {
- h.c = void 0;
- break;
- }
- }
- i.align && ((e["text-align"] = i.align), (i.align = void 0)),
- i.width &&
- ((e.width =
- parseFloat(i.width) + (i.width.includes("%") ? "%" : "px")),
- (i.width = void 0)),
- i.height &&
- ((e.height =
- parseFloat(i.height) + (i.height.includes("%") ? "%" : "px")),
- (i.height = void 0));
- var l = s
- .replace(/"/g, '"')
- .replace(/&/g, "&")
- .split(";");
- s = "";
- for (var o = 0, c = l.length; o < c; o++) {
- var d = l[o].split(":");
- if (!(d.length < 2)) {
- var u = d[0].trim().toLowerCase(),
- f = d.slice(1).join(":").trim();
- f.includes("-webkit") ||
- f.includes("-moz") ||
- f.includes("-ms") ||
- f.includes("-o") ||
- f.includes("safe")
- ? (s += ";" + u + ":" + f)
- : (e[u] && !f.includes("import") && e[u].includes("import")) ||
- (e[u] = f);
- }
- }
- if ("img" == t.name || "picture" == t.name) {
- i["data-src"] &&
- ((i.src = i.src || i["data-src"]), (i["data-src"] = void 0)),
- (!i.src && "picture" != t.name) ||
- i.ignore ||
- (this.bubble()
- ? ((i.src || "").includes(".webp") && (t.webp = 1),
- (i.i = (this.imgNum++).toString()))
- : (i.ignore = "T")),
- i.ignore && (e["max-width"] = "100%");
- var m = function (t) {
- return e[t] && !e[t].includes("auto");
- };
- if (m("width")) {
- var g = this.parent();
- e.width.includes("%") &&
- g &&
- (g.attrs.style || "").includes("inline") &&
- ((g.attrs.style += ";max-width:100%"), (t.auto = 1)),
- parseInt(e.width) > screenWidth && (e.height = "auto"),
- m("height") && (t.mode = "scaleToFill");
- } else m("height") ? (t.mode = "heightFix") : (t.auto = 1);
- }
- for (var p in e) {
- var b = e[p];
- if (
- ((p.includes("flex") || "order" == p || "self-align" == p) &&
- (t.c = 1),
- b.includes("url"))
- ) {
- var v = b.indexOf("(");
- if (-1 != v++) {
- for (; '"' == b[v] || "'" == b[v] || blankChar[b[v]]; ) v++;
- b = b.substr(0, v) + this.getUrl(b.substr(v));
- }
- } else
- b.includes("rpx")
- ? (b = b.replace(/[0-9.]+\s*rpx/g, function (t) {
- return (parseFloat(t) * screenWidth) / 750 + "px";
- }))
- : "white-space" == p &&
- b.includes("pre") &&
- (this.pre = t.pre = !0);
- s += ";" + p + ":" + b;
- }
- (s = s.substr(1)) && (i.style = s);
- },
- },
- {
- key: "popNode",
- value: function (t) {
- if (t.pre) {
- t.pre = this.pre = void 0;
- for (var i = this.STACK.length; i--; )
- this.STACK[i].pre && (this.pre = !0);
- }
- if ("head" == t.name || (cfg.filter && 0 == cfg.filter(t, this)))
- return this.siblings().pop();
- var s = t.attrs;
- if ("picture" == t.name)
- return (
- (t.name = "img"),
- s.src ||
- "img" != (t.children[0] || "").name ||
- (s.src = t.children[0].attrs.src),
- (t.children = void 0)
- );
- if (
- (cfg.blockTags[t.name]
- ? (t.name = "div")
- : cfg.trustTags[t.name] || (t.name = "span"),
- t.c)
- )
- if ("ul" == t.name) {
- for (var e = 1, a = this.STACK.length; a--; )
- "ul" == this.STACK[a].name && e++;
- if (1 != e)
- for (var r = t.children.length; r--; ) t.children[r].floor = e;
- } else if ("ol" == t.name)
- for (var h, n = 0, l = 1; (h = t.children[n++]); )
- "li" == h.name &&
- ((h.type = "ol"),
- (h.num =
- (function (t, i) {
- if ("a" == i)
- return String.fromCharCode(97 + ((t - 1) % 26));
- if ("A" == i)
- return String.fromCharCode(65 + ((t - 1) % 26));
- if ("i" == i || "I" == i) {
- t = ((t - 1) % 99) + 1;
- var s = [
- "I",
- "II",
- "III",
- "IV",
- "V",
- "VI",
- "VII",
- "VIII",
- "IX",
- ],
- e = [
- "X",
- "XX",
- "XXX",
- "XL",
- "L",
- "LX",
- "LXX",
- "LXXX",
- "XC",
- ],
- a =
- (e[Math.floor(t / 10) - 1] || "") +
- (s[(t % 10) - 1] || "");
- return "i" == i ? a.toLowerCase() : a;
- }
- return t;
- })(l++, s.type) + "."));
- if ("table" == t.name) {
- var o = s.cellpadding,
- c = s.cellspacing,
- d = s.border;
- t.c &&
- (this.bubble(),
- (s.style = (s.style || "") + ";display:table"),
- o || (o = 2),
- c || (c = 2)),
- d &&
- (s.style = "border:" + d + "px solid gray;" + (s.style || "")),
- c && (s.style = "border-spacing:" + c + "px;" + (s.style || "")),
- (d || o || t.c) &&
- (function i(s) {
- for (var e, a = 0; (e = s[a]); a++) {
- var r = e.attrs.style || "";
- t.c &&
- "t" == e.name[0] &&
- ((e.c = 1),
- (r +=
- ";display:table-" +
- ("th" == e.name || "td" == e.name
- ? "cell"
- : "tr" == e.name
- ? "row"
- : "row-group"))),
- "th" == e.name || "td" == e.name
- ? (d && (r = "border:" + d + "px solid gray;" + r),
- o && (r = "padding:" + o + "px;" + r))
- : i(e.children || []),
- r && (e.attrs.style = r);
- }
- })(t.children);
- }
- if (
- (this.CssHandler.pop && this.CssHandler.pop(t),
- "div" == t.name && !Object.keys(s).length)
- ) {
- var u = this.siblings();
- 1 == t.children.length &&
- "div" == t.children[0].name &&
- (u[u.length - 1] = t.children[0]);
- }
- },
- },
- {
- key: "bubble",
- value: function () {
- for (var t, i = this.STACK.length; (t = this.STACK[--i]); ) {
- if (cfg.richOnlyTags[t.name])
- return (
- "table" != t.name ||
- Object.hasOwnProperty.call(t, "c") ||
- (t.c = 1),
- !1
- );
- t.c = 1;
- }
- return !0;
- },
- },
- {
- key: "getUrl",
- value: function (t) {
- return (
- "/" == t[0]
- ? "/" == t[1]
- ? (t = this.protocol + ":" + t)
- : this.domain && (t = this.domain + t)
- : this.domain &&
- 0 != t.indexOf("data:") &&
- !t.includes("://") &&
- (t = this.domain + "/" + t),
- t
- );
- },
- },
- {
- key: "Text",
- value: function (t) {
- if ("<" == t) {
- var i = this.data[this.i + 1],
- s = function (t) {
- return (t >= "a" && t <= "z") || (t >= "A" && t <= "Z");
- };
- s(i)
- ? (this.setText(),
- (this.start = this.i + 1),
- (this.state = this.TagName))
- : "/" == i
- ? (this.setText(),
- s(this.data[++this.i + 1])
- ? ((this.start = this.i + 1), (this.state = this.EndTag))
- : this.Comment())
- : "!" == i && (this.setText(), this.Comment());
- }
- },
- },
- {
- key: "Comment",
- value: function () {
- var t;
- (t =
- "--" == this.data.substring(this.i + 2, this.i + 4)
- ? "--\x3e"
- : "[CDATA[" == this.data.substring(this.i + 2, this.i + 9)
- ? "]]>"
- : ">"),
- -1 == (this.i = this.data.indexOf(t, this.i + 2))
- ? (this.i = this.data.length)
- : (this.i += t.length - 1),
- (this.start = this.i + 1),
- (this.state = this.Text);
- },
- },
- {
- key: "TagName",
- value: function (t) {
- if (blankChar[t]) {
- for (this.tagName = this.section(); blankChar[this.data[this.i]]; )
- this.i++;
- this.isClose()
- ? this.setNode()
- : ((this.start = this.i), (this.state = this.AttrName));
- } else
- this.isClose() && ((this.tagName = this.section()), this.setNode());
- },
- },
- {
- key: "AttrName",
- value: function (t) {
- var i = blankChar[t];
- if (
- (i && ((this.attrName = this.section()), (t = this.data[this.i])),
- "=" == t)
- ) {
- for (
- i || (this.attrName = this.section());
- blankChar[this.data[++this.i]];
- );
- (this.start = this.i--), (this.state = this.AttrValue);
- } else
- i
- ? this.setAttr()
- : this.isClose() &&
- ((this.attrName = this.section()), this.setAttr());
- },
- },
- {
- key: "AttrValue",
- value: function (t) {
- if ('"' == t || "'" == t) {
- if (
- (this.start++, -1 == (this.i = this.data.indexOf(t, this.i + 1)))
- )
- return (this.i = this.data.length);
- (this.attrVal = this.section()), this.i++;
- } else {
- for (; !blankChar[this.data[this.i]] && !this.isClose(); this.i++);
- this.attrVal = this.section();
- }
- this.setAttr();
- },
- },
- {
- key: "EndTag",
- value: function (t) {
- if (blankChar[t] || ">" == t || "/" == t) {
- for (
- var i = this.getName(this.section()), s = this.STACK.length;
- s-- && this.STACK[s].name != i;
- );
- if (-1 != s) {
- for (var e; (e = this.STACK.pop()).name != i; );
- this.popNode(e);
- } else
- ("p" != i && "br" != i) ||
- this.siblings().push({ name: i, attrs: {} });
- (this.i = this.data.indexOf(">", this.i)),
- (this.start = this.i + 1),
- -1 == this.i
- ? (this.i = this.data.length)
- : (this.state = this.Text);
- }
- },
- },
- ]),
- t
- );
- })();
- module.exports = MpHtmlParser;
|