From eabe4de1b2ccfd937a246c17c4b5deab993cf0cb Mon Sep 17 00:00:00 2001 From: Will Yau <1339380+willyau@users.noreply.github.com> Date: Fri, 15 Jun 2018 15:25:35 -0700 Subject: [PATCH 1/3] Added support for byte size limit --- src/exports.js | 2 ++ src/inject.js | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/exports.js b/src/exports.js index b86f3d3..02e5e1b 100644 --- a/src/exports.js +++ b/src/exports.js @@ -9,6 +9,7 @@ import { addRenderedClassNames, getRenderedClassNames, getBufferedStyles, + setSizeLimit, } from './inject'; import {defaultSelectorHandlers} from './generate'; @@ -188,5 +189,6 @@ export default function makeExports( flushToStyleTag, injectAndGetClassName, defaultSelectorHandlers, + setSizeLimit, }; } diff --git a/src/inject.js b/src/inject.js index c5c85d9..4c8e076 100644 --- a/src/inject.js +++ b/src/inject.js @@ -5,6 +5,8 @@ import OrderedElements from './ordered-elements'; import {generateCSS} from './generate'; import {hashObject, hashString} from './util'; +const UNLIMITED_SIZE = -1; + /* :: import type { SheetDefinition, SheetDefinitions } from './index.js'; import type { MaybeSheetDefinition } from './exports.js'; @@ -150,6 +152,11 @@ let alreadyInjected = {}; // This is the buffer of styles which have not yet been flushed. let injectionBuffer /* : string[] */ = []; +let currentInjectionBufferSize = 0; + +// This is the size limit to be placed on the total css styles usage +let sizeLimit = UNLIMITED_SIZE; + // A flag to tell if we are already buffering styles. This could happen either // because we scheduled a flush call already, so newly added styles will // already be flushed, or because we are statically buffering on the server. @@ -174,6 +181,15 @@ const injectGeneratedCSSOnce = (key, generatedCSS) => { asap(flushToStyleTag); } + if (sizeLimit !== UNLIMITED_SIZE) { + const generatedCSSSize = Buffer.from(generatedCSS.toString()).length; + if (currentInjectionBufferSize + generatedCSSSize >= sizeLimit) { + throw new Error("Cannot inject css since size limit has been reached"); + } else { + currentInjectionBufferSize += generatedCSSSize; + } + } + injectionBuffer.push(...generatedCSS); alreadyInjected[key] = true; } @@ -322,3 +338,10 @@ export const injectAndGetClassName = ( return className; } + +/** + * @param {number} bytesSize + */ +export const setSizeLimit = (bytesSize) => { + sizeLimit = bytesSize; +} From b694ad67f8de9e8955d39969a32cf66b2911a269 Mon Sep 17 00:00:00 2001 From: Will Yau <1339380+willyau@users.noreply.github.com> Date: Mon, 18 Jun 2018 13:11:09 -0700 Subject: [PATCH 2/3] Fixed lint error --- src/inject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inject.js b/src/inject.js index 4c8e076..26a16a2 100644 --- a/src/inject.js +++ b/src/inject.js @@ -342,6 +342,6 @@ export const injectAndGetClassName = ( /** * @param {number} bytesSize */ -export const setSizeLimit = (bytesSize) => { +export const setSizeLimit = (bytesSize /* : number */,) => { sizeLimit = bytesSize; } From bf1060a5a89b13f9f90756c30e539c16435313d4 Mon Sep 17 00:00:00 2001 From: Will Yau <1339380+willyau@users.noreply.github.com> Date: Mon, 18 Jun 2018 13:36:57 -0700 Subject: [PATCH 3/3] Added tests --- src/inject.js | 2 +- tests/inject_test.js | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/inject.js b/src/inject.js index 26a16a2..2d9a9ed 100644 --- a/src/inject.js +++ b/src/inject.js @@ -5,7 +5,7 @@ import OrderedElements from './ordered-elements'; import {generateCSS} from './generate'; import {hashObject, hashString} from './util'; -const UNLIMITED_SIZE = -1; +export const UNLIMITED_SIZE = -1; /* :: import type { SheetDefinition, SheetDefinitions } from './index.js'; diff --git a/tests/inject_test.js b/tests/inject_test.js index af6b893..de07afb 100644 --- a/tests/inject_test.js +++ b/tests/inject_test.js @@ -12,6 +12,8 @@ import { flushToStyleTag, addRenderedClassNames, getRenderedClassNames, + setSizeLimit, + UNLIMITED_SIZE, } from '../src/inject'; import { defaultSelectorHandlers } from '../src/generate'; import { getSheetText } from './testUtils'; @@ -57,6 +59,22 @@ describe('injection', () => { assert.equal(className, 'red_137u7ef-o_O-blue_1tsdo2i'); }); + describe('size limit', () => { + beforeEach(() => { + setSizeLimit(1); + }); + + afterEach(() => { + setSizeLimit(UNLIMITED_SIZE); + }); + + it('uses should throw if over size limit', () => { + assert.throws(() => { + injectAndGetClassName(false, [sheet.red], defaultSelectorHandlers); + }, 'Cannot inject css since size limit has been reached'); + }); + }); + describe('process.env.NODE_ENV === \'production\'', () => { let prodSheet; beforeEach(() => {