Commit 0e393aee authored by Michael Murtaugh's avatar Michael Murtaugh

initial merged code

parents
Pipeline #230 canceled with stages
node_modules/
*.pyc
__pycache__/
*~
# CollageCode
## Changelog
### Feb 2019
Merging previously separate repos ccplayer + cceditors.
<html><head><script src="/__makeserver__/links.js"></script><link href="/2017/08/cceditor/README.md?edit" rel="alternate" title="Edit source" type="text/html"><meta charset="utf-8"></head><body></body></html>
Installation
==============
npm install codemirror
Building
==============
npm install --dev browserify
Notes
===========
* PDFjs
* What for images ? (leaflet ?!)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="cceditorapp.js"></script>
<script>
var app = new cceditorapp.CCEditorApp({
nosaver: "http://localhost/saver.php",
notlayout: {
content: [{
type: 'row',
content: [{
type: 'component',
componentName: 'cceditor',
componentState: { href: '/index.md', target: "editor" }
}, {
type: 'column',
content:[{
type: 'component',
componentName: 'ccframe',
componentState: { href: '', target: "video" }
},{
type: 'stack',
content: [{
type: 'component',
componentName: 'ccframe',
componentState: { href: '', target: "link" }
},{
type: 'component',
componentName: 'ccframe',
componentState: { href: '', target: "scans" }
}]
}]
}]
}]
}
});
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
<!DOCTYPE html>
<html>
<head>
<title>collage code</title>
<meta charset="utf-8">
<link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css">
<link rel="stylesheet" href="../node_modules/codemirror/addon/fold/foldgutter.css" />
<script src="../node_modules/codemirror/lib/codemirror.js"></script>
<script src="../node_modules/codemirror/addon/mode/overlay.js"></script>
<script src="../node_modules/codemirror/mode/markdown/markdown.js"></script>
<script src="../node_modules/codemirror/addon/fold/foldcode.js"></script>
<script src="../node_modules/codemirror/addon/fold/foldgutter.js"></script>
<script src="../node_modules/codemirror/addon/fold/markdown-fold.js"></script>
<link rel="stylesheet" href="../styles.css" />
</head>
<body>
<div id="content">
<div id="player"></div>
<div id="editor">
<textarea id="static">
<https://www.youtube.com/watch?v=Pb0iAFkiEv4>
[link](https://codemirror.net/doc/manual.html#api)
<http://sicv.activearchives.org/share/myfatherisavandal.jpg>
[movie](http://sicv.activearchives.org/share/output-3.mp4)
<http://sicv.activearchives.org/share/visual_vocabularies.pdf>
[local PDF](/sample/visual_vocabularies.pdf)
So imagine typing over this to annotate it now.
Cool eh?
00:00:01
00:00:30
00:01:00
</textarea>
</div>
</div>
<script src="editor.js"></script>
<style>
#player {
position: absolute;
left: 0; right: 0;
width: 50%; height: 100%;
z-index: 1;
}
#editor {
position: absolute;
left: 50%; right: 0;
width: 50%; height: 100%;
z-index: 1;
}
</style>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="gltest.js"></script>
</head>
<body>
<div id="layout"></div>
</body>
</html>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="cceditorapp.js"></script>
<script>
var app = new cceditorapp.CCEditorApp({
nosaver: "http://localhost/saver.php",
notlayout: {
content: [{
type: 'row',
content: [{
type: 'component',
componentName: 'cceditor',
componentState: { href: '/index.md', target: "editor" }
}, {
type: 'column',
content:[{
type: 'component',
componentName: 'ccframe',
componentState: { href: '', target: "video" }
},{
type: 'stack',
content: [{
type: 'component',
componentName: 'ccframe',
componentState: { href: '', target: "link" }
},{
type: 'component',
componentName: 'ccframe',
componentState: { href: '', target: "scans" }
}]
}]
}]
}]
}
});
</script>
</head>
<body>
</body>
</html>
\ No newline at end of file
<https://www.youtube.com/watch?v=Pb0iAFkiEv4>
[link](https://codemirror.net/doc/manual.html#api)
<http://sicv.activearchives.org/share/myfatherisavandal.jpg>
[movie](http://sicv.activearchives.org/share/output-3.mp4)
<http://sicv.activearchives.org/share/visual_vocabularies.pdf>
So imagine typing over this to annotate it now.
Cool eh?
00:00:01
00:00:30
00:01:00
This diff is collapsed.
dist/cceditorapp.js: src/*.js src/editor.css
node_modules/.bin/webpack
# dist/cceditor.js: src/cceditor.js src/editor.css src/*.js
# node_modules/.bin/webpack
dist/gltest.js: src/gltest.js
node_modules/.bin/webpack --config webpack.test.js
{
"name": "typing",
"version": "1.0.0",
"description": "",
"main": "ccframe.js",
"dependencies": {
"codemirror": "^5.28.0",
"golden-layout": "^1.5.9",
"jquery": "^3.3.1",
"notie": "^4.3.1"
},
"devDependencies": {
"browserify": "^14.4.0",
"css-loader": "^0.28.10",
"style-loader": "^0.20.2",
"webpack": "^4.0.1",
"webpack-cli": "^2.0.9",
"webpack-init": "^0.1.2"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
<?php
// Only allow saving to existing files (because of realpath)
// that fall within this directory
$allowedpath = "/var/www/testing/";
// ini_set('display_errors', 1);
// ini_set('display_startup_errors', 1);
// error_reporting(E_ALL);
function join_paths() {
$paths = array();
foreach (func_get_args() as $arg) {
if ($arg !== '') { $paths[] = $arg; }
}
return preg_replace('#/+#','/',join('/', $paths));
}
function startsWith($haystack, $needle)
{
$length = strlen($needle);
return (substr($haystack, 0, $length) === $needle);
}
$docroot = $_SERVER['DOCUMENT_ROOT'];
$path = $_REQUEST['path'];
$path = join_paths($docroot, $path);
$rpath = realpath($path);
if ($rpath && startsWith($rpath, $allowedpath)) {
$text = @$_REQUEST['text'];
if ($text) {
$result = file_put_contents($rpath, $text);
if ($result) {
header('Content-Type: application/json');
echo json_encode(array(message => "saved (".$result.")", error => 0));
} else {
$err = error_get_last();
header('Content-Type: application/json');
echo json_encode(array(message => $err['message'], error => 1));
}
} else {
header('Content-Type: application/json');
echo json_encode(array(message => "no text", error => 1));
}
} else {
header('Content-Type: application/json');
echo json_encode(array(message => "bad path", error => 1));
}
?>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
var timecode = require("./timecode.js"),
$ = require("jquery");
function strip_fragment (url) {
var p = url.indexOf("#");
if (p >= 0) { return url.substring(0, p); }
return url;
}
function parse_fragment (url) {
// console.log("parse_fragment", url);
ret = {}
if (url.indexOf("#") >= 0) {
var p = url.split("#", 2);
ret.base = p[0];
ret.fragment = p[1];
} else {
ret.base = url;
ret.fragment = '';
}
return ret;
}
function parseTime (h) {
var m = h.match("t=([^&,]*)");
// console.log("parseTime", h, m);
if (m) { return timecode.timecode_to_seconds(m[1]); }
}
class CCFrame {
constructor (elt) {
// console.log("ccframe.init", elt);
this.elt = elt;
this.url = null;
this.video = null;
this.iframe = null;
this.interval = null;
this.pageNumber = null;
var that = this;
$(elt).bind("control", function (e, cmd) {
// console.log("ccframe got control", e, cmd);
if (cmd == "toggle") {
that.toggle();
} else if (cmd == "jumpback") {
that.jumpback();
} else if (cmd == "jumpforward") {
that.jumpforward();
}
});
// this.elt.addEventListener("load", this.load);
}
_clear () {
if (this.video !== null) {
this.video.pause();
this.elt.removeChild(this.video);
this.video = null;
}
if (this.iframe !== null) {
this.elt.removeChild(this.iframe);
this.iframe = null;
}
if (this.interval !== null) {
window.clearInterval(this.interval);
this.interval = null;
}
this.pageNumber = null;
this.elt.innerHTML = "";
}
set src (url) {
// console.log("ccframe.src", url);
var purl = parse_fragment(url),
previous_url = this.url ? parse_fragment(this.url) : null;
// console.log("purl", purl, "previous", previous_url)
var viewers = {
'video': {
pattern: /\.(mp4|webm|ogv|ogg|mp3)$/,
viewer: function (m) {
/* Check if match previous_url */
if (this.video && previous_url && previous_url.base == purl.base) {
var t = parseTime(purl.fragment);
if (t) {
this.video.currentTime = t;
this.video.play();
return;
} else {
console.log("ccframe, bad timecode?", purl.fragment);
}
}
this._clear();
this.video = document.createElement("video");
this.video.setAttribute("autoplay", "");
this.video.setAttribute("controls", "");
this.elt.appendChild(this.video);
// console.log("adding load listeneer")
// this.video.addEventListener("loaded", this._load.bind(this));
this.video.addEventListener("timeupdate", this._timeupdate.bind(this));
this.video.src = url;
}
},
'local_pdf': {
pattern: function (url) {
// console.log("local_pdf?", url);
if (url.match(/\.pdf$/i)) {
if (url.match(/^https?:/) == null) {
return true;
}
}
return false;
},
viewer: function (m) {
this._clear();
this.iframe = document.createElement("iframe");
this.elt.appendChild(this.iframe);
this.iframe.src = '/lib/generic/web/viewer.html?file='+url;
this.iframe.addEventListener("load", this._load.bind(this));
}
}
}
var default_viewer = function () {
if (previous_url && previous_url.base == purl.base) {
// fragment change only
// console.log("ccframe: update hash", purl.fragment);
this.iframe.contentWindow.location.hash = purl.fragment;
return;
}
this._clear();
this.iframe = document.createElement("iframe");
this.elt.appendChild(this.iframe);
this.iframe.src = url;
this.iframe.addEventListener("load", this._load.bind(this));
}
//this._clear();
this.url = url;
$(this.elt).trigger("srcchange", this.url);
// var urlnf = strip_fragment(url);
// console.log("cceditor", setsrc, url);
for (var type in viewers) {
var v = viewers[type],
m = (v.pattern instanceof RegExp) ? v.pattern.exec(purl.base) : v.pattern.call(this, purl.base);
if (m) {
v.viewer.call(this, m);
return this;
}
}
default_viewer.call(this);
return this;
}
get src () {
return this.url;
}
_load (e) {
// console.log("ccframe._load", this, e, this.url);
if (this.iframe.contentDocument) {
var video = this.iframe.contentDocument.querySelector("video");
if (video) {
// console.log("iframe has video", video);
}
var pageNumber = this.iframe.contentDocument.querySelector("input#pageNumber");
this.pageNumberInput = pageNumber;
this.pageNumber = pageNumber && pageNumber.value;
if (pageNumber) {
// console.log("iframe has pageNumber", pageNumber);
this.interval = function () {
if (this.pageNumberInput.value != this.pageNumber) {
this.pageNumber = this.pageNumberInput.value;
// console.log("page changed", this.pageNumber);
}
};
window.setInterval(this.interval.bind(this), 1000);
// The input/change eventListeners only seem to fire on user initiated changes (in Firefox at least)
// pageNumber.addEventListener("input", function () {
// console.log("page changed", pageNumber.value);
// }, false);
}
} else {
// console.log("unable to access iframe.contentDocument");
}
if (this.iframe.contentWindow) {
var that = this;
// console.log("watching iframe.contentWindow")
this.iframe.contentWindow.addEventListener("hashchange", function () {
// console.log("iframe hashchange", that.iframe.contentWindow.location.hash);
$(that.elt).trigger("hashchange", that.iframe.contentWindow.location.hash);
})
} else {
// console.log("unable to access iframe.contentWindow")
}
}
_timeupdate (e) {
if (this.video) {
var h = "#t="+timecode.seconds_to_timecode(this.video.currentTime);
$(this.elt).trigger("hashchange", h);
}
// console.log("timeupdate", this.video.currentTime);
}
// pause () {
// if (this.video !== null) {
// this.video.pause();
// }
// }
// play () {
// if (this.video !== null) {
// this.video.play();
// }
// }
/* Functions for Ctrl Keys */
toggle () {
if (this.video !== null) {
this.video.paused ? this.video.play() : this.video.pause();
}
}
jumpforward () {
if (this.video !== null) {
this.video.currentTime += 5;
}
}
jumpback () {
if (this.video !== null) {
this.video.currentTime -= 5;
}
}
get currentTime () {
if (this.video !== null) {
return this.video.currentTime;
}
}
set currentTime (t) {
if (this.video !== null) {
this.video.currentTime = t;
}
}
get fragment () {
if (this.pageNumber !== null) {
return "#page="+this.pageNumber;
} else if (this.video) {
return "#t="+timecode.seconds_to_timecode(this.video.currentTime);
} else {
return this.iframe.contentWindow.location.hash;
}
}
set fragment (val) {
}
}
module.exports = CCFrame;
function classcycler (button, target, modes) {
var ret = {};
var i = 0;
function set_index () {
var l; // nb changes i in classcycler scope
for (i=0, l=modes.length; i<l; i++) {
if (target.classList.contains(modes[i])) { return; }
}
}
button.addEventListener("click", function () {
set_index();
console.log("i", i);
target.classList.replace(modes[i], modes[i = (i+1) % modes.length]);
});
ret.set_mode = function (m) {
set_index();
target.classList.replace(modes[i], m);
}
return ret;
}
// classcycler(gebi("toggle"), gebi("content"), "splitscreen overlay".split(" "));
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.cceditor {
width: 100%; height: 100%;
}
.CodeMirror {
position: absolute;
left: 0; right: 0;
width: 100%; height: 100%;
font-size: 12px;
}
.CodeMirror * { box-sizing: content-box }
.ccframe iframe {
border: none;
width: 100%;
height: 100%;
}
.ccframe video {
width: 100%;
height: 100%;
}
\ No newline at end of file
var GoldenLayout = require("golden-layout");
require("golden-layout/src/css/goldenlayout-base.css");
require("golden-layout/src/css/goldenlayout-light-theme.css");
var config = {
content: [{
type: 'row',
content:[{
type: 'component',
componentName: 'testComponent',
componentState: { label: 'A' }
},{
type: 'column',
content:[{
type: 'component',
componentName: 'testComponent',
componentState: { label: 'B' }
},{
type: 'component',
componentName: 'testComponent',
componentState: { label: 'C' }
}]
}]
}]
};
var myLayout = new GoldenLayout( config, document.getElementById("layout") );
console.log("myLayout", myLayout);
myLayout.registerComponent( 'testComponent', function( container, componentState ){
container.getElement().html( '<h2>' + componentState.label + '</h2>' );
});
myLayout.init();
\ No newline at end of file
function trim_parentheses (m) { return m.replace(/^\((.+)\)$/, "$1") }
// nb: trims []:? ... ie optional trailing colon too!
function trim_brackets (m) { return m.replace(/^\[(.+)\]:?$/, "$1") }
function trim_quotes (m) {
m = m || "";
return m.replace(/^["(']/, "").replace(/["('