Commit d94b71bb authored by Vincent Bechu's avatar Vincent Bechu

erp5_officejs: add pdf viewer app

parent 5ed8778f
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OfficeJS Jio PDF View</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script class="view-web-page-template" type="text/x-handlebars-template">
<form class="view-web-page-form">
<div class="center">
<div class="ui-field-contain">
<label data-i18n="Title:">Title:</label>
<div class="ui-input-text ui-body-inherit ui-corner-all ui-shadow-inset">
<input type="text" name="title" value="{{title}}">
</div>
</div>
<button type="submit" data-i18n="Save" style="display:none;">Save</button>
<div class="ui-field-contain">
<label data-i18n="Reference:">Reference:</label>
<input type="text" name="reference" value="{{reference}}">
</div>
<div class="ui-field-contain">
<label data-i18n="Version:">Version:</label>
<input type="text" name="version" value="{{version}}"></label>
</div>
<div class="ui-field-contain">
<label data-i18n="Language:">Language:</label>
<input type="text" name="language" value="{{language}}">
</div>
<div class="ui-field-contain">
<label data-i18n="Description:">Description:</label>
<textarea name="description">{{description}}</textarea>
</div>
<div class='document-content'></div>
</div>
</div>
</form>
</script>
<script src="gadget_officejs_jio_pdf_view.js"></script>
</head>
<body>
</body>
</html>
\ No newline at end of file
/*globals window, rJS, Handlebars, RSVP, loopEventListener, console, URL*/
/*jslint indent: 2, nomen: true, maxlen: 80*/
(function (window, RSVP, rJS, Handlebars, loopEventListener, URL) {
"use strict";
function saveContent(gadget, submit_event) {
var i,
doc = gadget.options.doc,
now = new Date(),
blob;
doc.parent_relative_url = "document_module";
doc.portal_type = "PDF";
doc.modification_date = now.toISOString();
for (i = 0; i < submit_event.target.length; i += 1) {
// XXX Should check input type instead
if (submit_event.target[i].name) {
doc[submit_event.target[i].name] = submit_event.target[i].value;
}
}
return RSVP.Queue()
.push(function () {
return gadget.getDeclaredGadget("my_text_content");
})
.push(function (text_content_gadget) {
return text_content_gadget.getContent();
})
.push(function (dataURI) {
if (dataURI.text_content === "data:") {
return new Blob([''], {type: 'application/pdf'});
}
return jIO.util.dataURItoBlob(dataURI['text_content']);
})
.push(function(blob) {
return RSVP.all([
gadget.put(gadget.options.jio_key, doc),
gadget.putAttachment(gadget.options.jio_key, "data", blob)
]);
});
}
function maximize(gadget) {
var iframe = gadget.props.element.querySelector('iframe'),
iframe_class_string = iframe.getAttribute('class') || "",
class_name = "ui-content-maximize",
class_index = iframe_class_string.indexOf(class_name);
if (class_index === -1) {
iframe_class_string += ' ' + class_name;
iframe.setAttribute('style', '');
iframe.setAttribute('class', iframe_class_string);
return;
}
iframe_class_string = iframe_class_string.substring(0, class_index)
+ iframe_class_string.substring(class_index + class_name.length);
iframe.setAttribute('style', 'width:100%; border: 0 none; height: 600px');
iframe.setAttribute('class', iframe_class_string);
return;
}
var gadget_klass = rJS(window),
source = gadget_klass.__template_element
.querySelector(".view-web-page-template")
.innerHTML,
template = Handlebars.compile(source);
gadget_klass
.ready(function (g) {
g.props = {};
g.options = null;
return g.getElement()
.push(function (element) {
g.props.element = element;
g.props.deferred = RSVP.defer();
});
})
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("get", "jio_get")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("put", "jio_put")
.declareAcquiredMethod("putAttachment", "jio_putAttachment")
.declareAcquiredMethod("getAttachment", "jio_getAttachment")
.declareAcquiredMethod("redirect", "redirect")
.allowPublicAcquisition('triggerMaximize', function () {
var gadget = this;
return RSVP.Queue()
.push(function () {
return maximize(gadget);
})
.fail(function (e) {
console.log(e);
});
})
.allowPublicAcquisition('triggerSubmit', function (option) {
if (option[0] === "maximize" || option === "maximize") {
var gadget = this;
return RSVP.Queue()
.push(function () {
return maximize(gadget);
});
}
return this.props.element.querySelector('button').click();
})
.declareMethod('triggerSubmit', function (option) {
if (option[0] === "maximize" || option === "maximize") {
var gadget = this;
return RSVP.Queue()
.push(function () {
return maximize(gadget);
});
}
return this.props.element.querySelector('button').click();
})
.declareMethod("render", function (options) {
var gadget = this;
gadget.options = options;
gadget.options.doc.title = gadget.options.doc.title || "";
return new RSVP.Queue()
.push(function () {
return gadget.translateHtml(template(options.doc));
})
.push(function (html) {
gadget.props.element.innerHTML = html;
return gadget.updateHeader({
title: options.doc.title + " | PDF",
save_action: true,
maximize_action: true,
maximized: gadget.options.doc.title !== ""
});
})
.push(function() {
return gadget.getAttachment(gadget.options.jio_key, "data");
})
.push(
function (blob_result) {
gadget.props.blob = blob_result;
return gadget.props.deferred.resolve();
}, function (error) {
if (error.status_code === 404) {
gadget.props.blob = new Blob([''], {type: 'application/pdf'});
return gadget.props.deferred.resolve();
}
throw new Error(error);
});
})
/////////////////////////////////////////
// Render text content gadget
/////////////////////////////////////////
.declareService(function () {
var gadget = this,
image_content_gadget;
return new RSVP.Queue()
.push(function () {
return gadget.props.deferred.promise;
})
.push(function () {
return gadget.declareGadget(
"../../officejs_pdf_viewer_gadget/development/",
{
scope: "my_text_content",
sandbox: "iframe",
element: gadget.props.element.querySelector(".document-content")
}
);
})
.push(function (image_gadget) {
image_content_gadget = image_gadget;
var iframe = gadget.props.element.querySelector('iframe');
iframe.setAttribute(
'style',
'width:100%; border: 0 none; height: 600px'
);
iframe.setAttribute(
'allowFullScreen',''
)
return jIO.util.readBlobAsDataURL(gadget.props.blob);
})
.push(function (dataURL) {
if (dataURL.target.result.split('data:')[1] === '') {
dataURL = '';
} else {
dataURL = dataURL.target.result.split(/data:application\/.*;base64,/)[1];
}
return image_content_gadget.render({
"key": 'text_content',
"value": dataURL,
"name": gadget.options.jio_key
});
})
.push(function () {
if (gadget.options.doc.title !== "") {
return gadget.triggerSubmit("maximize");
}
})
.push(undefined, function (error) {
var display_error_element;
if (error.indexOf("Timed out after ") === 0) {
display_error_element =
gadget.props.element.querySelector(
"form div.center"
);
display_error_element.innerHTML =
'<br/><p style="color: red"></p><br/><br/>' +
display_error_element.innerHTML;
display_error_element.querySelector('p').textContent =
"TIMEOUT: The editor gadget is taking too long to load but is" +
" currently being cached, please wait for the page to load" +
" (check your browser loading icon) and then refresh.";
} else {
throw error;
}
});
})
/////////////////////////////////////////
// Form submit
/////////////////////////////////////////
.declareService(function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return gadget.props.deferred.promise;
})
.push(function () {
return loopEventListener(
gadget.props.element.querySelector('form'),
'submit',
true,
function (event) {
return saveContent(gadget, event);
}
);
});
});
}(window, RSVP, rJS, Handlebars, loopEventListener, URL));
\ No newline at end of file
/*jslint indent: 2, nomen: true */
/*global window, rJS, RSVP, PDFJS, webViewerLoad, Uint8Array,
ArrayBuffer, PDFViewerApplication, FileReader */
(function (window, rJS, RSVP, PDFJS, webViewerLoad) {
"use strict";
rJS(window)
.ready(function (gadget) {
gadget.props = {};
return gadget.getElement()
.push(function (element) {
gadget.props.element = element;
});
})
.declareMethod("render", function (options) {
[].forEach.call(window.document.head.querySelectorAll("base"), function (el) {
// XXX GadgetField adds <base> tag to fit to the parent page location, it's BAD to remove them.
// In the case of pdf.js, all component are loaded dynamicaly through ajax requests in
// pdf-js "folder". By setting a <base> tag, we change the url resolution behavior, and
// we break all dynamic links. So, deleting <base> is required.
window.document.head.removeChild(el);
});
this.props.key = options.key;
var raw = window.atob(options.value);
var rawLength = raw.length;
var array = new Uint8Array(new ArrayBuffer(rawLength));
for (var i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
webViewerLoad(array);
// hide few buttons for now
this.props.element.querySelector('#viewBookmark').hidden = true;
this.props.element.querySelector('#documentProperties').hidden = true;
this.props.element.querySelector('#documentProperties').hidden = true;
return;
})
.declareMethod("getContent", function () {
var form_data = {};
var self = this;
return new RSVP.Queue()
.push(function () {
if (PDFViewerApplication.pdfDocument) {
return PDFViewerApplication.pdfDocument.getData();
} else {
return '';
}
})
.push(function (data) {
var blob = PDFJS.createBlob(data, "application/pdf");
var filereader = new FileReader();
return new RSVP.Promise(function (resolve, reject, notify) {
filereader.addEventListener("load", resolve);
filereader.addEventListener("error", reject);
filereader.addEventListener("progress", notify);
filereader.readAsDataURL(blob);
}, function () {
filereader.abort();
});
})
.push(function (evt) {
form_data[self.props.key] = evt.target.result;
return form_data;
});
});
}(window, rJS, RSVP, PDFJS, webViewerLoad, PDFViewerApplication));
<!DOCTYPE html>
<html manifest="gadget_officejs.appcache">
<head>
<base href="">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" href="favicon.ico">
<title>PDF Viewer</title>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="jquerymobile.css">
<link rel="stylesheet" href="gadget_erp5.css">
<script data-renderjs-configuration="application_title" type="text/x-renderjs-configuration">PDF Viewer</script>
<script data-renderjs-configuration="panel_gadget" type="text/x-renderjs-configuration">gadget_officejs_application_panel.html</script>
<script data-renderjs-configuration="action_view" type="text/x-renderjs-configuration">object_view</script>
<script data-renderjs-configuration="default_view_reference" type="text/x-renderjs-configuration">view</script>
<script data-renderjs-configuration="hateoas_url" type="text/x-renderjs-configuration">hateoas/</script>
<script data-renderjs-configuration="frontpage_gadget" type="text/x-renderjs-configuration">worklist</script>
<script src="jquery.js"></script>
<script src="jquerymobile.js"></script>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_global.js" ></script>
<script src="erp5_launcher.js"></script>
</head>
<body>
<div data-role="page">
<div data-gadget-url="gadget_jio.html"
data-gadget-scope="setting_gadget"
data-gadget-sandbox="public"></div>
<div data-gadget-url="gadget_officejs_pdf_viewer_router.html"
data-gadget-scope="router"
data-gadget-sandbox="public"></div>
<div data-gadget-url="gadget_translation.html"
data-gadget-scope="translation_gadget"
data-gadget-sandbox="public"></div>
<div data-gadget-url="gadget_officejs_header.html"
data-gadget-scope="header"
data-gadget-sandbox="public"></div>
<div data-gadget-url="gadget_officejs_jio.html"
data-gadget-scope="jio_gadget"
data-gadget-sandbox="public"></div>
<div data-gadget-url="gadget_erp5_editor_panel.html"
data-gadget-scope="editor_panel"
data-gadget-sandbox="public"></div>
<div data-gadget-url="gadget_officejs_application_panel.html"
data-gadget-scope="panel"
data-gadget-sandbox="public"></div>
<div role="main" class="ui-content gadget-content"></div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>OfficeJS Router Gadget</title>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_officejs_router.js" type="text/javascript"></script>
</head>
<body>
<script data-renderjs-configuration="portal_type" type="text/x-renderjs-configuration">PDF</script>
<script data-renderjs-configuration="parent_relative_url" type="text/x-renderjs-configuration">document_module</script>
<script data-renderjs-configuration="document_title" type="text/x-renderjs-configuration">PDF</script>
<script data-renderjs-configuration="document_title_plural" type="text/x-renderjs-configuration">PDFs</script>
<script data-renderjs-configuration="erp5_attachment_synchro" type="text/x-renderjs-configuration">/{+id}/Base_downloadWithCors</script>
<script data-renderjs-configuration="global_setting_gadget_url" type="text/x-renderjs-configuration">../officejs_setting_gadget/</script>
</body>
</html>
\ No newline at end of file
......@@ -15,4 +15,8 @@
<skin_folder>erp5_web_versioning</skin_folder>
<skin_selection>RJSVersioning</skin_selection>
</skin_folder_selection>
<skin_folder_selection>
<skin_folder>erp5_xhtml_style</skin_folder>
<skin_selection>RJS,RJSVersioning</skin_selection>
</skin_folder_selection>
</registered_skin_selection>
\ No newline at end of file
......@@ -16,3 +16,5 @@ web_site_module/officejs_svg_editor
web_site_module/officejs_svg_editor/**
web_site_module/officejs_svg_editor_gadget
web_site_module/officejs_svg_editor_gadget/**
web_site_module/officejs_pdf_viewer_gadget
web_site_module/officejs_pdf_viewer_gadget/**
\ No newline at end of file
......@@ -16,3 +16,5 @@ web_site_module/officejs_setting_gadget
web_site_module/officejs_setting_gadget/**
web_site_module/officejs_ckeditor_gadget
web_site_module/officejs_ckeditor_gadget/**
web_site_module/officejs_pdf_viewer_gadget
web_site_module/officejs_pdf_viewer_gadget/**
\ No newline at end of file
......@@ -6,6 +6,10 @@ web_site_module/officejs_bookmark_manager
web_site_module/officejs_bookmark_manager/**
web_site_module/officejs_ckeditor_gadget
web_site_module/officejs_ckeditor_gadget/**
web_site_module/officejs_pdf_viewer
web_site_module/officejs_pdf_viewer/**
web_site_module/officejs_pdf_viewer_gadget
web_site_module/officejs_pdf_viewer_gadget/**
web_site_module/officejs_setting_gadget
web_site_module/officejs_setting_gadget/**
web_site_module/officejs_spreadsheet
......
......@@ -2,3 +2,5 @@ erp5_officejs_jio_connector | RJSVersioning
erp5_web_renderjs_ui | RJSVersioning
erp5_web_renderjs_ui_unsafe | RJSUnsafe
erp5_web_versioning | RJSVersioning
erp5_xhtml_style | RJS
erp5_xhtml_style | RJSVersioning
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment