CommentCoreLibrary

jabbany/CommentCoreLibrary

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/23961/152310/CommentCoreLibrary.js

  1. /**
  2. * Binary Search Stubs for JS Arrays
  3. * @license MIT
  4. * @author Jim Chen
  5. */
  6. var BinArray = (function(){
  7. var BinArray = {};
  8. BinArray.bsearch = function(arr, what, how){
  9. if(arr.length === 0) {
  10. return 0;
  11. }
  12. if(how(what,arr[0]) < 0) {
  13. return 0;
  14. }
  15. if(how(what,arr[arr.length - 1]) >=0) {
  16. return arr.length;
  17. }
  18. var low =0;
  19. var i = 0;
  20. var count = 0;
  21. var high = arr.length - 1;
  22. while(low<=high){
  23. i = Math.floor((high + low + 1)/2);
  24. count++;
  25. if(how(what,arr[i-1])>=0 && how(what,arr[i])<0){
  26. return i;
  27. }
  28. if(how(what,arr[i-1])<0){
  29. high = i-1;
  30. }else if(how(what,arr[i])>=0){
  31. low = i;
  32. }else {
  33. console.error('Program Error');
  34. }
  35. if(count > 1500) { console.error('Too many run cycles.'); }
  36. }
  37. return -1; // Never actually run
  38. };
  39. BinArray.binsert = function(arr, what, how){
  40. var index = BinArray.bsearch(arr,what,how);
  41. arr.splice(index,0,what);
  42. return index;
  43. };
  44. return BinArray;
  45. })();
  46.  
  47. var __extends = (this && this.__extends) || function (d, b) {
  48. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  49. function __() { this.constructor = d; }
  50. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  51. };
  52. var CommentSpaceAllocator = (function () {
  53. function CommentSpaceAllocator(width, height) {
  54. if (width === void 0) { width = 0; }
  55. if (height === void 0) { height = 0; }
  56. this._pools = [
  57. []
  58. ];
  59. this.avoid = 1;
  60. this._width = width;
  61. this._height = height;
  62. }
  63. CommentSpaceAllocator.prototype.willCollide = function (existing, check) {
  64. return existing.stime + existing.ttl >= check.stime + check.ttl / 2;
  65. };
  66. CommentSpaceAllocator.prototype.pathCheck = function (y, comment, pool) {
  67. var bottom = y + comment.height;
  68. var right = comment.right;
  69. for (var i = 0; i < pool.length; i++) {
  70. if (pool[i].y > bottom || pool[i].bottom < y) {
  71. continue;
  72. }
  73. else if (pool[i].right < comment.x || pool[i].x > right) {
  74. if (this.willCollide(pool[i], comment)) {
  75. return false;
  76. }
  77. else {
  78. continue;
  79. }
  80. }
  81. else {
  82. return false;
  83. }
  84. }
  85. return true;
  86. };
  87. CommentSpaceAllocator.prototype.assign = function (comment, cindex) {
  88. while (this._pools.length <= cindex) {
  89. this._pools.push([]);
  90. }
  91. var pool = this._pools[cindex];
  92. if (pool.length === 0) {
  93. comment.cindex = cindex;
  94. return 0;
  95. }
  96. else if (this.pathCheck(0, comment, pool)) {
  97. comment.cindex = cindex;
  98. return 0;
  99. }
  100. var y = 0;
  101. for (var k = 0; k < pool.length; k++) {
  102. y = pool[k].bottom + this.avoid;
  103. if (y + comment.height > this._height) {
  104. break;
  105. }
  106. if (this.pathCheck(y, comment, pool)) {
  107. comment.cindex = cindex;
  108. return y;
  109. }
  110. }
  111. return this.assign(comment, cindex + 1);
  112. };
  113. CommentSpaceAllocator.prototype.add = function (comment) {
  114. if (comment.height > this._height) {
  115. comment.cindex = -2;
  116. comment.y = 0;
  117. }
  118. else {
  119. comment.y = this.assign(comment, 0);
  120. BinArray.binsert(this._pools[comment.cindex], comment, function (a, b) {
  121. if (a.bottom < b.bottom) {
  122. return -1;
  123. }
  124. else if (a.bottom > b.bottom) {
  125. return 1;
  126. }
  127. else {
  128. return 0;
  129. }
  130. });
  131. }
  132. };
  133. CommentSpaceAllocator.prototype.remove = function (comment) {
  134. if (comment.cindex < 0) {
  135. return;
  136. }
  137. if (comment.cindex >= this._pools.length) {
  138. throw new Error("cindex out of bounds");
  139. }
  140. var index = this._pools[comment.cindex].indexOf(comment);
  141. if (index < 0)
  142. return;
  143. this._pools[comment.cindex].splice(index, 1);
  144. };
  145. CommentSpaceAllocator.prototype.setBounds = function (width, height) {
  146. this._width = width;
  147. this._height = height;
  148. };
  149. return CommentSpaceAllocator;
  150. }());
  151. var AnchorCommentSpaceAllocator = (function (_super) {
  152. __extends(AnchorCommentSpaceAllocator, _super);
  153. function AnchorCommentSpaceAllocator() {
  154. _super.apply(this, arguments);
  155. }
  156. AnchorCommentSpaceAllocator.prototype.add = function (comment) {
  157. _super.prototype.add.call(this, comment);
  158. comment.x = (this._width - comment.width) / 2;
  159. };
  160. AnchorCommentSpaceAllocator.prototype.willCollide = function (a, b) {
  161. return true;
  162. };
  163. AnchorCommentSpaceAllocator.prototype.pathCheck = function (y, comment, pool) {
  164. var bottom = y + comment.height;
  165. for (var i = 0; i < pool.length; i++) {
  166. if (pool[i].y > bottom || pool[i].bottom < y) {
  167. continue;
  168. }
  169. else {
  170. return false;
  171. }
  172. }
  173. return true;
  174. };
  175. return AnchorCommentSpaceAllocator;
  176. }(CommentSpaceAllocator));
  177. //# sourceMappingURL=CommentSpaceAllocator.js.map
  178. var __extends = (this && this.__extends) || function (d, b) {
  179. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  180. function __() { this.constructor = d; }
  181. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  182. };
  183. var CoreComment = (function () {
  184. function CoreComment(parent, init) {
  185. if (init === void 0) { init = {}; }
  186. this.mode = 1;
  187. this.stime = 0;
  188. this.text = "";
  189. this.ttl = 4000;
  190. this.dur = 4000;
  191. this.cindex = -1;
  192. this.motion = [];
  193. this.movable = true;
  194. this._alphaMotion = null;
  195. this.absolute = true;
  196. this.align = 0;
  197. this._alpha = 1;
  198. this._size = 25;
  199. this._color = 0xffffff;
  200. this._border = false;
  201. this._shadow = true;
  202. this._font = "";
  203. if (!parent) {
  204. throw new Error("Comment not bound to comment manager.");
  205. }
  206. else {
  207. this.parent = parent;
  208. }
  209. if (init.hasOwnProperty("stime")) {
  210. this.stime = init["stime"];
  211. }
  212. if (init.hasOwnProperty("mode")) {
  213. this.mode = init["mode"];
  214. }
  215. else {
  216. this.mode = 1;
  217. }
  218. if (init.hasOwnProperty("dur")) {
  219. this.dur = init["dur"];
  220. this.ttl = this.dur;
  221. }
  222. this.dur *= this.parent.options.global.scale;
  223. this.ttl *= this.parent.options.global.scale;
  224. if (init.hasOwnProperty("text")) {
  225. this.text = init["text"];
  226. }
  227. if (init.hasOwnProperty("motion")) {
  228. this._motionStart = [];
  229. this._motionEnd = [];
  230. this.motion = init["motion"];
  231. var head = 0;
  232. for (var i = 0; i < init["motion"].length; i++) {
  233. this._motionStart.push(head);
  234. var maxDur = 0;
  235. for (var k in init["motion"][i]) {
  236. var m = init["motion"][i][k];
  237. maxDur = Math.max(m.dur, maxDur);
  238. if (m.easing === null || m.easing === undefined) {
  239. init["motion"][i][k]["easing"] = CoreComment.LINEAR;
  240. }
  241. }
  242. head += maxDur;
  243. this._motionEnd.push(head);
  244. }
  245. this._curMotion = 0;
  246. }
  247. if (init.hasOwnProperty("color")) {
  248. this._color = init["color"];
  249. }
  250. if (init.hasOwnProperty("size")) {
  251. this._size = init["size"];
  252. }
  253. if (init.hasOwnProperty("border")) {
  254. this._border = init["border"];
  255. }
  256. if (init.hasOwnProperty("opacity")) {
  257. this._alpha = init["opacity"];
  258. }
  259. if (init.hasOwnProperty("alpha")) {
  260. this._alphaMotion = init["alpha"];
  261. }
  262. if (init.hasOwnProperty("font")) {
  263. this._font = init["font"];
  264. }
  265. if (init.hasOwnProperty("x")) {
  266. this._x = init["x"];
  267. }
  268. if (init.hasOwnProperty("y")) {
  269. this._y = init["y"];
  270. }
  271. if (init.hasOwnProperty("shadow")) {
  272. this._shadow = init["shadow"];
  273. }
  274. if (init.hasOwnProperty("position")) {
  275. if (init["position"] === "relative") {
  276. this.absolute = false;
  277. if (this.mode < 7) {
  278. console.warn("Using relative position for CSA comment.");
  279. }
  280. }
  281. }
  282. }
  283. CoreComment.prototype.init = function (recycle) {
  284. if (recycle === void 0) { recycle = null; }
  285. if (recycle !== null) {
  286. this.dom = recycle.dom;
  287. }
  288. else {
  289. this.dom = document.createElement("div");
  290. }
  291. this.dom.className = this.parent.options.global.className;
  292. this.dom.appendChild(document.createTextNode(this.text));
  293. this.dom.textContent = this.text;
  294. this.dom.innerText = this.text;
  295. this.size = this._size;
  296. if (this._color != 0xffffff) {
  297. this.color = this._color;
  298. }
  299. this.shadow = this._shadow;
  300. if (this._border) {
  301. this.border = this._border;
  302. }
  303. if (this._font !== "") {
  304. this.font = this._font;
  305. }
  306. if (this._x !== undefined) {
  307. this.x = this._x;
  308. }
  309. if (this._y !== undefined) {
  310. this.y = this._y;
  311. }
  312. if (this._alpha !== 1 || this.parent.options.global.opacity < 1) {
  313. this.alpha = this._alpha;
  314. }
  315. if (this.motion.length > 0) {
  316. this.animate();
  317. }
  318. };
  319. Object.defineProperty(CoreComment.prototype, "x", {
  320. get: function () {
  321. if (this._x === null || this._x === undefined) {
  322. if (this.align % 2 === 0) {
  323. this._x = this.dom.offsetLeft;
  324. }
  325. else {
  326. this._x = this.parent.width - this.dom.offsetLeft - this.width;
  327. }
  328. }
  329. if (!this.absolute) {
  330. return this._x / this.parent.width;
  331. }
  332. return this._x;
  333. },
  334. set: function (x) {
  335. this._x = x;
  336. if (!this.absolute) {
  337. this._x *= this.parent.width;
  338. }
  339. if (this.align % 2 === 0) {
  340. this.dom.style.left = this._x + "px";
  341. }
  342. else {
  343. this.dom.style.right = this._x + "px";
  344. }
  345. },
  346. enumerable: true,
  347. configurable: true
  348. });
  349. Object.defineProperty(CoreComment.prototype, "y", {
  350. get: function () {
  351. if (this._y === null || this._y === undefined) {
  352. if (this.align < 2) {
  353. this._y = this.dom.offsetTop;
  354. }
  355. else {
  356. this._y = this.parent.height - this.dom.offsetTop - this.height;
  357. }
  358. }
  359. if (!this.absolute) {
  360. return this._y / this.parent.height;
  361. }
  362. return this._y;
  363. },
  364. set: function (y) {
  365. this._y = y;
  366. if (!this.absolute) {
  367. this._y *= this.parent.height;
  368. }
  369. if (this.align < 2) {
  370. this.dom.style.top = this._y + "px";
  371. }
  372. else {
  373. this.dom.style.bottom = this._y + "px";
  374. }
  375. },
  376. enumerable: true,
  377. configurable: true
  378. });
  379. Object.defineProperty(CoreComment.prototype, "bottom", {
  380. get: function () {
  381. return this.y + this.height;
  382. },
  383. enumerable: true,
  384. configurable: true
  385. });
  386. Object.defineProperty(CoreComment.prototype, "right", {
  387. get: function () {
  388. return this.x + this.width;
  389. },
  390. enumerable: true,
  391. configurable: true
  392. });
  393. Object.defineProperty(CoreComment.prototype, "width", {
  394. get: function () {
  395. if (this._width === null || this._width === undefined) {
  396. this._width = this.dom.offsetWidth;
  397. }
  398. return this._width;
  399. },
  400. set: function (w) {
  401. this._width = w;
  402. this.dom.style.width = this._width + "px";
  403. },
  404. enumerable: true,
  405. configurable: true
  406. });
  407. Object.defineProperty(CoreComment.prototype, "height", {
  408. get: function () {
  409. if (this._height === null || this._height === undefined) {
  410. this._height = this.dom.offsetHeight;
  411. }
  412. return this._height;
  413. },
  414. set: function (h) {
  415. this._height = h;
  416. this.dom.style.height = this._height + "px";
  417. },
  418. enumerable: true,
  419. configurable: true
  420. });
  421. Object.defineProperty(CoreComment.prototype, "size", {
  422. get: function () {
  423. return this._size;
  424. },
  425. set: function (s) {
  426. this._size = s;
  427. this.dom.style.fontSize = this._size + "px";
  428. },
  429. enumerable: true,
  430. configurable: true
  431. });
  432. Object.defineProperty(CoreComment.prototype, "color", {
  433. get: function () {
  434. return this._color;
  435. },
  436. set: function (c) {
  437. this._color = c;
  438. var color = c.toString(16);
  439. color = color.length >= 6 ? color : new Array(6 - color.length + 1).join("0") + color;
  440. this.dom.style.color = "#" + color;
  441. if (this._color === 0) {
  442. this.dom.className = this.parent.options.global.className + " rshadow";
  443. }
  444. },
  445. enumerable: true,
  446. configurable: true
  447. });
  448. Object.defineProperty(CoreComment.prototype, "alpha", {
  449. get: function () {
  450. return this._alpha;
  451. },
  452. set: function (a) {
  453. this._alpha = a;
  454. this.dom.style.opacity = Math.min(this._alpha, this.parent.options.global.opacity) + "";
  455. },
  456. enumerable: true,
  457. configurable: true
  458. });
  459. Object.defineProperty(CoreComment.prototype, "border", {
  460. get: function () {
  461. return this._border;
  462. },
  463. set: function (b) {
  464. this._border = b;
  465. if (this._border) {
  466. this.dom.style.border = "1px solid #00ffff";
  467. }
  468. else {
  469. this.dom.style.border = "none";
  470. }
  471. },
  472. enumerable: true,
  473. configurable: true
  474. });
  475. Object.defineProperty(CoreComment.prototype, "shadow", {
  476. get: function () {
  477. return this._shadow;
  478. },
  479. set: function (s) {
  480. this._shadow = s;
  481. if (!this._shadow) {
  482. this.dom.className = this.parent.options.global.className + " noshadow";
  483. }
  484. },
  485. enumerable: true,
  486. configurable: true
  487. });
  488. Object.defineProperty(CoreComment.prototype, "font", {
  489. get: function () {
  490. return this._font;
  491. },
  492. set: function (f) {
  493. this._font = f;
  494. if (this._font.length > 0) {
  495. this.dom.style.fontFamily = this._font;
  496. }
  497. else {
  498. this.dom.style.fontFamily = "";
  499. }
  500. },
  501. enumerable: true,
  502. configurable: true
  503. });
  504. CoreComment.prototype.time = function (time) {
  505. this.ttl -= time;
  506. if (this.ttl < 0) {
  507. this.ttl = 0;
  508. }
  509. if (this.movable) {
  510. this.update();
  511. }
  512. if (this.ttl <= 0) {
  513. this.finish();
  514. }
  515. };
  516. CoreComment.prototype.update = function () {
  517. this.animate();
  518. };
  519. CoreComment.prototype.invalidate = function () {
  520. this._x = null;
  521. this._y = null;
  522. this._width = null;
  523. this._height = null;
  524. };
  525. CoreComment.prototype._execMotion = function (currentMotion, time) {
  526. for (var prop in currentMotion) {
  527. if (currentMotion.hasOwnProperty(prop)) {
  528. var m = currentMotion[prop];
  529. this[prop] = m.easing(Math.min(Math.max(time - m.delay, 0), m.dur), m.from, m.to - m.from, m.dur);
  530. }
  531. }
  532. };
  533. CoreComment.prototype.animate = function () {
  534. if (this._alphaMotion) {
  535. this.alpha = (this.dur - this.ttl) * (this._alphaMotion["to"] - this._alphaMotion["from"]) / this.dur + this._alphaMotion["from"];
  536. }
  537. if (this.motion.length === 0) {
  538. return;
  539. }
  540. var ttl = Math.max(this.ttl, 0);
  541. var time = (this.dur - ttl) - this._motionStart[this._curMotion];
  542. this._execMotion(this.motion[this._curMotion], time);
  543. if (this.dur - ttl > this._motionEnd[this._curMotion]) {
  544. this._curMotion++;
  545. if (this._curMotion >= this.motion.length) {
  546. this._curMotion = this.motion.length - 1;
  547. }
  548. return;
  549. }
  550. };
  551. CoreComment.prototype.finish = function () {
  552. this.parent.finish(this);
  553. };
  554. CoreComment.prototype.toString = function () {
  555. return ["[", this.stime, "|", this.ttl, "/", this.dur, "]", "(", this.mode, ")", this.text].join("");
  556. };
  557. CoreComment.LINEAR = function (t, b, c, d) {
  558. return t * c / d + b;
  559. };
  560. return CoreComment;
  561. }());
  562. var ScrollComment = (function (_super) {
  563. __extends(ScrollComment, _super);
  564. function ScrollComment(parent, data) {
  565. _super.call(this, parent, data);
  566. this.dur *= this.parent.options.scroll.scale;
  567. this.ttl *= this.parent.options.scroll.scale;
  568. }
  569. Object.defineProperty(ScrollComment.prototype, "alpha", {
  570. set: function (a) {
  571. this._alpha = a;
  572. this.dom.style.opacity = Math.min(Math.min(this._alpha, this.parent.options.global.opacity), this.parent.options.scroll.opacity) + "";
  573. },
  574. enumerable: true,
  575. configurable: true
  576. });
  577. ScrollComment.prototype.init = function (recycle) {
  578. if (recycle === void 0) { recycle = null; }
  579. _super.prototype.init.call(this, recycle);
  580. this.x = this.parent.width;
  581. if (this.parent.options.scroll.opacity < 1) {
  582. this.alpha = this._alpha;
  583. }
  584. this.absolute = true;
  585. };
  586. ScrollComment.prototype.update = function () {
  587. this.x = (this.ttl / this.dur) * (this.parent.width + this.width) - this.width;
  588. };
  589. return ScrollComment;
  590. }(CoreComment));
  591. //# sourceMappingURL=Comment.js.map
  592. /**
  593. * Comment Filters Module Simplified (only supports modifiers & types)
  594. * @license MIT
  595. * @author Jim Chen
  596. */
  597. function CommentFilter(){
  598. this.modifiers = [];
  599. this.runtime = null;
  600. this.allowTypes = {
  601. "1":true,
  602. "4":true,
  603. "5":true,
  604. "6":true,
  605. "7":true,
  606. "8":true,
  607. "17":true
  608. };
  609. this.doModify = function(cmt){
  610. for(var k=0;k<this.modifiers.length;k++){
  611. cmt = this.modifiers[k](cmt);
  612. }
  613. return cmt;
  614. };
  615. this.beforeSend = function(cmt){
  616. return cmt;
  617. }
  618. this.doValidate = function(cmtData){
  619. if(!this.allowTypes[cmtData.mode])
  620. return false;
  621. return true;
  622. };
  623. this.addRule = function(rule){
  624. };
  625. this.addModifier = function(f){
  626. this.modifiers.push(f);
  627. };
  628. this.runtimeFilter = function(cmt){
  629. if(this.runtime == null)
  630. return cmt;
  631. return this.runtime(cmt);
  632. };
  633. this.setRuntimeFilter = function(f){
  634. this.runtime = f;
  635. }
  636. }
  637.  
  638. /*!
  639. * Comment Core Library CommentManager
  640. * @license MIT
  641. * @author Jim Chen
  642. *
  643. * Copyright (c) 2014 Jim Chen
  644. */
  645. var CommentManager = (function() {
  646. var getRotMatrix = function(yrot, zrot) {
  647. // Courtesy of @StarBrilliant, re-adapted to look better
  648. var DEG2RAD = Math.PI/180;
  649. var yr = yrot * DEG2RAD;
  650. var zr = zrot * DEG2RAD;
  651. var COS = Math.cos;
  652. var SIN = Math.sin;
  653. var matrix = [
  654. COS(yr) * COS(zr) , COS(yr) * SIN(zr) , SIN(yr) , 0,
  655. (-SIN(zr)) , COS(zr) , 0 , 0,
  656. (-SIN(yr) * COS(zr)) , (-SIN(yr) * SIN(zr)) , COS(yr) , 0,
  657. 0 , 0 , 0 , 1
  658. ];
  659. // CSS does not recognize scientific notation (e.g. 1e-6), truncating it.
  660. for(var i = 0; i < matrix.length;i++){
  661. if(Math.abs(matrix[i]) < 0.000001){
  662. matrix[i] = 0;
  663. }
  664. }
  665. return "matrix3d(" + matrix.join(",") + ")";
  666. };
  667.  
  668. function CommentManager(stageObject){
  669. var __timer = 0;
  670. this._listeners = {};
  671. this._lastPosition = 0;
  672. this.stage = stageObject;
  673. this.options = {
  674. global:{
  675. opacity:1,
  676. scale:1,
  677. className:"cmt"
  678. },
  679. scroll:{
  680. opacity:1,
  681. scale:1
  682. },
  683. limit: 0
  684. };
  685. this.timeline = [];
  686. this.runline = [];
  687. this.position = 0;
  688. this.limiter = 0;
  689. this.filter = null;
  690. this.csa = {
  691. scroll: new CommentSpaceAllocator(0,0),
  692. top:new AnchorCommentSpaceAllocator(0,0),
  693. bottom:new AnchorCommentSpaceAllocator(0,0),
  694. reverse:new CommentSpaceAllocator(0,0),
  695. scrollbtm:new CommentSpaceAllocator(0,0)
  696. };
  697. /** Precompute the offset width **/
  698. this.width = this.stage.offsetWidth;
  699. this.height = this.stage.offsetHeight;
  700. this.startTimer = function(){
  701. if(__timer > 0)
  702. return;
  703. var lastTPos = new Date().getTime();
  704. var cmMgr = this;
  705. __timer = window.setInterval(function(){
  706. var elapsed = new Date().getTime() - lastTPos;
  707. lastTPos = new Date().getTime();
  708. cmMgr.onTimerEvent(elapsed,cmMgr);
  709. },10);
  710. };
  711. this.stopTimer = function(){
  712. window.clearInterval(__timer);
  713. __timer = 0;
  714. };
  715. }
  716.  
  717. /** Public **/
  718. CommentManager.prototype.stop = function(){
  719. this.stopTimer();
  720. };
  721.  
  722. CommentManager.prototype.start = function(){
  723. this.startTimer();
  724. };
  725.  
  726. CommentManager.prototype.seek = function(time){
  727. this.position = BinArray.bsearch(this.timeline, time, function(a,b){
  728. if(a < b.stime) return -1
  729. else if(a > b.stime) return 1;
  730. else return 0;
  731. });
  732. };
  733.  
  734. CommentManager.prototype.validate = function(cmt){
  735. if(cmt == null)
  736. return false;
  737. return this.filter.doValidate(cmt);
  738. };
  739.  
  740. CommentManager.prototype.load = function(a){
  741. this.timeline = a;
  742. this.timeline.sort(function(a,b){
  743. if(a.stime > b.stime) return 2;
  744. else if(a.stime < b.stime) return -2;
  745. else{
  746. if(a.date > b.date) return 1;
  747. else if(a.date < b.date) return -1;
  748. else if(a.dbid != null && b.dbid != null){
  749. if(a.dbid > b.dbid) return 1;
  750. else if(a.dbid < b.dbid) return -1;
  751. return 0;
  752. }else
  753. return 0;
  754. }
  755. });
  756. this.dispatchEvent("load");
  757. };
  758.  
  759. CommentManager.prototype.insert = function(c){
  760. var index = BinArray.binsert(this.timeline, c, function(a,b){
  761. if(a.stime > b.stime) return 2;
  762. else if(a.stime < b.stime) return -2;
  763. else{
  764. if(a.date > b.date) return 1;
  765. else if(a.date < b.date) return -1;
  766. else if(a.dbid != null && b.dbid != null){
  767. if(a.dbid > b.dbid) return 1;
  768. else if(a.dbid < b.dbid) return -1;
  769. return 0;
  770. }else
  771. return 0;
  772. }
  773. });
  774. if(index <= this.position){
  775. this.position++;
  776. }
  777. this.dispatchEvent("insert");
  778. };
  779.  
  780. CommentManager.prototype.clear = function(){
  781. while(this.runline.length > 0){
  782. this.runline[0].finish();
  783. }
  784. this.dispatchEvent("clear");
  785. };
  786.  
  787. CommentManager.prototype.setBounds = function(){
  788. this.width = this.stage.offsetWidth;
  789. this.height= this.stage.offsetHeight;
  790. this.dispatchEvent("resize");
  791. for(var comAlloc in this.csa){
  792. this.csa[comAlloc].setBounds(this.width,this.height);
  793. }
  794. // Update 3d perspective
  795. this.stage.style.perspective = this.width * Math.tan(40 * Math.PI/180) / 2 + "px";
  796. this.stage.style.webkitPerspective = this.width * Math.tan(40 * Math.PI/180) / 2 + "px";
  797. };
  798. CommentManager.prototype.init = function(){
  799. this.setBounds();
  800. if(this.filter == null) {
  801. this.filter = new CommentFilter(); //Only create a filter if none exist
  802. }
  803. };
  804. CommentManager.prototype.time = function(time){
  805. time = time - 1;
  806. if(this.position >= this.timeline.length || Math.abs(this._lastPosition - time) >= 2000){
  807. this.seek(time);
  808. this._lastPosition = time;
  809. if(this.timeline.length <= this.position) {
  810. return;
  811. }
  812. }else{
  813. this._lastPosition = time;
  814. }
  815. for(;this.position < this.timeline.length;this.position++){
  816. if(this.timeline[this.position]['stime']<=time){
  817. if(this.options.limit > 0 && this.runline.length > this.limiter) {
  818. continue; // Skip comments but still move the position pointer
  819. } else if(this.validate(this.timeline[this.position])){
  820. this.send(this.timeline[this.position]);
  821. }
  822. }else{
  823. break;
  824. }
  825. }
  826. };
  827. CommentManager.prototype.rescale = function(){
  828. };
  829. CommentManager.prototype.send = function(data){
  830. if(data.mode === 8){
  831. console.log(data);
  832. if(this.scripting){
  833. console.log(this.scripting.eval(data.code));
  834. }
  835. return;
  836. }
  837. if(this.filter != null){
  838. data = this.filter.doModify(data);
  839. if(data == null) return;
  840. }
  841. if(data.mode === 1 || data.mode === 2 || data.mode === 6){
  842. var cmt = new ScrollComment(this, data);
  843. }else{
  844. var cmt = new CoreComment(this, data);
  845. }
  846. switch(cmt.mode){
  847. case 1:cmt.align = 0;break;
  848. case 2:cmt.align = 2;break;
  849. case 4:cmt.align = 2;break;
  850. case 5:cmt.align = 0;break;
  851. case 6:cmt.align = 1;break;
  852. }
  853. cmt.init();
  854. this.stage.appendChild(cmt.dom);
  855. switch(cmt.mode){
  856. default:
  857. case 1:{this.csa.scroll.add(cmt);}break;
  858. case 2:{this.csa.scrollbtm.add(cmt);}break;
  859. case 4:{this.csa.bottom.add(cmt);}break;
  860. case 5:{this.csa.top.add(cmt);}break;
  861. case 6:{this.csa.reverse.add(cmt);}break;
  862. case 17:
  863. case 7:{
  864. if(data.rY !== 0 || data.rZ !== 0){
  865. /** TODO: revise when browser manufacturers make up their mind on Transform APIs **/
  866. cmt.dom.style.transform = getRotMatrix(data.rY, data.rZ);
  867. cmt.dom.style.webkitTransform = getRotMatrix(data.rY, data.rZ);
  868. cmt.dom.style.OTransform = getRotMatrix(data.rY, data.rZ);
  869. cmt.dom.style.MozTransform = getRotMatrix(data.rY, data.rZ);
  870. cmt.dom.style.MSTransform = getRotMatrix(data.rY, data.rZ);
  871. }
  872. }break;
  873. }
  874. cmt.y = cmt.y;
  875. this.dispatchEvent("enterComment", cmt);
  876. this.runline.push(cmt);
  877. };
  878. CommentManager.prototype.sendComment = function(data){
  879. console.log("CommentManager.sendComment is deprecated. Please use send instead");
  880. this.send(data); // Wrapper for Backwards Compatible APIs
  881. };
  882. CommentManager.prototype.finish = function(cmt){
  883. this.dispatchEvent("exitComment", cmt);
  884. this.stage.removeChild(cmt.dom);
  885. var index = this.runline.indexOf(cmt);
  886. if(index >= 0){
  887. this.runline.splice(index, 1);
  888. }
  889. switch(cmt.mode){
  890. default:
  891. case 1:{this.csa.scroll.remove(cmt);}break;
  892. case 2:{this.csa.scrollbtm.remove(cmt);}break;
  893. case 4:{this.csa.bottom.remove(cmt);}break;
  894. case 5:{this.csa.top.remove(cmt);}break;
  895. case 6:{this.csa.reverse.remove(cmt);}break;
  896. case 7:break;
  897. }
  898. };
  899. CommentManager.prototype.addEventListener = function(event, listener){
  900. if(typeof this._listeners[event] !== "undefined"){
  901. this._listeners[event].push(listener);
  902. }else{
  903. this._listeners[event] = [listener];
  904. }
  905. };
  906. CommentManager.prototype.dispatchEvent = function(event, data){
  907. if(typeof this._listeners[event] !== "undefined"){
  908. for(var i = 0; i < this._listeners[event].length; i++){
  909. try{
  910. this._listeners[event][i](data);
  911. }catch(e){
  912. console.err(e.stack);
  913. }
  914. }
  915. }
  916. };
  917. /** Static Functions **/
  918. CommentManager.prototype.onTimerEvent = function(timePassed,cmObj){
  919. for(var i= 0;i < cmObj.runline.length; i++){
  920. var cmt = cmObj.runline[i];
  921. if(cmt.hold){
  922. continue;
  923. }
  924. cmt.time(timePassed);
  925. }
  926. };
  927. return CommentManager;
  928. })();
  929.  
  930. /**
  931. * AcFun Format Parser
  932. * @license MIT License
  933. * An alternative format comment parser
  934. */
  935. function AcfunParser(jsond){
  936. var list = [];
  937. try{
  938. var jsondt = JSON.parse(jsond);
  939. }catch(e){
  940. console.log('Error: Could not parse json list!');
  941. return [];
  942. }
  943. for(var i=0;i<jsondt.length;i++){
  944. //Read each comment and generate a correct comment object
  945. var data = {};
  946. var xc = jsondt[i]['c'].split(',');
  947. if(xc.length > 0){
  948. data.stime = parseFloat(xc[0]) * 1000;
  949. data.color = parseInt(xc[1])
  950. data.mode = parseInt(xc[2]);
  951. data.size = parseInt(xc[3]);
  952. data.hash = xc[4];
  953. data.date = parseInt(xc[5]);
  954. data.position = "absolute";
  955. if(data.mode != 7){
  956. data.text = jsondt[i].m.replace(/(\/n|\\n|\n|\r\n|\\r)/g,"\n");
  957. data.text = data.text.replace(/\r/g,"\n");
  958. data.text = data.text.replace(/\s/g,"\u00a0");
  959. }else{
  960. data.text = jsondt[i].m;
  961. }
  962. if(data.mode == 7){
  963. //High level positioned dm
  964. try{
  965. var x = JSON.parse(data.text);
  966. }catch(e){
  967. console.log('[Err] Error parsing internal data for comment');
  968. console.log('[Dbg] ' + data.text);
  969. continue;
  970. }
  971. data.position = "relative";
  972. data.text = x.n; /*.replace(/\r/g,"\n");*/
  973. data.text = data.text.replace(/\ /g,"\u00a0");
  974. if(x.a != null){
  975. data.opacity = x.a;
  976. }else{
  977. data.opacity = 1;
  978. }
  979. if(x.p != null){
  980. data.x = x.p.x / 1000; // relative position
  981. data.y = x.p.y / 1000;
  982. }else{
  983. data.x = 0;
  984. data.y = 0;
  985. }
  986. data.shadow = x.b;
  987. data.dur = 4000;
  988. if(x.l != null)
  989. data.moveDelay = x.l * 1000;
  990. if(x.z != null && x.z.length > 0){
  991. data.movable = true;
  992. data.motion = [];
  993. var moveDuration = 0;
  994. var last = {x:data.x, y:data.y, alpha:data.opacity, color:data.color};
  995. for(var m = 0; m < x.z.length; m++){
  996. var dur = x.z[m].l != null ? (x.z[m].l * 1000) : 500;
  997. moveDuration += dur;
  998. var motion = {
  999. x:{from:last.x, to:x.z[m].x/1000, dur: dur, delay: 0},
  1000. y:{from:last.y, to:x.z[m].y/1000, dur: dur, delay: 0}
  1001. };
  1002. last.x = motion.x.to;
  1003. last.y = motion.y.to;
  1004. if(x.z[m].t !== last.alpha){
  1005. motion.alpha = {from:last.alpha, to:x.z[m].t, dur: dur, delay: 0};
  1006. last.alpha = motion.alpha.to;
  1007. }
  1008. if(x.z[m].c != null && x.z[m].c !== last.color){
  1009. motion.color = {from:last.color, to:x.z[m].c, dur: dur, delay: 0};
  1010. last.color = motion.color.to;
  1011. }
  1012. data.motion.push(motion);
  1013. }
  1014. data.dur = moveDuration + (data.moveDelay ? data.moveDelay : 0);
  1015. }
  1016. if(x.r != null && x.k != null){
  1017. data.rX = x.r;
  1018. data.rY = x.k;
  1019. }
  1020. }
  1021. list.push(data);
  1022. }
  1023. }
  1024. return list;
  1025. }
  1026.  
  1027. /**
  1028. * Bilibili Format Parser
  1029. * @license MIT License
  1030. * Takes in an XMLDoc/LooseXMLDoc and parses that into a Generic Comment List
  1031. **/
  1032. function BilibiliParser(xmlDoc, text, warn){
  1033. function format(string){
  1034. // Format the comment text to be JSON Valid.
  1035. return string.replace(/\t/,"\\t");
  1036. }
  1037. function formatmode7(text) {
  1038. if (text.charAt(0) == '[') switch (text.charAt(text.length - 1)) {
  1039. case ']':
  1040. return text;
  1041. case '"':
  1042. return text + ']';
  1043. case ',':
  1044. return text.substring(0, text.length - 1) + '"]';
  1045. default:
  1046. return formatmode7(text.substring(0, text.length - 1));
  1047. };
  1048. if (text.charAt(0) !== '[') return text;
  1049. };
  1050. if(xmlDoc !== null){
  1051. var elems = xmlDoc.getElementsByTagName('d');
  1052. }else{
  1053. if(!document || !document.createElement){
  1054. // Maybe we are in a restricted context? Bail.
  1055. return [];
  1056. }
  1057. if(warn){
  1058. if(!confirm("XML Parse Error. \n Allow tag soup parsing?\n[WARNING: This is unsafe.]")){
  1059. return [];
  1060. }
  1061. }else{
  1062. // TODO: Make this safer in the future
  1063. text = text.replace(new RegExp("</([^d])","g"), "</disabled $1");
  1064. text = text.replace(new RegExp("</(\S{2,})","g"), "</disabled $1");
  1065. text = text.replace(new RegExp("<([^d/]\W*?)","g"), "<disabled $1");
  1066. text = text.replace(new RegExp("<([^/ ]{2,}\W*?)","g"), "<disabled $1");
  1067. }
  1068. var tmp = document.createElement("div");
  1069. tmp.innerHTML = text;
  1070. var elems = tmp.getElementsByTagName('d');
  1071. }
  1072. var tlist = [];
  1073. for(var i=0;i < elems.length;i++){
  1074. if(elems[i].getAttribute('p') != null){
  1075. var opt = elems[i].getAttribute('p').split(',');
  1076. if(!elems[i].childNodes[0])
  1077. continue;
  1078. var text = elems[i].childNodes[0].nodeValue;
  1079. var obj = {};
  1080. obj.stime = Math.round(parseFloat(opt[0])*1000);
  1081. obj.size = parseInt(opt[2]);
  1082. obj.color = parseInt(opt[3]);
  1083. obj.mode = parseInt(opt[1]);
  1084. obj.date = parseInt(opt[4]);
  1085. obj.pool = parseInt(opt[5]);
  1086. obj.position = "absolute";
  1087. if(opt[7] != null)
  1088. obj.dbid = parseInt(opt[7]);
  1089. obj.hash = opt[6];
  1090. obj.border = false;
  1091. if(obj.mode < 7){
  1092. obj.text = text.replace(/(\/n|\\n|\n|\r\n)/g, "\n");
  1093. }else{
  1094. if(obj.mode == 7){
  1095. try{
  1096. adv = JSON.parse(format(formatmode7(text)));
  1097. obj.shadow = true;
  1098. obj.x = parseFloat(adv[0]);
  1099. obj.y = parseFloat(adv[1]);
  1100. if(Math.floor(obj.x) < obj.x || Math.floor(obj.y) < obj.y){
  1101. obj.position = "relative";
  1102. }
  1103. obj.text = adv[4].replace(/(\/n|\\n|\n|\r\n)/g, "\n");
  1104. obj.rZ = 0;
  1105. obj.rY = 0;
  1106. if(adv.length >= 7){
  1107. obj.rZ = parseInt(adv[5], 10);
  1108. obj.rY = parseInt(adv[6], 10);
  1109. }
  1110. obj.motion = [];
  1111. obj.movable = false;
  1112. if(adv.length >= 11){
  1113. obj.movable = true;
  1114. var singleStepDur = 500;
  1115. var motion = {
  1116. x:{from: obj.x, to:parseFloat(adv[7]), dur:singleStepDur, delay:0},
  1117. y:{from: obj.y, to:parseFloat(adv[8]), dur:singleStepDur, delay:0},
  1118. };
  1119. if(adv[9] !== ''){
  1120. singleStepDur = parseInt(adv[9], 10);
  1121. motion.x.dur = singleStepDur;
  1122. motion.y.dur = singleStepDur;
  1123. }
  1124. if(adv[10] !== ''){
  1125. motion.x.delay = parseInt(adv[10], 10);
  1126. motion.y.delay = parseInt(adv[10], 10);
  1127. }
  1128. if(adv.length > 11){
  1129. obj.shadow = adv[11];
  1130. if(obj.shadow === "true"){
  1131. obj.shadow = true;
  1132. }
  1133. if(obj.shadow === "false"){
  1134. obj.shadow = false;
  1135. }
  1136. if(adv[12] != null){
  1137. obj.font = adv[12];
  1138. }
  1139. if(adv.length > 14){
  1140. // Support for Bilibili Advanced Paths
  1141. if(obj.position === "relative"){
  1142. console.log("Cannot mix relative and absolute positioning");
  1143. obj.position = "absolute";
  1144. }
  1145. var path = adv[14];
  1146. var lastPoint = {x:motion.x.from, y:motion.y.from};
  1147. var pathMotion = [];
  1148. var regex = new RegExp("([a-zA-Z])\\s*(\\d+)[, ](\\d+)","g");
  1149. var counts = path.split(/[a-zA-Z]/).length - 1;
  1150. var m = regex.exec(path);
  1151. while(m !== null){
  1152. switch(m[1]){
  1153. case "M":{
  1154. lastPoint.x = parseInt(m[2],10);
  1155. lastPoint.y = parseInt(m[3],10);
  1156. }break;
  1157. case "L":{
  1158. pathMotion.push({
  1159. "x":{"from":lastPoint.x, "to":parseInt(m[2],10), "dur": singleStepDur / counts, "delay": 0},
  1160. "y":{"from":lastPoint.y, "to":parseInt(m[3],10), "dur": singleStepDur / counts, "delay": 0}
  1161. });
  1162. lastPoint.x = parseInt(m[2],10);
  1163. lastPoint.y = parseInt(m[3],10);
  1164. }break;
  1165. }
  1166. m = regex.exec(path);
  1167. }
  1168. motion = null;
  1169. obj.motion = pathMotion;
  1170. }
  1171. }
  1172. if(motion !== null){
  1173. obj.motion.push(motion);
  1174. }
  1175. }
  1176. obj.dur = 2500;
  1177. if(adv[3] < 12){
  1178. obj.dur = adv[3] * 1000;
  1179. }
  1180. var tmp = adv[2].split('-');
  1181. if(tmp != null && tmp.length>1){
  1182. var alphaFrom = parseFloat(tmp[0]);
  1183. var alphaTo = parseFloat(tmp[1]);
  1184. obj.opacity = alphaFrom;
  1185. if(alphaFrom !== alphaTo){
  1186. obj.alpha = {from:alphaFrom, to:alphaTo}
  1187. }
  1188. }
  1189. }catch(e){
  1190. console.log('[Err] Error occurred in JSON parsing');
  1191. console.log('[Dbg] ' + text);
  1192. }
  1193. }else if(obj.mode == 8){
  1194. obj.code = text; //Code comments are special
  1195. }
  1196. }
  1197. if(obj.text != null)
  1198. obj.text = obj.text.replace(/\u25a0/g,"\u2588");
  1199. tlist.push(obj);
  1200. }
  1201. }
  1202. return tlist;
  1203. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址