Skip to content

Commit 848161b

Browse files
committed
0 parents  commit 848161b

File tree

11 files changed

+666
-0
lines changed

11 files changed

+666
-0
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
trim_trailing_whitespace = true
7+
charset = utf-8
8+
indent_style = space
9+
indent_size = 2

.eslintrc.json

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
{
2+
"root": true,
3+
"env": {
4+
"node": true,
5+
"es6": true
6+
},
7+
"parserOptions": {
8+
"ecmaVersion": 6
9+
},
10+
"rules": {
11+
// Possible errors
12+
"comma-dangle": ["error", "never"],
13+
"no-cond-assign": ["error", "except-parens"],
14+
"no-console": "error",
15+
"no-constant-condition": "off",
16+
"no-control-regex": "off",
17+
"no-debugger": "error",
18+
"no-dupe-args": "error",
19+
"no-dupe-keys": "error",
20+
"no-duplicate-case": "error",
21+
"no-empty": "error",
22+
"no-empty-character-class": "error",
23+
"no-ex-assign": "error",
24+
"no-extra-boolean-cast": "error",
25+
"no-extra-parens": ["error", "all", { "conditionalAssign": false, "nestedBinaryExpressions": false, "returnAssign": false }],
26+
"no-extra-semi": "error",
27+
"no-func-assign": "error",
28+
"no-inner-declarations": "off",
29+
"no-invalid-regexp": "error",
30+
"no-irregular-whitespace": "error",
31+
"no-negated-in-lhs": "error",
32+
"no-obj-calls": "error",
33+
"no-regex-spaces": "error",
34+
"no-sparse-arrays": "error",
35+
"no-unexpected-multiline": "error",
36+
"no-unreachable": "error",
37+
"no-unsafe-finally": "off",
38+
"use-isnan": "error",
39+
"valid-jsdoc": "off",
40+
"valid-typeof": "error",
41+
42+
// Best practices
43+
"accessor-pairs": "error",
44+
"array-callback-return": "error",
45+
"block-scoped-var": "off",
46+
"complexity": "off",
47+
"consistent-return": "error",
48+
"curly": ["error", "all"],
49+
"default-case": "off",
50+
"dot-location": ["error", "property"],
51+
"dot-notation": "error",
52+
"eqeqeq": "error",
53+
"guard-for-in": "off",
54+
"no-alert": "error",
55+
"no-caller": "error",
56+
"no-case-declarations": "error",
57+
"no-div-regex": "off",
58+
"no-else-return": "error",
59+
"no-empty-function": "error",
60+
"no-empty-pattern": "error",
61+
"no-eq-null": "error",
62+
"no-eval": "error",
63+
"no-extend-native": "error",
64+
"no-extra-bind": "error",
65+
"no-extra-label": "error",
66+
"no-fallthrough": "error",
67+
"no-floating-decimal": "error",
68+
"no-implicit-coercion": "error",
69+
"no-implicit-globals": "error",
70+
"no-implied-eval": "error",
71+
"no-invalid-this": "error",
72+
"no-iterator": "error",
73+
"no-labels": ["error", { "allowLoop": true }],
74+
"no-lone-blocks": "error",
75+
"no-loop-func": "off",
76+
"no-magic-numbers": "off",
77+
"no-multi-spaces": "error",
78+
"no-multi-str": "error",
79+
"no-native-reassign": "error",
80+
"no-new": "error",
81+
"no-new-func": "error",
82+
"no-new-wrappers": "error",
83+
"no-octal": "error",
84+
"no-octal-escape": "error",
85+
"no-param-reassign": "off",
86+
"no-process-env": "error",
87+
"no-proto": "error",
88+
"no-redeclare": "error",
89+
"no-return-assign": ["error", "except-parens"],
90+
"no-script-url": "off",
91+
"no-self-assign": "error",
92+
"no-self-compare": "error",
93+
"no-sequences": "error",
94+
"no-throw-literal": "error",
95+
"no-unmodified-loop-condition": "error",
96+
"no-unused-expressions": "error",
97+
"no-unused-labels": "error",
98+
"no-useless-call": "error",
99+
"no-useless-concat": "error",
100+
"no-useless-escape": "error",
101+
"no-void": "error",
102+
"no-warning-comments": "off",
103+
"no-with": "error",
104+
"radix": ["error", "as-needed"],
105+
"vars-on-top": "off",
106+
"wrap-iife": ["error", "outside"],
107+
"yoda": ["error", "never"],
108+
109+
// Strict Mode
110+
"strict": ["error", "global"],
111+
112+
// Variables
113+
"init-declarations": "off",
114+
"no-catch-shadow": "error",
115+
"no-delete-var": "error",
116+
"no-label-var": "error",
117+
"no-restricted-globals": "off",
118+
"no-shadow": "error",
119+
"no-shadow-restricted-names": "error",
120+
"no-undef": "error",
121+
"no-undef-init": "error",
122+
"no-undefined": "off",
123+
"no-unused-vars": "error",
124+
"no-use-before-define": ["error", "nofunc"],
125+
126+
// Node.js and CommonJS
127+
"callback-return": "off",
128+
"global-require": "error",
129+
"handle-callback-err": "error",
130+
"no-mixed-requires": ["error", true],
131+
"no-new-require": "error",
132+
"no-path-concat": "error",
133+
"no-process-exit": "error",
134+
"no-restricted-imports": "off",
135+
"no-restricted-modules": "off",
136+
"no-sync": "off",
137+
138+
// Stylistic Issues
139+
"array-bracket-spacing": ["error", "never"],
140+
"block-spacing": ["error", "always"],
141+
"brace-style": ["error", "1tbs", { "allowSingleLine": false }],
142+
"camelcase": ["error", { "properties": "always" }],
143+
"comma-spacing": ["error", { "before": false, "after": true }],
144+
"comma-style": ["error", "last"],
145+
"computed-property-spacing": ["error", "never"],
146+
"consistent-this": "off",
147+
"eol-last": "error",
148+
"func-names": "off",
149+
"func-style": ["error", "declaration"],
150+
"id-blacklist": "off",
151+
"id-length": "off",
152+
"id-match": "off",
153+
"indent": ["error", 2, { "SwitchCase": 1 }],
154+
"jsx-quotes": "off",
155+
"key-spacing": ["error", { "beforeColon": false, "afterColon": true, "mode": "strict" }],
156+
"keyword-spacing": ["error", { "before": true, "after": true }],
157+
"linebreak-style": ["error", "unix"],
158+
"lines-around-comment": "off",
159+
"max-depth": "off",
160+
"max-len": ["error", 120, { "ignoreUrls": true }],
161+
"max-nested-callbacks": "off",
162+
"max-params": "off",
163+
"max-statements": "off",
164+
"max-statements-per-line": ["error", { "max": 1 }],
165+
"new-cap": ["error", { "capIsNewExceptions": ["USVString"] }],
166+
"new-parens": "error",
167+
"newline-after-var": "off",
168+
"newline-before-return": "off",
169+
"newline-per-chained-call": "off",
170+
"no-array-constructor": "error",
171+
"no-bitwise": "off",
172+
"no-continue": "off",
173+
"no-inline-comments": "off",
174+
"no-lonely-if": "error",
175+
"no-mixed-spaces-and-tabs": "error",
176+
"no-multiple-empty-lines": "error",
177+
"no-negated-condition": "off",
178+
"no-nested-ternary": "error",
179+
"no-new-object": "error",
180+
"no-plusplus": "off",
181+
"no-restricted-syntax": "off",
182+
"no-spaced-func": "error",
183+
"no-ternary": "off",
184+
"no-trailing-spaces": "error",
185+
"no-underscore-dangle": "off",
186+
"no-unneeded-ternary": "error",
187+
"no-whitespace-before-property": "error",
188+
"object-curly-spacing": ["error", "always"],
189+
"object-property-newline": "off",
190+
"one-var": ["error", "never"],
191+
"one-var-declaration-per-line": ["error", "initializations"],
192+
"operator-assignment": ["error", "always"],
193+
"operator-linebreak": ["error", "after"],
194+
"padded-blocks": ["error", "never"],
195+
"quote-props": ["error", "as-needed"],
196+
"quotes": ["error", "double", { "avoidEscape": true, "allowTemplateLiterals": true }],
197+
"require-jsdoc": "off",
198+
"semi": ["error", "always"],
199+
"semi-spacing": "error",
200+
"sort-imports": "off",
201+
"sort-vars": "off",
202+
"space-before-blocks": ["error", "always"],
203+
"space-before-function-paren": ["error", { "anonymous": "always", "named": "never" }],
204+
"space-in-parens": ["error", "never"],
205+
"space-infix-ops": "error",
206+
"space-unary-ops": ["error", { "words": true, "nonwords": false }],
207+
"spaced-comment": ["error", "always", { "markers": ["///"] }],
208+
"wrap-regex": "off",
209+
210+
// ECMAScript 6
211+
"arrow-body-style": "off", // meh
212+
"arrow-parens": ["error", "as-needed"],
213+
"arrow-spacing": "error",
214+
"constructor-super": "error",
215+
"generator-star-spacing": ["error", "after"],
216+
"no-class-assign": "error",
217+
"no-confusing-arrow": "off",
218+
"no-const-assign": "error",
219+
"no-dupe-class-members": "error",
220+
"no-duplicate-imports": "error",
221+
"no-new-symbol": "error",
222+
"no-this-before-super": "error",
223+
"no-useless-computed-key": "error",
224+
"no-useless-constructor": "error",
225+
"no-var": "error",
226+
"object-shorthand": "error",
227+
"prefer-arrow-callback": "error",
228+
"prefer-const": ["error", { "ignoreReadBeforeAssign": true }],
229+
"prefer-reflect": "off",
230+
"prefer-rest-params": "off",
231+
"prefer-spread": "off", // TODO with new Node versions
232+
"prefer-template": "off",
233+
"require-yield": "error",
234+
"template-curly-spacing": ["error", "never"],
235+
"yield-star-spacing": ["error", "after"]
236+
}
237+
}

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/node_modules/
2+
/npm-debug.log
3+
4+
/lib/*.json

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
language: node_js
2+
node_js:
3+
- stable
4+
script:
5+
npm run lint && npm test

LICENSE.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright © 2016 Domenic Denicola <[email protected]>
2+
3+
This work is free. You can redistribute it and/or modify it under the
4+
terms of the Do What The Fuck You Want To Public License, Version 2,
5+
as published by Sam Hocevar. See below for more details.
6+
7+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
8+
Version 2, December 2004
9+
10+
Copyright (C) 2004 Sam Hocevar <[email protected]>
11+
12+
Everyone is permitted to copy and distribute verbatim or modified
13+
copies of this license document, and changing it is allowed as long
14+
as the name is changed.
15+
16+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
17+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
18+
19+
0. You just DO WHAT THE FUCK YOU WANT TO.

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Decode According to the WHATWG Encoding Standard
2+
3+
This package provides a thin layer on top of [iconv-lite](https://github.com/ashtuchkin/iconv-lite) which makes it expose some of the same primitives as the [Encoding Standard](https://encoding.spec.whatwg.org/).
4+
5+
```js
6+
const whatwgEncoding = require("whatwg-encoding");
7+
8+
console.assert(whatwgEncoding.labelToName("latin1") === "windows-1252");
9+
console.assert(whatwgEncoding.labelToName(" CYRILLic ") === "ISO-8859-5");
10+
11+
console.assert(whatwgEncoding.isSupported("IBM866") === true);
12+
13+
// Not supported by the Encoding Standard
14+
console.assert(whatwgEncoding.isSupported("UTF-32") === false);
15+
16+
// In the Encoding Standard, but this package can't decode it
17+
console.assert(whatwgEncoding.isSupported("x-mac-cyrillic") === false);
18+
19+
console.assert(whatwgEncoding.getBOMEncoding(new Buffer([0xFE, 0xFF])) === "UTF-16BE");
20+
console.assert(whatwgEncoding.getBOMEncoding(new Buffer([0x48, 0x69])) === null);
21+
22+
console.assert(whatwgEncoding.decode(new Buffer([0x48, 0x69]), "UTF-8") === "Hi");
23+
```
24+
25+
## API
26+
27+
- `decode(buffer, fallbackEncodingName)`: performs the [decode](https://encoding.spec.whatwg.org/#decode) algorithm (in which any BOM will override the passed fallback encoding), and returns the resulting string
28+
- `labelToName(label)`: performs the [get an encoding](https://encoding.spec.whatwg.org/#concept-encoding-get) algorithm and returns the resulting encoding's name, or `null` for failure
29+
- `isSupported(name)`: returns whether the encoding is one of [the encodings](https://encoding.spec.whatwg.org/#names-and-labels) of the Encoding Standard, _and_ is an encoding that this package can decode (via iconv-lite)
30+
- `getBOMEncoding(buffer)`: sniffs the first 2–3 bytes of the supplied `Buffer`, returning one of the encoding names `"UTF-8"`, `"UTF-16LE"`, or `"UTF-16BE"` if the appropriate BOM is present, or `null` if no BOM is present
31+
32+
## Unsupported encodings
33+
34+
Since we rely on iconv-lite, we are limited to support only the encodings that they support. Currently we are missing support for:
35+
36+
- ISO-2022-JP
37+
- ISO-8859-8-I
38+
- replacement
39+
- x-mac-cyrillic
40+
- x-user-defined
41+
42+
Passing these encoding names will return `false` when calling `isSupported`, and passing any of the possible labels for these encodings to `labelToName` will return `null`.
43+
44+
## Credits
45+
46+
This package was originally based on the excellent work of [@nicolashenry](https://github.com/nicolashenry), [in jsdom](https://github.com/tmpvar/jsdom/blob/7ce11776ce161e8d5921a7a183585327400f786b/lib/jsdom/living/helpers/encoding.js). It has since been pulled out into this separate package.
47+
48+
## Alternatives
49+
50+
If you are looking for a JavaScript implementation of the Encoding Standard's `TextEncoder` and `TextDecoder` APIs, you'll want [@inexorabletash](https://github.com/inexorabletash)'s [text-encoding](https://github.com/inexorabletash/text-encoding) package.

lib/whatwg-encoding.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"use strict";
2+
const iconvLite = require("iconv-lite");
3+
const supportedNames = require("./supported-names.json");
4+
const labelsToNames = require("./labels-to-names.json");
5+
6+
const supportedNamesSet = new Set(supportedNames);
7+
8+
// https://encoding.spec.whatwg.org/#concept-encoding-get
9+
exports.labelToName = label => {
10+
label = label.trim().toLowerCase();
11+
12+
return labelsToNames[label] || null;
13+
};
14+
15+
// https://encoding.spec.whatwg.org/#decode
16+
exports.decode = (buffer, fallbackEncodingName) => {
17+
let encoding = fallbackEncodingName;
18+
if (!exports.isSupported(encoding)) {
19+
throw new RangeError(`"${encoding}" is not a supported encoding name`);
20+
}
21+
22+
const bomEncoding = exports.getBOMEncoding(buffer);
23+
if (bomEncoding !== null) {
24+
encoding = bomEncoding;
25+
}
26+
27+
// iconv-lite will strip BOMs for us, so no need to do the stuff the spec does
28+
29+
return iconvLite.decode(buffer, encoding);
30+
};
31+
32+
// https://github.com/whatwg/html/issues/1910#issuecomment-254017369
33+
exports.getBOMEncoding = buffer => {
34+
if (buffer[0] === 0xFE && buffer[1] === 0xFF) {
35+
return "UTF-16BE";
36+
} else if (buffer[0] === 0xFF && buffer[1] === 0xFE) {
37+
return "UTF-16LE";
38+
} else if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
39+
return "UTF-8";
40+
}
41+
42+
return null;
43+
};
44+
45+
exports.isSupported = name => {
46+
return supportedNamesSet.has(name);
47+
};

0 commit comments

Comments
 (0)