Skip to content

Commit

Permalink
bom processing for native automation (#2906)
Browse files Browse the repository at this point in the history
* bom processing for native automation

* add server test
  • Loading branch information
AlexKamaev authored Jun 13, 2023
1 parent 7753bef commit 6e2b9c4
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 14 deletions.
8 changes: 6 additions & 2 deletions src/processing/resources/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import DomProcessor from '../dom';
import DomAdapter from '../dom/parse5-dom-adapter';
import ResourceProcessorBase from './resource-processor-base';
import * as parse5Utils from '../../utils/parse5';
import getBOM from '../../utils/get-bom';
import { getBOM, getBOMDecoded } from '../../utils/get-bom';
import getStorageKey from '../../utils/get-storage-key';
import SELF_REMOVING_SCRIPTS from '../../utils/self-removing-scripts';
import RequestPipelineContext from '../../request-pipeline/context';
Expand Down Expand Up @@ -275,6 +275,10 @@ class PageProcessor extends ResourceProcessorBase {

// NOTE: API for new implementation without request pipeline
injectResources (html: string, resources: PageInjectableResources, options?: PageRestoreStoragesOptions): string {
const bom = getBOMDecoded(html);

html = bom ? html.replace(bom, '') : html;

const root = parse5.parse(html);
const elements = parse5Utils.findElementsByTagNames(root, ['head', 'body']);
const head = elements.head[0];
Expand All @@ -283,7 +287,7 @@ class PageProcessor extends ResourceProcessorBase {
PageProcessor._addPageResources(head, resources, options);
PageProcessor._addBodyCreatedEventScript(body);

return parse5.serialize(root);
return (bom || '') + parse5.serialize(root);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/processing/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { add as addHeader, remove as removeHeader } from './header';
import { parse } from 'acorn-hammerhead';
import { generate, Syntax } from 'esotope-hammerhead';
import reEscape from '../../utils/regexp-escape';
import getBOM from '../../utils/get-bom';
import { getBOM } from '../../utils/get-bom';

const HTML_COMMENT_RE = /(^|\n)\s*<!--[^\n]*(\n|$)/g;
const OBJECT_RE = /^\s*\{.*\}\s*$/;
Expand Down
11 changes: 9 additions & 2 deletions src/utils/get-bom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@
// -------------------------------------------------------------
/* eslint hammerhead/proto-methods: 2 */

const BOM_RE = /^(\xEF\xBB\xBF|\xFE\xFF|\xFF\xFE|\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\x2B\x2F\x76\x38|\x2B\x2F\x76\x39|\x2B\x2F\x76\x2B|\x2B\x2F\x76\x2F|\xF7\x64\x4C|\xDD\x73\x66\x73|\x0E\xFE\xFF|\xFB\xEE\x28|\x84\x31\x95\x33)/; // eslint-disable-line no-control-regex
const BOM_RE = /^(\xEF\xBB\xBF|\xFE\xFF|\xFF\xFE|\x00\x00\xFE\xFF|\xFF\xFE\x00\x00|\x2B\x2F\x76\x38|\x2B\x2F\x76\x39|\x2B\x2F\x76\x2B|\x2B\x2F\x76\x2F|\xF7\x64\x4C|\xDD\x73\x66\x73|\x0E\xFE\xFF|\xFB\xEE\x28|\x84\x31\x95\x33)/; // eslint-disable-line no-control-regex
const BOM_DECODED_RE = /^\uFEFF/;

export default function (str: string): string | null {
export function getBOM (str: string): string | null {
const match = str.match(BOM_RE);

return match ? match[0] : null;
}

export function getBOMDecoded (str: string): string | null {
const match = str.match(BOM_DECODED_RE);

return match ? match[0] : null;
}
27 changes: 18 additions & 9 deletions test/server/proxy/without-request-pipeline-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,27 @@ const { injectResources } = require('../../../lib');
const { compareCode } = require('../common/utils');

describe('New API', () => {
const resources = {
stylesheets: ['./styles.css'],
scripts: ['common/script1.js', './common/script2.js'],
embeddedScripts: ['var script1 = 1;', 'var script2 = 2;'],
userScripts: ['/custom-script1.js', '/custom-script2.js'],
};

const pageContent = fs.readFileSync('test/server/data/without-request-pipeline/src.html').toString();
const expectedPageContent = fs.readFileSync('test/server/data/without-request-pipeline/expected.html').toString();

it('PageProcessor.injectResources', () => {
const pageContent = fs.readFileSync('test/server/data/without-request-pipeline/src.html').toString();
const updatedPageContent = injectResources(pageContent, resources);

compareCode(updatedPageContent, expectedPageContent);
});

const resources = {
stylesheets: ['./styles.css'],
scripts: ['common/script1.js', './common/script2.js'],
embeddedScripts: ['var script1 = 1;', 'var script2 = 2;'],
userScripts: ['/custom-script1.js', '/custom-script2.js'],
};
it('PageProcessor.injectResources - trim BOM', () => {
const bomSymbol = String.fromCharCode(65279);
const updatedPageContent = injectResources(bomSymbol + pageContent, resources);

const updatedPageContent = injectResources(pageContent, resources);
const expectedPageContent = fs.readFileSync('test/server/data/without-request-pipeline/expected.html').toString();
updatedPageContent.charCodeAt(0) === bomSymbol;

compareCode(updatedPageContent, expectedPageContent);
});
Expand Down

0 comments on commit 6e2b9c4

Please sign in to comment.