parser.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. // 小程序富文本插件 https://github.com/jin-yufeng/Parser
  2. "use strict";
  3. function _defineProperty(t, e, i) {
  4. return (
  5. e in t
  6. ? Object.defineProperty(t, e, {
  7. value: i,
  8. enumerable: !0,
  9. configurable: !0,
  10. writable: !0,
  11. })
  12. : (t[e] = i),
  13. t
  14. );
  15. }
  16. function hash(t) {
  17. for (var e = t.length, i = 5381; e--; ) i += (i << 5) + t.charCodeAt(e);
  18. return i;
  19. }
  20. var _typeof =
  21. "function" == typeof Symbol && "symbol" == typeof Symbol.iterator
  22. ? function (t) {
  23. return typeof t;
  24. }
  25. : function (t) {
  26. return t &&
  27. "function" == typeof Symbol &&
  28. t.constructor === Symbol &&
  29. t !== Symbol.prototype
  30. ? "symbol"
  31. : typeof t;
  32. },
  33. cache = {},
  34. Parser = require("./libs/MpHtmlParser.js"),
  35. fs = wx.getFileSystemManager && wx.getFileSystemManager();
  36. try {
  37. var dom = require("./libs/document.js.js.js");
  38. } catch (t) {}
  39. Component({
  40. options: { pureDataPattern: /^[acdgtux]|W/ },
  41. properties: {
  42. html: {
  43. type: null,
  44. observer: function (t) {
  45. this._refresh ? (this._refresh = !1) : this.setContent(t, !1, !0);
  46. },
  47. },
  48. autosetTitle: { type: Boolean, value: !0 },
  49. autopause: { type: Boolean, value: !0 },
  50. compress: Number,
  51. domain: String,
  52. gestureZoom: Boolean,
  53. lazyLoad: Boolean,
  54. selectable: Boolean,
  55. tagStyle: Object,
  56. showWithAnimation: Boolean,
  57. useAnchor: Boolean,
  58. useCache: Boolean,
  59. xml: Boolean,
  60. },
  61. relations: { "../parser-group/parser-group": { type: "ancestor" } },
  62. created: function () {
  63. (this.imgList = []),
  64. (this.imgList.setItem = function (t, e) {
  65. var i = this;
  66. if (t && e) {
  67. if (0 == e.indexOf("http") && this.includes(e)) {
  68. for (
  69. var s, a = "", n = 0;
  70. (s = e[n]) && ("/" != s || "/" == e[n - 1] || "/" == e[n + 1]);
  71. n++
  72. )
  73. a += Math.random() > 0.5 ? s.toUpperCase() : s;
  74. return (a += e.substr(n)), (this[t] = a);
  75. }
  76. if (((this[t] = e), e.includes("data:image"))) {
  77. var r = e.match(/data:image\/(\S+?);(\S+?),(.+)/);
  78. if (!r) return;
  79. var o = wx.env.USER_DATA_PATH + "/" + Date.now() + "." + r[1];
  80. fs &&
  81. fs.writeFile({
  82. filePath: o,
  83. data: r[3],
  84. encoding: r[2],
  85. success: function () {
  86. return (i[t] = o);
  87. },
  88. });
  89. }
  90. }
  91. }),
  92. (this.imgList.each = function (t) {
  93. for (var e = 0, i = this.length; e < i; e++)
  94. this.setItem(e, t(this[e], e, this));
  95. });
  96. },
  97. detached: function () {
  98. this.imgList.each(function (t) {
  99. t &&
  100. t.includes(wx.env.USER_DATA_PATH) &&
  101. fs &&
  102. fs.unlink({ filePath: t });
  103. }),
  104. clearInterval(this._timer);
  105. },
  106. methods: {
  107. navigateTo: function (t) {
  108. var e = this;
  109. if (!this.data.useAnchor)
  110. return t.fail && t.fail({ errMsg: "Anchor is disabled" });
  111. this.createSelectorQuery()
  112. .select(".top" + (t.id ? ">>>#" + t.id : ""))
  113. .boundingClientRect()
  114. .selectViewport()
  115. .scrollOffset()
  116. .exec(function (i) {
  117. if (!i[0])
  118. return e.group
  119. ? e.group.navigateTo(e.i, t)
  120. : t.fail && t.fail({ errMsg: "Label not found" });
  121. (t.scrollTop = i[1].scrollTop + i[0].top), wx.pageScrollTo(t);
  122. });
  123. },
  124. getText: function () {
  125. for (
  126. var t,
  127. e =
  128. arguments.length > 0 && void 0 !== arguments[0]
  129. ? arguments[0]
  130. : this.data.html,
  131. i = "",
  132. s = 0;
  133. (t = e[s++]);
  134. )
  135. if ("text" == t.type)
  136. i += t.text
  137. .replace(/&nbsp;/g, " ")
  138. .replace(/&lt;/g, "<")
  139. .replace(/&gt;/g, ">")
  140. .replace(/&amp;/g, "&");
  141. else if ("br" == t.type) i += "\n";
  142. else {
  143. var a =
  144. "p" == t.name ||
  145. "div" == t.name ||
  146. "tr" == t.name ||
  147. "li" == t.name ||
  148. ("h" == t.name[0] && t.name[1] > "0" && t.name[1] < "7");
  149. a && i && "\n" != i[i.length - 1] && (i += "\n"),
  150. t.children && (i += this.getText(t.children)),
  151. a && "\n" != i[i.length - 1]
  152. ? (i += "\n")
  153. : ("td" != t.name && "th" != t.name) || (i += "\t");
  154. }
  155. return i;
  156. },
  157. getVideoContext: function (t) {
  158. if (!t) return this.videoContexts;
  159. for (var e = this.videoContexts.length; e--; )
  160. if (this.videoContexts[e].id == t) return this.videoContexts[e];
  161. },
  162. setContent: function (t, e, i) {
  163. var s = this,
  164. a = {};
  165. if (t)
  166. if ("string" == typeof t) {
  167. var n = new Parser(t, this.data);
  168. if (this.data.useCache) {
  169. var r = hash(t);
  170. cache[r]
  171. ? (a.html = cache[r])
  172. : ((a.html = n.parse()), (cache[r] = a.html));
  173. } else a.html = n.parse();
  174. (this._refresh = !0), this.triggerEvent("parse", a.html);
  175. } else if (t.constructor == Array) {
  176. if (t.length && "Parser" != t[0].PoweredBy) {
  177. var o = new Parser("", this.data);
  178. !(function t(e) {
  179. for (var i, s = 0; (i = e[s]); s++)
  180. if ("text" != i.type) {
  181. i.attrs = i.attrs || {};
  182. for (var a in i.attrs)
  183. "string" != typeof i.attrs[a] &&
  184. (i.attrs[a] = i.attrs[a].toString());
  185. o.matchAttr(i),
  186. i.children &&
  187. (o.STACK.push(i),
  188. t(i.children),
  189. o.popNode(o.STACK.pop()));
  190. }
  191. })(t),
  192. (a.html = t);
  193. }
  194. i || (a.html = t);
  195. } else {
  196. if ("object" != (void 0 === t ? "undefined" : _typeof(t)) || !t.nodes)
  197. return console.warn(
  198. "错误的 html 类型:" + (void 0 === t ? "undefined" : _typeof(t))
  199. );
  200. (a.html = t.nodes),
  201. console.warn("错误的 html 类型:object 类型已废弃");
  202. }
  203. else {
  204. if (i || e) return;
  205. a.html = "";
  206. }
  207. e
  208. ? ((this._refresh = !0),
  209. (a.html = (this.data.html || []).concat(a.html)))
  210. : this.data.showWithAnimation && (a.showAm = "animation: show .5s"),
  211. (a.html || a.showAm) && this.setData(a),
  212. this.data.html.length &&
  213. this.data.html[0].title &&
  214. this.data.autosetTitle &&
  215. wx.setNavigationBarTitle({ title: this.data.html[0].title }),
  216. (this.imgList.length = 0),
  217. (this.videoContexts = []),
  218. dom && (this.document = new dom(this.data.html, "html", this));
  219. for (
  220. var h, l = this.selectAllComponents(".top,.top>>>._node"), c = 0;
  221. (h = l[c++]);
  222. ) {
  223. h.top = this;
  224. for (var m, f = 0; (m = h.data.nodes[f++]); )
  225. if (!m.c)
  226. if ("img" == m.name) this.imgList.setItem(m.attrs.i, m.attrs.src);
  227. else if ("video" == m.name || "audio" == m.name) {
  228. var u;
  229. (u =
  230. "video" == m.name
  231. ? wx.createVideoContext(m.attrs.id, h)
  232. : h.selectComponent("#" + m.attrs.id)),
  233. u && ((u.id = m.attrs.id), this.videoContexts.push(u));
  234. }
  235. }
  236. (wx.nextTick || setTimeout)(function () {
  237. return s.triggerEvent("load");
  238. }, 50);
  239. var d;
  240. clearInterval(this._timer),
  241. (this._timer = setInterval(function () {
  242. s.createSelectorQuery()
  243. .select(".top")
  244. .boundingClientRect(function (t) {
  245. (s.rect = t),
  246. t.height == d &&
  247. (s.triggerEvent("ready", t), clearInterval(s._timer)),
  248. (d = t.height);
  249. })
  250. .exec();
  251. }, 350));
  252. },
  253. preLoad: function (t, e) {
  254. if ("string" == typeof t) {
  255. var i = hash(t);
  256. (t = new Parser(t, this.data).parse()), (cache[i] = t);
  257. }
  258. var s,
  259. a = [];
  260. !(function t(e) {
  261. for (var i, s = 0; (i = e[s++]); )
  262. "img" == i.name &&
  263. i.attrs.src &&
  264. !a.includes(i.attrs.src) &&
  265. a.push(i.attrs.src),
  266. t(i.children || []);
  267. })(t),
  268. e && (a = a.slice(0, e)),
  269. (this._wait = (this._wait || []).concat(a)),
  270. this.data.imgs
  271. ? this.data.imgs.length < 15 &&
  272. (s = this.data.imgs.concat(
  273. this._wait.splice(0, 15 - this.data.imgs.length)
  274. ))
  275. : (s = this._wait.splice(0, 15)),
  276. s && this.setData({ imgs: s });
  277. },
  278. _load: function (t) {
  279. this._wait.length &&
  280. this.setData(
  281. _defineProperty({}, "imgs[" + t.target.id + "]", this._wait.shift())
  282. );
  283. },
  284. _tap: function (t) {
  285. if (this.data.gestureZoom && t.timeStamp - this._lastT < 300) {
  286. var e = t.detail.y - t.currentTarget.offsetTop;
  287. if (this._zoom)
  288. this._scaleAm.translateX(0).scale(1).step(),
  289. wx.pageScrollTo({
  290. scrollTop: (e + this._initY) / 2 - t.touches[0].clientY,
  291. duration: 400,
  292. });
  293. else {
  294. var i = t.detail.x - t.currentTarget.offsetLeft;
  295. (this._initY = e),
  296. (this._scaleAm = wx.createAnimation({
  297. transformOrigin: i + "px " + this._initY + "px 0",
  298. timingFunction: "ease-in-out",
  299. })),
  300. this._scaleAm.scale(2).step(),
  301. (this._tMax = i / 2),
  302. (this._tMin = (i - this.rect.width) / 2),
  303. (this._tX = 0);
  304. }
  305. (this._zoom = !this._zoom),
  306. this.setData({ scaleAm: this._scaleAm.export() });
  307. }
  308. this._lastT = t.timeStamp;
  309. },
  310. _touchstart: function (t) {
  311. 1 == t.touches.length && (this._initX = this._lastX = t.touches[0].pageX);
  312. },
  313. _touchmove: function (t) {
  314. var e = t.touches[0].pageX - this._lastX;
  315. if (this._zoom && 1 == t.touches.length && Math.abs(e) > 20) {
  316. if (
  317. ((this._lastX = t.touches[0].pageX),
  318. (this._tX <= this._tMin && e < 0) ||
  319. (this._tX >= this._tMax && e > 0))
  320. )
  321. return;
  322. (this._tX += e * Math.abs(this._lastX - this._initX) * 0.05),
  323. this._tX < this._tMin && (this._tX = this._tMin),
  324. this._tX > this._tMax && (this._tX = this._tMax),
  325. this._scaleAm.translateX(this._tX).step(),
  326. this.setData({ scaleAm: this._scaleAm.export() });
  327. }
  328. },
  329. },
  330. });