mirror of
/repos/Prototyper.git
synced 2025-12-30 06:31:32 +01:00
304 lines
11 KiB
HTML
304 lines
11 KiB
HTML
<!DOCTYPE html><!-- @@remove_ --><!-- @@import__app_main_json_ -->
|
|
{ "_availableModes" : [
|
|
{ "name": "none", "ace":"none" },
|
|
{ "name": "HTML", "ace":"html" },
|
|
{ "name": "Style", "ace":"css" },
|
|
{ "name": "Behaviour", "ace":"javascript" },
|
|
{ "name": "Text", "ace":"markdown" },
|
|
{ "name": "JSON", "ace":"json" }
|
|
]
|
|
}
|
|
<!-- @@_end_import__app_main_json -->
|
|
<!-- @@import_file__style.css__into__app_main_style -->
|
|
<!-- @@import_file__../README.md__into__app_main_readme -->
|
|
<!-- @@import_leftovers__app_main_index -->
|
|
<!-- @@_end_remove --><html>
|
|
<head>
|
|
<title>app/main/index</title>
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
|
|
<!-- @@remove_ -->
|
|
<link href="/style.css" rel="stylesheet" type="text/css">
|
|
<!-- @@_end_remove -->
|
|
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet" type="text/css">
|
|
<link href="//netdna.bootstrapcdn.com/font-awesome/3.0.2/css/font-awesome.css" rel="stylesheet" type="text/css">
|
|
<!-- @@style__app_main_style -->
|
|
</head>
|
|
|
|
<body>
|
|
<!-- @@template__app_main_body__context__app_main -->
|
|
<!-- @@import__app_main_body_ -->
|
|
<div id="header">
|
|
<div id="htext">
|
|
Editing <b>index</b>
|
|
<strong data-bind="text: _keys().length"></strong>
|
|
<div data-bind="visible: _getMode()">
|
|
mode: <strong data-bind="text: _getMode()"></strong>
|
|
</div>
|
|
<select data-bind="options: _availableModes(), optionsText: 'name', value: _selectedMode"></select>
|
|
<div id="main">
|
|
<ul class="folders">
|
|
<!-- ko foreach: _keys() -->
|
|
<li data-bind="text: $data,
|
|
css: { selected: $data == $root._chosenFolderId() },
|
|
click: $root._goToFolder"></li>
|
|
<!-- /ko -->
|
|
<li><input data-bind="value: $root._newAttribute" /></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="content">
|
|
<div id="tree">
|
|
<ul>
|
|
<li>
|
|
<span data-bind="text: name"></span>
|
|
<!--<ul data-bind="template: { name: 'nodeTmpl', foreach: nodes }"></ul>-->
|
|
</li></ul>
|
|
</div>
|
|
<div id="editor"></div>
|
|
</div>
|
|
</div>
|
|
<!-- @@template__app_main_scripts__context__app_main -->
|
|
<!-- @@import__app_main_scripts_ -->
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
|
<!-- @@remove_ -->
|
|
<!--<script src="//knockoutjs.com/downloads/knockout-2.2.1.debug.js"></script>-->
|
|
<!--<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.2.0/knockout-min.js"></script>-->
|
|
<!-- @@_end_remove -->
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
|
|
<script src="//underscorejs.org/underscore-min.js"></script>
|
|
<!--<script src="//raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.debug.js"></script>-->
|
|
<script src="/lib/knockout/knockout.mapping-latest.js"></script>
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout-validation/1.0.2/knockout.validation.min.js"></script>
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
|
|
<script src="/lib/knockout/knockout-bootstrap.min.js"></script>
|
|
<script src="/lib/markdown/markdown.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="/lib/ace/ace.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="/lib/ace/mode-html.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="/lib/ace/mode-javascript.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="/lib/ace/mode-css.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="/lib/ace/mode-markdown.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="/lib/ace/mode-json.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="//cdn.sockjs.org/sockjs-0.3.min.js"></script>
|
|
<!-- @@remove_ -->
|
|
<!--<script src="/channel/bcsocket.js"></script>-->
|
|
<!--<script src="/socket.io/socket.io.js"></script>-->
|
|
<!-- @@_end_remove -->
|
|
<script src="/lib/share/share.uncompressed.js"></script>
|
|
<script src="/lib/share/json.js"></script>
|
|
<script src="/lib/share/ace.js"></script>
|
|
<!-- @@_end_import__app_main_scripts -->
|
|
<!-- @@template__app_main_behaviour__context__app_main -->
|
|
<!-- @@import__app_main_behaviour_ -->
|
|
<script>
|
|
var attribute = 'index';
|
|
var editor = ace.edit("editor");
|
|
var aceMode = null;
|
|
var session = editor.getSession();
|
|
var viewModel = null;
|
|
var viewModel_updating = false;
|
|
var doc = null;
|
|
var mainDoc = null;
|
|
editor.setReadOnly(true);
|
|
|
|
var setMode = function(attribute, mode) {
|
|
console.log('setmode', attribute, mode);
|
|
var ace_mode = mode;
|
|
if (!mode || mode == 'none') {
|
|
ace_mode = 'markdown';
|
|
}
|
|
if (mainDoc.snapshot
|
|
&& mainDoc.snapshot[attribute]) {
|
|
aceMode = require("ace/mode/"+ace_mode).Mode;
|
|
session.setMode(new aceMode());
|
|
var currentMode = mainDoc.snapshot[attribute].mode;
|
|
if (!currentMode) {
|
|
currentMode = 'none';
|
|
}
|
|
console.log('modes',currentMode, mode);
|
|
|
|
|
|
if (currentMode != mode) {
|
|
console.log('mode differs',currentMode, mode);
|
|
var op = [];
|
|
if (mainDoc.snapshot[attribute].mode) {
|
|
console.log('// remove');
|
|
op.push({
|
|
p:[attribute,'mode'],
|
|
od:mainDoc.snapshot[attribute].mode
|
|
|
|
})
|
|
}
|
|
if (mode && mode != 'none') {
|
|
console.log('//insert');
|
|
op.push({
|
|
p:[attribute,'mode'],
|
|
oi:mode
|
|
});
|
|
}
|
|
console.log('op',op);
|
|
mainDoc.submitOp(op, function (err, result) {
|
|
console.log('err', err, 'result', result);
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
var setDoc = function(attribute) {
|
|
editor.setReadOnly(true);
|
|
var mode = (mainDoc.snapshot
|
|
&& mainDoc.snapshot[attribute]
|
|
&& mainDoc.snapshot[attribute].mode
|
|
) || 'none';
|
|
console.log('setDoc mode',mode);
|
|
setMode(attribute, mode);
|
|
document.title = attribute;
|
|
|
|
var docName='text:app:'+viewModel._id()+':'+attribute;
|
|
|
|
sharejs.open(docName, 'text', function(error, newDoc) {
|
|
|
|
if (doc != null) {
|
|
doc.close();
|
|
doc.detach_ace();
|
|
}
|
|
|
|
doc = newDoc;
|
|
|
|
if (error) {
|
|
console.error(error);
|
|
return;
|
|
}
|
|
doc.attach_ace(editor);
|
|
editor.setReadOnly(false);
|
|
editor.focus(); //To focus the ace editor
|
|
});
|
|
};
|
|
var mapping = {
|
|
'ignore': ["name", "version"]
|
|
};
|
|
|
|
function addComputed(doc) {
|
|
var snapshot = doc.snapshot;
|
|
snapshot._keys = _.filter(
|
|
Object.keys(snapshot),
|
|
function(key){
|
|
return key[0] != '_'
|
|
&& key != 'name'
|
|
&& key != 'version';
|
|
});
|
|
}
|
|
|
|
function getSelectedMode() {
|
|
var folder = viewModel._chosenFolderId();
|
|
if (!folder) {
|
|
return null;
|
|
}
|
|
var mode = _.filter(viewModel._availableModes(),
|
|
function (mode) {
|
|
return viewModel[folder].mode && (mode.ace() == viewModel[folder].mode());
|
|
});
|
|
if (mode.length) {
|
|
return mode[0];
|
|
}else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function updateSelectedMode() {
|
|
var selectedMode = getSelectedMode();
|
|
if (selectedMode) {
|
|
var folder = viewModel._chosenFolderId();
|
|
if (folder) {
|
|
viewModel._selectedMode(viewModel[folder].mode
|
|
&& selectedMode);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
function initViewModel(doc) {
|
|
viewModel_updating = true;
|
|
addComputed(doc);
|
|
var snapshot = doc.snapshot;
|
|
var viewModel = ko.mapping.fromJS(snapshot, mapping);
|
|
viewModel._chosenFolderId = ko.observable();
|
|
viewModel._newAttribute = ko.observable();
|
|
viewModel._selectedMode = ko.observable();
|
|
|
|
|
|
// Behaviours
|
|
viewModel._goToFolder = function(folder) {
|
|
viewModel._chosenFolderId(folder);
|
|
updateSelectedMode();
|
|
setDoc(folder);
|
|
};
|
|
viewModel._newAttribute.subscribe(function(newValue) {
|
|
if (newValue) {
|
|
mainDoc.submitOp({
|
|
p:[newValue],
|
|
oi: {}
|
|
}, function (err, result) {
|
|
viewModel._newAttribute("");
|
|
})
|
|
}
|
|
});
|
|
viewModel._getMode = ko.computed(function() {
|
|
var id = viewModel._chosenFolderId();
|
|
return id && viewModel[id].mode;
|
|
});
|
|
viewModel._selectedMode.subscribe(function (newValue) {
|
|
if( newValue && !viewModel_updating) {
|
|
console.log('_selectedMode, newValue',newValue.ace());
|
|
setMode(viewModel._chosenFolderId(), newValue.ace());
|
|
}
|
|
});
|
|
|
|
ko.applyBindings(viewModel);
|
|
window.viewModel=viewModel;
|
|
console.log('viewModel', viewModel);
|
|
viewModel_updating = false;
|
|
}
|
|
|
|
function updateViewModel(doc) {
|
|
viewModel_updating = true;
|
|
addComputed(doc);
|
|
ko.mapping.fromJS(doc.snapshot,viewModel);
|
|
console.log('updated viewModel', viewModel);
|
|
updateSelectedMode();
|
|
viewModel_updating = false;
|
|
|
|
}
|
|
|
|
sharejs.open('json:app:main','json', function (error, main) {
|
|
var indexField = null;
|
|
if (error) {
|
|
console.log('error opening app:main:json', error, main);
|
|
} else {
|
|
console.log('yes!!',main);
|
|
mainDoc = main;
|
|
var snapshot = main.snapshot;
|
|
if (snapshot == null) {
|
|
//TODO test/handle this situation
|
|
console.log('// TODO no data for main yet??');
|
|
} else {
|
|
initViewModel(main)
|
|
}
|
|
main.on('change', function () {
|
|
console.log('main changed!!',main.snapshot, viewModel);
|
|
if (main.snapshot && viewModel) {
|
|
updateViewModel(main);
|
|
} else {
|
|
initViewModel(main)
|
|
}
|
|
});
|
|
}
|
|
})
|
|
</script>
|
|
<!-- @@_end_import__app_main_behaviour -->
|
|
<!-- @@_end_import__app_main_body -->
|
|
</body>
|
|
</html>
|
|
|