encode.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. 'use strict';
  2. var punycode = require('punycode/');
  3. var $decode = punycode.ucs2.decode;
  4. var $encode = punycode.ucs2.encode;
  5. var $TypeError = require('es-errors/type');
  6. var regexTest = require('safe-regex-test');
  7. var revEntities = require('./reversed.json');
  8. var endsInSemicolon = regexTest(/;$/);
  9. var defaultSpecial = {
  10. '"': true,
  11. "'": true,
  12. '<': true,
  13. '>': true,
  14. '&': true
  15. };
  16. module.exports = function encode(str, opts) {
  17. if (typeof str !== 'string') {
  18. throw new $TypeError('Expected a String');
  19. }
  20. var numeric = !opts || !opts.named;
  21. if (opts && typeof opts.numeric !== 'undefined') { numeric = opts.numeric; }
  22. var special = (opts && opts.special) || defaultSpecial;
  23. var codePoints = $decode(str);
  24. var chars = [];
  25. for (var i = 0; i < codePoints.length; i++) {
  26. var cc = codePoints[i];
  27. var c = $encode([cc]);
  28. var e = revEntities[cc];
  29. if (e && (cc >= 127 || special[c]) && !numeric) {
  30. var hasSemi = endsInSemicolon(e);
  31. chars[chars.length] = '&' + (hasSemi ? e : e + ';');
  32. } else if (cc < 32 || cc >= 127 || special[c]) {
  33. chars[chars.length] = '&#' + cc + ';';
  34. } else {
  35. chars[chars.length] = c;
  36. }
  37. }
  38. return chars.join('');
  39. };