create examples directory with old prototypes

This commit is contained in:
ansuz
2016-12-30 13:22:01 +01:00
parent 0abf45bdc5
commit ba4df1a22c
23 changed files with 26 additions and 10 deletions

View File

@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script>
<style>
html, body{
padding: 0px;
margin: 0px;
overflow: hidden;
box-sizing: border-box;
}
form {
border: 3px solid black;
border-radius: 5px;
padding: 15px;
font-weight: bold !important;
font-size: 18px !important;
}
input[type="text"],
input[type="password"],
input[type="number"],
input[type="range"],
select
{
margin-top: 5px;
margin-bottom: 5px;
width: 80%;
}
textarea {
width: 80%;
height: 40vh;
font-weight: bold;
font-size: 18px;
}
</style>
</head>
<body>
<form>
<input type="radio" name="radio" value="one" checked>One
<input type="radio" name="radio" value="two">Two
<input type="radio" name="radio" value="three">Three<br>
<input type="checkbox" name="checkbox1" value="1">Checkbox One
<input type="checkbox" name="checkbox2" value="2">Checkbox Two<br>
<input type="text" name="text" placeholder="Text Input"><br>
<input type="password" name="password" placeholder="Passwords"><br>
<input type="number" name="number" min="1" max="5" placeholder="Numbers">Number<br>
<input type="range" name="range" min="0" max="100">Ranges<br>
<select name="select">
<option value="one">One</option>
<option value="two">Two</option>
<option value="three">Three</option>
<option value="four">Four</option>
</select> Dropdowns<br>
<select name="select-multiple" multiple>
<option value="pew">Pew</option>
<option value="bang">Bang</option>
<option value="kapow">Kapow</option>
<option value="zing">Zing</option>
</select>
<textarea name="textarea"></textarea><br>
</form>
</body>
</html>

226
www/examples/form/main.js Normal file
View File

@@ -0,0 +1,226 @@
require.config({ paths: { 'json.sortify': '/bower_components/json.sortify/dist/JSON.sortify' } });
define([
'/api/config?cb=' + Math.random().toString(16).substring(2),
'/bower_components/chainpad-netflux/chainpad-netflux.js',
'/bower_components/chainpad-crypto/crypto.js',
'/bower_components/textpatcher/TextPatcher.amd.js',
'json.sortify',
'ula.js',
'/bower_components/chainpad-json-validator/json-ot.js',
'/common/cryptpad-common.js',
'/bower_components/jquery/dist/jquery.min.js',
], function (Config, Realtime, Crypto, TextPatcher, Sortify, Formula, JsonOT, Cryptpad) {
var $ = window.jQuery;
var secret = Cryptpad.getSecrets();
var module = window.APP = {
TextPatcher: TextPatcher,
Sortify: Sortify,
Formula: Formula,
};
var initializing = true;
var uid = module.uid = Formula.uid;
var getInputType = Formula.getInputType;
var $elements = module.elements = $('input, select, textarea');
var eventsByType = Formula.eventsByType;
var Map = module.Map = {};
var UI = module.UI = {
ids: [],
each: function (f) {
UI.ids.forEach(function (id, i, list) {
if (!UI[id]) { return; }
f(UI[id], i, list);
});
},
add: function (id, ui) {
if (UI.ids.indexOf(id) === -1) {
UI.ids.push(id);
UI[id] = ui;
return true;
} else {
// it already exists
return false;
}
},
remove: function (id) {
delete UI[id];
var idx = UI.ids.indexOf(id);
if (idx > -1) {
UI.ids.splice(idx, 1);
return true;
}
}
};
var cursorTypes = ['textarea', 'password', 'text'];
var canonicalize = function (text) { return text.replace(/\r\n/g, '\n'); };
$elements.each(function (index, element) {
var $this = $(this);
var id = uid();
var type = getInputType($this);
// ignore hidden inputs, submit inputs, and buttons
if (['button', 'submit', 'hidden'].indexOf(type) !== -1) {
return;
}
$this // give each element a uid
.data('rtform-uid', id)
// get its type
.data('rt-ui-type', type);
var component = {
id: id,
$: $this,
element: element,
type: type,
preserveCursor: cursorTypes.indexOf(type) !== -1,
name: $this.prop('name'),
};
UI.add(id, component);
component.value = (function () {
var checker = ['radio', 'checkbox'].indexOf(type) !== -1;
if (checker) {
return function (content) {
return typeof content !== 'undefined'?
$this.prop('checked', !!content):
$this.prop('checked');
};
} else {
return function (content) {
return typeof content !== 'undefined' ?
$this.val(content):
typeof($this.val()) === 'string'? canonicalize($this.val()): $this.val();
};
}
}());
var update = component.update = function () { Map[id] = component.value(); };
update();
});
var config = module.config = {
initialState: Sortify(Map) || '{}',
websocketURL: Config.websocketURL,
userName: Crypto.rand64(8),
channel: secret.channel,
crypto: Crypto.createEncryptor(secret.key),
transformFunction: JsonOT.validate
};
var setEditable = module.setEditable = function (bool) {
/* (dis)allow editing */
$elements.each(function () {
$(this).attr('disabled', !bool);
});
};
setEditable(false);
var onInit = config.onInit = function (info) {
var realtime = module.realtime = info.realtime;
window.location.hash = info.channel + secret.key;
// create your patcher
module.patchText = TextPatcher.create({
realtime: realtime,
logging: true,
});
};
var readValues = function () {
UI.each(function (ui, i, list) {
Map[ui.id] = ui.value();
});
};
var onLocal = config.onLocal = function () {
if (initializing) { return; }
/* serialize local changes */
readValues();
module.patchText(Sortify(Map));
};
var updateValues = function () {
var userDoc = module.realtime.getUserDoc();
var parsed = JSON.parse(userDoc);
console.log(userDoc);
// flush received values to the map
// but only if you don't have them locally
// this *shouldn't* break cursors
Object.keys(parsed).forEach(function (key) {
if (UI.ids.indexOf(key) === -1) { Map[key] = parsed[key]; }
});
UI.each(function (ui, i, list) {
var newval = parsed[ui.id];
var oldval = ui.value();
if (typeof(newval) === 'undefined') { return; }
if (newval === oldval) { return; }
var op;
var selects;
var element = ui.element;
if (ui.preserveCursor) {
op = TextPatcher.diff(oldval, newval);
selects = ['selectionStart', 'selectionEnd'].map(function (attr) {
var before = element[attr];
var after = TextPatcher.transformCursor(element[attr], op);
return after;
});
}
ui.value(newval);
ui.update();
if (op && ui.preserveCursor) {
//console.log(selects);
element.selectionStart = selects[0];
element.selectionEnd = selects[1];
}
});
};
var onRemote = config.onRemote = function (info) {
if (initializing) { return; }
/* integrate remote changes */
updateValues();
};
var onReady = config.onReady = function (info) {
updateValues();
console.log("READY");
setEditable(true);
initializing = false;
};
var onAbort = config.onAbort = function (info) {
window.alert("Network Connection Lost");
};
var rt = Realtime.start(config);
UI.each(function (ui, i, list) {
var type = ui.type;
var events = eventsByType[type];
ui.$.on(events, onLocal);
});
});

View File

@@ -0,0 +1,14 @@
```Javascript
/* elements that we need to listen to */
/*
* text => $(text).val()
* password => $(password).val()
* radio => $(radio).prop('checked')
* checkbox => $(checkbox).prop('checked')
* number => $(number).val() // returns string, no default
* range => $(range).val()
* select => $(select).val()
* textarea => $(textarea).val()
*/
```

25
www/examples/form/ula.js Normal file
View File

@@ -0,0 +1,25 @@
define([], function () {
var ula = {};
var uid = ula.uid = (function () {
var i = 0;
var prefix = 'rt_';
return function () { return prefix + i++; };
}());
ula.getInputType = function ($el) { return $el[0].type; };
ula.eventsByType = {
text: 'change keyup',
password: 'change keyup',
radio: 'change click',
checkbox: 'change click',
number: 'change',
range: 'keyup change',
'select-one': 'change',
'select-multiple': 'change',
textarea: 'change keyup',
};
return ula;
});