index.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. 'use strict';
  2. var htmlparser = require('htmlparser2');
  3. var isObject = require('isobject');
  4. /**
  5. * @see https://github.com/fb55/htmlparser2/wiki/Parser-options
  6. */
  7. var defaultOptions = {lowerCaseTags: false, lowerCaseAttributeNames: false};
  8. /**
  9. * Parse html to PostHTMLTree
  10. * @param {String} html
  11. * @param {Object} [options=defaultOptions]
  12. * @return {PostHTMLTree}
  13. */
  14. function postHTMLParser(html, options) {
  15. var bufArray = [],
  16. results = [];
  17. bufArray.last = function() {
  18. return this[this.length - 1];
  19. };
  20. var parser = new htmlparser.Parser({
  21. onprocessinginstruction: function(name, data) {
  22. if (name.toLowerCase() === '!doctype') {
  23. results.push('<' + data + '>');
  24. }
  25. },
  26. oncomment: function(data) {
  27. var comment = '<!--' + data + '-->',
  28. last = bufArray.last();
  29. if (!last) {
  30. results.push(comment);
  31. return;
  32. }
  33. last.content || (last.content = []);
  34. last.content.push(comment);
  35. },
  36. onopentag: function(tag, attrs) {
  37. var buf = { tag: tag };
  38. if (Object.keys(attrs).length) {
  39. buf.attrs = attrs;
  40. }
  41. bufArray.push(buf);
  42. },
  43. onclosetag: function() {
  44. var buf = bufArray.pop();
  45. if (!bufArray.length) {
  46. results.push(buf);
  47. return;
  48. }
  49. var last = bufArray.last();
  50. if (!Array.isArray(last.content)) {
  51. last.content = [];
  52. }
  53. last.content.push(buf);
  54. },
  55. ontext: function(text) {
  56. var last = bufArray.last();
  57. if (!last) {
  58. results.push(text);
  59. return;
  60. }
  61. last.content || (last.content = []);
  62. last.content.push(text);
  63. }
  64. }, options || defaultOptions);
  65. parser.write(html);
  66. parser.end();
  67. return results;
  68. }
  69. function parserWrapper() {
  70. var option;
  71. function parser(html) {
  72. var opt = option || defaultOptions;
  73. return postHTMLParser(html, opt);
  74. }
  75. if (arguments.length === 1 && isObject(arguments[0])) {
  76. option = arguments[0];
  77. return parser;
  78. }
  79. option = arguments[1];
  80. return parser(arguments[0]);
  81. }
  82. module.exports = parserWrapper;
  83. module.exports.defaultOptions = defaultOptions;