Commit 4be61310 authored by Romain Courteaud's avatar Romain Courteaud Committed by Jérome Perrin

Skeleton of the new UI.

Start to separate all UI elements into distinct view with renderJS.
parent d6faeb86
*.pyc
*.xls
*.swp
*.project
*.pydevproject
.installed.cfg
......@@ -10,3 +10,6 @@ eggs/**
parts/**
outputJSON.json
trace*.xls
npm-debug.log
node_modules/
dream/platform/static/
/*global require */
module.exports = function (grunt) {
"use strict";
var global_config = {
src: "dream/platform/src2/",
lib: "dream/platform/vendor/",
// tmp: "tmp",
dest: "dream/platform/static/"
};
grunt.loadNpmTasks("grunt-jslint");
grunt.loadNpmTasks("grunt-contrib-uglify");
grunt.loadNpmTasks('grunt-contrib-watch');
// grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-curl');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
global_config: global_config,
jslint: {
config: {
src: ['package.json', 'Gruntfile.js'],
directives: {
maxlen: 120,
indent: 2,
maxerr: 3,
predef: [
'module'
]
}
},
gadget: {
src: ["<%= global_config.src %>/**/*.js"],
directives: {
maxlen: 79,
indent: 2,
maxerr: 3,
unparam: true,
predef: [
'window',
'document'
]
},
exclude: '<%= global_config.src %>/webodf_editor/**/*.*'
}
},
less: {
production: {
options: {
paths: ["<%= global_config.src %>/"],
cleancss: true,
syncImports: true,
strictMath: true,
strictUnits: true,
syncImport: true
},
files: {
"<%= global_config.dest %>/dream/index.css":
"<%= global_config.src %>/dream/index.less"
}
}
},
concat: {
options: {
separator: ';'
},
jio: {
src: [
'node_modules/jio/src/sha1.amd.js',
'node_modules/jio/src/sha2.amd.js',
'node_modules/jio/src/sha256.amd.js',
'node_modules/jio/jio.js',
'node_modules/jio/complex_queries.js',
'node_modules/jio/src/jio.storage/localstorage.js'
],
relative_dest: "lib/jio.js",
dest: "<%= global_config.dest %>/<%= concat.jio.relative_dest %>"
}
},
uglify: {
gadget: {
// XXX Dev options
options: {
report: false,
mangle: false,
compress: false,
beautify: true,
preserveComments: "all"
},
files: [{
expand: true,
cwd: "<%= global_config.src %>/",
src: '**/*.js',
dest: "<%= global_config.dest %>/"
}]
}
},
copy: {
images: {
expand: true,
cwd: "<%= global_config.src %>/",
src: "**/images/*.*",
dest: "<%= global_config.dest %>/"
},
rsvp: {
src: "node_modules/rsvp/dist/rsvp-2.0.4.min.js",
relative_dest: "lib/rsvp.min.js",
dest: "<%= global_config.dest %>/<%= copy.rsvp.relative_dest %>"
},
uritemplate: {
src: "node_modules/uritemplate/bin/uritemplate-min.js",
relative_dest: "lib/uritemplate.min.js",
dest: "<%= global_config.dest %>/<%= copy.uritemplate.relative_dest %>"
},
renderjs: {
src: "node_modules/renderjs/dist/renderjs-latest.js",
relative_dest: "lib/renderjs.min.js",
dest: "<%= global_config.dest %>/<%= copy.renderjs.relative_dest %>"
},
uri: {
src: "<%= global_config.lib %>/URI.js",
relative_dest: "lib/URI.js",
dest: "<%= global_config.dest %>/<%= copy.uri.relative_dest %>"
},
handlebars: {
src: 'node_modules/handlebars/dist/handlebars.min.js',
relative_dest: 'lib/handlebars.min.js',
dest: "<%= global_config.dest %>/<%= copy.handlebars.relative_dest %>"
},
qunitjs: {
src: 'node_modules/qunitjs/qunit/qunit.js',
relative_dest: 'lib/qunit.js',
dest: "<%= global_config.dest %>/<%= copy.qunitjs.relative_dest %>"
},
qunitcss: {
src: 'node_modules/qunitjs/qunit/qunit.css',
relative_dest: 'lib/qunit.css',
dest: "<%= global_config.dest %>/<%= copy.qunitcss.relative_dest %>"
},
gadget: {
expand: true,
cwd: "<%= global_config.src %>/",
src: "**/*.html",
dest: "<%= global_config.dest %>/",
nonull: true,
options: {
process: function (content) {
return grunt.template.process(content);
}
}
}
},
watch: {
src: {
files: [
'<%= global_config.src %>/**',
'<%= jslint.config.src %>'
],
tasks: ['default']
}
},
curl: {
jquery: {
src: 'http://code.jquery.com/jquery-2.0.3.js',
relative_dest: 'lib/jquery.js',
dest: '<%= global_config.dest %>/<%= curl.jquery.relative_dest %>'
},
jquerymobilejs: {
url_base: 'http://code.jquery.com/mobile/1.4.0-alpha.2/',
src_base: '<%= curl.jquerymobilejs.url_base %>jquery.mobile-1.4.0-alpha.2',
src: '<%= curl.jquerymobilejs.src_base %>.js',
relative_dest: 'lib/jquerymobile.js',
dest: '<%= global_config.dest %>/<%= curl.jquerymobilejs.relative_dest %>'
},
jquerymobileloader: {
src: '<%= curl.jquerymobilejs.url_base %>images/ajax-loader.gif',
relative_dest: 'lib/images/ajax-loader.gif',
dest: '<%= global_config.dest %>/<%= curl.jquerymobileloader.relative_dest %>'
},
jquerymobilecss: {
src: '<%= curl.jquerymobilejs.src_base %>.css',
relative_dest: 'lib/jquerymobile.css',
dest: '<%= global_config.dest %>/<%= curl.jquerymobilecss.relative_dest %>'
// },
// jqueryuijs: {
// src: 'https://code.jquery.com/ui/1.10.4/jquery-ui.js',
// relative_dest: 'lib/jquery-ui.js',
// dest: '<%= global_config.dest %>/<%= curl.jqueryuijs.relative_dest %>'
// },
// jqueryuicss: {
// src: 'https://code.jquery.com/ui/1.11.0-beta.1/themes/base/jquery-ui.css',
// relative_dest: 'lib/jquery-ui.css',
// dest: '<%= global_config.dest %>/<%= curl.jqueryuicss.relative_dest %>'
// },
// beautifyhtml: {
// src: 'https://raw.githubusercontent.com/einars/js-beautify/master/js/lib/beautify-html.js',
// relative_dest: 'lib/beautify-html.js',
// dest: '<%= global_config.dest %>/<%= curl.beautifyhtml.relative_dest %>'
}
// qunit: {
// all: ['test/index.html']
}
});
grunt.registerTask('default', ['all']);
grunt.registerTask('all', ['lint', 'build']);
grunt.registerTask('lint', ['jslint']);
grunt.registerTask('dep', ['curl']);
// grunt.registerTask('test', ['qunit']);
grunt.registerTask('build', ['concat', 'copy', 'uglify', 'less']);
};
......@@ -44,21 +44,7 @@ app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
@app.route("/")
def front_page():
return redirect(url_for('static', filename='index.html'))
@app.route("/postJSONData", methods=["POST", "OPTIONS"])
def postJSONData():
"""Returns posted JSON data as it is for Export button"""
data = json.loads(request.form.get('data'))
response = jsonify(data)
response.headers['Content-Disposition'] = 'attachment; filename=dream.json'
return response
@app.route("/postJSONFile", methods=["POST", "OPTIONS"])
def postJSONFile():
"""Returns posted JSON file as it is for Import button"""
data = json.load(request.files['file'])
return jsonify(data)
return redirect(url_for('static', filename='dream/index.html'))
@app.route("/positionGraph", methods=["POST", "OPTIONS"])
def positionGraph():
......@@ -134,7 +120,7 @@ def _runWithTimeout(queue, func, args, kw):
@app.route("/runSimulation", methods=["POST", "OPTIONS"])
def runSimulation():
parameter_dict = request.json['json']
parameter_dict = request.json
try:
timeout = int(parameter_dict['general']['processTimeout'])
except (KeyError, ValueError, TypeError):
......
......@@ -31,14 +31,6 @@
<a id="layout_graph"><i class="fa fa-sitemap"></i> Layout Graph</a>
<a id="zoom_in"><i class="fa fa-plus"></i> Zoom +</a>
<a id="zoom_out"><i class="fa fa-minus"></i> Zoom -</a>
<a id="export"><i class="fa fa-cloud-download"></i> Export</a>
<form id="export_form" style="display:none" method="post" action="../postJSONData">
<textarea id="export_json" name="data"></textarea>
</form>
<a id="import"><i class="fa fa-cloud-upload"></i> Import</a>
<form id="import_form" style="display:none">
<input id="import_file" name="file" type="file"></input>
</form>
<a id="run_knowledge_extraction">
<i class="fa fa-spinner fa-spin" id="ke_loading_spinner" style="display:none"></i>
Run Knowledge Extraction</a>
......@@ -132,9 +124,6 @@
<script type="text/javascript" src="lib/jquery-1.10.1.min.js"></script>
<script type="text/javascript" src="lib/jquery-ui-1.10.3.custom.min.js"></script>
<script type="text/javascript" src="lib/jquery.ui.touch-punch.min.js"></script>
<script type="text/javascript" src="lib/md5.js"></script>
<script type="text/javascript" src="lib/jio.js"></script>
<script type="text/javascript" src="lib/jio.localstorage.js"></script>
<script type="text/javascript" src="lib/pubsub.js"></script>
<script type="text/javascript" src="lib/jquery.jsPlumb-1.5.4-min.js"></script>
<!-- /DEP -->
......
......@@ -863,24 +863,6 @@
that.setGeneralProperties(properties);
}
/** Runs the simulation, and call the callback with results once the
* simulation is finished.
*/
that.runSimulation = function (callback) {
that.readGeneralPropertiesDialog()
$.ajax(
'../runSimulation', {
data: JSON.stringify({
json: that.getData()
}),
contentType: 'application/json',
type: 'POST',
success: function (data, textStatus, jqXHR) {
callback(data);
}
});
};
/** Runs the knowledge extraction, and call the callback with results once the
* KE is finished.
*/
......
......@@ -21,18 +21,6 @@
"use strict";
jsPlumb.bind("ready", function () {
var dream_instance, jio;
jio = new jIO.newJio({
type: "local",
username: "dream",
applicationname: "dream"
});
var configuration = { };
$.ajax(
'../getConfigurationDict', {
success: function (data) {
configuration = $.extend(configuration, data);
dream_instance = Dream(configuration);
dream_instance.start();
......@@ -190,21 +178,21 @@
});
});
// Enable "Run Simulation" button
$("#run_simulation").button().click(
function (e) {
$("#loading_spinner").show();
$("#run_simulation").button('disable');
dream_instance.runSimulation(
function (data) {
$("#loading_spinner").hide();
$("#run_simulation").button('enable');
$("#reports").show();
$("#result_zone").show();
$('#result_list').empty();
$('#error').empty();
if (data['success']) {
// // Enable "Run Simulation" button
// $("#run_simulation").button().click(
// function (e) {
// $("#loading_spinner").show();
// $("#run_simulation").button('disable');
// dream_instance.runSimulation(
// function (data) {
// $("#loading_spinner").hide();
// $("#run_simulation").button('enable');
// $("#reports").show();
// $("#result_zone").show();
// $('#result_list').empty();
// $('#error').empty();
// if (data['success']) {
//
$.each(data.data, function (idx, result) {
$('#result_list').append('<li class="result"></li>');
$('#result_list').children().last().text(idx + ' : ' + result['score'] + ' ' + result['key']).click(
......@@ -214,15 +202,15 @@
);
});
dream_instance.displayResult(0, data.data[0]);
} else {
$("#reports").hide();
$("#error").text(data["error"]).show().effect('shake', 50);
console.error(data['error'])
}
});
e.preventDefault();
return false;
});
// } else {
// $("#reports").hide();
// $("#error").text(data["error"]).show().effect('shake', 50);
// console.error(data['error'])
// }
// });
// e.preventDefault();
// return false;
// });
// Enable "Layout Graph" button
$("#layout_graph").button().click(
......@@ -252,39 +240,30 @@
dream_instance.zoom_out();
});
// Enable "Export" button
$("#export").button().click(
function (e) {
dream_instance.readGeneralPropertiesDialog();
$('#export_json').val(JSON.stringify(dream_instance.getData()));
$('#export_form').submit();
return false;
});
// Enable "Import" button
$("#import").button().click(
function (e) {
$('#import_file').click();
});
$("#import_file").change(function () {
var form = $(this).parent('form')[0];
var form_data = new FormData(form);
$.ajax('../postJSONFile', {
type: 'POST',
contentType: false,
processData: false,
data: form_data,
dataType: 'json',
error: function () {
console.error('error');
},
success: function (data, textStatus, jqXHR) {
form.reset();
// // Enable "Import" button
// $("#import").button().click(
// function (e) {
// $('#import_file').click();
// });
// $("#import_file").change(function () {
// var form = $(this).parent('form')[0];
// var form_data = new FormData(form);
// $.ajax('../postJSONFile', {
// type: 'POST',
// contentType: false,
// processData: false,
// data: form_data,
// dataType: 'json',
// error: function () {
// console.error('error');
// },
// success: function (data, textStatus, jqXHR) {
// form.reset();
loadData(data);
}
});
return false;
});
// }
// });
// return false;
// });
// Redraw if the graph area or the window is resized
$('#main').resizable().resize(function () {
......
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Create Document</title>
<script src="../<%= copy.rsvp.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.renderjs.relative_dest %>" type="text/javascript"></script>
<script src="create_document.js" type="text/javascript"></script>
</head>
<body>
<form class="import_form">
<input id="dream_import" type="file" required=""
name="dream_import">
<button type="submit" class="ui-btn ui-btn-b ui-btn-inline ui-icon-plus ui-btn-icon-right">Import</button>
</form>
</body>
</html>
/*global console, rJS, RSVP, FileReader */
(function (window, rJS, RSVP, FileReader) {
"use strict";
function promiseEventListener(target, type, useCapture) {
//////////////////////////
// Resolve the promise as soon as the event is triggered
// eventListener is removed when promise is cancelled/resolved/rejected
//////////////////////////
var handle_event_callback;
function canceller() {
target.removeEventListener(type, handle_event_callback, useCapture);
}
function resolver(resolve) {
handle_event_callback = function (evt) {
canceller();
evt.stopPropagation();
evt.preventDefault();
resolve(evt);
return false;
};
target.addEventListener(type, handle_event_callback, useCapture);
}
return new RSVP.Promise(resolver, canceller);
}
function promiseReadAsText(file) {
return new RSVP.Promise(function (resolve, reject) {
var reader = new FileReader();
reader.onload = function (evt) {
resolve(evt.target.result);
};
reader.onerror = function (evt) {
reject(evt);
};
reader.readAsText(file);
});
}
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("aq_post", "jio_post")
.declareAcquiredMethod("aq_putAttachment", "jio_putAttachment")
.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash")
.declareAcquiredMethod("whoWantToDisplayThisDocument",
"whoWantToDisplayThisDocument")
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("startService", function () {
var gadget = this,
json_data,
name;
return new RSVP.Queue()
.push(function () {
return promiseEventListener(
gadget.props.element.getElementsByClassName("import_form")[0],
'submit',
false
);
})
.push(function (evt) {
// Prevent double click
gadget.props.element
.getElementsByClassName("ui-btn")[0].disabled = true;
var file = evt.target.dream_import.files[0];
name = file.name;
return promiseReadAsText(file);
})
.push(function (json) {
var now = new Date();
json_data = json;
// Create jIO document
return gadget.aq_post({
title: name,
type: "Dream",
format: "application/json",
modified: now.toUTCString(),
date: now.getFullYear() + "-" + (now.getMonth() + 1) + "-" +
now.getDate()
});
})
.push(function (jio_document) {
// Add JSON as attachment
return gadget.aq_putAttachment({
"_id": jio_document.id,
"_attachment": "body.json",
"_data": json_data,
"_mimetype": "application/json"
});
})
.push(function (result) {
return gadget.whoWantToDisplayThisDocument(result.id);
})
.push(function (url) {
return gadget.pleaseRedirectMyHash(url);
});
});
}(window, rJS, RSVP, FileReader));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Debug JSON</title>
<script src="../<%= copy.rsvp.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.renderjs.relative_dest %>" type="text/javascript"></script>
<script src="../<%= curl.jquery.relative_dest %>" type="text/javascript"></script>
<script src="../<%= curl.jquerymobilejs.relative_dest %>" type="text/javascript"></script>
<script src="document_page_mixin.js" type="text/javascript"></script>
<script src="debug_json.js" type="text/javascript"></script>
</head>
<body>
<label for="json_input">Input</label>
<textarea rows="20" cols="47" name="json_input" class="json_input"></textarea>
<label for="json_output">Output</label>
<textarea rows="20" cols="47" name="json_output" class="json_output"></textarea>
</body>
</html>
/*global console, rJS, RSVP, initDocumentPageMixin */
(function (window, rJS, RSVP, initDocumentPageMixin) {
"use strict";
var gadget_klass = rJS(window);
initDocumentPageMixin(gadget_klass);
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("aq_getAttachment", "jio_getAttachment")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) {
var gadget = this;
this.props.jio_key = options.id;
return new RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.aq_getAttachment({
"_id": gadget.props.jio_key,
"_attachment": "body.json"
}),
gadget.aq_getAttachment({
"_id": gadget.props.jio_key,
"_attachment": "simulation.json"
})
]);
})
.push(function (result_list) {
gadget.props.element.querySelector(".json_input").textContent =
result_list[0];
gadget.props.element.querySelector(".json_output").textContent =
result_list[1];
});
});
}(window, rJS, RSVP, initDocumentPageMixin));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Document List</title>
<script src="../<%= copy.rsvp.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.renderjs.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.handlebars.relative_dest %>" type="text/javascript"></script>
<script id="table-template" type="text/x-handlebars-template">
<ul data-role="listview" data-inset="true" class="document-listview">
{{#documentlist}}
<li><a href="{{link}}">{{title}}</a></li>
{{/documentlist}}
</ul>
</script>
<script src="document_list.js" type="text/javascript"></script>
</head>
<body>
<section class="document_list"></section>
</body>
</html>
/*global console, rJS, RSVP, Handlebars */
/*jslint nomen: true */
(function (window, rJS, RSVP, Handlebars) {
"use strict";
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
var gadget_klass = rJS(window),
source = gadget_klass.__template_element
.getElementById("table-template")
.innerHTML,
table_template = Handlebars.compile(source);
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("aq_allDocs", "allDocs")
.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash")
.declareAcquiredMethod("whoWantToDisplayThisPage",
"whoWantToDisplayThisPage")
.declareAcquiredMethod("whoWantToDisplayThisDocument",
"whoWantToDisplayThisDocument")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) {
var gadget = this;
return gadget.aq_allDocs({"select_list": ["title", "modified"]})
.push(function (document_list) {
var result_list = [gadget.whoWantToDisplayThisPage(
"create_document"
)],
doc,
i;
for (i = 0; i < document_list.data.total_rows; i += 1) {
doc = document_list.data.rows[i];
result_list.push(RSVP.all([
gadget.whoWantToDisplayThisDocument(doc.id),
doc.value.title,
doc.value.modified
]));
}
return RSVP.all(result_list);
})
.push(function (document_list) {
// Create new doc if nothing exists
if (document_list.length === 1) {
return gadget.pleaseRedirectMyHash(document_list[0]);
}
var i,
parameter_list = [],
doc;
for (i = 1; i < document_list.length; i += 1) {
doc = document_list[i];
parameter_list[i - 1] = {
link: doc[0],
title: doc[1] + " (" + doc[2] + ")"
};
}
// gadget.props.element.querySelector('a').href = document_list[0];
gadget.props.element.querySelector('.document_list').innerHTML =
table_template({
documentlist: parameter_list
});
});
})
.declareMethod("getNavigationList", function () {
return this.whoWantToDisplayThisPage("create_document")
.push(function (url) {
return [{title: "New Document", link: url}];
});
});
}(window, rJS, RSVP, Handlebars));
/*global console, rJS, RSVP */
(function (window, rJS, RSVP) {
"use strict";
window.initDocumentPageMixin = function (gadget_klass) {
gadget_klass
.declareAcquiredMethod("whoWantToDisplayThisDocumentPage",
"whoWantToDisplayThisDocumentPage")
.declareMethod("getNavigationList", function () {
var key = this.props.jio_key,
gadget = this;
return new RSVP.Queue()
.push(function () {
// XXX Conditional simulation menu
return RSVP.all([
gadget.whoWantToDisplayThisDocumentPage("edit_table", key),
gadget.whoWantToDisplayThisDocumentPage("run_simulation", key),
gadget.whoWantToDisplayThisDocumentPage("manage_document", key),
gadget.whoWantToDisplayThisDocumentPage("debug_json", key)
]);
})
.push(function (result_list) {
return [
{link: result_list[0], title: "Edit table"},
{link: result_list[1], title: "Run simulation"},
{link: result_list[2], title: "Manage document"},
{link: result_list[3], title: "Debug JSON"}
];
});
});
};
}(window, rJS, RSVP));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Edit table</title>
<script src="../<%= copy.rsvp.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.renderjs.relative_dest %>" type="text/javascript"></script>
<script src="document_page_mixin.js" type="text/javascript"></script>
<script src="edit_table.js" type="text/javascript"></script>
</head>
<body>
<section class="document_list"></section>
</body>
</html>
/*global console, rJS, RSVP, initDocumentPageMixin */
(function (window, rJS, RSVP, initDocumentPageMixin) {
"use strict";
var gadget_klass = rJS(window);
initDocumentPageMixin(gadget_klass);
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("aq_getAttachment", "jio_getAttachment")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) {
var jio_key = options.id,
gadget = this;
gadget.props.jio_key = jio_key;
return gadget.aq_getAttachment({
"_id": jio_key,
"_attachment": "body.json"
})
.push(function (result) {
gadget.props.element.textContent = result;
});
});
}(window, rJS, RSVP, initDocumentPageMixin));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Dream Simulation</title>
<link rel="stylesheet" href="../<%= curl.jquerymobilecss.relative_dest %>">
<link rel="stylesheet" href="index.css" />
<script src="../<%= copy.rsvp.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.renderjs.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.handlebars.relative_dest %>" type="text/javascript"></script>
<script src="../<%= curl.jquery.relative_dest %>" type="text/javascript"></script>
<script src="../<%= curl.jquerymobilejs.relative_dest %>" type="text/javascript"></script>
<script src="index.js" type="text/javascript"></script>
<script id="navigation-template" type="text/x-handlebars-template">
<ul data-role="listview">
<li data-icon="delete" class="close-entry"><a href="#" data-rel="close">Close menu</a></li>
{{#navigationlist}}
<li><a href="{{link}}">{{title}}</a></li>
{{/navigationlist}}
</ul>
</script>
</head>
<body>
<!-- ID are bad, but required for JQM panel -->
<div class="jqm-navmenu-panel"
data-role="panel"
id="leftpanel"
data-display="overlay"
data-position="left"
data-theme="b">
</div>
<header data-role="header">
<a href="#leftpanel" class="menu_link">Menu</a>
<h1>Dream Simulation</h1>
<a class="home_link ui-icon-home ui-btn-icon-right">Home</a>
</header>
<article class="gadget_container"></article>
<aside>
<section data-gadget-url="../jio_bridge/index.html"
data-gadget-scope="jio"
data-gadget-sandbox="public"></section>
</aside>
</body>
</html>
/*global console, jQuery, rJS, RSVP, alert, Handlebars */
/*jslint nomen: true */
(function (window, $, rJS, RSVP, Handlebars) {
"use strict";
/////////////////////////////////////////////////////////////////
// Desactivate jQuery Mobile URL management
/////////////////////////////////////////////////////////////////
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
var navigation_template;
rJS(window)
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash")
/////////////////////////////////////////////////////////////////
// Handle acquisition
/////////////////////////////////////////////////////////////////
// Bridge to jio gadget
.allowPublicAcquisition("allDocs", function (param_list) {
return this.getDeclaredGadget("jio")
.push(function (jio_gadget) {
return jio_gadget.allDocs.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("jio_ajax", function (param_list) {
return this.getDeclaredGadget("jio")
.push(function (jio_gadget) {
return jio_gadget.ajax.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("jio_post", function (param_list) {
return this.getDeclaredGadget("jio")
.push(function (jio_gadget) {
return jio_gadget.post.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("jio_remove", function (param_list) {
return this.getDeclaredGadget("jio")
.push(function (jio_gadget) {
return jio_gadget.remove.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("jio_get", function (param_list) {
return this.getDeclaredGadget("jio")
.push(function (jio_gadget) {
return jio_gadget.get.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("jio_putAttachment", function (param_list) {
return this.getDeclaredGadget("jio")
.push(function (jio_gadget) {
return jio_gadget.putAttachment.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("jio_getAttachment", function (param_list) {
return this.getDeclaredGadget("jio")
.push(function (jio_gadget) {
return jio_gadget.getAttachment.apply(jio_gadget, param_list);
});
})
.allowPublicAcquisition("whoWantToDisplayHome", function (param_list) {
// Hey, I want to display some URL
return this.aq_pleasePublishMyState({});
})
.allowPublicAcquisition("whoWantToDisplayThisPage", function (param_list) {
// Hey, I want to display some URL
return this.aq_pleasePublishMyState({page: param_list[0]});
})
.allowPublicAcquisition("whoWantToDisplayThisDocument",
function (param_list) {
// Hey, I want to display some jIO document
return this.aq_pleasePublishMyState({
page: "edit_table",
id: param_list[0]
});
})
.allowPublicAcquisition("whoWantToDisplayThisDocumentPage",
function (param_list) {
// Hey, I want to display some jIO document
return this.aq_pleasePublishMyState({
page: param_list[0],
id: param_list[1]
});
})
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
// Create some link on the page
.ready(function (g) {
return g.aq_pleasePublishMyState({})
.push(function (link) {
g.props.element.getElementsByClassName("home_link")[0].href = link;
});
})
// Configure jIO to use localstorage
// And load configuration from server
.ready(function (g) {
var jio_gadget;
return g.getDeclaredGadget("jio")
.push(function (gadget) {
jio_gadget = gadget;
return jio_gadget.createJio({
type: "local",
username: "dream",
applicationname: "dream"
});
})
.push(function () {
// XXX Hardcoded relative URL
return jio_gadget.ajax({url: "../../getConfigurationDict"});
})
.push(function (evt) {
g.props.configuration_dict = JSON.parse(evt.target.responseText);
});
})
/////////////////////////////////////////////////////////////////
// Handlebars
/////////////////////////////////////////////////////////////////
// Precompile the templates while loading the first gadget instance
.ready(function (g) {
if (navigation_template === undefined) {
// XXX Only works as root gadget
var source = document.getElementById("navigation-template")
.innerHTML;
navigation_template = Handlebars.compile(source);
}
})
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
// Render the page
.declareMethod("render", function (options) {
var gadget = this,
page_gadget,
element = gadget.props.element
.getElementsByClassName("gadget_container")[0];
if (options.page === undefined) {
// Redirect to the about page
return gadget.aq_pleasePublishMyState({page: "document_list"})
.push(gadget.pleaseRedirectMyHash.bind(gadget));
}
// Clear the previous rendering
element.innerHTML = "";
return gadget.declareGadget(options.page + ".html")
.push(function (g) {
page_gadget = g;
if (page_gadget.render !== undefined) {
return page_gadget.render(options);
}
}).push(function () {
var navigation_list = [];
if (page_gadget.getNavigationList !== undefined) {
navigation_list = page_gadget.getNavigationList();
}
return RSVP.all([
page_gadget.getTitle(),
page_gadget.getElement(),
navigation_list
]);
}).push(function (result_list) {
var title = result_list[0],
page_element = result_list[1],
navigation_list = result_list[2],
panel = gadget.props.element.querySelector("#leftpanel");
gadget.props.element.querySelector("header h1").textContent =
title;
// Append in the DOM at the end to reduce flickering and reduce DOM
// modifications
element.appendChild(page_element);
panel.innerHTML =
navigation_template({navigationlist: navigation_list});
// XXX JQuery mobile
$(element).trigger('create');
$(panel).trigger("create");
// XXX RenderJS hack to start sub gadget services
// Only work if this gadget has no parent.
if (page_gadget.startService !== undefined) {
return page_gadget.startService();
}
});
});
}(window, jQuery, rJS, RSVP, Handlebars));
@margin: 17em;
@media (min-width:35em) {
.jqm-navmenu-panel.ui-panel-closed {
visibility: visible !important;
width: @margin;
-webkit-transition: none !important;
-moz-transition: none !important;
transition: none !important;
-webkit-transform: none !important;
-moz-transform: none !important;
transform: none !important;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
height: 100%;
position: absolute;
display: block;
}
/* wrap on wide viewports once open */
.ui-panel-page-content-open {
width: auto;
&.ui-panel-page-content-position-left {
margin-right: @margin;
}
}
/* disable "dismiss" on wide viewports */
.ui-panel-dismiss, .menu_link {
display: none !important;
}
.gadget_container, header {
margin-left: @margin;
}
.close-entry {
display: none !important;
}
.gadget_container {
padding: 1em;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Manage document</title>
<script src="../<%= copy.rsvp.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.renderjs.relative_dest %>" type="text/javascript"></script>
<script src="document_page_mixin.js" type="text/javascript"></script>
<script src="manage_document.js" type="text/javascript"></script>
</head>
<body>
<a class="export_link ui-btn ui-btn-inline ui-icon-action ui-btn-icon-right">Export</a>
<form class="delete_form">
<button type="submit" class="ui-btn ui-btn-b ui-btn-inline ui-icon-delete ui-btn-icon-right">Delete</button>
</form>
</body>
</html>
/*global console, rJS, RSVP, initDocumentPageMixin */
(function (window, rJS, RSVP, initDocumentPageMixin) {
"use strict";
function datatouri(data, mime_type) {
var result = "data:";
if (mime_type !== undefined) {
result += mime_type;
}
return result + ";base64," + window.btoa(data);
}
function promiseEventListener(target, type, useCapture) {
//////////////////////////
// Resolve the promise as soon as the event is triggered
// eventListener is removed when promise is cancelled/resolved/rejected
//////////////////////////
var handle_event_callback;
function canceller() {
target.removeEventListener(type, handle_event_callback, useCapture);
}
function resolver(resolve) {
handle_event_callback = function (evt) {
canceller();
evt.stopPropagation();
evt.preventDefault();
resolve(evt);
return false;
};
target.addEventListener(type, handle_event_callback, useCapture);
}
return new RSVP.Promise(resolver, canceller);
}
var gadget_klass = rJS(window);
initDocumentPageMixin(gadget_klass);
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("aq_remove", "jio_remove")
.declareAcquiredMethod("aq_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("aq_get", "jio_get")
.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash")
.declareAcquiredMethod("whoWantToDisplayHome",
"whoWantToDisplayHome")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) {
this.props.jio_key = options.id;
var gadget = this;
return new RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.aq_get({
"_id": options.id
}),
gadget.aq_getAttachment({
"_id": options.id,
"_attachment": "body.json"
})
]);
})
.push(function (result_list) {
var export_link = gadget.props.element.querySelector(".export_link");
export_link.download = result_list[0].data.title;
export_link.href = datatouri(result_list[1], "application/json");
});
})
.declareMethod("startService", function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return promiseEventListener(
gadget.props.element.getElementsByClassName("delete_form")[0],
'submit',
false
);
})
.push(function () {
// Prevent double click
gadget.props.element
.getElementsByClassName("ui-btn")[0].disabled = true;
// Delete jIO document
return gadget.aq_remove({
"_id": gadget.props.jio_key
});
})
.push(function (result) {
return gadget.whoWantToDisplayHome();
})
.push(function (url) {
return gadget.pleaseRedirectMyHash(url);
});
});
}(window, rJS, RSVP, initDocumentPageMixin));
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Run Simulation</title>
<script src="../<%= copy.rsvp.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.renderjs.relative_dest %>" type="text/javascript"></script>
<script src="../<%= curl.jquery.relative_dest %>" type="text/javascript"></script>
<script src="../<%= curl.jquerymobilejs.relative_dest %>" type="text/javascript"></script>
<script src="document_page_mixin.js" type="text/javascript"></script>
<script src="run_simulation.js" type="text/javascript"></script>
</head>
<body>
<form class="run_form">
<button type="submit" class="ui-btn ui-btn-b ui-btn-inline
ui-icon-refresh ui-btn-icon-right">Run Simulation</button>
</form>
</body>
</html>
/*global console, rJS, RSVP, initDocumentPageMixin, jQuery */
(function (window, rJS, RSVP, initDocumentPageMixin, $) {
"use strict";
function promiseEventListener(target, type, useCapture) {
//////////////////////////
// Resolve the promise as soon as the event is triggered
// eventListener is removed when promise is cancelled/resolved/rejected
//////////////////////////
var handle_event_callback;
function canceller() {
target.removeEventListener(type, handle_event_callback, useCapture);
}
function resolver(resolve) {
handle_event_callback = function (evt) {
canceller();
evt.stopPropagation();
evt.preventDefault();
resolve(evt);
return false;
};
target.addEventListener(type, handle_event_callback, useCapture);
}
return new RSVP.Promise(resolver, canceller);
}
var gadget_klass = rJS(window);
initDocumentPageMixin(gadget_klass);
gadget_klass
/////////////////////////////////////////////////////////////////
// ready
/////////////////////////////////////////////////////////////////
// Init local properties
.ready(function (g) {
g.props = {};
})
// Assign the element to a variable
.ready(function (g) {
return g.getElement()
.push(function (element) {
g.props.element = element;
});
})
/////////////////////////////////////////////////////////////////
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("aq_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("aq_putAttachment", "jio_putAttachment")
.declareAcquiredMethod("aq_ajax", "jio_ajax")
.declareAcquiredMethod("pleaseRedirectMyHash", "pleaseRedirectMyHash")
.declareAcquiredMethod("whoWantToDisplayThisDocumentPage",
"whoWantToDisplayThisDocumentPage")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.declareMethod("render", function (options) {
this.props.jio_key = options.id;
})
.declareMethod("startService", function () {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return promiseEventListener(
gadget.props.element.getElementsByClassName("run_form")[0],
'submit',
false
);
})
.push(function () {
// Prevent double click
gadget.props.element
.getElementsByClassName("ui-btn")[0].disabled = true;
return gadget.aq_getAttachment({
"_id": gadget.props.jio_key,
"_attachment": "body.json"
});
})
.push(function (body_json) {
$.mobile.loading('show');
// XXX Hardcoded relative URL
return gadget.aq_ajax({
url: "../../runSimulation",
type: "POST",
data: body_json,
headers: {
"Content-Type": 'application/json'
}
});
})
.push(undefined, function (error) {
// Always drop the loader
$.mobile.loading('hide');
throw error;
})
.push(function (evt) {
$.mobile.loading('hide');
var json_data = JSON.parse(evt.target.responseText);
if (json_data.success !== true) {
throw new Error(json_data.error);
}
return gadget.aq_putAttachment({
"_id": gadget.props.jio_key,
"_attachment": "simulation.json",
"_data": JSON.stringify(json_data.data, null, 2),
"_mimetype": "application/json"
});
})
.push(function (result) {
return gadget.whoWantToDisplayThisDocumentPage(
"debug_json",
gadget.props.jio_key
);
})
.push(function (url) {
return gadget.pleaseRedirectMyHash(url);
});
});
}(window, rJS, RSVP, initDocumentPageMixin, jQuery));
<!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>Jio Gadget</title>
<!-- renderjs -->
<script src="../<%= copy.rsvp.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.uritemplate.relative_dest %>" type="text/javascript"></script>
<script src="../<%= copy.uri.relative_dest %>" type="text/javascript"></script>
<script src="../<%= concat.jio.relative_dest %>" type="text/javascript"></script>
<!-- custom script -->
<script src="jiogadget.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
/*global rJS, jIO, console */
(function (rJS, jIO) {
"use strict";
rJS(window)
.ready(function (gadget) {
// Initialize the gadget local parameters
gadget.state_parameter_dict = {};
})
.declareMethod('createJio', function (jio_options) {
this.state_parameter_dict.jio_storage = jIO.createJIO(jio_options);
})
.declareMethod('ajax', function () {
return jIO.util.ajax.apply(this, arguments);
})
.declareMethod('allDocs', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.allDocs.apply(storage, arguments);
})
.declareMethod('get', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.get.apply(storage, arguments);
})
.declareMethod('remove', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.remove.apply(storage, arguments);
})
.declareMethod('getAttachment', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.getAttachment.apply(storage, arguments)
// XXX Where to put this &@! blob reading
.then(function (response) {
return jIO.util.readBlobAsText(response.data);
})
.then(function (lala) {
return lala.target.result;
});
})
.declareMethod('putAttachment', function () {
var storage = this.state_parameter_dict.jio_storage;
return storage.putAttachment.apply(storage, arguments);
})
.declareMethod('post', function () {
// XXX set modified value
var storage = this.state_parameter_dict.jio_storage;
return storage.post.apply(storage, arguments);
});
}(rJS, jIO));
This diff is collapsed.
{
"name": "dream",
"title": "Dream",
"version": "0.0.1",
"description": "The Dream Project",
"dependencies": {
"handlebars": "^2.0.0-alpha.4",
"jio": "git+http://git.erp5.org/repos/jio.git",
"renderjs": "git+http://git.erp5.org/repos/renderjs.git",
"rsvp": "git+http://git.erp5.org/repos/rsvp.js.git",
"uritemplate": "git+http://git.erp5.org/repos/uritemplate-js.git"
},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-cli": "~0.1.11",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-copy": "~0.5.0",
"grunt-contrib-less": "~0.9.0",
"grunt-contrib-uglify": "~0.2.x",
"grunt-contrib-watch": "~0.5.3",
"grunt-curl": "~1.2.1",
"grunt-jslint": "~1.1.x",
"grunt-zip": "~0.13.0",
"qunitjs": "^1.14.0"
},
"scripts": {
"test": "./node_modules/.bin/grunt test",
"lint": "./node_modules/.bin/grunt lint",
"prepublish": "./node_modules/.bin/grunt build"
}
}
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