Add the new preprocessor.

This commit is contained in:
Brendan Dahl 2012-08-01 11:29:13 -07:00
parent 6d35073a9c
commit 492fa6edb4
6 changed files with 431 additions and 315 deletions

430
make.js
View File

@ -1,6 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
require('./external/shelljs/make'); require('./external/shelljs/make');
var fs = require('fs'); var fs = require('fs');
var path = require('path');
var vm = require('vm'); var vm = require('vm');
var ROOT_DIR = __dirname + '/', // absolute path to project's root var ROOT_DIR = __dirname + '/', // absolute path to project's root
@ -10,6 +11,7 @@ var ROOT_DIR = __dirname + '/', // absolute path to project's root
EXTENSION_SRC_DIR = 'extensions/', EXTENSION_SRC_DIR = 'extensions/',
LOCALE_SRC_DIR = 'l10n/', LOCALE_SRC_DIR = 'l10n/',
GH_PAGES_DIR = BUILD_DIR + 'gh-pages/', GH_PAGES_DIR = BUILD_DIR + 'gh-pages/',
GENERIC_DIR = BUILD_DIR + 'generic/',
REPO = 'git@github.com:mozilla/pdf.js.git', REPO = 'git@github.com:mozilla/pdf.js.git',
PYTHON_BIN = 'python2.7', PYTHON_BIN = 'python2.7',
MOZCENTRAL_PREF_PREFIX = 'pdfjs', MOZCENTRAL_PREF_PREFIX = 'pdfjs',
@ -17,48 +19,147 @@ var ROOT_DIR = __dirname + '/', // absolute path to project's root
MOZCENTRAL_STREAM_CONVERTER_ID = 'd0c5195d-e798-49d4-b1d3-9324328b2291', MOZCENTRAL_STREAM_CONVERTER_ID = 'd0c5195d-e798-49d4-b1d3-9324328b2291',
FIREFOX_STREAM_CONVERTER_ID = '6457a96b-2d68-439a-bcfa-44465fbcdbb1'; FIREFOX_STREAM_CONVERTER_ID = '6457a96b-2d68-439a-bcfa-44465fbcdbb1';
function preprocess(inFilename, outFilename, flags) { var DEFINES = {
// TODO make this really read line by line. PRODUCTION: true,
var lines = fs.readFileSync(inFilename).toString().split("\n"); // The main build targets:
var totalLines = lines.length; GENERIC: false,
var out = ''; FIREFOX: false,
var i = 0; MOZCENTRAL: false,
function readLine() { B2G: false,
if (i < totalLines) { CHROME: false
return lines[i++]; };
}
return null;
}
function writeLine(line) {
out += line + '\n';
}
var s, state = 0, stack = []; function extendDefines(obj) {
while ((s = readLine()) !== null) { var ret = {};
var m = new RegExp(/^\/\/\s*#(if|else|endif)\b(?:\s+(.*))?/).exec(s); for (var key in DEFINES)
if (m) { ret[key] = DEFINES[key];
if (m[1] === "if") { for (key in obj)
stack.push(state); ret[key] = obj[key];
state = vm.runInNewContext(m[2], flags) ? 3 : 1; return ret;
} else if (m[1] === "else") { }
state = state === 1 ? 3 : 2;
var BuildHelper = {
/**
* A simple preprocessor that is based on the firefox preprocessor
* see (https://developer.mozilla.org/en/Build/Text_Preprocessor). The main
* difference is that this supports a subset of the commands and it supports
* preproccesor commands in html style comments.
* Currently Supported commands:
* - if
* - else
* - endif
* - include
* - expand
*/
preprocess: function preprocess(inFilename, outFilename, defines) {
// TODO make this really read line by line.
var lines = fs.readFileSync(inFilename).toString().split('\n');
var totalLines = lines.length;
var out = '';
var i = 0;
function readLine() {
if (i < totalLines) {
return lines[i++];
}
return null;
}
var writeLine = typeof outFilename === 'function' ? outFilename : function(line) {
out += line + '\n';
}
function include(file) {
var realPath = fs.realpathSync(inFilename);
var dir = path.dirname(realPath);
preprocess(path.join(dir, file), writeLine, defines);
}
function expand(line) {
line = line.replace(/__[\w]+__/g, function(variable) {
variable = variable.substring(2, variable.length - 2);
if (variable in defines) {
return defines[variable];
}
return '';
});
writeLine(line);
}
var s, state = 0, stack = [];
var control = /^(?:\/\/|<!--)\s*#(if|else|endif|expand|include)(?:\s+(.*?)(?:-->)?$)?/;
var lineNumber = 0;
while ((s = readLine()) !== null) {
++lineNumber;
var m = control.exec(s);
if (m) {
switch (m[1]) {
case 'if':
stack.push(state);
try {
state = vm.runInNewContext(m[2], defines) ? 3 : 1;
} catch (e) {
console.error('Could not evalute line \'' + m[2] + '\' at ' +
fs.realpathSync(inFilename) + ':' + lineNumber);
throw e;
}
break;
case 'else':
state = state === 1 ? 3 : 2;
break;
case 'endif':
state = stack.pop();
break;
case 'expand':
if (state === 0 || state === 3)
expand(m[2]);
break;
case 'include':
if (state === 0 || state === 3)
include(m[2]);
break;
}
} else { } else {
state = stack.pop(); if (state === 0) {
} writeLine(s);
} else { } else if(state === 3) {
if (state === 0) { writeLine(s.replace(/^\/\/|^<!--|-->/g, " "));
writeLine(s); }
} else if(state === 3) {
writeLine(s.replace(/^\/\//g, " "));
} }
} }
} if (state !== 0 || stack.length !== 0)
fs.writeFileSync(outFilename, out); throw new Error('Missing endif in preprocessor.');
} if (typeof outFilename !== 'function')
fs.writeFileSync(outFilename, out);
},
/**
* Simplifies common build steps.
* @param setup
* .defines defines for preprocessors
* .copy array of arrays of source and destination pairs of files to copy
* .preprocess array of arrays of source and destination pairs of files
* run through preprocessor
*/
build: function build(setup) {
var defines = setup.defines;
target.pre = function() { setup.copy.forEach(function(option) {
preprocess('in.txt', 'out.txt', {B2G: true}); var source = option[0];
} var destination = option[1];
cp('-R', source, destination);
});
setup.preprocess.forEach(function(option) {
var sources = option[0];
var destination = option[1];
sources = ls('-R', sources);
sources.forEach(function(source) {
// ??? Warn if the source is wildcard and dest is file?
var destWithFolder = destination;
if (test('-d', destination))
destWithFolder += '/' + path.basename(source);
BuildHelper.preprocess(source, destWithFolder, defines);
});
});
}
};
// //
// make all // make all
@ -76,14 +177,59 @@ target.all = function() {
// Production stuff // Production stuff
// //
// Files that need to be included in every build.
var COMMON_WEB_FILES =
['web/viewer.css',
'web/images',
'web/debugger.js'],
COMMON_WEB_FILES_PREPROCESS =
['web/viewer.js',
'web/viewer.html'];
//
// make generic
// Builds the generic production viewer that should be compatible with most
// modern HTML5 browsers.
//
target.generic = function() {
target.bundle();
target.locale();
cd(ROOT_DIR);
echo();
echo('### Creating generic viewer');
rm('-rf', GENERIC_DIR);
mkdir('-p', GENERIC_DIR);
mkdir('-p', GENERIC_DIR + BUILD_DIR);
mkdir('-p', GENERIC_DIR + '/web');
var defines = extendDefines({GENERIC: true});
var setup = {
defines: defines,
copy: [
[COMMON_WEB_FILES, GENERIC_DIR + '/web'],
['external/webL10n/l10n.js', GENERIC_DIR + '/web'],
['web/compatibility.js', GENERIC_DIR + '/web'],
['web/compressed.tracemonkey-pldi-09.pdf', GENERIC_DIR + '/web'],
['web/locale.properties', GENERIC_DIR + '/web']
],
preprocess: [
[BUILD_TARGET, GENERIC_DIR + BUILD_TARGET],
[COMMON_WEB_FILES_PREPROCESS, GENERIC_DIR + '/web']
]
};
BuildHelper.build(setup);
};
// //
// make web // make web
// Generates the website for the project, by checking out the gh-pages branch underneath // Generates the website for the project, by checking out the gh-pages branch underneath
// the build directory, and then moving the various viewer files into place. // the build directory, and then moving the various viewer files into place.
// //
target.web = function() { target.web = function() {
target.production(); target.generic();
target.locale();
target.extension(); target.extension();
target.pagesrepo(); target.pagesrepo();
@ -91,25 +237,18 @@ target.web = function() {
echo(); echo();
echo('### Creating web site'); echo('### Creating web site');
var GH_PAGES_SRC_FILES = [ cp('-R', GENERIC_DIR + '/*', GH_PAGES_DIR);
'web/*',
'external/webL10n/l10n.js'
];
cp(BUILD_TARGET, GH_PAGES_DIR + BUILD_TARGET);
cp('-R', GH_PAGES_SRC_FILES, GH_PAGES_DIR + '/web');
cp(FIREFOX_BUILD_DIR + '/*.xpi', FIREFOX_BUILD_DIR + '/*.rdf', cp(FIREFOX_BUILD_DIR + '/*.xpi', FIREFOX_BUILD_DIR + '/*.rdf',
GH_PAGES_DIR + EXTENSION_SRC_DIR + 'firefox/'); GH_PAGES_DIR + EXTENSION_SRC_DIR + 'firefox/');
cp(GH_PAGES_DIR + '/web/index.html.template', GH_PAGES_DIR + '/index.html'); cp('web/index.html.template', GH_PAGES_DIR + '/index.html');
mv('-f', GH_PAGES_DIR + '/web/viewer-production.html',
GH_PAGES_DIR + '/web/viewer.html');
cd(GH_PAGES_DIR); cd(GH_PAGES_DIR);
exec('git add -A'); exec('git add -A');
echo(); echo();
echo("Website built in " + GH_PAGES_DIR); echo("Website built in " + GH_PAGES_DIR);
echo("Don't forget to cd into " + GH_PAGES_DIR + echo("Don't forget to cd into " + GH_PAGES_DIR +
" and issue 'git commit' to push changes."); " and issue 'git commit' to push changes.");
}; };
// //
@ -169,20 +308,10 @@ target.locale = function() {
chromeManifestContent.to(CHROME_MANIFEST_OUTPUT); chromeManifestContent.to(CHROME_MANIFEST_OUTPUT);
}; };
//
// make production
// Creates production output (pdf.js, and corresponding changes to web/ files)
//
target.production = function() {
target.bundle();
target.viewer();
};
// //
// make bundle // make bundle
// Bundles all source files into one wrapper 'pdf.js' file, in the given order. // Bundles all source files into one wrapper 'pdf.js' file, in the given order.
// //
target.bundle = function() { target.bundle = function() {
cd(ROOT_DIR); cd(ROOT_DIR);
echo(); echo();
@ -223,29 +352,12 @@ target.bundle = function() {
bundleVersion = exec('git log --format="%h" -n 1', bundleVersion = exec('git log --format="%h" -n 1',
{silent: true}).output.replace('\n', ''); {silent: true}).output.replace('\n', '');
sed(/.*PDFJSSCRIPT_INCLUDE_ALL.*\n/, bundle, 'pdf.js') // This just preprocesses the empty pdf.js file, we don't actually want to
.to(ROOT_DIR + BUILD_TARGET); // preprocess everything yet since other build targets use this file.
sed('-i', 'PDFJSSCRIPT_BUNDLE_VER', bundleVersion, ROOT_DIR + BUILD_TARGET); BuildHelper.preprocess('pdf.js', ROOT_DIR + BUILD_TARGET,
{BUNDLE: bundle, BUNDLE_VERSION: bundleVersion});
}; };
//
// make viewer
// Changes development <script> tags in our web viewer to use only 'pdf.js'.
// Produces 'viewer-production.html'
//
target.viewer = function() {
cd(ROOT_DIR);
echo();
echo('### Generating production-level viewer');
cd('web');
// Remove development lines
sed(/.*PDFJSSCRIPT_REMOVE_CORE.*\n/g, '', 'viewer.html')
.to('viewer-production.html');
// Introduce snippet
sed('-i', /.*PDFJSSCRIPT_INCLUDE_BUILD.*\n/g, cat('viewer-snippet.html'),
'viewer-production.html');
};
// //
// make pagesrepo // make pagesrepo
@ -283,15 +395,7 @@ target.pagesrepo = function() {
// Extension stuff // Extension stuff
// //
var EXTENSION_WEB_FILES = var EXTENSION_BASE_VERSION = 'f0f0418a9c6637981fe1182b9212c2d592774c7d',
['web/debugger.js',
'web/images',
'web/viewer.css',
'web/viewer.js',
'web/viewer.html',
'extensions/firefox/tools/l10n.js',
'web/viewer-production.html'],
EXTENSION_BASE_VERSION = 'f0f0418a9c6637981fe1182b9212c2d592774c7d',
EXTENSION_VERSION_PREFIX = '0.3.', EXTENSION_VERSION_PREFIX = '0.3.',
EXTENSION_BUILD_NUMBER, EXTENSION_BUILD_NUMBER,
EXTENSION_VERSION; EXTENSION_VERSION;
@ -305,7 +409,6 @@ target.extension = function() {
echo('### Building extensions'); echo('### Building extensions');
target.locale(); target.locale();
target.production();
target.firefox(); target.firefox();
target.chrome(); target.chrome();
}; };
@ -332,8 +435,10 @@ target.firefox = function() {
cd(ROOT_DIR); cd(ROOT_DIR);
echo(); echo();
echo('### Building Firefox extension'); echo('### Building Firefox extension');
var defines = extendDefines({FIREFOX: true});
var FIREFOX_BUILD_CONTENT_DIR = FIREFOX_BUILD_DIR + '/content/', var FIREFOX_BUILD_CONTENT_DIR = FIREFOX_BUILD_DIR + '/content/',
FIREFOX_EXTENSION_DIR = 'extensions/firefox/',
FIREFOX_CONTENT_DIR = EXTENSION_SRC_DIR + '/firefox/content/', FIREFOX_CONTENT_DIR = EXTENSION_SRC_DIR + '/firefox/content/',
FIREFOX_EXTENSION_FILES_TO_COPY = FIREFOX_EXTENSION_FILES_TO_COPY =
['*.js', ['*.js',
@ -358,7 +463,7 @@ target.firefox = function() {
FIREFOX_AMO_EXTENSION_NAME = 'pdf.js.amo.xpi'; FIREFOX_AMO_EXTENSION_NAME = 'pdf.js.amo.xpi';
target.locale(); target.locale();
target.production(); target.bundle();
target.buildnumber(); target.buildnumber();
cd(ROOT_DIR); cd(ROOT_DIR);
@ -373,25 +478,18 @@ target.firefox = function() {
cp('-R', FIREFOX_EXTENSION_FILES_TO_COPY, ROOT_DIR + FIREFOX_BUILD_DIR); cp('-R', FIREFOX_EXTENSION_FILES_TO_COPY, ROOT_DIR + FIREFOX_BUILD_DIR);
cd(ROOT_DIR); cd(ROOT_DIR);
// Copy a standalone version of pdf.js inside the content directory var setup = {
cp(BUILD_TARGET, FIREFOX_BUILD_CONTENT_DIR + BUILD_DIR); defines: defines,
cp('-R', EXTENSION_WEB_FILES, FIREFOX_BUILD_CONTENT_DIR + '/web'); copy: [
rm(FIREFOX_BUILD_CONTENT_DIR + '/web/viewer-production.html'); [COMMON_WEB_FILES, FIREFOX_BUILD_CONTENT_DIR + '/web'],
['extensions/firefox/tools/l10n.js', FIREFOX_BUILD_CONTENT_DIR + '/web']
],
preprocess: [
[COMMON_WEB_FILES_PREPROCESS, FIREFOX_BUILD_CONTENT_DIR + '/web']
]
};
BuildHelper.build(setup);
// Copy over the firefox extension snippet so we can inline pdf.js in it
cp('web/viewer-snippet-firefox-extension.html', FIREFOX_BUILD_CONTENT_DIR + '/web');
// Modify the viewer so it does all the extension-only stuff.
cd(FIREFOX_BUILD_CONTENT_DIR + '/web');
sed('-i', /.*PDFJSSCRIPT_INCLUDE_BUNDLE.*\n/, cat(ROOT_DIR + BUILD_TARGET), 'viewer-snippet-firefox-extension.html');
sed('-i', /.*PDFJSSCRIPT_REMOVE_CORE.*\n/g, '', 'viewer.html');
sed('-i', /.*PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION.*\n/g, '', 'viewer.html');
sed('-i', /.*PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION.*\n/, cat('viewer-snippet-firefox-extension.html'), 'viewer.html');
cd(ROOT_DIR);
// We don't need pdf.js anymore since its inlined
rm('-Rf', FIREFOX_BUILD_CONTENT_DIR + BUILD_DIR);
rm(FIREFOX_BUILD_CONTENT_DIR + '/web/viewer-snippet-firefox-extension.html');
// Remove '.DS_Store' and other hidden files // Remove '.DS_Store' and other hidden files
find(FIREFOX_BUILD_DIR).forEach(function(file) { find(FIREFOX_BUILD_DIR).forEach(function(file) {
if (file.match(/^\./)) if (file.match(/^\./))
@ -433,6 +531,7 @@ target.mozcentral = function() {
cd(ROOT_DIR); cd(ROOT_DIR);
echo(); echo();
echo('### Building mozilla-central extension'); echo('### Building mozilla-central extension');
var defines = extendDefines({MOZCENTRAL: true});
var MOZCENTRAL_DIR = BUILD_DIR + 'mozcentral/', var MOZCENTRAL_DIR = BUILD_DIR + 'mozcentral/',
MOZCENTRAL_EXTENSION_DIR = MOZCENTRAL_DIR + 'browser/extensions/pdfjs/', MOZCENTRAL_EXTENSION_DIR = MOZCENTRAL_DIR + 'browser/extensions/pdfjs/',
@ -457,7 +556,7 @@ target.mozcentral = function() {
'content', 'content',
'LICENSE']; 'LICENSE'];
target.production(); target.bundle();
target.buildnumber(); target.buildnumber();
cd(ROOT_DIR); cd(ROOT_DIR);
@ -477,25 +576,18 @@ target.mozcentral = function() {
ROOT_DIR + MOZCENTRAL_EXTENSION_DIR + '/chrome.manifest') ROOT_DIR + MOZCENTRAL_EXTENSION_DIR + '/chrome.manifest')
cd(ROOT_DIR); cd(ROOT_DIR);
// Copy a standalone version of pdf.js inside the content directory var setup = {
cp(BUILD_TARGET, MOZCENTRAL_CONTENT_DIR + BUILD_DIR); defines: defines,
cp('-R', EXTENSION_WEB_FILES, MOZCENTRAL_CONTENT_DIR + '/web'); copy: [
rm(MOZCENTRAL_CONTENT_DIR + '/web/viewer-production.html'); [COMMON_WEB_FILES, MOZCENTRAL_CONTENT_DIR + '/web'],
['extensions/firefox/tools/l10n.js', MOZCENTRAL_CONTENT_DIR + '/web']
],
preprocess: [
[COMMON_WEB_FILES_PREPROCESS, MOZCENTRAL_CONTENT_DIR + '/web']
]
};
BuildHelper.build(setup);
// Copy over the firefox extension snippet so we can inline pdf.js in it
cp('web/viewer-snippet-firefox-extension.html', MOZCENTRAL_CONTENT_DIR + '/web');
// Modify the viewer so it does all the extension-only stuff.
cd(MOZCENTRAL_CONTENT_DIR + '/web');
sed('-i', /.*PDFJSSCRIPT_INCLUDE_BUNDLE.*\n/, cat(ROOT_DIR + BUILD_TARGET), 'viewer-snippet-firefox-extension.html');
sed('-i', /.*PDFJSSCRIPT_REMOVE_CORE.*\n/g, '', 'viewer.html');
sed('-i', /.*PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION.*\n/g, '', 'viewer.html');
sed('-i', /.*PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION.*\n/, cat('viewer-snippet-firefox-extension.html'), 'viewer.html');
cd(ROOT_DIR);
// We don't need pdf.js anymore since its inlined
rm('-Rf', MOZCENTRAL_CONTENT_DIR + BUILD_DIR);
rm(MOZCENTRAL_CONTENT_DIR + '/web/viewer-snippet-firefox-extension.html');
// Remove '.DS_Store' and other hidden files // Remove '.DS_Store' and other hidden files
find(MOZCENTRAL_DIR).forEach(function(file) { find(MOZCENTRAL_DIR).forEach(function(file) {
if (file.match(/^\./)) if (file.match(/^\./))
@ -532,42 +624,29 @@ target.b2g = function() {
echo('### Building B2G (Firefox OS App)'); echo('### Building B2G (Firefox OS App)');
var B2G_BUILD_DIR = BUILD_DIR + '/b2g/', var B2G_BUILD_DIR = BUILD_DIR + '/b2g/',
B2G_BUILD_CONTENT_DIR = B2G_BUILD_DIR + '/content/'; B2G_BUILD_CONTENT_DIR = B2G_BUILD_DIR + '/content/';
target.production(); var defines = extendDefines({ B2G: true });
target.buildnumber(); target.bundle();
// Clear out everything in the b2g build directory // Clear out everything in the b2g build directory
cd(ROOT_DIR); cd(ROOT_DIR);
rm('-Rf', B2G_BUILD_DIR); rm('-Rf', B2G_BUILD_DIR);
mkdir('-p', B2G_BUILD_CONTENT_DIR); mkdir('-p', B2G_BUILD_CONTENT_DIR);
mkdir('-p', B2G_BUILD_CONTENT_DIR + BUILD_DIR); mkdir('-p', B2G_BUILD_CONTENT_DIR + BUILD_DIR);
mkdir('-p', B2G_BUILD_CONTENT_DIR + '/web'); mkdir('-p', B2G_BUILD_CONTENT_DIR + '/web');
// Copy a standalone version of pdf.js inside the content directory var setup = {
cp(BUILD_TARGET, B2G_BUILD_CONTENT_DIR + BUILD_DIR); defines: defines,
cp('-R', EXTENSION_WEB_FILES, B2G_BUILD_CONTENT_DIR + '/web'); copy: [
cp('web/viewer-snippet-b2g.html', B2G_BUILD_CONTENT_DIR + '/web/'); [COMMON_WEB_FILES, B2G_BUILD_CONTENT_DIR + '/web'],
// Replacing the l10n.js file with regular gh-pages one ['web/locale.properties', B2G_BUILD_CONTENT_DIR + '/web'],
rm(B2G_BUILD_CONTENT_DIR + '/web/l10n.js'); ['external/webL10n/l10n.js', B2G_BUILD_CONTENT_DIR + '/web']
cp('external/webL10n/l10n.js', B2G_BUILD_CONTENT_DIR + '/web'); ],
cp('web/locale.properties', B2G_BUILD_CONTENT_DIR + '/web'); preprocess: [
[COMMON_WEB_FILES_PREPROCESS, B2G_BUILD_CONTENT_DIR + '/web'],
mv('-f', B2G_BUILD_CONTENT_DIR + '/web/viewer-production.html', [BUILD_TARGET, B2G_BUILD_CONTENT_DIR + BUILD_TARGET]
B2G_BUILD_CONTENT_DIR + '/web/viewer.html'); ]
cd(B2G_BUILD_CONTENT_DIR + '/web');
sed('-i', /.*PDFJSSCRIPT_INCLUDE_B2G.*\n/, cat('viewer-snippet-b2g.html'), 'viewer.html');
rm('viewer-snippet-b2g.html');
cd(ROOT_DIR);
var flags = {
B2G: true
}; };
var prep = [ BuildHelper.build(setup);
B2G_BUILD_CONTENT_DIR + '/web/viewer.js',
B2G_BUILD_CONTENT_DIR + '/build/pdf.js'
];
for (var i in prep) {
preprocess(prep[i], prep[i], flags);
}
}; };
// //
@ -577,15 +656,12 @@ target.chrome = function() {
cd(ROOT_DIR); cd(ROOT_DIR);
echo(); echo();
echo('### Building Chrome extension'); echo('### Building Chrome extension');
var defines = extendDefines({CHROME: true});
var CHROME_BUILD_DIR = BUILD_DIR + '/chrome/', var CHROME_BUILD_DIR = BUILD_DIR + '/chrome/',
CHROME_CONTENT_DIR = EXTENSION_SRC_DIR + '/chrome/content/', CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR + '/content/';
CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR + '/content/',
CHROME_EXTENSION_FILES =
['extensions/chrome/*.json',
'extensions/chrome/*.html'];
target.production(); target.bundle();
target.buildnumber(); target.buildnumber();
cd(ROOT_DIR); cd(ROOT_DIR);
@ -595,18 +671,20 @@ target.chrome = function() {
mkdir('-p', CHROME_BUILD_CONTENT_DIR + BUILD_DIR); mkdir('-p', CHROME_BUILD_CONTENT_DIR + BUILD_DIR);
mkdir('-p', CHROME_BUILD_CONTENT_DIR + '/web'); mkdir('-p', CHROME_BUILD_CONTENT_DIR + '/web');
// Copy extension files var setup = {
cp('-R', CHROME_EXTENSION_FILES, CHROME_BUILD_DIR); defines: defines,
copy: [
// Copy a standalone version of pdf.js inside the content directory [COMMON_WEB_FILES, CHROME_BUILD_CONTENT_DIR + '/web'],
cp(BUILD_TARGET, CHROME_BUILD_CONTENT_DIR + BUILD_DIR); [['extensions/chrome/*.json', 'extensions/chrome/*.html'], CHROME_BUILD_DIR],
cp('-R', EXTENSION_WEB_FILES, CHROME_BUILD_CONTENT_DIR + '/web'); [BUILD_TARGET, CHROME_BUILD_CONTENT_DIR + BUILD_TARGET],
// Replacing the l10n.js file with regular gh-pages one ['external/webL10n/l10n.js', CHROME_BUILD_CONTENT_DIR + '/web']
rm(CHROME_BUILD_CONTENT_DIR + '/web/l10n.js'); ],
cp('external/webL10n/l10n.js', CHROME_BUILD_CONTENT_DIR + '/web'); preprocess: [
cp('web/locale.properties', CHROME_BUILD_CONTENT_DIR + '/web'); [COMMON_WEB_FILES_PREPROCESS, CHROME_BUILD_CONTENT_DIR + '/web'],
mv('-f', CHROME_BUILD_CONTENT_DIR + '/web/viewer-production.html', ['web/locale.properties', CHROME_BUILD_CONTENT_DIR + '/web']
CHROME_BUILD_CONTENT_DIR + '/web/viewer.html'); ]
};
BuildHelper.build(setup);
}; };

View File

@ -430,19 +430,18 @@ var WorkerTransport = (function WorkerTransportClosure() {
try { try {
var worker; var worker;
if (PDFJS.isFirefoxExtension) { //#if !(FIREFOX || MOZCENTRAL)
// The firefox extension can't load the worker from the resource:// // Some versions of FF can't create a worker on localhost, see:
// url so we have to inline the script and then use the blob loader. // https://bugzilla.mozilla.org/show_bug.cgi?id=683280
var bb = new MozBlobBuilder(); worker = new Worker(workerSrc);
bb.append(document.querySelector('#PDFJS_SCRIPT_TAG').textContent); //#else
var blobUrl = window.URL.createObjectURL(bb.getBlob()); // // The firefox extension can't load the worker from the resource://
worker = new Worker(blobUrl); // // url so we have to inline the script and then use the blob loader.
} else { // var bb = new MozBlobBuilder();
// Some versions of FF can't create a worker on localhost, see: // bb.append(document.querySelector('#PDFJS_SCRIPT_TAG').textContent);
// https://bugzilla.mozilla.org/show_bug.cgi?id=683280 // var blobUrl = window.URL.createObjectURL(bb.getBlob());
worker = new Worker(workerSrc); // worker = new Worker(blobUrl);
} //#endif
var messageHandler = new MessageHandler('main', worker); var messageHandler = new MessageHandler('main', worker);
this.messageHandler = messageHandler; this.messageHandler = messageHandler;

View File

@ -7,9 +7,13 @@ var PDFJS = {};
// Use strict in our context only - users might not want it // Use strict in our context only - users might not want it
'use strict'; 'use strict';
PDFJS.build = 'PDFJSSCRIPT_BUNDLE_VER'; PDFJS.build =
//#if !BUNDLE_VERSION
'PDFJSSCRIPT_BUNDLE_VER';
//#else
//#expand '__BUNDLE_VERSION__';
//#endif
// Files are inserted below - see Makefile //#expand __BUNDLE__
/* PDFJSSCRIPT_INCLUDE_ALL */
}).call((typeof window === 'undefined') ? this : window); }).call((typeof window === 'undefined') ? this : window);

View File

@ -1,14 +1,11 @@
<!-- This snippet is used in firefox extension, see Makefile --> <!-- This snippet is used in firefox extension, see Makefile -->
<base href="resource://pdf.js/web/" /> <base href="resource://pdf.js/web/" />
<script type="application/l10n">
<!-- PDFJSSCRIPT_LOCALE_DATA -->
</script>
<script type="text/javascript" src="l10n.js"></script> <script type="text/javascript" src="l10n.js"></script>
<script type="text/javascript" id="PDFJS_SCRIPT_TAG"> <script type="text/javascript" id="PDFJS_SCRIPT_TAG">
<!-- <!--
// pdf.js is inlined here because resource:// urls won't work // pdf.js is inlined here because resource:// urls won't work
// for loading workers. // for loading workers.
/* PDFJSSCRIPT_INCLUDE_BUNDLE */ //#include ../build/pdf.js
--> -->
</script> </script>
<script type="text/javascript"> <script type="text/javascript">

View File

@ -4,41 +4,60 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>PDF.js viewer</title> <title>PDF.js viewer</title>
<!-- PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION -->
<!--#if FIREFOX-->
<!--#include viewer-snippet-firefox-extension.html-->
<!--#endif-->
<link rel="stylesheet" href="viewer.css"/> <link rel="stylesheet" href="viewer.css"/>
<link rel="resource" type="application/l10n" href="locale.properties"/><!-- PDFJSSCRIPT_REMOVE_CORE --> <!--#if !PRODUCTION-->
<link rel="resource" type="application/l10n" href="locale.properties"/>
<!--#endif-->
<script type="text/javascript" src="compatibility.js"></script> <!-- PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION --> <!--#if !FIREFOX -->
<script type="text/javascript" src="../external/webL10n/l10n.js"></script><!-- PDFJSSCRIPT_REMOVE_CORE --> <script type="text/javascript" src="compatibility.js"></script>
<!--#endif-->
<!--#if !PRODUCTION-->
<script type="text/javascript" src="../external/webL10n/l10n.js"></script>
<!--#endif-->
<!--#if !PRODUCTION-->
<script type="text/javascript" src="../src/core.js"></script>
<script type="text/javascript" src="../src/util.js"></script>
<script type="text/javascript" src="../src/api.js"></script>
<script type="text/javascript" src="../src/metadata.js"></script>
<script type="text/javascript" src="../src/canvas.js"></script>
<script type="text/javascript" src="../src/obj.js"></script>
<script type="text/javascript" src="../src/function.js"></script>
<script type="text/javascript" src="../src/charsets.js"></script>
<script type="text/javascript" src="../src/cidmaps.js"></script>
<script type="text/javascript" src="../src/colorspace.js"></script>
<script type="text/javascript" src="../src/crypto.js"></script>
<script type="text/javascript" src="../src/evaluator.js"></script>
<script type="text/javascript" src="../src/fonts.js"></script>
<script type="text/javascript" src="../src/glyphlist.js"></script>
<script type="text/javascript" src="../src/image.js"></script>
<script type="text/javascript" src="../src/metrics.js"></script>
<script type="text/javascript" src="../src/parser.js"></script>
<script type="text/javascript" src="../src/pattern.js"></script>
<script type="text/javascript" src="../src/stream.js"></script>
<script type="text/javascript" src="../src/worker.js"></script>
<script type="text/javascript" src="../external/jpgjs/jpg.js"></script>
<script type="text/javascript" src="../src/jpx.js"></script>
<script type="text/javascript" src="../src/jbig2.js"></script>
<script type="text/javascript" src="../src/bidi.js"></script>
<script type="text/javascript">PDFJS.workerSrc = '../src/worker_loader.js';</script>
<!--#endif-->
<!--#if GENERIC || CHROME-->
<!--#include viewer-snippet.html-->
<!--#endif-->
<!--#if B2G-->
<!--#include viewer-snippet-b2g.html-->
<!--#endif-->
<!-- PDFJSSCRIPT_INCLUDE_BUILD -->
<script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/util.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/api.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/metadata.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/canvas.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/obj.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/function.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/charsets.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/cidmaps.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/colorspace.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/crypto.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/evaluator.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/fonts.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/glyphlist.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/image.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/metrics.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/parser.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/pattern.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/stream.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/worker.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../external/jpgjs/jpg.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/jpx.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/jbig2.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript" src="../src/bidi.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<script type="text/javascript">PDFJS.workerSrc = '../src/worker_loader.js';</script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
<!-- PDFJSSCRIPT_INCLUDE_B2G -->
<script type="text/javascript" src="debugger.js"></script> <script type="text/javascript" src="debugger.js"></script>
<script type="text/javascript" src="viewer.js"></script> <script type="text/javascript" src="viewer.js"></script>
</head> </head>

View File

@ -90,6 +90,7 @@ var ProgressBar = (function ProgressBarClosure() {
return ProgressBar; return ProgressBar;
})(); })();
//#if FIREFOX || MOZCENTRAL
var FirefoxCom = (function FirefoxComClosure() { var FirefoxCom = (function FirefoxComClosure() {
return { return {
/** /**
@ -150,6 +151,7 @@ var FirefoxCom = (function FirefoxComClosure() {
} }
}; };
})(); })();
//#endif
// Settings Manager - This is a utility for saving settings // Settings Manager - This is a utility for saving settings
// First we see if localStorage is available // First we see if localStorage is available
@ -167,17 +169,17 @@ var Settings = (function SettingsClosure() {
} }
})(); })();
var isFirefoxExtension = PDFJS.isFirefoxExtension;
function Settings(fingerprint) { function Settings(fingerprint) {
var database = null; var database = null;
var index; var index;
if (isFirefoxExtension) //#if !(FIREFOX || MOZCENTRAL)
database = FirefoxCom.requestSync('getDatabase', null) || '{}'; if (isLocalStorageEnabled)
else if (isLocalStorageEnabled)
database = localStorage.getItem('database') || '{}'; database = localStorage.getItem('database') || '{}';
else else
return false; return false;
//#else
// database = FirefoxCom.requestSync('getDatabase', null) || '{}';
//#endif
database = JSON.parse(database); database = JSON.parse(database);
if (!('files' in database)) if (!('files' in database))
@ -205,10 +207,12 @@ var Settings = (function SettingsClosure() {
var file = this.file; var file = this.file;
file[name] = val; file[name] = val;
var database = JSON.stringify(this.database); var database = JSON.stringify(this.database);
if (isFirefoxExtension) //#if !(FIREFOX || MOZCENTRAL)
FirefoxCom.requestSync('setDatabase', database); if (isLocalStorageEnabled)
else if (isLocalStorageEnabled)
localStorage.setItem('database', database); localStorage.setItem('database', database);
//#else
// FirefoxCom.requestSync('setDatabase', database);
//#endif
}, },
get: function settingsGet(name, defaultValue) { get: function settingsGet(name, defaultValue) {
@ -460,52 +464,54 @@ var PDFView = {
} }
var url = this.url.split('#')[0]; var url = this.url.split('#')[0];
if (PDFJS.isFirefoxExtension) { //#if !(FIREFOX || MOZCENTRAL)
// Document isn't ready just try to download with the url. url += '#pdfjs.action=download', '_parent';
if (!this.pdfDocument) { window.open(url, '_parent');
noData(); //#else
return; // // Document isn't ready just try to download with the url.
} // if (!this.pdfDocument) {
this.pdfDocument.getData().then( // noData();
function getDataSuccess(data) { // return;
var bb = new MozBlobBuilder(); // }
bb.append(data.buffer); // this.pdfDocument.getData().then(
var blobUrl = window.URL.createObjectURL( // function getDataSuccess(data) {
bb.getBlob('application/pdf')); // var bb = new MozBlobBuilder();
// bb.append(data.buffer);
FirefoxCom.request('download', { blobUrl: blobUrl, originalUrl: url }, // var blobUrl = window.URL.createObjectURL(
function response(err) { // bb.getBlob('application/pdf'));
if (err) { //
// This error won't really be helpful because it's likely the // FirefoxCom.request('download', { blobUrl: blobUrl, originalUrl: url },
// fallback won't work either (or is already open). // function response(err) {
PDFView.error('PDF failed to download.'); // if (err) {
} // // This error won't really be helpful because it's likely the
window.URL.revokeObjectURL(blobUrl); // // fallback won't work either (or is already open).
} // PDFView.error('PDF failed to download.');
); // }
}, // window.URL.revokeObjectURL(blobUrl);
noData // Error ocurred try downloading with just the url. // }
); // );
} else { // },
url += '#pdfjs.action=download', '_parent'; // noData // Error ocurred try downloading with just the url.
window.open(url, '_parent'); // );
} //#endif
}, },
fallback: function pdfViewFallback() { fallback: function pdfViewFallback() {
if (!PDFJS.isFirefoxExtension) //#if !(FIREFOX || MOZCENTRAL)
return; return;
// Only trigger the fallback once so we don't spam the user with messages //#else
// for one PDF. // // Only trigger the fallback once so we don't spam the user with messages
if (this.fellback) // // for one PDF.
return; // if (this.fellback)
this.fellback = true; // return;
var url = this.url.split('#')[0]; // this.fellback = true;
FirefoxCom.request('fallback', url, function response(download) { // var url = this.url.split('#')[0];
if (!download) // FirefoxCom.request('fallback', url, function response(download) {
return; // if (!download)
PDFView.download(); // return;
}); // PDFView.download();
// });
//#endif
}, },
navigateTo: function pdfViewNavigateTo(dest) { navigateTo: function pdfViewNavigateTo(dest) {
@ -557,9 +563,11 @@ var PDFView = {
* @param {String} anchor The anchor hash include the #. * @param {String} anchor The anchor hash include the #.
*/ */
getAnchorUrl: function getAnchorUrl(anchor) { getAnchorUrl: function getAnchorUrl(anchor) {
if (PDFJS.isFirefoxExtension) //#if !(FIREFOX || MOZCENTRAL)
return this.url.split('#')[0] + anchor;
return anchor; return anchor;
//#else
// return this.url.split('#')[0] + anchor;
//#endif
}, },
/** /**
@ -593,11 +601,7 @@ var PDFView = {
} }
} }
} }
if (PDFJS.isFirefoxExtension) { //#if !(FIREFOX || MOZCENTRAL)
console.error(message + '\n' + moreInfoText);
this.fallback();
return;
}
var errorWrapper = document.getElementById('errorWrapper'); var errorWrapper = document.getElementById('errorWrapper');
errorWrapper.removeAttribute('hidden'); errorWrapper.removeAttribute('hidden');
@ -627,6 +631,10 @@ var PDFView = {
errorMoreInfo.value = moreInfoText; errorMoreInfo.value = moreInfoText;
errorMoreInfo.rows = moreInfoText.split('\n').length - 1; errorMoreInfo.rows = moreInfoText.split('\n').length - 1;
//#else
// console.error(message + '\n' + moreInfoText);
// this.fallback();
//#endif
}, },
progress: function pdfViewProgress(level) { progress: function pdfViewProgress(level) {
@ -1804,15 +1812,21 @@ window.addEventListener('load', function webViewerLoad(evt) {
PDFView.initialize(); PDFView.initialize();
var params = PDFView.parseQueryString(document.location.search.substring(1)); var params = PDFView.parseQueryString(document.location.search.substring(1));
var file = PDFJS.isFirefoxExtension ? //#if !(FIREFOX || MOZCENTRAL)
window.location.toString() : params.file || kDefaultURL; var file = params.file || kDefaultURL;
//#else
//var file = window.location.toString()
//#endif
if (PDFJS.isFirefoxExtension || !window.File || !window.FileReader || //#if !(FIREFOX || MOZCENTRAL)
!window.FileList || !window.Blob) { if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
document.getElementById('openFile').setAttribute('hidden', 'true'); document.getElementById('openFile').setAttribute('hidden', 'true');
} else { } else {
document.getElementById('fileInput').value = null; document.getElementById('fileInput').value = null;
} }
//#else
//document.getElementById('openFile').setAttribute('hidden', 'true');
//#endif
// Special debugging flags in the hash section of the URL. // Special debugging flags in the hash section of the URL.
var hash = document.location.hash.substring(1); var hash = document.location.hash.substring(1);
@ -1821,18 +1835,21 @@ window.addEventListener('load', function webViewerLoad(evt) {
if ('disableWorker' in hashParams) if ('disableWorker' in hashParams)
PDFJS.disableWorker = (hashParams['disableWorker'] === 'true'); PDFJS.disableWorker = (hashParams['disableWorker'] === 'true');
if (!PDFJS.isFirefoxExtension) { //#if !(FIREFOX || MOZCENTRAL)
var locale = navigator.language; var locale = navigator.language;
if ('locale' in hashParams) if ('locale' in hashParams)
locale = hashParams['locale']; locale = hashParams['locale'];
mozL10n.language.code = locale; mozL10n.language.code = locale;
} //#endif
if ('disableTextLayer' in hashParams) if ('disableTextLayer' in hashParams)
PDFJS.disableTextLayer = (hashParams['disableTextLayer'] === 'true'); PDFJS.disableTextLayer = (hashParams['disableTextLayer'] === 'true');
if ('pdfBug' in hashParams && //#if !(FIREFOX || MOZCENTRAL)
(!PDFJS.isFirefoxExtension || FirefoxCom.requestSync('pdfBugEnabled'))) { if ('pdfBug' in hashParams) {
//#else
//if ('pdfBug' in hashParams && FirefoxCom.requestSync('pdfBugEnabled')) {
//#endif
PDFJS.pdfBug = true; PDFJS.pdfBug = true;
var pdfBug = hashParams['pdfBug']; var pdfBug = hashParams['pdfBug'];
var enabled = pdfBug.split(','); var enabled = pdfBug.split(',');
@ -1840,10 +1857,12 @@ window.addEventListener('load', function webViewerLoad(evt) {
PDFBug.init(); PDFBug.init();
} }
if (!PDFJS.isFirefoxExtension || //#if !(FIREFOX || MOZCENTRAL)
(PDFJS.isFirefoxExtension && FirefoxCom.requestSync('searchEnabled'))) { //#else
document.querySelector('#viewSearch').classList.remove('hidden'); //if (FirefoxCom.requestSync('searchEnabled')) {
} // document.querySelector('#viewSearch').classList.remove('hidden');
//}
//#endif
if (!PDFView.supportsPrinting) { if (!PDFView.supportsPrinting) {
document.getElementById('print').classList.add('hidden'); document.getElementById('print').classList.add('hidden');
@ -2143,19 +2162,19 @@ window.addEventListener('afterprint', function afterPrint(evt) {
})(); })();
//#if B2G //#if B2G
// window.navigator.mozSetMessageHandler('activity', function(activity) { //window.navigator.mozSetMessageHandler('activity', function(activity) {
// var url = activity.source.data.url; // var url = activity.source.data.url;
// // Temporarily get the data here since the cross domain xhr is broken in // // Temporarily get the data here since the cross domain xhr is broken in
// // the worker currently, see bug 761227. // // the worker currently, see bug 761227.
// var params = { // var params = {
// url: url, // url: url,
// error: function(e) { // error: function(e) {
// PDFView.error(mozL10n.get('loading_error', null, // PDFView.error(mozL10n.get('loading_error', null,
// 'An error occurred while loading the PDF.'), e); // 'An error occurred while loading the PDF.'), e);
// } // }
// }; // };
// PDFJS.getPdf(params, function successCallback(data) { // PDFJS.getPdf(params, function successCallback(data) {
// PDFView.open(data, 0); // PDFView.open(data, 0);
// }); // });
// }); //});
//#endif //#endif