reader/android: initial web-veiw JS
A make task has been added to web/Makefile for generating the JS build to be
loaded into the Android web view for PDF rendering via PDF.js:
make public/pdf-web-view.js
The source file lives in browser/pdf-web-view.js to access the build artifacts
from a normal browser visit http://127.0.0.1:8080/pdf-web-view.html after
running `make start`.
The state atom has been attached to the global window and can be accessed from
the developers console or via [Android's evaluateJavascript
API](http://goo.gl/JWUIaz):
window.atom.href.set(<url to pdf file>)
window.atom.pages.current.set(<page number>)
This CL is a first pass at trying to get the rendering working and has some
small issues (error handling, render optimizations, etc.) being tracked as TODOs
in #44.
Change-Id: If7b91453107aa3b5f898ccb66e067163b03eb4af
diff --git a/.gitignore b/.gitignore
index f398c60..ee53436 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@
web/npm-debug.log
web/public/bundle.*
web/tmp
+web/public/pdf-web-view.js
# VDL generated stubs should be ignored
web/browser/vanadium/v.io/*
diff --git a/web/Makefile b/web/Makefile
index 39e4120..74ab93e 100644
--- a/web/Makefile
+++ b/web/Makefile
@@ -19,7 +19,7 @@
cloudsync_port ?= 8000
id ?= $(shell if test -e tmp/id; then cat tmp/id; else PATH=$(PATH) bin/uuid; fi)
-all: public/bundle.js node_modules
+all: public/bundle.js public/pdf-web-view.js
@true # silences watch
.DELETE_ON_ERROR:
@@ -42,6 +42,10 @@
--transform [ envify --ID $(id) ] \
$< 1> $@
+.DELETE_ON_ERROR:
+public/pdf-web-view.js: browser/pdf-web-view.js node_modules
+ browserify --debug $< 1> $@
+
.PHONY:
distclean: clean
@$(RM) -fr node_modules
@@ -59,9 +63,12 @@
@$(RM) -fr browser/vanadium/vdl
.PHONY:
-lint: node_modules
+dependency-check:
@dependency-check package.json --entry browser/main.js
@dependency-check package.json --entry browser/main.js --unused --no-dev
+
+.PHONY:
+lint: node_modules
@jshint .
.PHONY:
diff --git a/web/browser/pdf-web-view.js b/web/browser/pdf-web-view.js
new file mode 100644
index 0000000..8270076
--- /dev/null
+++ b/web/browser/pdf-web-view.js
@@ -0,0 +1,130 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+var debug = require('debug')('pdf-viewer');
+var document = require('global/document');
+var domready = require('domready');
+var struct = require('observ-struct');
+var value = require('observ');
+var window = require('global/window');
+
+var atom = struct({
+ debug: value(true),
+ href: value(null),
+ pdf: struct({
+ document: value(null),
+ page: value(null)
+ }),
+ pages: struct({
+ current: value(1),
+ total: value(0),
+ }),
+ scale: value(1),
+ progress: value(0),
+});
+
+window.atom = atom;
+window.debug = require('debug');
+
+// When the state atom is updated to toggle debugging call the correct methods
+// on the debug module.
+atom.debug(function debugchange(value) {
+ // TODO(jasoncampbell): reload page so changes are picked up.
+ if (value) {
+ window.debug.enable('pdf-*');
+ } else {
+ window.debug.disable();
+ }
+});
+
+// Global cache of the canvas element.
+var canvas = null;
+
+domready(function ondomready() {
+ debug('domready');
+
+ // Initial DOM Node setup.
+ canvas = document.createElement('canvas');
+ canvas.setAttribute('class','pdf-canvas');
+ document.body.style.margin = '0px';
+ document.body.style.padding = '0px';
+ document.body.appendChild(canvas);
+
+ // Watch for changes on the atom.href value, when it updates load the PDF file
+ // located at that location.
+ // Trigger with: atom.href.set(value)
+ atom.href(function hrefchange(href) {
+ debug('loading pdf file: %s', href);
+ PDFJS
+ .getDocument(href, null, password, progress)
+ .then(setPDF, error);
+ });
+
+ // Watch for page number changes and asyncronosly load the page from PDF.js
+ // APIs.
+ // Trigger with: atom.pages.current.set(value)
+ atom.pages.current(function pagechange(current) {
+ var total = atom.pages.total();
+
+ // Skip invalid operations.
+ if (current === 0 || !atom.pdf.document() || current > total) {
+ return;
+ }
+
+ debug('loading page: %s of %s', current, total);
+
+ var pdf = atom.pdf.document();
+ var success = atom.pdf.page.set.bind(null);
+ pdf.getPage(current).then(success, error);
+ });
+
+ // Watch for changes on the PDF.js page object. When it is updated trigger a
+ // render.
+ // TODO(jasoncampbell): To prevent rendering errors with frequent state
+ // updates renders should be queued in a raf.
+ atom.pdf.page(function pagechange(page) {
+ debug('rendering page');
+ // TODO(jasoncampbell): Use state set scale instead of defaulting to 1.0.
+ var scale = window.innerWidth/page.getViewport(1.0).width;
+ var viewport = page.getViewport(scale);
+
+ canvas.height = viewport.height;
+ canvas.width = viewport.width;
+
+ page.render({
+ canvasContext: canvas.getContext('2d'),
+ viewport: viewport
+ }).promise.then(noop, error);
+ });
+});
+
+function setPDF(pdf) {
+ atom.pdf.document.set(pdf);
+ atom.pages.total.set(pdf.numPages);
+ atom.pages.current.set(1);
+}
+
+function progress(update) {
+ var float = (update.loaded/update.total) * 100;
+ var value = Math.floor(float);
+
+ // For some reason the update.loaded value above can be higher than the
+ // update.total value, in that case we can assume the progress is 100%.
+ if (value > 100) {
+ value = 100;
+ }
+
+ atom.progress.set(value);
+}
+
+function password() {
+ debug('password required');
+}
+
+// TODO(jasoncampbell): Add better error reporting and exception capturing.
+function error(err) {
+ debug('error: %s', err.stack);
+}
+
+function noop() {}
diff --git a/web/package.json b/web/package.json
index 094463c..b966425 100644
--- a/web/package.json
+++ b/web/package.json
@@ -37,6 +37,8 @@
"global": "^4.3.0",
"insert-css": "^0.2.0",
"mercury": "^14.0.0",
+ "observ": "^0.2.0",
+ "observ-struct": "^6.0.0",
"once": "^1.3.2",
"path-to-regexp": "^1.2.1",
"pump": "^1.0.1",
diff --git a/web/public/pdf-web-view.html b/web/public/pdf-web-view.html
new file mode 100644
index 0000000..701a420
--- /dev/null
+++ b/web/public/pdf-web-view.html
@@ -0,0 +1,2 @@
+<script type="text/javascript" src="./pdf.js"></script>
+<script type="text/javascript" src="./pdf-web-view.js"></script>
\ No newline at end of file