CssHandler.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // eslint-disable
  2. const cfg = require('./config.js'),
  3. isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
  4. function CssHandler(tagStyle) {
  5. var styles = Object.assign(Object.create(null), cfg.userAgentStyles);
  6. for (var item in tagStyle)
  7. styles[item] = (styles[item] ? styles[item] + ';' : '') + tagStyle[item];
  8. this.styles = styles;
  9. }
  10. CssHandler.prototype.getStyle = function(data) {
  11. this.styles = new parser(data, this.styles).parse();
  12. };
  13. CssHandler.prototype.match = function(name, attrs) {
  14. var tmp, matched = (tmp = this.styles[name]) ? tmp + ';' : '';
  15. if (attrs.class) {
  16. var items = attrs.class.split(' ');
  17. for (var i = 0, item; item = items[i]; i++)
  18. if (tmp = this.styles['.' + item])
  19. matched += tmp + ';';
  20. }
  21. if (tmp = this.styles['#' + attrs.id])
  22. matched += tmp + ';';
  23. return matched;
  24. };
  25. module.exports = CssHandler;
  26. function parser(data, init) {
  27. this.data = data;
  28. this.floor = 0;
  29. this.i = 0;
  30. this.list = [];
  31. this.res = init;
  32. this.state = this.Space;
  33. }
  34. parser.prototype.parse = function() {
  35. for (var c; c = this.data[this.i]; this.i++)
  36. this.state(c);
  37. return this.res;
  38. };
  39. parser.prototype.section = function() {
  40. return this.data.substring(this.start, this.i);
  41. };
  42. // 状态机
  43. parser.prototype.Space = function(c) {
  44. if (c == '.' || c == '#' || isLetter(c)) {
  45. this.start = this.i;
  46. this.state = this.Name;
  47. } else if (c == '/' && this.data[this.i + 1] == '*')
  48. this.Comment();
  49. else if (!cfg.blankChar[c] && c != ';')
  50. this.state = this.Ignore;
  51. };
  52. parser.prototype.Comment = function() {
  53. this.i = this.data.indexOf('*/', this.i) + 1;
  54. if (!this.i) this.i = this.data.length;
  55. this.state = this.Space;
  56. };
  57. parser.prototype.Ignore = function(c) {
  58. if (c == '{') this.floor++;
  59. else if (c == '}' && !--this.floor) this.state = this.Space;
  60. };
  61. parser.prototype.Name = function(c) {
  62. if (cfg.blankChar[c]) {
  63. this.list.push(this.section());
  64. this.state = this.NameSpace;
  65. } else if (c == '{') {
  66. this.list.push(this.section());
  67. this.Content();
  68. } else if (c == ',') {
  69. this.list.push(this.section());
  70. this.Comma();
  71. } else if (!isLetter(c) && (c < '0' || c > '9') && c != '-' && c != '_')
  72. this.state = this.Ignore;
  73. };
  74. parser.prototype.NameSpace = function(c) {
  75. if (c == '{') this.Content();
  76. else if (c == ',') this.Comma();
  77. else if (!cfg.blankChar[c]) this.state = this.Ignore;
  78. };
  79. parser.prototype.Comma = function() {
  80. while (cfg.blankChar[this.data[++this.i]]) ;
  81. if (this.data[this.i] == '{') this.Content();
  82. else {
  83. this.start = this.i--;
  84. this.state = this.Name;
  85. }
  86. };
  87. parser.prototype.Content = function() {
  88. this.start = ++this.i;
  89. if ((this.i = this.data.indexOf('}', this.i)) == -1) this.i = this.data.length;
  90. var content = this.section();
  91. for (var i = 0, item; item = this.list[i++];)
  92. if (this.res[item]) this.res[item] += ';' + content;
  93. else this.res[item] = content;
  94. this.list = [];
  95. this.state = this.Space;
  96. };