Skip to content

Commit

Permalink
fix: handle multi-byte unicode sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickhulce committed Apr 21, 2021
1 parent 2b35657 commit e0743ba
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 12 deletions.
32 changes: 24 additions & 8 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@ const RawSource = require('webpack-sources').RawSource
const FONT_REGEX = /\.(eot|ttf|svg|woff|woff2)$/
const TEXT_REGEX = /\.(js|css|html)$/
const GLYPH_REGEX = /content\s*:[^};]*?('|")(.*?)\s*('|"|;)/g
const UNICODE_REGEX = /\\(\w{4})/
const UNICODE_REGEX = /\\([0-9a-f]{4,6})/i
const FONTMIN_EXTENSIONS = ['eot', 'woff', 'svg']

function getSurrogatePair(astralCodePoint) {
let highSurrogate = Math.floor((astralCodePoint - 0x10000) / 0x400) + 0xd800
let lowSurrogate = ((astralCodePoint - 0x10000) % 0x400) + 0xdc00
return [highSurrogate, lowSurrogate]
}

class FontminPlugin {
constructor(options) {
this._options = _.assign(
Expand Down Expand Up @@ -105,7 +111,15 @@ class FontminPlugin {
return matches
.map(match => {
const unicodeMatch = match.match(UNICODE_REGEX)
return unicodeMatch ? String.fromCharCode(parseInt(unicodeMatch[1], 16)) : false
if (!unicodeMatch) return false
const unicodeHex = unicodeMatch[1]
const numericValue = parseInt(unicodeHex, 16)
const character = String.fromCharCode(numericValue)
if (unicodeHex.length === 4) return character
const multiCharacter = getSurrogatePair(numericValue)
.map(v => String.fromCharCode(v))
.join('')
return multiCharacter
})
.filter(Boolean)
})
Expand Down Expand Up @@ -173,13 +187,15 @@ class FontminPlugin {

const glyphs = this.computeFinalGlyphs(glyphsInCss)
return minifiableFonts.reduce((prev, group) => {
return prev.then(() => this.minifyFontGroup(group, glyphs)).then(files => {
files.forEach(file => {
if (file.buffer.length > file.minified.length) {
compilation.assets[file.asset] = new RawSource(file.minified)
}
return prev
.then(() => this.minifyFontGroup(group, glyphs))
.then(files => {
files.forEach(file => {
if (file.buffer.length > file.minified.length) {
compilation.assets[file.asset] = new RawSource(file.minified)
}
})
})
})
}, Promise.resolve())
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"webpack": "5.x"
},
"devDependencies": {
"@mdi/font": "^5.9.55",
"@patrickhulce/lint": "^3.0.2",
"chai": "^4.3.0",
"css-loader": "^5.0.2",
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/entry-utf32.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require('@mdi/font/css/materialdesignicons.min.css')
14 changes: 14 additions & 0 deletions test/fixtures/webpack.unicode.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const FontminPlugin = require('../../lib')

module.exports = {
entry: `${__dirname}/entry-utf32.js`,
output: {filename: 'out.js', path: `${__dirname}/dist`, publicPath: '/test/fixtures/dist/'},
module: {
rules: [
{test: /\.(woff|woff2)(\?v=.+)?$/, use: ['file-loader']},
{test: /\.(svg|ttf|eot|png)(\?v=.+)?$/, use: ['file-loader']},
{test: /\.css$/, use: ['style-loader', 'css-loader']},
],
},
plugins: [new FontminPlugin()],
}
18 changes: 14 additions & 4 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('FontminPlugin', () => {
let fontStats
const baseConfig = require('./fixtures/webpack.config.js')
const baseExtractConfig = require('./fixtures/webpack.extract-text.config.js')
const baseUnicodeConfig = require('./fixtures/webpack.unicode.config.js')
const originalStats = collectFontStats(FONT_AWESOME_FOLDER + '/fonts', {
'fontawesome-webfont.eot': true,
'fontawesome-webfont.ttf': true,
Expand Down Expand Up @@ -60,7 +61,7 @@ describe('FontminPlugin', () => {
}

describe('FontAwesome micro', () => {
it('should run successfully', function (done) {
it('should run successfully', function(done) {
this.timeout(10000)
const plugin = new Plugin({autodetect: false, glyphs: '\uF0C7'})
const config = _.cloneDeep(baseConfig)
Expand Down Expand Up @@ -109,7 +110,7 @@ describe('FontminPlugin', () => {
})

describe('FontAwesome inferred', () => {
it('should run successfully', function (done) {
it('should run successfully', function(done) {
this.timeout(60000)
testWithConfig(baseConfig, done)
})
Expand All @@ -127,7 +128,7 @@ describe('FontminPlugin', () => {
})

describe('FontAwesome full', () => {
it('should run successfully', function (done) {
it('should run successfully', function(done) {
this.timeout(60000)
const plugin = new Plugin({autodetect: false})
const config = _.cloneDeep(baseConfig)
Expand All @@ -144,7 +145,7 @@ describe('FontminPlugin', () => {
})

describe('FontAwesome with ExtractTextPlugin', () => {
it('should run successfully', function (done) {
it('should run successfully', function(done) {
this.timeout(60000)
testWithConfig(baseExtractConfig, done)
})
Expand Down Expand Up @@ -195,4 +196,13 @@ describe('FontminPlugin', () => {
expect(glyphs).to.contain('remove')
})
})

describe('FontAwesome with multi-byte unicode characters', () => {
it('should run successfully', function(done) {
this.timeout(60000)
testWithConfig(baseUnicodeConfig, done)
})

after(done => rimraf(DIST_FOLDER, done))
})
})
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752"
integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==

"@mdi/font@^5.9.55":
version "5.9.55"
resolved "https://registry.yarnpkg.com/@mdi/font/-/font-5.9.55.tgz#41acd50b88073ded7095fc3029d8712b6e12f38e"
integrity sha512-jswRF6q3eq8NWpWiqct6q+6Fg/I7nUhrxYJfiEM8JJpap0wVJLQdbKtyS65GdlK7S7Ytnx3TTi/bmw+tBhkGmg==

"@patrickhulce/lint@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@patrickhulce/lint/-/lint-3.0.2.tgz#6b4fd8030bfad70df33dcf19a88a0176f23ff83d"
Expand Down

0 comments on commit e0743ba

Please sign in to comment.