edit_diff.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import htmlparser from 'htmlparser2';
  2. import { escapeFormatting } from './functions.js';
  3. /**
  4. * Change edit diffs to markdown text.
  5. * @param {String} html - The edit diff in HTML.
  6. * @param {String} more - The localized string for more content.
  7. * @param {String} whitespace - The localized string for only whitespace.
  8. * @returns {[String, String]}
  9. */
  10. export default function diffParser(html, more, whitespace) {
  11. var current_tag = '';
  12. var last_ins = null;
  13. var last_del = null;
  14. var empty = false;
  15. var small_prev_ins = '';
  16. var small_prev_del = '';
  17. var ins_length = more.length;
  18. var del_length = more.length;
  19. var parser = new htmlparser.Parser( {
  20. onopentag: (tagname, attribs) => {
  21. if ( tagname === 'ins' || tagname == 'del' ) current_tag = tagname;
  22. if ( tagname === 'td' ) {
  23. let classes = ( attribs.class?.split(' ') || [] );
  24. if ( classes.includes( 'diff-addedline' ) && ins_length <= 1000 ) {
  25. current_tag = 'tda';
  26. last_ins = '';
  27. }
  28. if ( classes.includes( 'diff-deletedline' ) && del_length <= 1000 ) {
  29. current_tag = 'tdd';
  30. last_del = '';
  31. }
  32. if ( classes.includes( 'diff-empty' ) ) empty = true;
  33. }
  34. },
  35. ontext: (htmltext) => {
  36. if ( current_tag === 'ins' && ins_length <= 1000 ) {
  37. ins_length += ( '**' + escapeFormatting(htmltext) + '**' ).length;
  38. if ( ins_length <= 1000 ) last_ins += '**' + escapeFormatting(htmltext) + '**';
  39. }
  40. if ( current_tag === 'del' && del_length <= 1000 ) {
  41. del_length += ( '~~' + escapeFormatting(htmltext) + '~~' ).length;
  42. if ( del_length <= 1000 ) last_del += '~~' + escapeFormatting(htmltext) + '~~';
  43. }
  44. if ( current_tag === 'tda' && ins_length <= 1000 ) {
  45. ins_length += escapeFormatting(htmltext).length;
  46. if ( ins_length <= 1000 ) last_ins += escapeFormatting(htmltext);
  47. }
  48. if ( current_tag === 'tdd' && del_length <= 1000 ) {
  49. del_length += escapeFormatting(htmltext).length;
  50. if ( del_length <= 1000 ) last_del += escapeFormatting(htmltext);
  51. }
  52. },
  53. onclosetag: (tagname) => {
  54. if ( tagname === 'ins' ) current_tag = 'tda';
  55. if ( tagname === 'del' ) current_tag = 'tdd';
  56. if ( tagname === 'td' ) current_tag = '';
  57. if ( tagname === 'tr' ) {
  58. if ( last_ins !== null ) {
  59. ins_length++;
  60. if ( empty && last_ins.trim().length ) {
  61. if ( last_ins.includes( '**' ) ) last_ins = last_ins.replace( /\*\*/g, '__' );
  62. ins_length += 4;
  63. last_ins = '**' + last_ins + '**';
  64. }
  65. small_prev_ins += '\n' + last_ins;
  66. if ( ins_length > 1000 ) small_prev_ins += more;
  67. last_ins = null;
  68. }
  69. if ( last_del !== null ) {
  70. del_length++;
  71. if ( empty && last_del.trim().length ) {
  72. if ( last_del.includes( '~~' ) ) last_del = last_del.replace( /\~\~/g, '__' );
  73. del_length += 4;
  74. last_del = '~~' + last_del + '~~';
  75. }
  76. small_prev_del += '\n' + last_del;
  77. if ( del_length > 1000 ) small_prev_del += more;
  78. last_del = null;
  79. }
  80. empty = false;
  81. }
  82. }
  83. } );
  84. parser.write( html );
  85. parser.end();
  86. var compare = ['', ''];
  87. if ( small_prev_del.length ) {
  88. if ( small_prev_del.replace( /\~\~|__/g, '' ).trim().length ) {
  89. compare[0] = small_prev_del.replace( /\~\~\~\~|____/g, '' );
  90. } else compare[0] = whitespace;
  91. }
  92. if ( small_prev_ins.length ) {
  93. if ( small_prev_ins.replace( /\*\*|__/g, '' ).trim().length ) {
  94. compare[1] = small_prev_ins.replace( /\*\*\*\*|____/g, '' );
  95. } else compare[1] = whitespace;
  96. }
  97. return compare;
  98. }