This commit is contained in:
user
2013-03-09 14:59:29 +01:00
parent 44afc36ead
commit 7b25d7e446
7 changed files with 492 additions and 165 deletions

View File

@@ -6,127 +6,126 @@
padding: 0px;
font-family: Arial, sans-serif;
width: 100%;
height: 100%;
height: 100%;
}
html body{
background: #FFF;
width: 100%;
height: 100%;
background: #FFF;
width: 100%;
height: 100%;
}
/* ************** LAYOUT ****************************************
*****************************************************************/
#wrapper {
width: 100%;
height: 100%;
background:linear-gradient(to bottom, rgba(0,0,0,0) 80%,rgba(0,0,0,0.65) 100%);
width: 100%;
height: 100%;
background:linear-gradient(to bottom, rgba(0,0,0,0) 80%,rgba(0,0,0,0.65) 100%);
}
#mlibheader{
width: 100%;
height: 20%;
max-height: 100px;
min-height: 50px;
line-height: 100px;
float: left;
text-align: center;
font-size: 48px;
font-weight: 500;
color: #FFF;
background: linear-gradient(to right, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%);
width: 100%;
height: 20%;
max-height: 100px;
min-height: 50px;
line-height: 100px;
float: left;
text-align: center;
font-size: 48px;
font-weight: 500;
color: #FFF;
background: linear-gradient(to right, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%);
}
#breadcrumb{
height:10%;
width: 100%;
max-height:30px;
min-height: 10px;
float:left;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
background: rgba(155,155,155,1);
}
height:10%;
width: 100%;
max-height:30px;
min-height: 10px;
float:left;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
background: rgba(155,155,155,1);
}
#contentwrapper {
padding-top: 1%;
width: 100%;
height:50%;
float:left;
padding-top: 1%;
width: 100%;
height:50%;
float:left;
}
#sidenav {
width: 29%;
float:left;
height:49%;
}
width: 29%;
float:left;
height:49%;
}
#playersec {
width: 40%;
float:left;
margin-left: 1%;
margin-right : 1%;
margin-bottom: auto;
background: linear-gradient(to bottom, rgba(155,155,155,1) 0%,rgba(14,14,14,1) 100%);
vertical-align: bottom;
}
width: 40%;
float:left;
margin-left: 1%;
margin-right : 1%;
margin-bottom: auto;
background: linear-gradient(to bottom, rgba(155,155,155,1) 0%,rgba(14,14,14,1) 100%);
vertical-align: bottom;
}
#timeline {
height: 90%;
}
#player {
height: 10%;
}
height: 90%;
}
#player {
height: 10%;
}
#playerlistsec {
width: 29%;
float:left;
}
width: 29%;
float:left;
}
footer{
height: 20%;
width: 100%;
float:left;
height: 20%;
width: 100%;
float:left;
}
/* ************** NAV ****************************************
/* ************** NAV ****************************************
*****************************************************************/
#playerlistsec.menu {
list-style-type: none;
width: 97%;
}
list-style-type: none;
width: 97%;
}
#playerlistsec .menu li {
height: 5%;
min-height: 50px;
line-height: 50px;
list-style-type: none;
text-align: center;
vertical-align: middle;
margin-bottom: 1%;
background: linear-gradient(to bottom, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%);
cursor: pointer;
float: left;
}
height: 5%;
min-height: 50px;
line-height: 50px;
list-style-type: none;
text-align: center;
vertical-align: middle;
margin-bottom: 1%;
background: linear-gradient(to bottom, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%);
cursor: pointer;
float: left;
}
#playerlistsec .menu li.subli{
width: auto;
height: 3%;
min-height: 30px;
line-height: 30px;
margin: 1%;
padding-left: 5px;
padding-right: 5px;
float: left;
background: linear-gradient(to left, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%);
width: auto;
height: 3%;
min-height: 30px;
line-height: 30px;
margin: 1%;
padding-left: 5px;
padding-right: 5px;
float: left;
background: linear-gradient(to left, rgba(207,231,250,1) 0%,rgba(99,147,193,1) 100%);
}
#sidenav li {
height: 50px;
width: 100px;
}
#sidenav ul {
margin-left: 50px;
}
height: 50px;
width: 100px;
}
#sidenav ul {
margin-left: 50px;
}

View File

@@ -1,80 +1,49 @@
<!doctype html>
<html>
<head>
<title>Mlib5</title>
<meta name="robots" content="noindex, nofollow">
<meta name="creator" content="stubbfel">
<meta http-equiv="content-type" content="text/html; charset=UTF-8" >
<head>
<title>Mlib5</title>
<meta name="robots" content="noindex, nofollow">
<meta name="creator" content="stubbfel">
<meta http-equiv="content-type" content="text/html; charset=UTF-8" >
<link rel="stylesheet" type="text/css" href="css/style.css" title="style">
<script type="text/javascript" src="js/json_sans_eval.js"></script>
<script type="text/javascript" src="js/mlib.js"></script>
</head>
<body onload="pageLoad();">
<div id="wrapper">
<header id="mlibheader">
mlib5
</header>
<div id="breadcrumb"></div>
<div id="contentwrapper">
<nav id="sidenav">
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>subitem1</li>
<li>subitem2</li>
<li>item4</li>
</ul>
</nav>
<link rel="stylesheet" type="text/css" href="css/style.css" title="style">
</head>
<body onload="pageLoad();">
<div id="wrapper">
<header id="mlibheader">
mlib5
</header>
<div id="breadcrumb"></div>
<div id="contentwrapper">
<nav id="sidenav">
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
<li>subitem1</li>
<li>subitem2</li>
<li>item4</li>
</ul>
</nav>
<section id="playersec">
<section id="playersec">
<div id="timeline">test</div>
<audio controls autoplay id="player">
<source id ="playersource" src="audio.ogg">;
</audio>
</section>
<audio controls autoplay id="player">
<source id ="playersource" src="">;
</audio>
</section>
<nav id="playerlistsec">
<ul class="menu">
<li onclick="jump('audio.ogg#t=3000','Kapitel1')">Kapitel1</li>
<li class="subli" onclick="jump('audio.ogg#t=3000','Kapitel1')">UnterKapitel1</li>
<li class="subli" onclick="jump('audio.ogg#t=6000','Kapitel2')">UnterKapitel2</li>
<li class="subli" onclick="jump('audio.ogg#t=9000','Kapitel3')">UnterKapitel3</li>
<li onclick="jump('audio2.ogg#t=5000','Kapitel4')">Kapitel4</li>
<nav id="playerlistsec">
<ul class="menu" id="playList">
</ul>
</nav>
</div>
<footer></footer>
</div>
</body>
</html>
</nav>
</div>
<footer></footer>
</div>
<script>
var actTitle = "start";
var bread = document.getElementById('breadcrumb');
var player = document.getElementById('player');
var mediaSource = document.getElementById('playersource');
function pageLoad() {
player.addEventListener('timeupdate', timeUpdate);
player.addEventListener('onended', trackEndet);
}
function jump(newSrc,newTitle) {
mediaSource.src = newSrc;
actTitle = newTitle;
player.load();
}
function timeUpdate() {
if (player.currentTime > 9000) {
actTitle = 'Kapitelbread2';
}
bread.innerHTML = actTitle;
}
function trackEndet() {
bread.innerHTML = actTitle;
}
</script>
<object data="js/test.json" type="application/json" id="episode" hidden>
<param name="src" value="js/test.json">
</object>
</body>
</html>

238
js/json_sans_eval.js Normal file
View File

@@ -0,0 +1,238 @@
// This source code is free for use in the public domain.
// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
// http://code.google.com/p/json-sans-eval/
/**
* Parses a string of well-formed JSON text.
*
* If the input is not well-formed, then behavior is undefined, but it is
* deterministic and is guaranteed not to modify any object other than its
* return value.
*
* This does not use `eval` so is less likely to have obscure security bugs than
* json2.js.
* It is optimized for speed, so is much faster than json_parse.js.
*
* This library should be used whenever security is a concern (when JSON may
* come from an untrusted source), speed is a concern, and erroring on malformed
* JSON is *not* a concern.
*
* Pros Cons
* +-----------------------+-----------------------+
* json_sans_eval.js | Fast, secure | Not validating |
* +-----------------------+-----------------------+
* json_parse.js | Validating, secure | Slow |
* +-----------------------+-----------------------+
* json2.js | Fast, some validation | Potentially insecure |
* +-----------------------+-----------------------+
*
* json2.js is very fast, but potentially insecure since it calls `eval` to
* parse JSON data, so an attacker might be able to supply strange JS that
* looks like JSON, but that executes arbitrary javascript.
* If you do have to use json2.js with untrusted data, make sure you keep
* your version of json2.js up to date so that you get patches as they're
* released.
*
* @param {string} json per RFC 4627
* @param {function (this:Object, string, *):*} opt_reviver optional function
* that reworks JSON objects post-parse per Chapter 15.12 of EcmaScript3.1.
* If supplied, the function is called with a string key, and a value.
* The value is the property of 'this'. The reviver should return
* the value to use in its place. So if dates were serialized as
* {@code { "type": "Date", "time": 1234 }}, then a reviver might look like
* {@code
* function (key, value) {
* if (value && typeof value === 'object' && 'Date' === value.type) {
* return new Date(value.time);
* } else {
* return value;
* }
* }}.
* If the reviver returns {@code undefined} then the property named by key
* will be deleted from its container.
* {@code this} is bound to the object containing the specified property.
* @return {Object|Array}
* @author Mike Samuel <mikesamuel@gmail.com>
*/
var jsonParse = (function () {
var number
= '(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)';
var oneChar = '(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]'
+ '|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))';
var string = '(?:\"' + oneChar + '*\")';
// Will match a value in a well-formed JSON file.
// If the input is not well-formed, may match strangely, but not in an unsafe
// way.
// Since this only matches value tokens, it does not match whitespace, colons,
// or commas.
var jsonToken = new RegExp(
'(?:false|true|null|[\\{\\}\\[\\]]'
+ '|' + number
+ '|' + string
+ ')', 'g');
// Matches escape sequences in a string literal
var escapeSequence = new RegExp('\\\\(?:([^u])|u(.{4}))', 'g');
// Decodes escape sequences in object literals
var escapes = {
'"': '"',
'/': '/',
'\\': '\\',
'b': '\b',
'f': '\f',
'n': '\n',
'r': '\r',
't': '\t'
};
function unescapeOne(_, ch, hex) {
return ch ? escapes[ch] : String.fromCharCode(parseInt(hex, 16));
}
// A non-falsy value that coerces to the empty string when used as a key.
var EMPTY_STRING = new String('');
var SLASH = '\\';
// Constructor to use based on an open token.
var firstTokenCtors = { '{': Object, '[': Array };
var hop = Object.hasOwnProperty;
return function (json, opt_reviver) {
// Split into tokens
var toks = json.match(jsonToken);
// Construct the object to return
var result;
var tok = toks[0];
var topLevelPrimitive = false;
if ('{' === tok) {
result = {};
} else if ('[' === tok) {
result = [];
} else {
// The RFC only allows arrays or objects at the top level, but the JSON.parse
// defined by the EcmaScript 5 draft does allow strings, booleans, numbers, and null
// at the top level.
result = [];
topLevelPrimitive = true;
}
// If undefined, the key in an object key/value record to use for the next
// value parsed.
var key;
// Loop over remaining tokens maintaining a stack of uncompleted objects and
// arrays.
var stack = [result];
for (var i = 1 - topLevelPrimitive, n = toks.length; i < n; ++i) {
tok = toks[i];
var cont;
switch (tok.charCodeAt(0)) {
default: // sign or digit
cont = stack[0];
cont[key || cont.length] = +(tok);
key = void 0;
break;
case 0x22: // '"'
tok = tok.substring(1, tok.length - 1);
if (tok.indexOf(SLASH) !== -1) {
tok = tok.replace(escapeSequence, unescapeOne);
}
cont = stack[0];
if (!key) {
if (cont instanceof Array) {
key = cont.length;
} else {
key = tok || EMPTY_STRING; // Use as key for next value seen.
break;
}
}
cont[key] = tok;
key = void 0;
break;
case 0x5b: // '['
cont = stack[0];
stack.unshift(cont[key || cont.length] = []);
key = void 0;
break;
case 0x5d: // ']'
stack.shift();
break;
case 0x66: // 'f'
cont = stack[0];
cont[key || cont.length] = false;
key = void 0;
break;
case 0x6e: // 'n'
cont = stack[0];
cont[key || cont.length] = null;
key = void 0;
break;
case 0x74: // 't'
cont = stack[0];
cont[key || cont.length] = true;
key = void 0;
break;
case 0x7b: // '{'
cont = stack[0];
stack.unshift(cont[key || cont.length] = {});
key = void 0;
break;
case 0x7d: // '}'
stack.shift();
break;
}
}
// Fail if we've got an uncompleted object.
if (topLevelPrimitive) {
if (stack.length !== 1) { throw new Error(); }
result = result[0];
} else {
if (stack.length) { throw new Error(); }
}
if (opt_reviver) {
// Based on walk as implemented in http://www.json.org/json2.js
var walk = function (holder, key) {
var value = holder[key];
if (value && typeof value === 'object') {
var toDelete = null;
for (var k in value) {
if (hop.call(value, k) && value !== holder) {
// Recurse to properties first. This has the effect of causing
// the reviver to be called on the object graph depth-first.
// Since 'this' is bound to the holder of the property, the
// reviver can access sibling properties of k including ones
// that have not yet been revived.
// The value returned by the reviver is used in place of the
// current value of property k.
// If it returns undefined then the property is deleted.
var v = walk(value, k);
if (v !== void 0) {
value[k] = v;
} else {
// Deleting properties inside the loop has vaguely defined
// semantics in ES3 and ES3.1.
if (!toDelete) { toDelete = []; }
toDelete.push(k);
}
}
}
if (toDelete) {
for (var i = toDelete.length; --i >= 0;) {
delete value[toDelete[i]];
}
}
}
return opt_reviver.call(holder, key, value);
};
result = walk({ '': result }, '');
}
return result;
};
})();

90
js/mlib.js Normal file
View File

@@ -0,0 +1,90 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
function pageLoad() {
bread = document.getElementById('breadcrumb');
player = document.getElementById('player');
mediaSource = document.getElementById('playersource');
player.addEventListener('timeupdate', timeUpdate);
player.addEventListener('ended', trackEnded);
var episodeHTML = document.getElementById('episode');
var episodeJson = episodeHTML.contentDocument.body.firstChild.innerHTML;
episodeObj = jsonParse(episodeJson);
actTitle = episodeObj.title;
actTrack = 0;
actChapter = 0;
createPlayList();
jumpById(actTrack, actChapter);
}
function createPlayList() {
var playList = document.getElementById('playList');
var entryNumber = 1;
var listEntries = "";
for (var track in episodeObj.tracks) {
var trackObj = episodeObj.tracks[track];
if (trackObj.chapters) {
for (var chapter in trackObj.chapters) {
var chapterObj = trackObj.chapters[chapter];
listEntries = listEntries + "<li onclick=\"jumpById(" + track + "," + chapter + ");\">" + entryNumber++ + ": " + chapterObj.title + "</li>";
}
} else {
listEntries = listEntries + "<li onclick=\"jumpById(" + track + ",0);\">" + entryNumber++ + ": " + trackObj.title + "</li>";
}
}
playList.innerHTML = listEntries;
}
function jumpById(trackId, chapterId) {
if (!episodeObj.tracks || trackId >= episodeObj.tracks.length) {
return;
}
var trackObj = episodeObj.tracks[trackId];
var trackSrc = trackObj.src;
var trackTime = 0;
if (trackObj.chapters && chapterId < trackObj.chapters.length) {
var chapterObj = trackObj.chapters[chapterId];
trackTime = chapterObj.time;
}
actTrack = trackId;
actChapter = chapterId;
mediaSource.src = trackSrc + "#t=" + trackTime;
player.load();
}
function timeUpdate() {
actChapter = calcChapterId(actTrack, player.currentTime);
bread.innerHTML = createBreadCrumb(actTrack,actChapter);
}
function createBreadCrumb(trackId, chapterId) {
var trackObj = episodeObj.tracks[trackId];
var actNewTitle = episodeObj.title + " -> " + trackObj.title;
if (trackObj.chapters && chapterId < trackObj.chapters.length) {
var chapterObj = trackObj.chapters[chapterId];
actNewTitle = actNewTitle + " -> "+chapterObj.title;
}
return actNewTitle;
}
function calcChapterId(trackId, time) {
var trackObj = episodeObj.tracks[trackId];
var newChapId = 0;
for (var chapter in trackObj.chapters) {
var chapterObj = trackObj.chapters[chapter];
if (chapterObj.time <= time) {
newChapId = chapter;
} else {
return newChapId;
}
}
return newChapId;
}
function trackEnded() {
jumpById(actTrack+1, 0);
}

View File

@@ -1,3 +0,0 @@
{
"name": "user"
}

34
js/test.json Normal file
View File

@@ -0,0 +1,34 @@
{
"title": "Testepisode",
"info": "this is a testepisode",
"tracks": [
{
"title": "testtrack1",
"info": "this the testtrack1",
"src": "audio.ogg",
"chapters": [
{
"title": "testtrackcheapter1",
"info": "this the cheapter1",
"time": "0"
},
{
"title": "testtrackcheapter2",
"info": "this the cheapter2",
"time": "3000"
},
{
"title": "testtrackcheapter3",
"info": "this the cheapter3",
"time": "9000"
}
]
},
{
"title": "testtrack2",
"info": "this the testtrack2",
"src": "audio2.ogg",
"cheapter": null
}
]
}