diff --git a/bower.json b/bower.json index 3dc8be8..c88745e 100644 --- a/bower.json +++ b/bower.json @@ -7,7 +7,7 @@ "homepage": "http://github.com/sayanee/angularjs-pdf", "dependencies": { "angular": "1.4.7", - "pdfjs-dist": "1.2.43" + "pdfjs-dist": "1.2.83" }, "ignore": [ "**/.*", diff --git a/example/js/lib/pdf.js b/example/js/lib/pdf.js index 76b9c4d..39d4815 100644 --- a/example/js/lib/pdf.js +++ b/example/js/lib/pdf.js @@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') { (typeof window !== 'undefined' ? window : this).PDFJS = {}; } -PDFJS.version = '1.2.43'; -PDFJS.build = '1672c77'; +PDFJS.version = '1.2.83'; +PDFJS.build = '1280b7b'; (function pdfjsWrapper() { // Use strict in our context only - users might not want it @@ -1699,7 +1699,9 @@ PDFJS.disableWorker = (PDFJS.disableWorker === undefined ? /** * Path and filename of the worker file. Required when the worker is enabled in * development mode. If unspecified in the production build, the worker will be - * loaded based on the location of the pdf.js file. + * loaded based on the location of the pdf.js file. It is recommended that + * the workerSrc is set in a custom application to prevent issues caused by + * third-party frameworks and libraries. * @var {string} */ PDFJS.workerSrc = (PDFJS.workerSrc === undefined ? null : PDFJS.workerSrc); @@ -4875,16 +4877,13 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var x = 0, i; for (i = 0; i < glyphsLength; ++i) { var glyph = glyphs[i]; - if (glyph === null) { - // word break - x += fontDirection * wordSpacing; - continue; - } else if (isNum(glyph)) { + if (isNum(glyph)) { x += spacingDir * glyph * fontSize / 1000; continue; } var restoreNeeded = false; + var spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; var character = glyph.fontChar; var accent = glyph.accent; var scaledX, scaledY, scaledAccentX, scaledAccentY; @@ -4928,7 +4927,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { } } - var charWidth = width * widthAdvanceScale + charSpacing * fontDirection; + var charWidth = width * widthAdvanceScale + spacing * fontDirection; x += charWidth; if (restoreNeeded) { @@ -4973,18 +4972,14 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { for (i = 0; i < glyphsLength; ++i) { glyph = glyphs[i]; - if (glyph === null) { - // word break - this.ctx.translate(wordSpacing, 0); - current.x += wordSpacing * textHScale; - continue; - } else if (isNum(glyph)) { + if (isNum(glyph)) { spacingLength = spacingDir * glyph * fontSize / 1000; this.ctx.translate(spacingLength, 0); current.x += spacingLength * textHScale; continue; } + var spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; var operatorList = font.charProcOperatorList[glyph.operatorListId]; if (!operatorList) { warn('Type3 character \"' + glyph.operatorListId + @@ -4999,7 +4994,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { this.restore(); var transformed = Util.applyTransform([glyph.width, 0], fontMatrix); - width = transformed[0] * fontSize + charSpacing; + width = transformed[0] * fontSize + spacing; ctx.translate(width, 0); current.x += width * textHScale; @@ -8291,10 +8286,8 @@ if (!PDFJS.workerSrc && typeof document !== 'undefined') { // workerSrc is not set -- using last script url to define default location PDFJS.workerSrc = (function () { 'use strict'; - var scriptTagContainer = document.body || - document.getElementsByTagName('head')[0]; - var pdfjsSrc = scriptTagContainer.lastChild.src; - return pdfjsSrc && pdfjsSrc.replace(/\.js$/i, '.worker.js'); + var pdfJsSrc = document.currentScript.src; + return pdfJsSrc && pdfJsSrc.replace(/\.js$/i, '.worker.js'); })(); } diff --git a/example/js/lib/pdf.worker.js b/example/js/lib/pdf.worker.js index d36ebe5..06663fa 100644 --- a/example/js/lib/pdf.worker.js +++ b/example/js/lib/pdf.worker.js @@ -22,8 +22,8 @@ if (typeof PDFJS === 'undefined') { (typeof window !== 'undefined' ? window : this).PDFJS = {}; } -PDFJS.version = '1.2.43'; -PDFJS.build = '1672c77'; +PDFJS.version = '1.2.83'; +PDFJS.build = '1280b7b'; (function pdfjsWrapper() { // Use strict in our context only - users might not want it @@ -11154,9 +11154,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { for (var i = 0, ii = glyphs.length; i < ii; i++) { var glyph = glyphs[i]; - if (glyph === null) { - continue; - } buildPath(glyph.fontChar); // If the glyph has an accent we need to build a path for its @@ -11727,9 +11724,26 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { items: [], styles: Object.create(null) }; - var bidiTexts = textContent.items; + var textContentItem = { + initialized: false, + str: [], + width: 0, + height: 0, + vertical: false, + lastAdvanceWidth: 0, + lastAdvanceHeight: 0, + textAdvanceScale: 0, + spaceWidth: 0, + fakeSpaceMin: Infinity, + fakeMultiSpaceMin: Infinity, + fakeMultiSpaceMax: -0, + textRunBreakAllowed: false, + transform: null, + fontName: null + }; var SPACE_FACTOR = 0.3; var MULTI_SPACE_FACTOR = 1.5; + var MULTI_SPACE_FACTOR_MAX = 4; var self = this; var xref = this.xref; @@ -11744,7 +11758,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var textState; - function newTextChunk() { + function ensureTextContentItem() { + if (textContentItem.initialized) { + return textContentItem; + } var font = textState.font; if (!(font.loadedName in textContent.styles)) { textContent.styles[font.loadedName] = { @@ -11754,24 +11771,79 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { vertical: font.vertical }; } - return { - // |str| is initially an array which we push individual chars to, and - // then runBidi() overwrites it with the final string. - str: [], - dir: null, - width: 0, - height: 0, - transform: null, - fontName: font.loadedName - }; + textContentItem.fontName = font.loadedName; + + // 9.4.4 Text Space Details + var tsm = [textState.fontSize * textState.textHScale, 0, + 0, textState.fontSize, + 0, textState.textRise]; + + if (font.isType3Font && + textState.fontMatrix !== FONT_IDENTITY_MATRIX && + textState.fontSize === 1) { + var glyphHeight = font.bbox[3] - font.bbox[1]; + if (glyphHeight > 0) { + glyphHeight = glyphHeight * textState.fontMatrix[3]; + tsm[3] *= glyphHeight; + } + } + + var trm = Util.transform(textState.ctm, + Util.transform(textState.textMatrix, tsm)); + textContentItem.transform = trm; + if (!font.vertical) { + textContentItem.width = 0; + textContentItem.height = Math.sqrt(trm[2] * trm[2] + trm[3] * trm[3]); + textContentItem.vertical = false; + } else { + textContentItem.width = Math.sqrt(trm[0] * trm[0] + trm[1] * trm[1]); + textContentItem.height = 0; + textContentItem.vertical = true; + } + + var a = textState.textLineMatrix[0]; + var b = textState.textLineMatrix[1]; + var scaleLineX = Math.sqrt(a * a + b * b); + a = textState.ctm[0]; + b = textState.ctm[1]; + var scaleCtmX = Math.sqrt(a * a + b * b); + textContentItem.textAdvanceScale = scaleCtmX * scaleLineX; + textContentItem.lastAdvanceWidth = 0; + textContentItem.lastAdvanceHeight = 0; + + var spaceWidth = font.spaceWidth / 1000 * textState.fontSize; + if (spaceWidth) { + textContentItem.spaceWidth = spaceWidth; + textContentItem.fakeSpaceMin = spaceWidth * SPACE_FACTOR; + textContentItem.fakeMultiSpaceMin = spaceWidth * MULTI_SPACE_FACTOR; + textContentItem.fakeMultiSpaceMax = + spaceWidth * MULTI_SPACE_FACTOR_MAX; + // It's okay for monospace fonts to fake as much space as needed. + textContentItem.textRunBreakAllowed = !font.isMonospace; + } else { + textContentItem.spaceWidth = 0; + textContentItem.fakeSpaceMin = Infinity; + textContentItem.fakeMultiSpaceMin = Infinity; + textContentItem.fakeMultiSpaceMax = 0; + textContentItem.textRunBreakAllowed = false; + } + + + textContentItem.initialized = true; + return textContentItem; } - function runBidi(textChunk) { + function runBidiTransform(textChunk) { var str = textChunk.str.join(''); - var bidiResult = PDFJS.bidi(str, -1, textState.font.vertical); - textChunk.str = bidiResult.str; - textChunk.dir = bidiResult.dir; - return textChunk; + var bidiResult = PDFJS.bidi(str, -1, textChunk.vertical); + return { + str: bidiResult.str, + dir: bidiResult.dir, + width: textChunk.width, + height: textChunk.height, + transform: textChunk.transform, + fontName: textChunk.fontName + }; } function handleSetFont(fontName, fontRef) { @@ -11783,43 +11855,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { }); } - function buildTextGeometry(chars, textChunk) { + function buildTextContentItem(chars) { var font = textState.font; - textChunk = textChunk || newTextChunk(); - if (!textChunk.transform) { - // 9.4.4 Text Space Details - var tsm = [textState.fontSize * textState.textHScale, 0, - 0, textState.fontSize, - 0, textState.textRise]; - - if (font.isType3Font && - textState.fontMatrix !== FONT_IDENTITY_MATRIX && - textState.fontSize === 1) { - var glyphHeight = font.bbox[3] - font.bbox[1]; - if (glyphHeight > 0) { - glyphHeight = glyphHeight * textState.fontMatrix[3]; - tsm[3] *= glyphHeight; - } - } - - var trm = textChunk.transform = Util.transform(textState.ctm, - Util.transform(textState.textMatrix, tsm)); - if (!font.vertical) { - textChunk.height = Math.sqrt(trm[2] * trm[2] + trm[3] * trm[3]); - } else { - textChunk.width = Math.sqrt(trm[0] * trm[0] + trm[1] * trm[1]); - } - } + var textChunk = ensureTextContentItem(); var width = 0; var height = 0; var glyphs = font.charsToGlyphs(chars); var defaultVMetrics = font.defaultVMetrics; for (var i = 0; i < glyphs.length; i++) { var glyph = glyphs[i]; - if (!glyph) { // Previous glyph was a space. - width += textState.wordSpacing * textState.textHScale; - continue; - } var vMetricX = null; var vMetricY = null; var glyphWidth = null; @@ -11855,11 +11899,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { // var x = pt[0]; // var y = pt[1]; - var charSpacing = 0; - if (textChunk.str.length > 0) { - // Apply char spacing only when there are chars. - // As a result there is only spacing between glyphs. - charSpacing = textState.charSpacing; + var charSpacing = textState.charSpacing; + if (glyph.isSpace) { + var wordSpacing = textState.wordSpacing; + charSpacing += wordSpacing; + if (wordSpacing > 0) { + addFakeSpaces(wordSpacing, textChunk.str); + } } var tx = 0; @@ -11879,20 +11925,41 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { textChunk.str.push(glyphUnicode); } - var a = textState.textLineMatrix[0]; - var b = textState.textLineMatrix[1]; - var scaleLineX = Math.sqrt(a * a + b * b); - a = textState.ctm[0]; - b = textState.ctm[1]; - var scaleCtmX = Math.sqrt(a * a + b * b); if (!font.vertical) { - textChunk.width += width * scaleCtmX * scaleLineX; + textChunk.lastAdvanceWidth = width; + textChunk.width += width * textChunk.textAdvanceScale; } else { - textChunk.height += Math.abs(height * scaleCtmX * scaleLineX); + textChunk.lastAdvanceHeight = height; + textChunk.height += Math.abs(height * textChunk.textAdvanceScale); } + return textChunk; } + function addFakeSpaces(width, strBuf) { + if (width < textContentItem.fakeSpaceMin) { + return; + } + if (width < textContentItem.fakeMultiSpaceMin) { + strBuf.push(' '); + return; + } + var fakeSpaces = Math.round(width / textContentItem.spaceWidth); + while (fakeSpaces-- > 0) { + strBuf.push(' '); + } + } + + function flushTextContentItem() { + if (!textContentItem.initialized) { + return; + } + textContent.items.push(runBidiTransform(textContentItem)); + + textContentItem.initialized = false; + textContentItem.str.length = 0; + } + var timeSlotManager = new TimeSlotManager(); return new Promise(function next(resolve, reject) { @@ -11911,35 +11978,62 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { textState = stateManager.state; var fn = operation.fn; args = operation.args; + var advance; switch (fn | 0) { case OPS.setFont: + flushTextContentItem(); textState.fontSize = args[1]; return handleSetFont(args[0].name).then(function() { next(resolve, reject); }, reject); case OPS.setTextRise: + flushTextContentItem(); textState.textRise = args[0]; break; case OPS.setHScale: + flushTextContentItem(); textState.textHScale = args[0] / 100; break; case OPS.setLeading: + flushTextContentItem(); textState.leading = args[0]; break; case OPS.moveText: + // Optimization to treat same line movement as advance + var isSameTextLine = !textState.font ? false : + ((textState.font.vertical ? args[0] : args[1]) === 0); + advance = args[0] - args[1]; + if (isSameTextLine && textContentItem.initialized && + advance > 0 && + advance <= textContentItem.fakeMultiSpaceMax) { + textState.translateTextLineMatrix(args[0], args[1]); + textContentItem.width += + (args[0] - textContentItem.lastAdvanceWidth); + textContentItem.height += + (args[1] - textContentItem.lastAdvanceHeight); + var diff = (args[0] - textContentItem.lastAdvanceWidth) - + (args[1] - textContentItem.lastAdvanceHeight); + addFakeSpaces(diff, textContentItem.str); + break; + } + + flushTextContentItem(); textState.translateTextLineMatrix(args[0], args[1]); textState.textMatrix = textState.textLineMatrix.slice(); break; case OPS.setLeadingMoveText: + flushTextContentItem(); textState.leading = -args[1]; textState.translateTextLineMatrix(args[0], args[1]); textState.textMatrix = textState.textLineMatrix.slice(); break; case OPS.nextLine: + flushTextContentItem(); textState.carriageReturn(); break; case OPS.setTextMatrix: + flushTextContentItem(); textState.setTextMatrix(args[0], args[1], args[2], args[3], args[4], args[5]); textState.setTextLineMatrix(args[0], args[1], args[2], args[3], @@ -11952,17 +12046,19 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { textState.wordSpacing = args[0]; break; case OPS.beginText: + flushTextContentItem(); textState.textMatrix = IDENTITY_MATRIX.slice(); textState.textLineMatrix = IDENTITY_MATRIX.slice(); break; case OPS.showSpacedText: var items = args[0]; - var textChunk = newTextChunk(); var offset; for (var j = 0, jj = items.length; j < jj; j++) { if (typeof items[j] === 'string') { - buildTextGeometry(items[j], textChunk); + buildTextContentItem(items[j]); } else { + ensureTextContentItem(); + // PDF Specification 5.3.2 states: // The number is expressed in thousandths of a unit of text // space. @@ -11971,48 +12067,57 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { // In the default coordinate system, a positive adjustment // has the effect of moving the next glyph painted either to // the left or down by the given amount. - var val = items[j] * textState.fontSize / 1000; + advance = items[j] * textState.fontSize / 1000; + var breakTextRun = false; if (textState.font.vertical) { - offset = val * textState.textMatrix[3]; - textState.translateTextMatrix(0, offset); - // Value needs to be added to height to paint down. - textChunk.height += offset; + offset = advance * + (textState.textHScale * textState.textMatrix[2] + + textState.textMatrix[3]); + textState.translateTextMatrix(0, advance); + breakTextRun = textContentItem.textRunBreakAllowed && + advance > textContentItem.fakeMultiSpaceMax; + if (!breakTextRun) { + // Value needs to be added to height to paint down. + textContentItem.height += offset; + } } else { - offset = val * textState.textHScale * - textState.textMatrix[0]; - textState.translateTextMatrix(offset, 0); - // Value needs to be subtracted from width to paint left. - textChunk.width -= offset; - } - if (items[j] < 0 && textState.font.spaceWidth > 0) { - var fakeSpaces = -items[j] / textState.font.spaceWidth; - if (fakeSpaces > MULTI_SPACE_FACTOR) { - fakeSpaces = Math.round(fakeSpaces); - while (fakeSpaces--) { - textChunk.str.push(' '); - } - } else if (fakeSpaces > SPACE_FACTOR) { - textChunk.str.push(' '); + advance = -advance; + offset = advance * ( + textState.textHScale * textState.textMatrix[0] + + textState.textMatrix[1]); + textState.translateTextMatrix(advance, 0); + breakTextRun = textContentItem.textRunBreakAllowed && + advance > textContentItem.fakeMultiSpaceMax; + if (!breakTextRun) { + // Value needs to be subtracted from width to paint left. + textContentItem.width += offset; } } + if (breakTextRun) { + flushTextContentItem(); + } else if (advance > 0) { + addFakeSpaces(advance, textContentItem.str); + } } } - bidiTexts.push(runBidi(textChunk)); break; case OPS.showText: - bidiTexts.push(runBidi(buildTextGeometry(args[0]))); + buildTextContentItem(args[0]); break; case OPS.nextLineShowText: + flushTextContentItem(); textState.carriageReturn(); - bidiTexts.push(runBidi(buildTextGeometry(args[0]))); + buildTextContentItem(args[0]); break; case OPS.nextLineSetSpacingShowText: + flushTextContentItem(); textState.wordSpacing = args[0]; textState.charSpacing = args[1]; textState.carriageReturn(); - bidiTexts.push(runBidi(buildTextGeometry(args[2]))); + buildTextContentItem(args[2]); break; case OPS.paintXObject: + flushTextContentItem(); if (args[0].code) { break; } @@ -12024,7 +12129,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var name = args[0].name; if (xobjsCache.key === name) { if (xobjsCache.texts) { - Util.appendToArray(bidiTexts, xobjsCache.texts.items); + Util.appendToArray(textContent.items, xobjsCache.texts.items); Util.extendObj(textContent.styles, xobjsCache.texts.styles); } break; @@ -12055,7 +12160,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { return self.getTextContent(xobj, task, xobj.dict.get('Resources') || resources, stateManager). then(function (formTextContent) { - Util.appendToArray(bidiTexts, formTextContent.items); + Util.appendToArray(textContent.items, formTextContent.items); Util.extendObj(textContent.styles, formTextContent.styles); stateManager.restore(); @@ -12065,6 +12170,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { next(resolve, reject); }, reject); case OPS.setGState: + flushTextContentItem(); var dictName = args[0]; var extGState = resources.get('ExtGState'); @@ -12095,6 +12201,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { }, reject); return; } + flushTextContentItem(); resolve(textContent); }); }, @@ -16674,23 +16781,26 @@ function getFontType(type, subtype) { } var Glyph = (function GlyphClosure() { - function Glyph(fontChar, unicode, accent, width, vmetric, operatorListId) { + function Glyph(fontChar, unicode, accent, width, vmetric, operatorListId, + isSpace) { this.fontChar = fontChar; this.unicode = unicode; this.accent = accent; this.width = width; this.vmetric = vmetric; this.operatorListId = operatorListId; + this.isSpace = isSpace; } - Glyph.prototype.matchesForCache = - function(fontChar, unicode, accent, width, vmetric, operatorListId) { + Glyph.prototype.matchesForCache = function(fontChar, unicode, accent, width, + vmetric, operatorListId, isSpace) { return this.fontChar === fontChar && this.unicode === unicode && this.accent === accent && this.width === width && this.vmetric === vmetric && - this.operatorListId === operatorListId; + this.operatorListId === operatorListId && + this.isSpace === isSpace; }; return Glyph; @@ -18653,6 +18763,20 @@ var Font = (function FontClosure() { tables.hhea.data[11] = 0xFF; } + // Extract some more font properties from the OpenType head and + // hhea tables; yMin and descent value are always negative. + var metricsOverride = { + unitsPerEm: int16(tables.head.data[18], tables.head.data[19]), + yMax: int16(tables.head.data[42], tables.head.data[43]), + yMin: int16(tables.head.data[38], tables.head.data[39]) - 0x10000, + ascent: int16(tables.hhea.data[4], tables.hhea.data[5]), + descent: int16(tables.hhea.data[6], tables.hhea.data[7]) - 0x10000 + }; + + // PDF FontDescriptor metrics lie -- using data from actual font. + this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm; + this.descent = metricsOverride.descent / metricsOverride.unitsPerEm; + // The 'post' table has glyphs names. if (tables.post) { var valid = readPostScriptTable(tables.post, properties, numGlyphs); @@ -18819,20 +18943,10 @@ var Font = (function FontClosure() { }; if (!tables['OS/2'] || !validateOS2Table(tables['OS/2'])) { - // extract some more font properties from the OpenType head and - // hhea tables; yMin and descent value are always negative - var override = { - unitsPerEm: int16(tables.head.data[18], tables.head.data[19]), - yMax: int16(tables.head.data[42], tables.head.data[43]), - yMin: int16(tables.head.data[38], tables.head.data[39]) - 0x10000, - ascent: int16(tables.hhea.data[4], tables.hhea.data[5]), - descent: int16(tables.hhea.data[6], tables.hhea.data[7]) - 0x10000 - }; - tables['OS/2'] = { tag: 'OS/2', data: createOS2Table(properties, newMapping.charCodeToGlyphId, - override) + metricsOverride) }; } @@ -19205,7 +19319,7 @@ var Font = (function FontClosure() { return width; }, - charToGlyph: function Font_charToGlyph(charcode) { + charToGlyph: function Font_charToGlyph(charcode, isSpace) { var fontCharCode, width, operatorListId; var widthCode = charcode; @@ -19248,9 +19362,9 @@ var Font = (function FontClosure() { var glyph = this.glyphCache[charcode]; if (!glyph || !glyph.matchesForCache(fontChar, unicode, accent, width, vmetric, - operatorListId)) { + operatorListId, isSpace)) { glyph = new Glyph(fontChar, unicode, accent, width, vmetric, - operatorListId); + operatorListId, isSpace); this.glyphCache[charcode] = glyph; } return glyph; @@ -19286,22 +19400,16 @@ var Font = (function FontClosure() { charcode = c.charcode; var length = c.length; i += length; - glyph = this.charToGlyph(charcode); + // Space is char with code 0x20 and length 1 in multiple-byte codes. + var isSpace = length === 1 && chars.charCodeAt(i - 1) === 0x20; + glyph = this.charToGlyph(charcode, isSpace); glyphs.push(glyph); - // placing null after each word break charcode (ASCII SPACE) - // Ignore occurences of 0x20 in multiple-byte codes. - if (length === 1 && chars.charCodeAt(i - 1) === 0x20) { - glyphs.push(null); - } } } else { for (i = 0, ii = chars.length; i < ii; ++i) { charcode = chars.charCodeAt(i); - glyph = this.charToGlyph(charcode); + glyph = this.charToGlyph(charcode, charcode === 0x20); glyphs.push(glyph); - if (charcode === 0x20) { - glyphs.push(null); - } } } @@ -39826,10 +39934,8 @@ if (!PDFJS.workerSrc && typeof document !== 'undefined') { // workerSrc is not set -- using last script url to define default location PDFJS.workerSrc = (function () { 'use strict'; - var scriptTagContainer = document.body || - document.getElementsByTagName('head')[0]; - var pdfjsSrc = scriptTagContainer.lastChild.src; - return pdfjsSrc && pdfjsSrc.replace(/\.js$/i, '.worker.js'); + var pdfJsSrc = document.currentScript.src; + return pdfJsSrc && pdfJsSrc.replace(/\.js$/i, '.worker.js'); })(); }