Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2017-05-05 21:43:13 +0300
committerPhil Hughes <me@iamphill.com>2017-05-05 21:43:13 +0300
commitecaa68a7095750ef7575fdefdb200ef01ef88748 (patch)
tree8728d073f15d64f8b5254ab8126804f6855aa4e4 /app/assets/javascripts
parent1bf9f012ccd744f415ffcb32c6af36dc04d7e07a (diff)
parent165bcec30506380efa912b3dba25815aeea9c92f (diff)
Merge branch 'balsalmiq-support' into 'master'
Initial balsamiq support See merge request !10564
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js114
-rw-r--r--app/assets/javascripts/blob/balsamiq_viewer.js6
2 files changed, 120 insertions, 0 deletions
diff --git a/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js b/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js
new file mode 100644
index 00000000000..cdbfe36ca1c
--- /dev/null
+++ b/app/assets/javascripts/blob/balsamiq/balsamiq_viewer.js
@@ -0,0 +1,114 @@
+/* global Flash */
+
+import sqljs from 'sql.js';
+import { template as _template } from 'underscore';
+
+const PREVIEW_TEMPLATE = _template(`
+ <div class="panel panel-default">
+ <div class="panel-heading"><%- name %></div>
+ <div class="panel-body">
+ <img class="img-thumbnail" src="data:image/png;base64,<%- image %>"/>
+ </div>
+ </div>
+`);
+
+class BalsamiqViewer {
+ constructor(viewer) {
+ this.viewer = viewer;
+ this.endpoint = this.viewer.dataset.endpoint;
+ }
+
+ loadFile() {
+ const xhr = new XMLHttpRequest();
+
+ xhr.open('GET', this.endpoint, true);
+ xhr.responseType = 'arraybuffer';
+
+ xhr.onload = this.renderFile.bind(this);
+ xhr.onerror = BalsamiqViewer.onError;
+
+ xhr.send();
+ }
+
+ renderFile(loadEvent) {
+ const container = document.createElement('ul');
+
+ this.initDatabase(loadEvent.target.response);
+
+ const previews = this.getPreviews();
+ previews.forEach((preview) => {
+ const renderedPreview = this.renderPreview(preview);
+
+ container.appendChild(renderedPreview);
+ });
+
+ container.classList.add('list-inline');
+ container.classList.add('previews');
+
+ this.viewer.appendChild(container);
+ }
+
+ initDatabase(data) {
+ const previewBinary = new Uint8Array(data);
+
+ this.database = new sqljs.Database(previewBinary);
+ }
+
+ getPreviews() {
+ const thumbnails = this.database.exec('SELECT * FROM thumbnails');
+
+ return thumbnails[0].values.map(BalsamiqViewer.parsePreview);
+ }
+
+ getResource(resourceID) {
+ const resources = this.database.exec(`SELECT * FROM resources WHERE id = '${resourceID}'`);
+
+ return resources[0];
+ }
+
+ renderPreview(preview) {
+ const previewElement = document.createElement('li');
+
+ previewElement.classList.add('preview');
+ previewElement.innerHTML = this.renderTemplate(preview);
+
+ return previewElement;
+ }
+
+ renderTemplate(preview) {
+ const resource = this.getResource(preview.resourceID);
+ const name = BalsamiqViewer.parseTitle(resource);
+ const image = preview.image;
+
+ const template = PREVIEW_TEMPLATE({
+ name,
+ image,
+ });
+
+ return template;
+ }
+
+ static parsePreview(preview) {
+ return JSON.parse(preview[1]);
+ }
+
+ /*
+ * resource = {
+ * columns: ['ID', 'BRANCHID', 'ATTRIBUTES', 'DATA'],
+ * values: [['id', 'branchId', 'attributes', 'data']],
+ * }
+ *
+ * 'attributes' being a JSON string containing the `name` property.
+ */
+ static parseTitle(resource) {
+ return JSON.parse(resource.values[0][2]).name;
+ }
+
+ static onError() {
+ const flash = new Flash('Balsamiq file could not be loaded.');
+
+ return flash;
+ }
+}
+
+export default BalsamiqViewer;
diff --git a/app/assets/javascripts/blob/balsamiq_viewer.js b/app/assets/javascripts/blob/balsamiq_viewer.js
new file mode 100644
index 00000000000..1dacf84470f
--- /dev/null
+++ b/app/assets/javascripts/blob/balsamiq_viewer.js
@@ -0,0 +1,6 @@
+import BalsamiqViewer from './balsamiq/balsamiq_viewer';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const balsamiqViewer = new BalsamiqViewer(document.getElementById('js-balsamiq-viewer'));
+ balsamiqViewer.loadFile();
+});