Skip to content

Commit

Permalink
Require Node.js 12
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed May 14, 2021
1 parent b835409 commit 9ea8bd5
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 48 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ jobs:
fail-fast: false
matrix:
node-version:
- 16
- 14
- 12
- 10
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
18 changes: 10 additions & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/* eslint-disable no-redeclare */

declare namespace srcset {
interface SrcSetDefinition {
url: string;
width?: number;
density?: number;
}

interface SrcSetOptions {
interface Options {
/**
When strict mode is enabled, errors will be thrown on invalid input.
Expand All @@ -21,9 +23,9 @@ declare const srcset: {
/**
Parse the HTML `<img>` [srcset](http://mobile.smashingmagazine.com/2013/08/21/webkit-implements-srcset-and-why-its-a-good-thing/) attribute.
Accepts a srcset string and returns an array of objects with the possible properties: `url` (always), `width`, `density`, and `height`.
Accepts a srcset string and returns an array of objects with the possible properties: `url` (always), `width`, `density`, and `height`.
@param srcset - A srcset string.
@param srcset - A srcset string.
@example
```
Expand All @@ -42,14 +44,14 @@ declare const srcset: {
// ]
```
*/
parse: (srcset: string, options?: srcset.SrcSetOptions) => srcset.SrcSetDefinition[];
parse: (srcset: string, options?: srcset.Options) => srcset.SrcSetDefinition[];

/**
Stringify `SrcSetDefinition`s. Accepts an array of `SrcSetDefinition` objects and returns a srcset string.
Stringify `SrcSetDefinition`s.
@param SrcSetDefinitions - An array of `SrcSetDefinition` objects. Each object should have a `url` field and may have either `width` or `density`. When `options.strict` is set to false, a `height` field is also accepted, and multiple descriptors (`width`, `height`, and`density`) are accepted.
@param SrcSetDefinitions - Each object should have a `url` field and may have either `width` or `density`. When the `strict` option is `true`, only `width` or `density` is accepted.
@returns A srcset string.
@returns A srcset string.
@example
```
Expand All @@ -70,7 +72,7 @@ declare const srcset: {
// banner-HD.jpg 2x, banner-phone.jpg 100w
```
*/
stringify: (srcSetDefinitions: srcset.SrcSetDefinition[], options?: srcset.SrcSetOptions) => string;
stringify: (srcSetDefinitions: readonly srcset.SrcSetDefinition[], options?: srcset.Options) => string;
};

export = srcset;
84 changes: 60 additions & 24 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,32 @@ const validDescriptorCheck = (value, postfix, descriptor) => {
throw new TypeError(`${descriptor || value} is not a valid number`);
}

if (postfix === 'w') {
if (value <= 0) {
throw new Error('Width descriptor must be greater than zero');
} else if (!Number.isInteger(value)) {
throw new TypeError('Width descriptor must be an integer');
switch (postfix) {
case 'w': {
if (value <= 0) {
throw new Error('Width descriptor must be greater than zero');
} else if (!Number.isInteger(value)) {
throw new TypeError('Width descriptor must be an integer');
}

break;
}

case 'x': {
if (value <= 0) {
throw new Error('Pixel density descriptor must be greater than zero');
}

break;
}
} else if (postfix === 'x') {
if (value <= 0) {
throw new Error('Pixel density descriptor must be greater than zero');

case 'h': {
throw new Error('Height descriptor is no longer allowed');
}

default: {
throw new Error(`Invalid srcset descriptor: ${descriptor}`);
}
} else if (postfix === 'h') {
throw new Error('Height descriptor is no longer allowed');
} else {
throw new Error(`Invalid srcset descriptor: ${descriptor}`);
}
};

Expand All @@ -90,12 +102,23 @@ exports.parse = (string, {strict = false} = {}) => {
duplicateDescriptorCheck(allDescriptors, value, postfix);
}

if (postfix === 'w') {
result.width = value;
} else if (postfix === 'h') {
result.height = value;
} else if (postfix === 'x') {
result.density = value;
switch (postfix) {
case 'w': {
result.width = value;
break;
}

case 'h': {
result.height = value;
break;
}

case 'x': {
result.density = value;
break;
}

// No default
}
}

Expand Down Expand Up @@ -127,12 +150,25 @@ exports.stringify = (array, {strict = false} = {}) => {
for (const descriptorKey of descriptorKeys) {
const value = element[descriptorKey];
let postfix;
if (descriptorKey === 'width') {
postfix = 'w';
} else if (descriptorKey === 'height') {
postfix = 'h';
} else if (descriptorKey === 'density') {
postfix = 'x';
switch (descriptorKey) {
case 'width': {
postfix = 'w';

break;
}

case 'height': {
postfix = 'h';

break;
}

case 'density': {
postfix = 'x';

break;
}
// No default
}

const descriptor = `${value}${postfix}`;
Expand Down
6 changes: 2 additions & 4 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import {expectType, expectError} from 'tsd';
import srcset = require('.');
import srcset = require('./index.js');

const parsed = srcset.parse('banner-HD.jpg 2x, banner-phone.jpg 100w');
expectType<srcset.SrcSetDefinition[]>(parsed);

parsed.push({url: 'banner-phone-HD.jpg'});
parsed.push({url: 'banner-phone-HD.jpg', width: 100});
parsed.push({url: 'banner-phone-HD.jpg', density: 2});
parsed.push({url: 'banner-phone-HD.jpg'}, {url: 'banner-phone-HD.jpg', width: 100}, {url: 'banner-phone-HD.jpg', density: 2});
expectError(parsed.push({}));

expectType<string>(srcset.stringify(parsed));
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"url": "https://sindresorhus.com"
},
"engines": {
"node": ">=10"
"node": ">=12"
},
"scripts": {
"test": "xo && ava && tsd"
Expand All @@ -36,6 +36,6 @@
"devDependencies": {
"ava": "^2.4.0",
"tsd": "^0.13.1",
"xo": "^0.32.1"
"xo": "^0.39.0"
}
}
13 changes: 6 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,35 +60,34 @@ banner-HD.jpg 2x, banner-phone.jpg 100w, banner-super-HD.jpg 3x

Parse the HTML `<img>` [srcset](http://mobile.smashingmagazine.com/2013/08/21/webkit-implements-srcset-and-why-its-a-good-thing/) attribute.

Accepts a srcset string and returns an array of objects with the possible properties: `url` (always), `width`, `height`, and `density`.
Accepts a srcset string and returns an array of objects with the possible properties: `url` (always), `width`, `height`, and `density`.

#### string

Type: `string`

A srcset string
A srcset string.

#### options

Type: `object`

##### strict

Type: `boolean`

Type: `boolean`\
Default: `false`

Enable or disable validation of the srcset string. When enabled, an invalid srcset string will cause an error to be thrown. When disabled, a best effort will be made to parse the string, potentially resulting in invalid or nonsensical output.
When enabled, an invalid srcset string will cause an error to be thrown. When disabled, a best effort will be made to parse the string, potentially resulting in invalid or nonsensical output.

### .stringify(SrcSetDefinitions, options?)

Stringify `SrcSetDefinition`s. Accepts an array of `SrcSetDefinition` objects and returns a srcset string.
Stringify `SrcSetDefinition`s. Accepts an array of `SrcSetDefinition` objects and returns a srcset string.

#### srcsetDescriptors

Type: `array`

An array of `SrcSetDefinition` objects. Each object should have a `url` field and may have `width`, `height` or `density` fields. When `options.strict` is set to true, only `width` or `density` is permitted.
An array of `SrcSetDefinition` objects. Each object should have a `url` field and may have `width`, `height` or `density` fields. When the `strict` option is `true`, only `width` or `density` is accepted.

#### options

Expand Down
2 changes: 1 addition & 1 deletion test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'ava';
import srcset from '.';
import srcset from './index.js';

test('.parse() should parse srcset', t => {
const fixture = ' banner-HD.jpeg 2x, banner-phone.jpeg 100w, http://site.com/image.jpg?foo=bar,lorem 3x ,banner.jpeg ';
Expand Down

0 comments on commit 9ea8bd5

Please sign in to comment.