From 751d8db9d88d45b33792982103f8682e21ac876e Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sat, 14 Feb 2015 22:42:44 +1100 Subject: [PATCH] WIP --- .gitignore | 3 + .jshintignore | 0 .jshintrc | 56 ++ assets/icons/collapse.svg | 13 + assets/icons/expand.svg | 13 + assets/icons/fast-forward.svg | 6 + assets/icons/film.svg | 6 + assets/icons/pause.svg | 13 + assets/icons/play.svg | 6 + assets/icons/refresh.svg | 7 + assets/icons/rewind.svg | 10 + assets/icons/sound.svg | 7 + assets/js/docs.js | 19 + assets/js/lib/hogan-3.0.2.mustache.js | 802 ++++++++++++++++++ assets/js/simple-media.js | 627 ++++++++++++++ assets/less/docs.less | 37 + assets/less/lib/mixins.less | 27 + assets/less/lib/normalize.less | 406 +++++++++ assets/less/simple-player.less | 552 ++++++++++++ assets/templates/controls.html | 51 ++ bower.json | 29 + bundles.json | 14 + design/IcoMoon - 7 Icons/PNG/fast-forward.png | Bin 0 -> 360 bytes design/IcoMoon - 7 Icons/PNG/film.png | Bin 0 -> 157 bytes design/IcoMoon - 7 Icons/PNG/monitor.png | Bin 0 -> 199 bytes design/IcoMoon - 7 Icons/PNG/play.png | Bin 0 -> 329 bytes design/IcoMoon - 7 Icons/PNG/refresh.png | Bin 0 -> 441 bytes design/IcoMoon - 7 Icons/PNG/sound.png | Bin 0 -> 328 bytes design/IcoMoon - 7 Icons/PNG/up.png | Bin 0 -> 419 bytes design/IcoMoon - 7 Icons/Read Me.txt | 7 + design/IcoMoon - 7 Icons/SVG/fast-forward.svg | 6 + design/IcoMoon - 7 Icons/SVG/film.svg | 6 + design/IcoMoon - 7 Icons/SVG/monitor.svg | 6 + design/IcoMoon - 7 Icons/SVG/play.svg | 6 + design/IcoMoon - 7 Icons/SVG/refresh.svg | 7 + design/IcoMoon - 7 Icons/SVG/sound.svg | 7 + design/IcoMoon - 7 Icons/SVG/up.svg | 7 + design/IcoMoon - 7 Icons/demo-files/demo.css | 147 ++++ design/IcoMoon - 7 Icons/demo.html | 90 ++ design/IcoMoon - 7 Icons/style.css | 6 + design/IcoMoon - 7 Icons/svgdefs.svg | 35 + design/collapse.sketch | Bin 0 -> 32768 bytes design/expand.sketch | Bin 0 -> 40960 bytes design/pause.sketch | Bin 0 -> 32768 bytes design/rewind.sketch | Bin 0 -> 32768 bytes dist/css/docs.css | 1 + dist/css/simple-player.css | 1 + dist/js/docs.js | 1 + dist/js/simple-player.js | 1 + dist/js/templates.js | 2 + dist/svg/sprite.svg | 1 + docs/index.html | 52 ++ gulpfile.js | 139 +++ media/captions_PayPal_Austin_en.vtt.txt | 145 ++++ media/poster_PayPal_Austin2.jpg | Bin 0 -> 39528 bytes package.json | 36 + readme.md | 12 + 57 files changed, 3425 insertions(+) create mode 100644 .gitignore create mode 100644 .jshintignore create mode 100644 .jshintrc create mode 100644 assets/icons/collapse.svg create mode 100644 assets/icons/expand.svg create mode 100755 assets/icons/fast-forward.svg create mode 100755 assets/icons/film.svg create mode 100644 assets/icons/pause.svg create mode 100755 assets/icons/play.svg create mode 100755 assets/icons/refresh.svg create mode 100644 assets/icons/rewind.svg create mode 100755 assets/icons/sound.svg create mode 100644 assets/js/docs.js create mode 100644 assets/js/lib/hogan-3.0.2.mustache.js create mode 100644 assets/js/simple-media.js create mode 100644 assets/less/docs.less create mode 100644 assets/less/lib/mixins.less create mode 100644 assets/less/lib/normalize.less create mode 100644 assets/less/simple-player.less create mode 100644 assets/templates/controls.html create mode 100644 bower.json create mode 100644 bundles.json create mode 100755 design/IcoMoon - 7 Icons/PNG/fast-forward.png create mode 100755 design/IcoMoon - 7 Icons/PNG/film.png create mode 100755 design/IcoMoon - 7 Icons/PNG/monitor.png create mode 100755 design/IcoMoon - 7 Icons/PNG/play.png create mode 100755 design/IcoMoon - 7 Icons/PNG/refresh.png create mode 100755 design/IcoMoon - 7 Icons/PNG/sound.png create mode 100755 design/IcoMoon - 7 Icons/PNG/up.png create mode 100755 design/IcoMoon - 7 Icons/Read Me.txt create mode 100755 design/IcoMoon - 7 Icons/SVG/fast-forward.svg create mode 100755 design/IcoMoon - 7 Icons/SVG/film.svg create mode 100755 design/IcoMoon - 7 Icons/SVG/monitor.svg create mode 100755 design/IcoMoon - 7 Icons/SVG/play.svg create mode 100755 design/IcoMoon - 7 Icons/SVG/refresh.svg create mode 100755 design/IcoMoon - 7 Icons/SVG/sound.svg create mode 100755 design/IcoMoon - 7 Icons/SVG/up.svg create mode 100755 design/IcoMoon - 7 Icons/demo-files/demo.css create mode 100755 design/IcoMoon - 7 Icons/demo.html create mode 100755 design/IcoMoon - 7 Icons/style.css create mode 100755 design/IcoMoon - 7 Icons/svgdefs.svg create mode 100644 design/collapse.sketch create mode 100644 design/expand.sketch create mode 100644 design/pause.sketch create mode 100644 design/rewind.sketch create mode 100644 dist/css/docs.css create mode 100644 dist/css/simple-player.css create mode 100644 dist/js/docs.js create mode 100644 dist/js/simple-player.js create mode 100644 dist/js/templates.js create mode 100644 dist/svg/sprite.svg create mode 100644 docs/index.html create mode 100644 gulpfile.js create mode 100644 media/captions_PayPal_Austin_en.vtt.txt create mode 100644 media/poster_PayPal_Austin2.jpg create mode 100644 package.json create mode 100644 readme.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..48745e76 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +*.sublime-project +*.sublime-workspace diff --git a/.jshintignore b/.jshintignore new file mode 100644 index 00000000..e69de29b diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 00000000..7884da2c --- /dev/null +++ b/.jshintrc @@ -0,0 +1,56 @@ +{ + // Settings + "passfail" : false, // Stop on first error. + "maxerr" : 100, // Maximum error before stopping. + + // Predefined globals whom JSHint will ignore. + "browser" : true, // Standard browser globals e.g. `window`, `document`. + "node" : false, + "rhino" : false, + "couch" : false, + "wsh" : true, // Windows Scripting Host. + "jquery" : true, + "predef" : [ "jQuery", "$" ], + + // Development. + "debug" : false, // Allow debugger statements e.g. browser breakpoints. + "devel" : true, // Allow developments statements e.g. `console.log();`. + + // ECMAScript 5. + "strict" : false, // Require `use strict` pragma in every file. + "globalstrict" : false, // Allow global "use strict" (also enables 'strict'). + + // The Good Parts. + "asi" : true, // Tolerate Automatic Semicolon Insertion (no semicolons). + "laxbreak" : true, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons. + "bitwise" : false, // Prohibit bitwise operators (&, |, ^, etc.). + "boss" : false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. + "curly" : true, // Require {} for every new block or scope. + "eqeqeq" : false, // Require triple equals i.e. `===`. + "eqnull" : false, // Tolerate use of `== null`. + "evil" : false, // Tolerate use of `eval`. + "expr" : false, // Tolerate `ExpressionStatement` as Programs. + "forin" : false, // Tolerate `for in` loops without `hasOwnPrototype`. + "immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` + "latedef" : false, // Prohipit variable use before definition. + "loopfunc" : true, // Allow functions to be defined within loops. + "noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`. + "regexp" : true, // Prohibit `.` and `[^...]` in regular expressions. + "regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`. + "scripturl" : true, // Tolerate script-targeted URLs. + "shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`. + "supernew" : false, // Tolerate `new function () { ... };` and `new Object;`. + "undef" : true, // Require all non-global variables be declared before they are used. + + // Personal styling preferences. + "newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`. + "noempty" : true, // Prohibit use of empty blocks. + "nonew" : true, // Prohibit use of constructors for side-effects. + "nomen" : true, // Prohibit use of initial or trailing underbars in names. + "onevar" : false, // Allow only one `var` statement per function. + "plusplus" : false, // Prohibit use of `++` & `--`. + "sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`. + "trailing" : true, // Prohibit trailing whitespaces. + "white" : false, // Check against strict whitespace and indentation rules. + "indent" : 2 // Specify indentation spacing +} \ No newline at end of file diff --git a/assets/icons/collapse.svg b/assets/icons/collapse.svg new file mode 100644 index 00000000..d41e0402 --- /dev/null +++ b/assets/icons/collapse.svg @@ -0,0 +1,13 @@ + + + + collapse + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/assets/icons/expand.svg b/assets/icons/expand.svg new file mode 100644 index 00000000..9c541d48 --- /dev/null +++ b/assets/icons/expand.svg @@ -0,0 +1,13 @@ + + + + expand + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/assets/icons/fast-forward.svg b/assets/icons/fast-forward.svg new file mode 100755 index 00000000..cc4ee6d1 --- /dev/null +++ b/assets/icons/fast-forward.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/film.svg b/assets/icons/film.svg new file mode 100755 index 00000000..ad3d3551 --- /dev/null +++ b/assets/icons/film.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/pause.svg b/assets/icons/pause.svg new file mode 100644 index 00000000..d451beca --- /dev/null +++ b/assets/icons/pause.svg @@ -0,0 +1,13 @@ + + + + pause + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/assets/icons/play.svg b/assets/icons/play.svg new file mode 100755 index 00000000..ebe9ff57 --- /dev/null +++ b/assets/icons/play.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/icons/refresh.svg b/assets/icons/refresh.svg new file mode 100755 index 00000000..10ffb198 --- /dev/null +++ b/assets/icons/refresh.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/rewind.svg b/assets/icons/rewind.svg new file mode 100644 index 00000000..7be18d37 --- /dev/null +++ b/assets/icons/rewind.svg @@ -0,0 +1,10 @@ + + + + rewind + Created with Sketch. + + + + + \ No newline at end of file diff --git a/assets/icons/sound.svg b/assets/icons/sound.svg new file mode 100755 index 00000000..6c6ca54d --- /dev/null +++ b/assets/icons/sound.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/js/docs.js b/assets/js/docs.js new file mode 100644 index 00000000..c8a3bd44 --- /dev/null +++ b/assets/js/docs.js @@ -0,0 +1,19 @@ +// ========================================================================== +// Docs example +// ========================================================================== + +/*global InitPxVideo, Mustache, templates */ + +// Initialize +var video = new InitPxVideo({ + "videoId": "myvid", + "captionsOnDefault": true, + "seekInterval": 20, + "videoTitle": "PayPal Austin promo", + "debug": true, + "html": templates.controls.render({ + + }) +}); + +console.log(video); \ No newline at end of file diff --git a/assets/js/lib/hogan-3.0.2.mustache.js b/assets/js/lib/hogan-3.0.2.mustache.js new file mode 100644 index 00000000..f1300c46 --- /dev/null +++ b/assets/js/lib/hogan-3.0.2.mustache.js @@ -0,0 +1,802 @@ +/*! + * Copyright 2011 Twitter, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// A wrapper for compatibility with Mustache.js, quirks and all + + + +var Hogan = {}; + +(function (Hogan) { + Hogan.Template = function (codeObj, text, compiler, options) { + codeObj = codeObj || {}; + this.r = codeObj.code || this.r; + this.c = compiler; + this.options = options || {}; + this.text = text || ''; + this.partials = codeObj.partials || {}; + this.subs = codeObj.subs || {}; + this.buf = ''; + } + + Hogan.Template.prototype = { + // render: replaced by generated code. + r: function (context, partials, indent) { return ''; }, + + // variable escaping + v: hoganEscape, + + // triple stache + t: coerceToString, + + render: function render(context, partials, indent) { + return this.ri([context], partials || {}, indent); + }, + + // render internal -- a hook for overrides that catches partials too + ri: function (context, partials, indent) { + return this.r(context, partials, indent); + }, + + // ensurePartial + ep: function(symbol, partials) { + var partial = this.partials[symbol]; + + // check to see that if we've instantiated this partial before + var template = partials[partial.name]; + if (partial.instance && partial.base == template) { + return partial.instance; + } + + if (typeof template == 'string') { + if (!this.c) { + throw new Error("No compiler available."); + } + template = this.c.compile(template, this.options); + } + + if (!template) { + return null; + } + + // We use this to check whether the partials dictionary has changed + this.partials[symbol].base = template; + + if (partial.subs) { + // Make sure we consider parent template now + if (!partials.stackText) partials.stackText = {}; + for (key in partial.subs) { + if (!partials.stackText[key]) { + partials.stackText[key] = (this.activeSub !== undefined && partials.stackText[this.activeSub]) ? partials.stackText[this.activeSub] : this.text; + } + } + template = createSpecializedPartial(template, partial.subs, partial.partials, + this.stackSubs, this.stackPartials, partials.stackText); + } + this.partials[symbol].instance = template; + + return template; + }, + + // tries to find a partial in the current scope and render it + rp: function(symbol, context, partials, indent) { + var partial = this.ep(symbol, partials); + if (!partial) { + return ''; + } + + return partial.ri(context, partials, indent); + }, + + // render a section + rs: function(context, partials, section) { + var tail = context[context.length - 1]; + + if (!isArray(tail)) { + section(context, partials, this); + return; + } + + for (var i = 0; i < tail.length; i++) { + context.push(tail[i]); + section(context, partials, this); + context.pop(); + } + }, + + // maybe start a section + s: function(val, ctx, partials, inverted, start, end, tags) { + var pass; + + if (isArray(val) && val.length === 0) { + return false; + } + + if (typeof val == 'function') { + val = this.ms(val, ctx, partials, inverted, start, end, tags); + } + + pass = !!val; + + if (!inverted && pass && ctx) { + ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]); + } + + return pass; + }, + + // find values with dotted names + d: function(key, ctx, partials, returnFound) { + var found, + names = key.split('.'), + val = this.f(names[0], ctx, partials, returnFound), + doModelGet = this.options.modelGet, + cx = null; + + if (key === '.' && isArray(ctx[ctx.length - 2])) { + val = ctx[ctx.length - 1]; + } else { + for (var i = 1; i < names.length; i++) { + found = findInScope(names[i], val, doModelGet); + if (found !== undefined) { + cx = val; + val = found; + } else { + val = ''; + } + } + } + + if (returnFound && !val) { + return false; + } + + if (!returnFound && typeof val == 'function') { + ctx.push(cx); + val = this.mv(val, ctx, partials); + ctx.pop(); + } + + return val; + }, + + // find values with normal names + f: function(key, ctx, partials, returnFound) { + var val = false, + v = null, + found = false, + doModelGet = this.options.modelGet; + + for (var i = ctx.length - 1; i >= 0; i--) { + v = ctx[i]; + val = findInScope(key, v, doModelGet); + if (val !== undefined) { + found = true; + break; + } + } + + if (!found) { + return (returnFound) ? false : ""; + } + + if (!returnFound && typeof val == 'function') { + val = this.mv(val, ctx, partials); + } + + return val; + }, + + // higher order templates + ls: function(func, cx, partials, text, tags) { + var oldTags = this.options.delimiters; + + this.options.delimiters = tags; + this.b(this.ct(coerceToString(func.call(cx, text)), cx, partials)); + this.options.delimiters = oldTags; + + return false; + }, + + // compile text + ct: function(text, cx, partials) { + if (this.options.disableLambda) { + throw new Error('Lambda features disabled.'); + } + return this.c.compile(text, this.options).render(cx, partials); + }, + + // template result buffering + b: function(s) { this.buf += s; }, + + fl: function() { var r = this.buf; this.buf = ''; return r; }, + + // method replace section + ms: function(func, ctx, partials, inverted, start, end, tags) { + var textSource, + cx = ctx[ctx.length - 1], + result = func.call(cx); + + if (typeof result == 'function') { + if (inverted) { + return true; + } else { + textSource = (this.activeSub && this.subsText && this.subsText[this.activeSub]) ? this.subsText[this.activeSub] : this.text; + return this.ls(result, cx, partials, textSource.substring(start, end), tags); + } + } + + return result; + }, + + // method replace variable + mv: function(func, ctx, partials) { + var cx = ctx[ctx.length - 1]; + var result = func.call(cx); + + if (typeof result == 'function') { + return this.ct(coerceToString(result.call(cx)), cx, partials); + } + + return result; + }, + + sub: function(name, context, partials, indent) { + var f = this.subs[name]; + if (f) { + this.activeSub = name; + f(context, partials, this, indent); + this.activeSub = false; + } + } + + }; + + //Find a key in an object + function findInScope(key, scope, doModelGet) { + var val; + + if (scope && typeof scope == 'object') { + + if (scope[key] !== undefined) { + val = scope[key]; + + // try lookup with get for backbone or similar model data + } else if (doModelGet && scope.get && typeof scope.get == 'function') { + val = scope.get(key); + } + } + + return val; + } + + function createSpecializedPartial(instance, subs, partials, stackSubs, stackPartials, stackText) { + function PartialTemplate() {}; + PartialTemplate.prototype = instance; + function Substitutions() {}; + Substitutions.prototype = instance.subs; + var key; + var partial = new PartialTemplate(); + partial.subs = new Substitutions(); + partial.subsText = {}; //hehe. substext. + partial.buf = ''; + + stackSubs = stackSubs || {}; + partial.stackSubs = stackSubs; + partial.subsText = stackText; + for (key in subs) { + if (!stackSubs[key]) stackSubs[key] = subs[key]; + } + for (key in stackSubs) { + partial.subs[key] = stackSubs[key]; + } + + stackPartials = stackPartials || {}; + partial.stackPartials = stackPartials; + for (key in partials) { + if (!stackPartials[key]) stackPartials[key] = partials[key]; + } + for (key in stackPartials) { + partial.partials[key] = stackPartials[key]; + } + + return partial; + } + + var rAmp = /&/g, + rLt = //g, + rApos = /\'/g, + rQuot = /\"/g, + hChars = /[&<>\"\']/; + + function coerceToString(val) { + return String((val === null || val === undefined) ? '' : val); + } + + function hoganEscape(str) { + str = coerceToString(str); + return hChars.test(str) ? + str + .replace(rAmp, '&') + .replace(rLt, '<') + .replace(rGt, '>') + .replace(rApos, ''') + .replace(rQuot, '"') : + str; + } + + var isArray = Array.isArray || function(a) { + return Object.prototype.toString.call(a) === '[object Array]'; + }; + +})(typeof exports !== 'undefined' ? exports : Hogan); + + + +(function (Hogan) { + // Setup regex assignments + // remove whitespace according to Mustache spec + var rIsWhitespace = /\S/, + rQuot = /\"/g, + rNewline = /\n/g, + rCr = /\r/g, + rSlash = /\\/g, + rLineSep = /\u2028/, + rParagraphSep = /\u2029/; + + Hogan.tags = { + '#': 1, '^': 2, '<': 3, '$': 4, + '/': 5, '!': 6, '>': 7, '=': 8, '_v': 9, + '{': 10, '&': 11, '_t': 12 + }; + + Hogan.scan = function scan(text, delimiters) { + var len = text.length, + IN_TEXT = 0, + IN_TAG_TYPE = 1, + IN_TAG = 2, + state = IN_TEXT, + tagType = null, + tag = null, + buf = '', + tokens = [], + seenTag = false, + i = 0, + lineStart = 0, + otag = '{{', + ctag = '}}'; + + function addBuf() { + if (buf.length > 0) { + tokens.push({tag: '_t', text: new String(buf)}); + buf = ''; + } + } + + function lineIsWhitespace() { + var isAllWhitespace = true; + for (var j = lineStart; j < tokens.length; j++) { + isAllWhitespace = + (Hogan.tags[tokens[j].tag] < Hogan.tags['_v']) || + (tokens[j].tag == '_t' && tokens[j].text.match(rIsWhitespace) === null); + if (!isAllWhitespace) { + return false; + } + } + + return isAllWhitespace; + } + + function filterLine(haveSeenTag, noNewLine) { + addBuf(); + + if (haveSeenTag && lineIsWhitespace()) { + for (var j = lineStart, next; j < tokens.length; j++) { + if (tokens[j].text) { + if ((next = tokens[j+1]) && next.tag == '>') { + // set indent to token value + next.indent = tokens[j].text.toString() + } + tokens.splice(j, 1); + } + } + } else if (!noNewLine) { + tokens.push({tag:'\n'}); + } + + seenTag = false; + lineStart = tokens.length; + } + + function changeDelimiters(text, index) { + var close = '=' + ctag, + closeIndex = text.indexOf(close, index), + delimiters = trim( + text.substring(text.indexOf('=', index) + 1, closeIndex) + ).split(' '); + + otag = delimiters[0]; + ctag = delimiters[delimiters.length - 1]; + + return closeIndex + close.length - 1; + } + + if (delimiters) { + delimiters = delimiters.split(' '); + otag = delimiters[0]; + ctag = delimiters[1]; + } + + for (i = 0; i < len; i++) { + if (state == IN_TEXT) { + if (tagChange(otag, text, i)) { + --i; + addBuf(); + state = IN_TAG_TYPE; + } else { + if (text.charAt(i) == '\n') { + filterLine(seenTag); + } else { + buf += text.charAt(i); + } + } + } else if (state == IN_TAG_TYPE) { + i += otag.length - 1; + tag = Hogan.tags[text.charAt(i + 1)]; + tagType = tag ? text.charAt(i + 1) : '_v'; + if (tagType == '=') { + i = changeDelimiters(text, i); + state = IN_TEXT; + } else { + if (tag) { + i++; + } + state = IN_TAG; + } + seenTag = i; + } else { + if (tagChange(ctag, text, i)) { + tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag, + i: (tagType == '/') ? seenTag - otag.length : i + ctag.length}); + buf = ''; + i += ctag.length - 1; + state = IN_TEXT; + if (tagType == '{') { + if (ctag == '}}') { + i++; + } else { + cleanTripleStache(tokens[tokens.length - 1]); + } + } + } else { + buf += text.charAt(i); + } + } + } + + filterLine(seenTag, true); + + return tokens; + } + + function cleanTripleStache(token) { + if (token.n.substr(token.n.length - 1) === '}') { + token.n = token.n.substring(0, token.n.length - 1); + } + } + + function trim(s) { + if (s.trim) { + return s.trim(); + } + + return s.replace(/^\s*|\s*$/g, ''); + } + + function tagChange(tag, text, index) { + if (text.charAt(index) != tag.charAt(0)) { + return false; + } + + for (var i = 1, l = tag.length; i < l; i++) { + if (text.charAt(index + i) != tag.charAt(i)) { + return false; + } + } + + return true; + } + + // the tags allowed inside super templates + var allowedInSuper = {'_t': true, '\n': true, '$': true, '/': true}; + + function buildTree(tokens, kind, stack, customTags) { + var instructions = [], + opener = null, + tail = null, + token = null; + + tail = stack[stack.length - 1]; + + while (tokens.length > 0) { + token = tokens.shift(); + + if (tail && tail.tag == '<' && !(token.tag in allowedInSuper)) { + throw new Error('Illegal content in < super tag.'); + } + + if (Hogan.tags[token.tag] <= Hogan.tags['$'] || isOpener(token, customTags)) { + stack.push(token); + token.nodes = buildTree(tokens, token.tag, stack, customTags); + } else if (token.tag == '/') { + if (stack.length === 0) { + throw new Error('Closing tag without opener: /' + token.n); + } + opener = stack.pop(); + if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) { + throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n); + } + opener.end = token.i; + return instructions; + } else if (token.tag == '\n') { + token.last = (tokens.length == 0) || (tokens[0].tag == '\n'); + } + + instructions.push(token); + } + + if (stack.length > 0) { + throw new Error('missing closing tag: ' + stack.pop().n); + } + + return instructions; + } + + function isOpener(token, tags) { + for (var i = 0, l = tags.length; i < l; i++) { + if (tags[i].o == token.n) { + token.tag = '#'; + return true; + } + } + } + + function isCloser(close, open, tags) { + for (var i = 0, l = tags.length; i < l; i++) { + if (tags[i].c == close && tags[i].o == open) { + return true; + } + } + } + + function stringifySubstitutions(obj) { + var items = []; + for (var key in obj) { + items.push('"' + esc(key) + '": function(c,p,t,i) {' + obj[key] + '}'); + } + return "{ " + items.join(",") + " }"; + } + + function stringifyPartials(codeObj) { + var partials = []; + for (var key in codeObj.partials) { + partials.push('"' + esc(key) + '":{name:"' + esc(codeObj.partials[key].name) + '", ' + stringifyPartials(codeObj.partials[key]) + "}"); + } + return "partials: {" + partials.join(",") + "}, subs: " + stringifySubstitutions(codeObj.subs); + } + + Hogan.stringify = function(codeObj, text, options) { + return "{code: function (c,p,i) { " + Hogan.wrapMain(codeObj.code) + " }," + stringifyPartials(codeObj) + "}"; + } + + var serialNo = 0; + Hogan.generate = function(tree, text, options) { + serialNo = 0; + var context = { code: '', subs: {}, partials: {} }; + Hogan.walk(tree, context); + + if (options.asString) { + return this.stringify(context, text, options); + } + + return this.makeTemplate(context, text, options); + } + + Hogan.wrapMain = function(code) { + return 'var t=this;t.b(i=i||"");' + code + 'return t.fl();'; + } + + Hogan.template = Hogan.Template; + + Hogan.makeTemplate = function(codeObj, text, options) { + var template = this.makePartials(codeObj); + template.code = new Function('c', 'p', 'i', this.wrapMain(codeObj.code)); + return new this.template(template, text, this, options); + } + + Hogan.makePartials = function(codeObj) { + var key, template = {subs: {}, partials: codeObj.partials, name: codeObj.name}; + for (key in template.partials) { + template.partials[key] = this.makePartials(template.partials[key]); + } + for (key in codeObj.subs) { + template.subs[key] = new Function('c', 'p', 't', 'i', codeObj.subs[key]); + } + return template; + } + + function esc(s) { + return s.replace(rSlash, '\\\\') + .replace(rQuot, '\\\"') + .replace(rNewline, '\\n') + .replace(rCr, '\\r') + .replace(rLineSep, '\\u2028') + .replace(rParagraphSep, '\\u2029'); + } + + function chooseMethod(s) { + return (~s.indexOf('.')) ? 'd' : 'f'; + } + + function createPartial(node, context) { + var prefix = "<" + (context.prefix || ""); + var sym = prefix + node.n + serialNo++; + context.partials[sym] = {name: node.n, partials: {}}; + context.code += 't.b(t.rp("' + esc(sym) + '",c,p,"' + (node.indent || '') + '"));'; + return sym; + } + + Hogan.codegen = { + '#': function(node, context) { + context.code += 'if(t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),' + + 'c,p,0,' + node.i + ',' + node.end + ',"' + node.otag + " " + node.ctag + '")){' + + 't.rs(c,p,' + 'function(c,p,t){'; + Hogan.walk(node.nodes, context); + context.code += '});c.pop();}'; + }, + + '^': function(node, context) { + context.code += 'if(!t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),c,p,1,0,0,"")){'; + Hogan.walk(node.nodes, context); + context.code += '};'; + }, + + '>': createPartial, + '<': function(node, context) { + var ctx = {partials: {}, code: '', subs: {}, inPartial: true}; + Hogan.walk(node.nodes, ctx); + var template = context.partials[createPartial(node, context)]; + template.subs = ctx.subs; + template.partials = ctx.partials; + }, + + '$': function(node, context) { + var ctx = {subs: {}, code: '', partials: context.partials, prefix: node.n}; + Hogan.walk(node.nodes, ctx); + context.subs[node.n] = ctx.code; + if (!context.inPartial) { + context.code += 't.sub("' + esc(node.n) + '",c,p,i);'; + } + }, + + '\n': function(node, context) { + context.code += write('"\\n"' + (node.last ? '' : ' + i')); + }, + + '_v': function(node, context) { + context.code += 't.b(t.v(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));'; + }, + + '_t': function(node, context) { + context.code += write('"' + esc(node.text) + '"'); + }, + + '{': tripleStache, + + '&': tripleStache + } + + function tripleStache(node, context) { + context.code += 't.b(t.t(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));'; + } + + function write(s) { + return 't.b(' + s + ');'; + } + + Hogan.walk = function(nodelist, context) { + var func; + for (var i = 0, l = nodelist.length; i < l; i++) { + func = Hogan.codegen[nodelist[i].tag]; + func && func(nodelist[i], context); + } + return context; + } + + Hogan.parse = function(tokens, text, options) { + options = options || {}; + return buildTree(tokens, '', [], options.sectionTags || []); + } + + Hogan.cache = {}; + + Hogan.cacheKey = function(text, options) { + return [text, !!options.asString, !!options.disableLambda, options.delimiters, !!options.modelGet].join('||'); + } + + Hogan.compile = function(text, options) { + options = options || {}; + var key = Hogan.cacheKey(text, options); + var template = this.cache[key]; + + if (template) { + var partials = template.partials; + for (var name in partials) { + delete partials[name].instance; + } + return template; + } + + template = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options); + return this.cache[key] = template; + } +})(typeof exports !== 'undefined' ? exports : Hogan); + + +var Mustache = (function (Hogan) { + + // Mustache.js has non-spec partial context behavior + function mustachePartial(name, context, partials, indent) { + var partialScope = this.f(name, context, partials, 0); + var cx = context; + if (partialScope) { + cx = cx.concat(partialScope); + } + + return Hogan.Template.prototype.rp.call(this, name, cx, partials, indent); + } + + var HoganTemplateWrapper = function(renderFunc, text, compiler){ + this.rp = mustachePartial; + Hogan.Template.call(this, renderFunc, text, compiler); + }; + HoganTemplateWrapper.prototype = Hogan.Template.prototype; + + // Add a wrapper for Hogan's generate method. Mustache and Hogan keep + // separate caches, and Mustache returns wrapped templates. + var wrapper; + var HoganWrapper = function(){ + this.cache = {}; + this.generate = function(code, text, options) { + return new HoganTemplateWrapper(new Function('c', 'p', 'i', code), text, wrapper); + } + }; + HoganWrapper.prototype = Hogan; + wrapper = new HoganWrapper(); + + return { + to_html: function(text, data, partials, sendFun) { + var template = wrapper.compile(text); + var result = template.render(data, partials); + if (!sendFun) { + return result; + } + + sendFun(result); + } + } + +})(Hogan); diff --git a/assets/js/simple-media.js b/assets/js/simple-media.js new file mode 100644 index 00000000..954cc9b2 --- /dev/null +++ b/assets/js/simple-media.js @@ -0,0 +1,627 @@ +function InitPxVideo(options) { + + "use strict"; + + // Replace all + // --------------------------------- + if (!String.prototype.replaceAll) { + Object.defineProperty(String.prototype, "replaceAll", { + value: function(find, replace) { + return this.replace(new RegExp(find.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"), "g"), replace); + } + }); + } + + // Utilities for caption time codes + function video_timecode_min(tc) { + var tcpair = []; + tcpair = tc.split(" --> "); + return videosub_tcsecs(tcpair[0]); + } + + function video_timecode_max(tc) { + var tcpair = []; + tcpair = tc.split(" --> "); + return videosub_tcsecs(tcpair[1]); + } + + function videosub_tcsecs(tc) { + if (tc === null || tc === undefined) { + return 0; + } + else { + var tc1 = [], + tc2 = [], + seconds; + tc1 = tc.split(","); + tc2 = tc1[0].split(":"); + seconds = Math.floor(tc2[0]*60*60) + Math.floor(tc2[1]*60) + Math.floor(tc2[2]); + return seconds; + } + } + + // For "manual" captions, adjust caption position when play time changed (via rewind, clicking progress bar, etc.) + function adjustManualCaptions(obj) { + obj.subcount = 0; + while (video_timecode_max(obj.captions[obj.subcount][0]) < obj.movie.currentTime.toFixed(1)) { + obj.subcount++; + if (obj.subcount > obj.captions.length-1) { + obj.subcount = obj.captions.length-1; + break; + } + } + } + + // Display captions container and button (for initialization) + function showCaptionContainerAndButton(obj) { + //obj.captionsBtnContainer.className = "px-video-captions-btn-container show"; + if (obj.isCaptionDefault) { + obj.captionsContainer.className = "px-video-captions show"; + obj.captionsBtn.setAttribute("checked", "checked"); + } + } + + // Unfortunately, due to scattered support, browser sniffing is required + function browserSniff() { + var nAgt = navigator.userAgent, + browserName = navigator.appName, + fullVersion = ""+parseFloat(navigator.appVersion), + majorVersion = parseInt(navigator.appVersion,10), + nameOffset, + verOffset, + ix; + + // MSIE 11 + if ((navigator.appVersion.indexOf("Windows NT") !== -1) && (navigator.appVersion.indexOf("rv:11") !== -1)) { + browserName = "IE"; + fullVersion = "11;"; + } + // MSIE + else if ((verOffset=nAgt.indexOf("MSIE")) !== -1) { + browserName = "IE"; + fullVersion = nAgt.substring(verOffset+5); + } + // Chrome + else if ((verOffset=nAgt.indexOf("Chrome")) !== -1) { + browserName = "Chrome"; + fullVersion = nAgt.substring(verOffset+7); + } + // Safari + else if ((verOffset=nAgt.indexOf("Safari")) !== -1) { + browserName = "Safari"; + fullVersion = nAgt.substring(verOffset+7); + if ((verOffset=nAgt.indexOf("Version")) !== -1) { + fullVersion = nAgt.substring(verOffset+8); + } + } + // Firefox + else if ((verOffset=nAgt.indexOf("Firefox")) !== -1) { + browserName = "Firefox"; + fullVersion = nAgt.substring(verOffset+8); + } + // In most other browsers, "name/version" is at the end of userAgent + else if ( (nameOffset=nAgt.lastIndexOf(" ")+1) < (verOffset=nAgt.lastIndexOf("/")) ) { + browserName = nAgt.substring(nameOffset,verOffset); + fullVersion = nAgt.substring(verOffset+1); + if (browserName.toLowerCase()==browserName.toUpperCase()) { + browserName = navigator.appName; + } + } + // Trim the fullVersion string at semicolon/space if present + if ((ix=fullVersion.indexOf(";")) !== -1) { + fullVersion=fullVersion.substring(0,ix); + } + if ((ix=fullVersion.indexOf(" ")) !== -1) { + fullVersion=fullVersion.substring(0,ix); + } + // Get major version + majorVersion = parseInt(""+fullVersion,10); + if (isNaN(majorVersion)) { + fullVersion = ""+parseFloat(navigator.appVersion); + majorVersion = parseInt(navigator.appVersion,10); + } + // Return data + return [browserName, majorVersion]; + } + + // Global variable + var obj = {}; + + obj.arBrowserInfo = browserSniff(); + obj.browserName = obj.arBrowserInfo[0]; + obj.browserMajorVersion = obj.arBrowserInfo[1]; + + // If IE8, stop customization (use fallback) + // If IE9, stop customization (use native controls) + if (obj.browserName === "IE" && (obj.browserMajorVersion === 8 || obj.browserMajorVersion === 9) ) { + return false; + } + + // If smartphone or tablet, stop customization as video (and captions in latest devices) are handled natively + obj.isSmartphoneOrTablet = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent); + if (obj.isSmartphoneOrTablet) { + return false; + } + + // Set debug mode + if (typeof(options.debug)==="undefined") { + options.debug = false; + } + obj.debug = options.debug; + + // Output browser info to log if debug on + if (options.debug) { + console.log(obj.browserName + " " + obj.browserMajorVersion); + } + + // Set up aria-label for Play button with the videoTitle option + if ((typeof(options.videoTitle)==="undefined") || (options.videoTitle==="")) { + obj.playAriaLabel = "Play"; + } + else { + obj.playAriaLabel = "Play video, " + options.videoTitle; + } + + // Get the container, video element, and controls container + obj.container = document.getElementById(options.videoId); + obj.container.className = obj.container.className + " stopped"; + obj.movie = obj.container.getElementsByTagName("video")[0]; + obj.controls = obj.container.getElementsByClassName("px-video-controls")[0]; + + // Remove native video controls + obj.movie.removeAttribute("controls"); + + // Generate random number for ID/FOR attribute values for controls + obj.randomNum = Math.floor(Math.random() * (10000)); + + // Insert custom video controls + if (options.debug) { + console.log("Inserting custom video controls"); + } + obj.controls.innerHTML = options.html + .replaceAll("{aria-label}", obj.playAriaLabel) + .replaceAll("{id}", obj.randomNum); + + // Responsive ffs + // ---- + // Adjust layout per width of video - container + //obj.movieWidth = obj.movie.width; + //if (obj.movieWidth < 360) { + // obj.movieWidth = 360; + //} + //obj.container.setAttribute("style", "width:" + obj.movieWidth + "px"); + + // Adjust layout per width of video - controls/mute offset + obj.labelMute = document.getElementById("labelMute" + obj.randomNum); + obj.labelMuteOffset = obj.movieWidth - 390; + if (obj.labelMuteOffset < 0) { + obj.labelMuteOffset = 0; + } + obj.labelMute.setAttribute("style", "margin-left:" + obj.labelMuteOffset + "px"); + + // Get URL of caption file if exists + var captionSrc = "", + kind, + children = obj.movie.childNodes; + + for (var i = 0; i < children.length; i++) { + if (children[i].nodeName.toLowerCase() === "track") { + kind = children[i].getAttribute("kind"); + if (kind === "captions") { + captionSrc = children[i].getAttribute("src"); + } + } + } + + // Record if caption file exists or not + obj.captionExists = true; + if (captionSrc === "") { + obj.captionExists = false; + if (options.debug) { + console.log("No caption track found."); + } + } + else { + if (options.debug) { + console.log("Caption track found; URI: " + captionSrc); + } + } + + // Set captions on/off - on by default + if (typeof(options.captionsOnDefault) === "undefined") { + options.captionsOnDefault = true; + } + obj.isCaptionDefault = options.captionsOnDefault; + + // Number of seconds for rewind and forward buttons + if (typeof(options.seekInterval) === "undefined") { + options.seekInterval = 10; + } + obj.seekInterval = options.seekInterval; + + // Get the elements for the controls + obj.btnPlay = obj.container.getElementsByClassName("px-video-play")[0]; + obj.btnPause = obj.container.getElementsByClassName("px-video-pause")[0]; + obj.btnRestart = obj.container.getElementsByClassName("px-video-restart")[0]; + obj.btnRewind = obj.container.getElementsByClassName("px-video-rewind")[0]; + obj.btnForward = obj.container.getElementsByClassName("px-video-forward")[0]; + obj.btnVolume = obj.container.getElementsByClassName("px-video-volume")[0]; + obj.btnMute = obj.container.getElementsByClassName("px-video-mute")[0]; + obj.progressBar = obj.container.getElementsByClassName("px-video-progress")[0]; + obj.progressBarSpan = obj.progressBar.getElementsByTagName("span")[0]; + obj.captionsContainer = obj.container.getElementsByClassName("px-video-captions")[0]; + obj.captionsBtn = obj.container.getElementsByClassName("px-video-btnCaptions")[0]; + obj.captionsBtnContainer = obj.container.getElementsByClassName("px-video-captions-btn-container")[0]; + obj.duration = obj.container.getElementsByClassName("px-video-duration")[0]; + obj.txtSeconds = obj.container.getElementsByClassName("px-seconds"); + + // Update number of seconds in rewind and fast forward buttons + obj.txtSeconds[0].innerHTML = obj.seekInterval; + obj.txtSeconds[1].innerHTML = obj.seekInterval; + + // Determine if HTML5 textTracks is supported (for captions) + obj.isTextTracks = false; + if (obj.movie.textTracks) { + obj.isTextTracks = true; + } + + // Play + obj.btnPlay.addEventListener("click", function() { + obj.movie.play(); + + obj.container.className = obj.container.className.replace("stopped", "playing"); + + obj.btnPlay.className = "px-video-play hide"; + obj.btnPause.className = "px-video-pause px-video-show-inline"; + obj.btnPause.focus(); + }, false); + + // Pause + obj.btnPause.addEventListener("click", function() { + obj.movie.pause(); + + obj.container.className = obj.container.className.replace("playing", "stopped"); + + obj.btnPlay.className = "px-video-play px-video-show-inline"; + obj.btnPause.className = "px-video-pause hide"; + obj.btnPlay.focus(); + }, false); + + // Restart + obj.btnRestart.addEventListener("click", function() { + // Move to beginning + obj.movie.currentTime = 0; + + // Special handling for "manual" captions + if (!obj.isTextTracks) { + obj.subcount = 0; + } + + // Play and ensure the play button is in correct state + obj.movie.play(); + obj.btnPlay.className = "px-video-play hide"; + obj.btnPause.className = "px-video-pause px-video-show-inline"; + + }, false); + + // Rewind + obj.btnRewind.addEventListener("click", function() { + var targetTime = obj.movie.currentTime - obj.seekInterval; + if (targetTime < 0) { + obj.movie.currentTime = 0; + } + else { + obj.movie.currentTime = targetTime; + } + // Special handling for "manual" captions + if (!obj.isTextTracks) { + adjustManualCaptions(obj); + } + }, false); + + // Fast forward + obj.btnForward.addEventListener("click", function() { + var targetTime = obj.movie.currentTime + obj.seekInterval; + if (targetTime > obj.movie.duration) { + obj.movie.currentTime = obj.movie.duration; + } + else { + obj.movie.currentTime = targetTime; + } + // Special handling for "manual" captions + if (!obj.isTextTracks) { + adjustManualCaptions(obj); + } + }, false); + + // Get the HTML5 range input element and append audio volume adjustment on change + obj.btnVolume.addEventListener("change", function() { + obj.movie.volume = parseFloat(this.value / 10); + }, false); + + // Mute + obj.btnMute.addEventListener("click", function() { + if (obj.movie.muted === true) { + obj.movie.muted = false; + } + else { + obj.movie.muted = true; + } + }, false); + + // Duration + obj.movie.addEventListener("timeupdate", function() { + obj.secs = parseInt(obj.movie.currentTime % 60); + obj.mins = parseInt((obj.movie.currentTime / 60) % 60); + + // Ensure it"s two digits. For example, 03 rather than 3. + obj.secs = ("0" + obj.secs).slice(-2); + obj.mins = ("0" + obj.mins).slice(-2); + + // Render + obj.duration.innerHTML = obj.mins + ":" + obj.secs; + }, false); + + // Progress bar + obj.movie.addEventListener("timeupdate", function() { + obj.percent = (100 / obj.movie.duration) * obj.movie.currentTime; + if (obj.percent > 0) { + obj.progressBar.value = obj.percent; + obj.progressBarSpan.innerHTML = obj.percent; + } + }, false); + + // Skip when clicking progress bar + obj.progressBar.addEventListener("click", function(e) { + obj.pos = (e.pageX - this.offsetLeft) / this.offsetWidth; + obj.movie.currentTime = obj.pos * obj.movie.duration; + + // Special handling for "manual" captions + if (!obj.isTextTracks) { + adjustManualCaptions(obj); + } + }); + + // Clear captions at end of video + obj.movie.addEventListener("ended", function() { + obj.captionsContainer.innerHTML = ""; + }); + + // *** + // Captions + // *** + + // Toggle display of captions via captions button + obj.captionsBtn.addEventListener("click", function() { + if (this.checked) { + obj.captionsContainer.className = "px-video-captions show"; + } else { + obj.captionsContainer.className = "px-video-captions hide"; + } + }, false); + + // If no caption file exists, hide container for caption text + if (!obj.captionExists) { + obj.captionsContainer.className = "px-video-captions hide"; + } + + // If caption file exists, process captions + else { + + // If IE 10/11 or Firefox 31+ or Safari 7+, don"t use native captioning (still doesn"t work although they claim it"s now supported) + if ((obj.browserName==="IE" && obj.browserMajorVersion===10) || + (obj.browserName==="IE" && obj.browserMajorVersion===11) || + (obj.browserName==="Firefox" && obj.browserMajorVersion>=31) || + (obj.browserName==="Safari" && obj.browserMajorVersion>=7)) { + if (options.debug) { + console.log("Detected IE 10/11 or Firefox 31+ or Safari 7+"); + } + // set to false so skips to "manual" captioning + obj.isTextTracks = false; + + // turn off native caption rendering to avoid double captions [doesn"t work in Safari 7; see patch below] + var track = {}; + var tracks = obj.movie.textTracks; + for (var j=0; j < tracks.length; j++) { + track = obj.movie.textTracks[j]; + track.mode = "hidden"; + } + } + + // Rendering caption tracks - native support required - http://caniuse.com/webvtt + if (obj.isTextTracks) { + if (options.debug) { + console.log("textTracks supported"); + } + showCaptionContainerAndButton(obj); + + var track = {}; + var tracks = obj.movie.textTracks; + for (var j=0; j < tracks.length; j++) { + track = obj.movie.textTracks[j]; + track.mode = "hidden"; + if (track.kind === "captions") { + track.addEventListener("cuechange",function() { + if (this.activeCues[0]) { + if (this.activeCues[0].hasOwnProperty("text")) { + obj.captionsContainer.innerHTML = this.activeCues[0].text; + } + } + },false); + } + } + } + // Caption tracks not natively supported + else { + if (options.debug) { + console.log("textTracks not supported so rendering captions manually"); + } + showCaptionContainerAndButton(obj); + + // Render captions from array at appropriate time + obj.currentCaption = ""; + obj.subcount = 0; + obj.captions = []; + + obj.movie.addEventListener("timeupdate", function() { + // Check if the next caption is in the current time range + if (obj.movie.currentTime.toFixed(1) > video_timecode_min(obj.captions[obj.subcount][0]) && + obj.movie.currentTime.toFixed(1) < video_timecode_max(obj.captions[obj.subcount][0])) { + obj.currentCaption = obj.captions[obj.subcount][1]; + } + // Is there a next timecode? + if (obj.movie.currentTime.toFixed(1) > video_timecode_max(obj.captions[obj.subcount][0]) && + obj.subcount < (obj.captions.length-1)) { + obj.subcount++; + } + // Render the caption + obj.captionsContainer.innerHTML = obj.currentCaption; + }, false); + + if (captionSrc !== "") { + // Create XMLHttpRequest object + var xhr; + if (window.XMLHttpRequest) { + xhr = new XMLHttpRequest(); + } else if (window.ActiveXObject) { // IE8 + xhr = new ActiveXObject("Microsoft.XMLHTTP"); + } + xhr.onreadystatechange = function() { + if (xhr.readyState === 4) { + if (xhr.status === 200) { + if (options.debug) { + console.log("xhr = 200"); + } + + obj.captions = []; + var records = [], + record, + req = xhr.responseText; + records = req.split("\n\n"); + for (var r=0; r < records.length; r++) { + record = records[r]; + obj.captions[r] = []; + obj.captions[r] = record.split("\n"); + } + // Remove first element ("VTT") + obj.captions.shift(); + + if (options.debug) { + console.log("Successfully loaded the caption file via ajax."); + } + } else { + if (options.debug) { + console.log("There was a problem loading the caption file via ajax."); + } + } + } + } + xhr.open("get", captionSrc, true); + xhr.send(); + } + } + + // If Safari 7, removing track from DOM [see "turn off native caption rendering" above] + if (obj.browserName === "Safari" && obj.browserMajorVersion === 7) { + console.log("Safari 7 detected; removing track from DOM"); + var tracks = obj.movie.getElementsByTagName("track"); + obj.movie.removeChild(tracks[0]); + } + + } +}; + + + +/*$(function() { + $("video").simplePlayer(); +});*/ + +// Simple player plugin +// --------------------------------- +/*;(function($) { + $.fn.simplePlayer = function (settings) { + // Config defaults + var config = { + wrapperClass: "media", // Class name added to replaced selects + shownClass: "in", + autoplay: false, + templates: { + controls: "
\ + \ +
\ +
\ +
\ +
\ +
\ + 88:88 \ + / \ + 88:88 \ +
\ +
\ + \ +
\ +
\ +
\ +
\ +
100%
\ +
\ +
\ + \ +
", + overlay: "
" + } + }; + + // Extend settings if they"re passed + if (settings) { + $.extend(config, settings); + } + + this.each(function() { + var player = this, + status = {}, + $player = $(this).wrap("
"), + $wrapper = $player.parents("." + config.wrapperClass), + supportMP4 = (function (v) { return (v.canPlayType && v.canPlayType("video/mp4")); }(document.createElement("video"))); + + console.log($wrapper); + + // Inject the controls + $(config.templates.controls).insertAfter($player); + $(config.templates.overlay).insertAfter($player); + + // Select controls + var $playbackToggle = $(".js-button-toggle-play"), + $muteToggle = $(".js-button-toggle-mute"); + + function togglePlayback() { + if(status.playing && status.playing == true) { + player.pause(); + status.playing = false; + $wrapper.removeClass("playing").addClass("paused"); + } else { + player.play(); + status.playing = true; + $wrapper.removeClass("paused stopped").addClass("playing"); + } + $("span", this).attr("class", "icon-" + (status.playing ? "pause" : "play")); + }; + + function toggleMute() { + player.muted = !status.muted; + status.muted = player.muted; + $("span", this).attr("class", "icon-" + (status.muted ? "mute" : "volume-up")); + }; + + $playbackToggle.on("click", togglePlayback); + $muteToggle.on("click", toggleMute); + }); + }; +})(jQuery);*/ \ No newline at end of file diff --git a/assets/less/docs.less b/assets/less/docs.less new file mode 100644 index 00000000..05b19a48 --- /dev/null +++ b/assets/less/docs.less @@ -0,0 +1,37 @@ +// ========================================================================== +// HTML5 Video Player Demo Page +// ========================================================================== + +// Reset +@import "lib/normalize.less"; +// Mixins +@import "lib/mixins.less"; + +// BORDER-BOX ALL THE THINGS! +// http://paulirish.com/2012/box-sizing-border-box-ftw/ +*, *::after, *::before { + box-sizing: border-box; +} +html { + font-size: 62.5%; +} +body { + font-family: "Avenir Next", "Helvetica Neue", Helvetica, Arial, sans-serif; + .font-size(18); + color: #6D797F; + line-height: 1.5; + background: #ECF0F1; + max-width: 960px; + margin: 50px auto; + text-align: center; +} +h1 { + .font-size(48); + letter-spacing: -.025em; + color: #2E3C44; + margin: 0 0 20px; + line-height: 1.2; +} +p { + margin: 0 0 20px; +} \ No newline at end of file diff --git a/assets/less/lib/mixins.less b/assets/less/lib/mixins.less new file mode 100644 index 00000000..c6412a55 --- /dev/null +++ b/assets/less/lib/mixins.less @@ -0,0 +1,27 @@ +// ========================================================================== +// Mixins +// ========================================================================== + +// Contain floats: nicolasgallagher.com/micro-clearfix-hack/ +.clearfix() { + zoom: 1; + &:before, + &:after { content: ""; display: table; } + &:after { clear: both; } +} + +// Webkit-style focus +.tab-focus() { + // Default + outline: thin dotted @gray-dark; + // Webkit + //outline: 5px auto -webkit-focus-ring-color; + outline-offset: 1px; +} + +// Use rems for font sizing +.font-size(@font-size: 16){ + @rem: (@font-size / 10); + font-size: @font-size * 1px; + font-size: ~"@{rem}rem"; +} \ No newline at end of file diff --git a/assets/less/lib/normalize.less b/assets/less/lib/normalize.less new file mode 100644 index 00000000..562891ab --- /dev/null +++ b/assets/less/lib/normalize.less @@ -0,0 +1,406 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */ + +/* ========================================================================== + HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined in IE 8/9. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} + +/** + * Correct `inline-block` display not defined in IE 8/9. + */ + +audio, +canvas, +video { + display: inline-block; +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9. + * Hide the `template` element in IE, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* ========================================================================== + Base + ========================================================================== */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* ========================================================================== + Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background: transparent; +} + +/** + * Address `outline` inconsistency between Chrome and other browsers. + */ + +a:focus { + outline: thin dotted; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ + +a:active, +a:hover { + outline: 0; +} + +/* ========================================================================== + Typography + ========================================================================== */ + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari 5, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9, Safari 5, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari 5 and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Correct font family set oddly in Safari 5 and Chrome. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +/** + * Improve readability of pre-formatted text in all browsers. + */ + +pre { + white-space: pre-wrap; +} + +/** + * Set consistent quote types. + */ + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ========================================================================== + Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9. + */ + +img { + border: 0; +} + +/** + * Correct overflow displayed oddly in IE 9. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* ========================================================================== + Figures + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari 5. + */ + +figure { + margin: 0; +} + +/* ========================================================================== + Forms + ========================================================================== */ + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * 1. Correct font family not being inherited in all browsers. + * 2. Correct font size not being inherited in all browsers. + * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. + */ + +button, +input, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +button, +input { + line-height: normal; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. + * Correct `select` style inheritance in Firefox 4+ and Opera. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome + * (include `-moz` to future-proof). + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari 5 and Chrome + * on OS X. + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * 1. Remove default vertical scrollbar in IE 8/9. + * 2. Improve readability and alignment in all browsers. + */ + +textarea { + overflow: auto; /* 1 */ + vertical-align: top; /* 2 */ +} + +/* ========================================================================== + Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/assets/less/simple-player.less b/assets/less/simple-player.less new file mode 100644 index 00000000..a935e09e --- /dev/null +++ b/assets/less/simple-player.less @@ -0,0 +1,552 @@ +// ========================================================================== +// HTML5 Media Player +// ========================================================================== + +// Variables +// ------------------------------- +@base-color: #2E3C44; +@green: #1ABC9C; +@red: #D44334; +//@green: #4CB953; +@blue: #3498DB; +@control-color: @blue; + + +// BORDER-BOX ALL THE THINGS! (http://paulirish.com/2012/box-sizing-border-box-ftw/) +// ------------------------------- +.player, +.player *, +.player *::after, +.player *::before { + box-sizing: border-box; +} + +// Utility classes & mixins +// ------------------------------- +.sr-only { + position: absolute !important; + clip: rect(1px, 1px, 1px, 1px); + padding: 0 !important; + border: 0 !important; + height: 1px !important; + width: 1px !important; + overflow: hidden; +} +.hide { + display: none; +} +.show-inline { + display: inline-block; +} +// Contain floats: nicolasgallagher.com/micro-clearfix-hack/ +.clearfix() { + zoom: 1; + &:before, + &:after { content: ""; display: table; } + &:after { clear: both; } +} + +// Base +.player { + position: relative; + max-width: 100%; + overflow: hidden; // For the controls + + video { + width: 100%; + height: auto; + vertical-align: middle; + } + svg { + width: 18px; + height: 18px; + } + .controls { + .clearfix(); + position: absolute; + bottom: 0; + left: 0; + right: 0; + padding: 10px 5px; + background: rgba(0,0,0, .75); + transition: transform .3s ease; + line-height: 1; + + button { + border: 0; + background: transparent; + overflow: hidden; + } + label, + button { + display: inline-block; + vertical-align: middle; + margin: 0 2px; + padding: 5px 10px; + color: #ddd; + transition: background .3s ease; + border-radius: 3px; + + svg { + display: block; + fill: currentColor; + transition: fill .3s ease; + } + &:focus { + background: #000; + outline: 0; + } + &:hover { + background: @control-color; + } + &:hover svg, + &:focus svg { + fill: #fff; + } + } + .px-video-time { + display: inline-block; + vertical-align: middle; + padding-top: 3px; + margin-left: 10px; + color: #fff; + font-weight: 600; + font-size: 14px; + -webkit-font-smoothing: antialiased; + } + } + progress { + position: absolute; + top: -10px; + left: 0; + right: 0; + width: 100%; + height: 10px; + margin: 0; + vertical-align: top; + + &[value] { + /* Reset the default appearance */ + -webkit-appearance: none; + border: none; + + &::-webkit-progress-bar { + background-color: #eee; + } + &::-webkit-progress-value { + background-color: @control-color; + } + } + } + .play-controls { + float: left; + } + .sound-controls { + float: right; + } + /*&.playing .controls { + transform: translateY(100%); + }*/ +} + + +/* containers */ +.px-video-img-captions-container * { + box-sizing: border-box; +} + +.px-video-img-captions-container { + position: relative; +} + +/* progress indicator */ +.px-video-progress { + + +} + +/* time */ +/*.px-video-time { + float: right; + margin-top: 2px; + font-size: 14px; +}*/ + +/* caption area */ +.px-video-captions { + position: absolute; + top: 0; + left: 0; + width: 100%; + padding: .5em; + min-height: 2.5em; + background-color: #000; + color: #fff; + font-size: 1.1em; + text-align: center; + opacity: 0.75; + + -webkit-font-smoothing: antialiased; + font-weight: 500; +} + +/* buttons */ +.px-video-controls button { + + //background: no-repeat url('../images/px-video-sprite.png'); +} +.px-video-controls button:focus { + //border: 1px #999 dotted; + //outline: none; +} +.px-video-controls button { + //cursor: pointer; +} + +/* captions button */ +.px-video-captions-btn-container label { + display: inline-block; + width: 25px; + height: 20px; + margin-left: 25px; + background: no-repeat url('../images/px-video-sprite.png'); + background-position: -6px -835px; +} +.px-video-captions-btn-container input[type="checkbox"]:focus+label { + outline: 1px #999 dotted; + background-position: -6px -799px; +} +.px-video-captions-btn-container input[type="checkbox"]:hover+label { + background-position: -6px -799px; + cursor: pointer; +} +.px-video-captions-btn-container input[type="checkbox"]:focus+label { + outline: 1px #999 dotted; + background-position: -6px -799px; +} +.px-video-captions-btn-container input[type="checkbox"]:checked+label { + background-position: -6px -871px; +} + +/* mute button */ +.px-video-mute-btn-container label { + display: inline-block; + width: 25px; + height: 20px; + margin-left: 240px; + margin-top: 2px; + background: no-repeat url('../images/px-video-sprite.png'); + background-position: -6px -476px; +} +.px-video-mute-btn-container input[type="checkbox"]:focus+label { + outline: 1px #999 dotted; + background-position: -6px -440px; +} +.px-video-mute-btn-container input[type="checkbox"]:hover+label { + background-position: -6px -440px; + cursor: pointer; +} +.px-video-mute-btn-container input[type="checkbox"]:focus+label { + outline: 1px #999 dotted; + background-position: -6px -440px; +} +/* checked state of mute button */ +.px-video-mute-btn-container input[type="checkbox"]:checked+label { + background-position: -6px -692px; +} +.px-video-mute-btn-container input[type="checkbox"]:checked:hover+label, +.px-video-mute-btn-container input[type="checkbox"]:checked:focus+label { + background-position: -6px -656px; +} + +/* volume range input */ +.px-video-controls input[type='range'] { + -webkit-appearance: none; + height: 6px; + width: 100px; + margin-top: 8px; + background-color: #E6E6E6; + outline:none; +} +.px-video-controls input[type='range']:focus::-webkit-slider-thumb { + outline: 1px #999 dotted; +} +.px-video-controls input[type='range']::-moz-range-track { + -moz-appearance: none; + height: 6px; + background-color: #E6E6E6; + border: none; +} +.px-video-controls input[type='range']::-webkit-slider-thumb { + -webkit-appearance: none !important; + height: 10px; + width: 6px; + background-color: #666; +} +.px-video-controls input[type='range']::-moz-range-thumb { + height: 12px; + width: 8px; +} +/* fixing display for IE10+ */ +@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { + .px-video-controls input[type='range'] { + position: relative; + padding: 0; + height: 8px; + top: -3px; + } + .px-video-time { + margin-top: 4px; + } + .px-video-captions { + padding: 8px; + min-height: 36px; + } +} + +/*.media { + position: relative; + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + + video { + width: 100%; + + &::-webkit-media-controls { + display:none !important; + } + } + &.stopped, + &.paused { + .overlay-play { + display: block; + } + .media-controls { + transform: translate3d(0, 0, 0); + } + } +} +.media-controls { + height: 50px; + position: absolute; + bottom: 0; + left: 0; + right: 0; + z-index: 2; + + .translate3d(0, 100%, 0); + .transition-transform(.5s); + + background-color: @base-color; + color: #fff; + .font-size(15); + -webkit-font-smoothing: antialiased; + font-weight: 600; + .user-select(none); + + button { + display: inline-block; + padding: 8px 15px; + margin: 0; + + -webkit-appearance: none; + background: none; + border: none; + color: #fff; + .font-size(24); + + .transition(); + + &:focus { + outline: none; + } + + &:hover, + &:focus { + text-shadow: 0 0 15px @green; + } + } + + .progress { + position: relative; + .border-radius(10px); + height: 10px; + background: lighten(@base-color, 10%); + + div { + position: absolute; + z-index: 1; + left: 0; + .border-radius(10px); + height: 10px; + min-width: 10px; // So it doesn't look strange at 0% + + &.progress-played, + &.progress-volume { + background: @green; + z-index: 2; + } + &.progress-buffered { + background: lighten(@base-color, 20%); + } + } + &.vertical-progress { + margin: 0 auto; + width: 10px; + height: auto; + min-height: 100px; + + div { + bottom: 0; + width: 10px; + height: auto; + min-height: 10px; + } + } + } + + .popover { + display: none; + position: absolute; + left: 50%; + bottom: 100%; + margin-bottom: 10px; + + background: @base-color; + .border-radius(4px); + + -webkit-animation: pop-upwards 160ms forwards linear; + -moz-animation: pop-upwards 160ms forwards linear; + -ms-animation: pop-upwards 160ms forwards linear; + -o-animation: pop-upwards 160ms forwards linear; + animation: pop-upwards 160ms forwards linear; + + .transition(); + + // Psuedo bits + &::before { + position: absolute; + bottom: -7px; + left: 50%; + margin-left: -7px; + width: 0; + height: 0; + border-right: 7px solid transparent; + border-top: 7px solid @base-color; + border-left: 7px solid transparent; + content: ''; + z-index: 1; + } + } + .has-popover:focus, + .has-popover:hover { + .popover { + display: block; + } + } + + .popover-volume { + width: 54px; + padding: 15px 5px 8px; + margin-left: -27px; + + text-align: center; + + .progress { + height: 120px; + margin-bottom: 5px; + } + } + + // Layout + .play, + .progress-play, + .volume, + .time, + .fullscreen { + position: absolute; + top: 0; + } + .play { + left: 10px; + } + .progress-play { + left: 70px; + right: 240px; + margin-top: 20px; + } + .time { + right: 120px; + width: 100px; + text-align: center; + line-height: 1; + padding-top: 17px; + } + .volume { + right: 60px; + } + .fullscreen { + right: 10px; + } + + @media only screen + and (max-width: 480px) { + .time-seperator, + .time-total { + display: none; + } + .time { + width: 50px; + right: 70px; + } + .fullscreen { + display: none; + } + .volume { + right: 10px; + } + .progress-play { + right: 140px; + } + } + @media only screen + and (max-width: 320px) { + .time { + display: none; + } + .progress-play { + right: 70px; + } + } +} +.media-pause .mejs-overlay-play { + background: rgba(0,0,0, .1); +} +.overlay { + display: none; + position: absolute; + z-index: 1; + top: 0; + left: 0; + bottom: 0; + right: 0; + background: rgba(0,0,0, .1); +} +.overlay-play > span { + display: block; + position: absolute; + top: 50%; + left: 50%; + width: 60px; + height: 60px; + line-height: 1.5; + margin: -34px 0 0 -34px !important; + text-align: center; + background: rgba(red(@base-color), green(@base-color), blue(@base-color), .8); + border: 4px solid #fff; + color: #fff; + .border-radius(50%); + @shadow: 0 1px 5px rgba(0,0,0, .25), inset 0 1px 1px rgba(0,0,0,.25); + .box-shadow(@shadow); + .font-size(34); +}*/ \ No newline at end of file diff --git a/assets/templates/controls.html b/assets/templates/controls.html new file mode 100644 index 00000000..2fc38196 --- /dev/null +++ b/assets/templates/controls.html @@ -0,0 +1,51 @@ +
+ 0% played + +
+ + + + + +
+ Time + 00:00 +
+
+ +
+ + + + + + + + + + + + +
+
diff --git a/bower.json b/bower.json new file mode 100644 index 00000000..40ee7646 --- /dev/null +++ b/bower.json @@ -0,0 +1,29 @@ +{ + "name": "simple-media", + "description": "A simple HTML5 media player using custom controls", + "homepage": "https://github.com/sampotts/simple-media", + "keywords": [ + "Audio", + "Video", + "HTML5 Audio", + "HTml5 Video" + ], + "authors": [ + "Sam Potts " + ], + "dependencies": {}, + "main": [ + "dist/css/simple-media.css", + "dist/js/simple-media.js" + ], + "ignore": [ + "node_modules", + "bower_components", + ".gitignore" + ], + "repository": { + "type": "git", + "url": "git://github.com/sampotts/simple-media.git" + }, + "license": "MIT" +} \ No newline at end of file diff --git a/bundles.json b/bundles.json new file mode 100644 index 00000000..d34362a3 --- /dev/null +++ b/bundles.json @@ -0,0 +1,14 @@ +{ + "less": { + "simple-media.css": ["assets/less/simple-media.less"], + "docs.css": ["assets/less/docs.less"] + }, + "js": { + "simple-media.js": ["assets/js/simple-media.js"], + "docs.js": [ + "assets/js/lib/hogan-3.0.2.mustache.js", + "dist/js/templates.js", + "assets/js/docs.js" + ] + } +} \ No newline at end of file diff --git a/design/IcoMoon - 7 Icons/PNG/fast-forward.png b/design/IcoMoon - 7 Icons/PNG/fast-forward.png new file mode 100755 index 0000000000000000000000000000000000000000..07f2fd1b10b26e1dcb34a5a785328e64278b8019 GIT binary patch literal 360 zcmV-u0hj)XP)>cOH}3!d literal 0 HcmV?d00001 diff --git a/design/IcoMoon - 7 Icons/PNG/monitor.png b/design/IcoMoon - 7 Icons/PNG/monitor.png new file mode 100755 index 0000000000000000000000000000000000000000..4e6f77d6f9354134ba04341b642341668936023e GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@RheK2I0N5DWk0lm$WwEHfX!c~jFk zabnPSb@h57dNEc`MS9~vc`Wo2YoA|fL0C7W`j z7#X%5xN@MT>EWWl<_8BYgbsIPaZZ|Yq+^ZPJO#~@TmJw5zkf&h`#9z~kxUX>c^#r( yUyQlQu|-y;kMV=%d#@Y*u5xu`fcX&MH;^KPAXQ!*$LBs+7ifh- zj=7Y86qda(46`m^D=3Ph*L%}6*Q%-pSk5FMfL*`M?pF{M8-_90G>t>imY!jkGIL?~ z)Ku3Csy}udX8{PQd)tL_ir_WIg7zd*)?NUr*Zm-}rtA8S>`1_)swy{0lH*`&6gINi zW6othhq5gB;IL6d-pR(IwgH$sdi!h12=^v;=;s4TEFWhk_^Cx?)8+uI|7zOiE{t7I bb{{15KkSn#=yOEcf^?@;ncO5VUW;3go)3z|TT< z;LuMT$L7#Q@Ex#TlO);jnF?fCmZ|G{itQCU5V!{DMTUExH-p`W?Uw9CQ9Ln>L58Mj z-zd+JK=%OchBQP4biq4ihBD_=CYMIHykQ+Vt1Qc|5pWm+$#QV!EwL$8WJR}$ZdqL* zva(?N#HyOY8I=?W!{~8IXFXf($d(h@8))4M59NAUO-_Sl#6SXZ+qA$+OV~BAYuL-b(f(N6)UXxLQf-&t9BV1_D>-`Yrsskw_YrAP16a&j=-%UQ jiTz)f#`;DN;5pzQwiDkITnHEf00000NkvXXu0mjf69mNH literal 0 HcmV?d00001 diff --git a/design/IcoMoon - 7 Icons/PNG/sound.png b/design/IcoMoon - 7 Icons/PNG/sound.png new file mode 100755 index 0000000000000000000000000000000000000000..5358f3fc6ccf28f966d998fdb6b793b39f7f5090 GIT binary patch literal 328 zcmV-O0k{5%P)lnl`rLb8 z!dU4OD{+ijkd)G~EbA$RaMCnAaDgX5K@do#6hT}90L1#U7ryV`0l4%P%!2T!z@t4Q zJA(bzSJe5dx~>m-o>z3&Dnbfs3_(hzX_}`bNeX?h74-ra8a4pIxX}^%;4!FcKu%d8 z;3Lbj>j1>nU<{%lfVsA9zXAFHv|9sI0^}`D4QgHx=HW!hBxH*X2kPW`s@T+!rfDSA zwFS+zKZFaN-#~W$6`FG#wEy4yEE-5|f4UWkk>YmoifA~^3Z(T~{cjKHPN^P?99M5P~4rp1i86gPrgV1V{tO zh7!hceDORlFUyjYtg>Vt~#cUgfHAgxouVIk(hSkhK_=F9^ z%n?adLtbf6nx-R-2=F_3@QB^sEc5xlLSF2yTLb|T_I)qm(Wmj^-uHb4a0`%}1##JJ zqxmeZT8{J4NHr=KEt>rkXx8kd@|%k4hNN9xHIwo?EzqK)<7*9x4nM($aMF;xlXFFm z02a;_*#YoO`Rom^{nw?nl`Mj2f;>a1=?+P|kMOS068Wz_BfP_3$1_3K9wJbJS&{$% N002ovPDHLkV1fWdxIq8_ literal 0 HcmV?d00001 diff --git a/design/IcoMoon - 7 Icons/Read Me.txt b/design/IcoMoon - 7 Icons/Read Me.txt new file mode 100755 index 00000000..968528f9 --- /dev/null +++ b/design/IcoMoon - 7 Icons/Read Me.txt @@ -0,0 +1,7 @@ +The *SVG* folder contains the icons you selected as separate SVG files. + +The *demo.html* lists the icons that you selected. To learn how to insert your icons as inline SVGs (with the element), refer to the source of this HTML file. If you prefer to reference an external SVG instead of embedding it in the HTML, you will need to use javascript to fetch the SVG in order to make sure your SVGs will work fine in IE. IcoMoon's Quick Usage mode can take care of that and host your SVGs too. + +You can ignore the *svgdefs.svg* file. It contains the same SVG definitions as the ones you can find in the demo.html file. + +If you prefer using PNGs or CSS sprites, refer to the Preferences panel of the IcoMoon app before downloading your zip pack. diff --git a/design/IcoMoon - 7 Icons/SVG/fast-forward.svg b/design/IcoMoon - 7 Icons/SVG/fast-forward.svg new file mode 100755 index 00000000..13670b17 --- /dev/null +++ b/design/IcoMoon - 7 Icons/SVG/fast-forward.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/design/IcoMoon - 7 Icons/SVG/film.svg b/design/IcoMoon - 7 Icons/SVG/film.svg new file mode 100755 index 00000000..538a30b6 --- /dev/null +++ b/design/IcoMoon - 7 Icons/SVG/film.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/design/IcoMoon - 7 Icons/SVG/monitor.svg b/design/IcoMoon - 7 Icons/SVG/monitor.svg new file mode 100755 index 00000000..28625055 --- /dev/null +++ b/design/IcoMoon - 7 Icons/SVG/monitor.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/design/IcoMoon - 7 Icons/SVG/play.svg b/design/IcoMoon - 7 Icons/SVG/play.svg new file mode 100755 index 00000000..65db2254 --- /dev/null +++ b/design/IcoMoon - 7 Icons/SVG/play.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/design/IcoMoon - 7 Icons/SVG/refresh.svg b/design/IcoMoon - 7 Icons/SVG/refresh.svg new file mode 100755 index 00000000..90ad4431 --- /dev/null +++ b/design/IcoMoon - 7 Icons/SVG/refresh.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/design/IcoMoon - 7 Icons/SVG/sound.svg b/design/IcoMoon - 7 Icons/SVG/sound.svg new file mode 100755 index 00000000..58db4ded --- /dev/null +++ b/design/IcoMoon - 7 Icons/SVG/sound.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/design/IcoMoon - 7 Icons/SVG/up.svg b/design/IcoMoon - 7 Icons/SVG/up.svg new file mode 100755 index 00000000..ee57849b --- /dev/null +++ b/design/IcoMoon - 7 Icons/SVG/up.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/design/IcoMoon - 7 Icons/demo-files/demo.css b/design/IcoMoon - 7 Icons/demo-files/demo.css new file mode 100755 index 00000000..b6189ee8 --- /dev/null +++ b/design/IcoMoon - 7 Icons/demo-files/demo.css @@ -0,0 +1,147 @@ +body { + padding: 0; + margin: 0; + font-family: sans-serif; + font-size: 1em; + line-height: 1.5; + color: #555; + background: #fff; +} +h1 { + font-size: 1.5em; + font-weight: normal; + box-shadow: 0 1px #ddd, 0 2px #fff, 0 3px #ddd; +} +small { + font-size: .66666667em; +} +a { + color: #e74c3c; + text-decoration: none; +} +a:hover, a:focus { + box-shadow: 0 1px #e74c3c; +} +.bshadow0, input { + box-shadow: inset 0 -2px #e7e7e7; +} +input:hover { + box-shadow: inset 0 -2px #ccc; +} +input, fieldset { + font-size: 1em; + margin: 0; + padding: 0; + border: 0; +} +input { + color: inherit; + line-height: 1.5; + height: 1.5em; + padding: .25em 0; +} +input:focus { + outline: none; + box-shadow: inset 0 -2px #449fdb; +} +.glyph { + font-size: 16px; + width: 17em; + margin-right: 1.5em; + float: left; + overflow: hidden; +} +.glyph svg { + color: #444444; +} +.liga { + width: 80%; + width: calc(100% - 2.5em); +} +.talign-right { + text-align: right; +} +.talign-center { + text-align: center; +} +.bgc1 { + background: #f1f1f1; +} +.fgc0 { + color: #000; +} +.fgc1 { + color: #999; +} +p { + margin-top: 1em; + margin-bottom: 1em; +} +.mvm { + margin-top: .75em; + margin-bottom: .75em; +} +.mtn { + margin-top: 0; +} +.mtl, .mal { + margin-top: 1.5em; +} +.mbl, .mal { + margin-bottom: 1.5em; +} +.mal, .mhl { + margin-left: 1.5em; + margin-right: 1.5em; +} +.mhmm { + margin-left: 1em; + margin-right: 1em; +} +.mls { + margin-left: .25em; +} +.ptl { + padding-top: 1.5em; +} +.pbs, .pvs { + padding-bottom: .25em; +} +.pvs, .pts { + padding-top: .25em; +} +.unit { + float: left; +} +.unitRight { + float: right; +} +.size1of2 { + width: 50%; +} +.size1of1 { + width: 100%; +} +.clearfix:before, .clearfix:after { + content: " "; + display: table; +} +.clearfix:after { + clear: both; +} +.hidden-true { + display: none; +} +.textbox0 { + width: 3em; + background: #f1f1f1; + padding: .25em .5em; + line-height: 1.5; + height: 1.5em; +} +.fs0 { + font-size: 16px; +} +.fs1 { + font-size: 18px; +} diff --git a/design/IcoMoon - 7 Icons/demo.html b/design/IcoMoon - 7 Icons/demo.html new file mode 100755 index 00000000..053be7a4 --- /dev/null +++ b/design/IcoMoon - 7 Icons/demo.html @@ -0,0 +1,90 @@ + + + + IcoMoon - SVG Icons + + + + + + + + + + sound + + + + + monitor + + + + up + + + + + play + + + + fast-forward + + + + refresh + + + + + film + + + + + +
+

SVG Icons - Generated by IcoMoon

+
+
+

Grid Size: 18

+
+
+ icon-sound +
+
+
+
+ icon-monitor +
+
+
+
+ icon-up +
+
+
+
+ icon-play +
+
+
+
+ icon-fast-forward +
+
+
+
+ icon-refresh +
+
+
+
+ icon-film +
+
+
+ + + diff --git a/design/IcoMoon - 7 Icons/style.css b/design/IcoMoon - 7 Icons/style.css new file mode 100755 index 00000000..c0b7744f --- /dev/null +++ b/design/IcoMoon - 7 Icons/style.css @@ -0,0 +1,6 @@ +.icon { + display: inline-block; + width: 1em; + height: 1em; + fill: currentColor; +} diff --git a/design/IcoMoon - 7 Icons/svgdefs.svg b/design/IcoMoon - 7 Icons/svgdefs.svg new file mode 100755 index 00000000..a66b1366 --- /dev/null +++ b/design/IcoMoon - 7 Icons/svgdefs.svg @@ -0,0 +1,35 @@ + + + + sound + + + + + monitor + + + + up + + + + + play + + + + fast-forward + + + + refresh + + + + + film + + + + diff --git a/design/collapse.sketch b/design/collapse.sketch new file mode 100644 index 0000000000000000000000000000000000000000..3efc91f47b8c2e2e23b0f4fdf2f3767be15b6526 GIT binary patch literal 32768 zcmeHw2Y3@#y7nn!Tg9>^%M~{jcPv|@8MPF^6$}^%w&}shw!i}0GLr2;2ry0v2_)HU zNZa%RA!U=zZaS$f={>X*b~mJvo{-+l{boj%h%pdjAjUw9ffxfZ24W1v7>F?t zV<5&rjDZ*fF$Q7`#2EO$&Okkh&&bZk-ab!Tm$%omw#)D72z}6+xph^|b%y4u>X~(h zP@$ou$J6aK^m*6xl^X^;UHx7|TbIABv;oIwh%pdjAjUw9f&UE*)Fm+4gJ{4L@OgUr7xbrtG~O=8$g>jCCqA?Cw@l_htPVY#j;JC@ajvgn;YYpjKS2leqUF||8HZ1 zzZPw7Vi^5kfv2~3+{VV~;DmO6cSW1O)7uU7wEH`Ngo@xQZ(n;Sx7kf;M$dA8PhW8C zR-unofq-Z2$Ugee=2?Wv8cgl-_N?gZ9Q$Tq14DaL0Bg7JciXU}!)moT zoozht;B0NYlef0n932j?i{tq=r_*j@y-usk(eB2cf!G#5$KzpYTikl1i{Jkj% zZ@%_+9oC`*q(HgwR~$^J6jdS)IguNkh^kNnnu%tklh8u61hpa$T7`O009}i2Mz^BB zpueFz(Ju5jdImj<_MunMA@m0N5`Bk$L_cGM307e>PQ+TQ$61)g4(!Iq<4Jf5o`xIn zbUX();rX}&_uwF2kI%rH@m72lz8>FzZ^XCYTk)OvE_^?J2)~WLz+d98@Ync9LJ33S zNIXd0~ZxBF&_QoJ^LI zRJ@O&>m>eaalkdq7+D-fE06m4Sp#mMGr_(d&IrLn59{mHogkDPjL@%S)(d+4Ux`WF??~1b^E@h14h!X;2bMMp~ppDM*h}Q5s4|87LEFp$YIi zr&X(M?+*mLJ$-XLE4&Ro9o{wbeBE#uT-@bZ>kTyZt?lv#TY9CE4u7lcoej0E+H`M^ zxXG!h%hwL~^?3uH_C6Rz<`uMed4j=KZL)NKGwf`V+X&w=Q*1ZtjwSMg)^@k~yMkII z5FuVj9mGk>L7XgTl|te^=t?rmL-_&~;`YL!QDF8VGb%uZsA!S=JaHS<0{PGj57*CX zYV4ObPu2P)Sf0Sz?NGfKl`NUn6e(LUG>pmZm7$5PT3usPgUCRQzpD#|Oz6`NRE{jD z0+oz)u~nPWI_i#-8=D&a9o{Z^jNFH;fSN_N`Jvzz5(M==#6zJSITm=t@us!IFDL|+ z*gcn^l;IqQj$az?h%_o~N5`QPP|5tzASG9ugeK2#lt-=YXcC%&N=80jX30dI$71j#TpFcv~;@&Hl?0 ztJW~QZ=+lNpSQCZ1zkW&nxNVThkoQjs~68|s*ppa!YU|*^uyXr6hwWf9}S>W&>FNB zor>0>(;&GeqxEP5+K2=+h)zdmpiSsZv>Ba+&PH3%R&)+J7o7*6=c7MD^1A?SLl>fp z;Cw5(6#WU(pIGNg>Gu{$g#LhUg|EjG3R*G8>3zZaE?+N9tEa)mQ^iQ>Y6*%daY4Y} z=Mi&5%kluE9!Phco?s2+!d1~$ zq=f2&SRvko4x;PO^=LboYzMjl?F56|h_)vlNA+AqA%SJW!X_>V(z;O-3=CMYyy%a?C(JLpnK7MVjzvY z1b85DhSeUPo?b@x!=oNR52A*(v8*Xi}G=NX1FQbwLV)hWdefU#k?q3C-&4Ow_`UgDcpXgr@w}+$RmW?{L3SUDM7aZ26KxB$B zJP7f73dHT{5Y=k{Y%;|5CWz>b5YYlq`4)N`y@QURci~u$(k)u2mXDHK|w6uuP7qy6nG^tJ47LWximcAxK|3&l~cBD&8nP*xf)dj(1! z0#Nr$wtg7x#te?b@n|bnV5N{}p2EwP5+<6bobiTq4CV|Knx~wA@H7H%}>$%BFyYYijM* zDyOx|QeDT^S@=4(9**3srMAjeZFjnOuC~_J0#l}5??Eu!4DkBrAxQV)Mkz$Mv@G{^ zbp-{ZaGYpt8R zqOnkB3wV@207mHb^g-D7H2Yw}4r7UTf%r7hSWA2SzMwRJ?+N<)AbBN+s@8`pEDBYC zg#ipEb<&)_Lzpa_XrBC;%tts7m14)dcsX8yJFyS1#H(-@?rwtFW{an*x6{+y2HH`} zih$SKBTO<+-m8;-BJD&g#EY|G84?k{ec~DvKj~E%p{eJ%uJ9jaUbqq97K_40#Tv+sy#tpyIiCjsu3<5x_=IMarl1mWGpZn z@J1Ns8=J(&Li6pRWyK9xz=LQKK3yDw#;zijOSg&bLyto%l95jm6T>F(>uPBdh0g+S z*)qagY7T3)5Z(ik)Qiu-=i>7q^(KdsFQi_4KK>)V074tmF1{FL;!C0IGC0@6=aoQE zo8RB%_4Lf{g$18Du+8&!z=+b(3~tk@2)lw%D>R51S^sP3M=8uu2!Dd0ogS5z@zwa6 zP|!{l>cT<09Xe7U4p2E1Zi2FD;j&@FFTPD2e(_)N-|!s~0OGJJN9nF`44WT(Np{)h zIe>OQz8l{Iyxj}E+%>P)?*mN`CP+11{-C!*n5h&ll^^{8Ji1X(9oFjc!}t-r8~+{e z!H?p{@Zky$ zU*MxIL?7FuE7^q=!ui4~!7p4W1cg(Cb;2xRqtFCdYrb%Xuvj=tXcgLpb6&;o;3Gib zyZAl)KK=lI2!<@eALCE(r}!xT3~gN^POJL^1K#?8zk4A_6$4&z5NVOjC7+8|mcRf6 zOW3)d4qtz8zErK*zi8;*X1_w1E1V?Ej=0AhMXR=SowdSY<6RE7jprOZ>u_*9TW+vc zxSS4~-5UO}t^ZHel@r`I_}e9r;KaVo5xsB+{tkbSe*mc>y7XkoLyJQ{i?QQ(h>il|8<(V(qLEd$^e2@4|N z7ly#QI6KF3oZD)(b573g;zi>*ID0g9t2<;prwgvwc?WN`f~i@DORQ{nIh;|JW`9@R zF`%QP06mSQlMIrHGL-;)sjwsh{A8u*No<9cwb=lUmF28%-r;acP&ijKZdUXZIGjaW)qR`oG=na@(BlF*`XL_*RK?12Ga4F{4b;UD||Y5#SyG zE`b@VeV%3EiQ#au+5vfq+)E&uhp!=ctJ}#*p~c(X(N#sle@DBcfy>S^k(3h)sQ_mI z;LC-M2ykyG&g~H7ZkyE#hG*TZL^!ZN%**Xu2#g(wbFwa*)5W=*cFrMkXyqKk`p7$e zU*)lo+rd|y#6{fXIPeuM1?($@&IooNke&%1V7J;_yqmQ;>^9D3b#rzA1W%VP0VwF1 z!v*<^cez})s7qD|W9YLTvKb^dR&<5+W5AGHwwlzCT2d#wY>&_t0nrU0EC7OcyBzS1 zlilug^E~V3B{u|{NBgW5zI_tIEkgp$a&{}{=I!9@08a)cx8!y^9d@Uk<()1&YnP%H zS{h~yo^|qLp(P?|jbs*?P3FjG143^E?dlL^yqLgUPA9mV+i7*WMc)fi#=D)YmA67r zIc>a~lafaGlHJK!Z8ouk;3-ZqMT`ML4weOEAz4Hg%fT`r^hH4Q1Bi(tWmfPamV@@d zM&hHOxv?Eds?Av)4wi*ya~$yE8sA5MPupV{TnhDe(m}jrxg0U43Q>B*T8NnPbrwJh zNy-X235;sDIjs=JB7R^Lf+7;^V$g_yAV6R&g>N3Mkce4u3%T|fsp0q39s|DQuRX+1 zddX_p12zb!MaW+tBH!w=^RVo)x**xRz?xPuG{nIn+Ra!oihrZCc23Ntk>6s66I&$AB$P%E%^iCfQ8Rl4lc}g-sFIXNCr3APZc^>2`zDgU(@> zhM)0f6aR_IqoKCV;(~Jrd4N1f9+Cx!p+ZSO7&;j~tCt&j zgzT1eiJ?l8LcWvyo$MixlE=v7qIw|e7Q?QCFemC3!^%KKk?s{`UFl$~$301&f@Ozv z<5c(}qxTl_GTCg zpJiPU6vZ83MUi4q6mO6eMam!-jgMN&i;CjTF%?CsLVBtO9zanXNBNUDph>{NO_Bmd zb@VT6VagKaL}iIOsFS)PNhYE!f&Oa{od}`u)sUz}VMdR434a?Bk?16N z${nJJq@z`|n%2--T1V^YR630|pkz9o&Y&}CBb`NO(>e4cI+r%lX4*pM(fM=%T?k|@ zrc3C_bSZ76%cv)c*m3ous5<{!C8B4A7lr-8E5bj7!@`}y+rquzf)5Dq36BUL36Ba- z3P;Bn0mPXI_0r{Z1?`k)BKHV)h3OaW4h`p!r=xWpY4uYv-b~~_QF%0UX#}OcbTtjo zpge-!FWeV_zAFTMgsR~fcS0xXS0hvndDcC~O!3(3jsaYpa?^G6G`gN{kf+=a3lBzs zKLn%h7^;T2Os#+!bo4}YJXOOki38(FHzQOHyR4Utlx{`?m!=DJGd+u*O}EI?g+0RV z2=Kp$rVC@Xe{8CTO~P_)s)mevbi1R0%dT<(-9|5@uwOw`HJ%V2ivWKdTt!?)4OcZB z&fi`$j?gvu-(HU%YwfYn!y=ttNw1<;(`#gZc}93Dg8u2yymf@GVH1S_dEN?cGfdZT zMy=oN!*vboIE(a5$!Tw-H_@BvEi#A~gy$k4o(B+P=o*|9ZR6+~vKTW=*We{tWvHoP z!bVskiC%HSoOpa;gWf^!q<7J~Ww`rwwJJ5~kQ}k*2 z41HD(nnS{?5%jM?(2Tv-mzLMZDr`s=uNWQ0W6L1p)gA-BqkqkfODA!`Z8C~U~^M~x?=(aWj!b$Xb-LEn^J=Plul2>Lexy*LJq5H_Tk zA4`Q7S8*eh4OViT@y3W_Yj_Oc(uCpz`XT*@!WI)z`F>Y;Cj$IPXjC4#ikDQ&@g@}i ziOQp)%cI0s^lSPJ{Z@AP4~6$5&_DPs=;JML$Amt5fh(`GkFoN2(0^qRgBc<_`=`Rk z5$KsA)e2AnoReHUKhNy|RQ1!X@-YgOiWYS}utz;U5n&lc75T zGli*Qs+k(57U`L~mY}$K2IQ6jc~hmdmqy%1Gf)1%*9`Av5q=SV7Jh094y>3Xo27x7 z4rY;e6gI(@#~sWJW+u}pnIlpv>LpQU!#0tRk`$OZ%t_2#V6~ZP5hVqiyc8Y82==1A zFP*?1h)^l)MeCG`KvSsZ*jkVSt1MNuywk$ltKi7V)>vwsF4keKc7a4!J!~rvvyfTD zEM}I7yLN^){fvJg?uDvy*tjZZwWY4!4(?i8&B0!%dWVIx*Ml-_x8>cneoo&06?+tJ~sYA)@OYb-cq`4=-@lvNA;* z83A^GiaR@RVKy>@%<0S-%qHeciKNZ)PEhgUu&DpHg*QNEv(;DEx@)QckIiA>UAB6Q z%Wid8;0tBD&E}}7udU~0WLuc6OB1^IQSz04n(3z`Fdf1iNiRi`X?(P<*QCUG2^Oxod9pl##^c)dq_t>+m~=RPDq z(KKoTxu*zT;VFYxcq%AMIm&}*GZ~bY8qim!gO;)sjU~N zj6Vt(0TP)sCJ$1Ti794E;gy>zc+qAKIK7AIWCnoqtC(AurkpVJsI~_+-Gs$$Nd=hb9{WfB3>1r9IuO?5Pw2^W4u3p zTl`<+UyT1Cfk{Y7$WF*j$WJIq;1e7Pu7oQR{*v%m!ZQi`6JAUBNP!i}ied$;s8cLd zcoi!Zs}<`Mf?|u}62(=DyA+Qq9#=e}cuKKXv0rgO@rvR##aoIaiuV;CDLz(wqByGf zT=9kCE5+A}?-V~MepLLdOi^YkCn{aa8fBews2;QO;K`Q7%=kQ2Lasl)cJ; za-H%#RC zJk|NC3se`XE>>Nw+Nru-b)V`9)r+dVs{N`rR3EFpQ~jX&N%f1mK|NhPQ{AGTuU@EL ztX`r%S>38$rfySrsJ-gt>Q1#!y-MA!K3%;@y;*&>dW(9S`Xcou>MPV&sduVxQs1J! zUHv!p3+k8Duc`l`en)*o{i*uf#Jt4fL|5W*i6LU~G_{&~%~Z`aO@n5JW~Qc5Gh5T4S+42S ztkkU1^l1h(Yc%UM8#QNZwrbART%fs7^H+!%0siJ(KiY(!r$HlMW|+mGoWG zFUd4nnXFDuP0md&O0GR#EZLXbpS(GFTk$K~&yS4kZhqQ;aZ)iWzex&_G`>FP*_H*qI+8?z)Yk$!p z9o7*Yqs!7|>vDDZI)koMH&JKN*>t?_MBQXvm9AblP3O_A)OG2)bpyJMy0dlX=`Pn@ zr@KXWtL`@4?YjGP_v;=^QKw|26r@;FPDp7;X-R2I@u#dyIXmT|lxtINOWBq3M9RLD z*Hb=9`6T6N%I7IxrhJ|9ZOZp4Kc@Vg@~a-}sXk7hpjYbEdW}9=uhZM~ll2Yy+4_b0 z<@z4|TK%c|)ASqkf_{ts9R0ca`}FUmYE!dPi&867Pe`4fx*&CJ>Zz%xrEW+SQn#d@ zlX`CIuGDwa^l5yWJ>z`Rivfj&je?t0%+6jRP7f!fn!X*>_ zG~x0I+b7&GVdsQ{*)*HYo}1m2-I6^&dtr84c1N~1`@-x!*++AdC zW6qhCvo2?6&XYM$d7tI0^NaGQ z=1+sa2tG4^R{s3_h53u}&&t0m|IPdl^S{ae)u1+H8j1{+hHArXLz`j1u)%Pa;bOzp zhCds28=g1(!|=Z08zW=X8;!=(j2ny_jf2Lm#&eD58P7LfVBBWB$at~w662-D%Z!&B zuP|O^yu)~x@gC!S#$Coe#>b3L7@svhZ+zMKs_~HVu<=dfFD7JCn$)ILQ<^EyRBW1M znrB*N>NfdJt4%@EX{HS(!L-G6vFTFNWv2U051Jk}J!yK$wAXaV^iR|4ruR%=n!YxD zYd+3=yt&p~Z=PmuFi$tnG&h=Oo9CG4nw!kc=6U8-=5Dj!yxJTvuQRVVZ!~W*Z#JKA zzQBB;`A_D{&3Bp~G(T*9#Qcc;q;N~&J%w)H~ zJzTWAXiw2&Mb8(#SoBiSPsOFhEyV-HrxdR(URS)ncysaD#aoK+DSopgsid;RT4F2V zOB^MWOR7q$OL|MLE_trxlafzMJ}dd6pkh(Q zk_vCdii*yPi!1h29Iez=>MHe>X_Xn3hDuYVx$?xy1(m_diz+X!ytMMN$}1{&RPL<2 zvGRZw!)}Zg>r(3~>uJ_4)=RB7Snsm#VdK~gww$%VW-k|e9D6)_0y~MVVyju$mCsIP zr?E5GMz)RZV3)I=E`o z_9OOV_G=rlsco6IA{%cz$<}0BVr#W^+I+TvZJq6U+r743wmr6IZ3k@s;uucDP2h?- zo~!2Oa3^zZoR90`{M;ID9k-r4o!i8n$6dx<&;5mafP0#Il{><{&wa#w#eK_t&;7z9 zz8E$sIr*7WYkv!`sME+#9$)7{N?Ir&O DEU@}K literal 0 HcmV?d00001 diff --git a/design/expand.sketch b/design/expand.sketch new file mode 100644 index 0000000000000000000000000000000000000000..e1f83eff956db609c5d57e485f40ef9f2661e2c3 GIT binary patch literal 40960 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 literal 0 HcmV?d00001 diff --git a/design/pause.sketch b/design/pause.sketch new file mode 100644 index 0000000000000000000000000000000000000000..ec185203db49bbe18793d43e820e9be8c625ba9a GIT binary patch literal 32768 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 G@IL`MAx577 literal 0 HcmV?d00001 diff --git a/design/rewind.sketch b/design/rewind.sketch new file mode 100644 index 0000000000000000000000000000000000000000..8bf121f100c0aa0c7cfda2b208ee9d0f38d687fa GIT binary patch literal 32768 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 Vx?z*V(2)@FPWOxV!Ovln{|g@2590s; literal 0 HcmV?d00001 diff --git a/dist/css/docs.css b/dist/css/docs.css new file mode 100644 index 00000000..9372da09 --- /dev/null +++ b/dist/css/docs.css @@ -0,0 +1 @@ +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:0 0}a:focus{outline:dotted thin}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}*,::after,::before{box-sizing:border-box}html{font-size:62.5%}body{font-family:"Avenir Next","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:18px;font-size:1.8rem;color:#6D797F;line-height:1.5;background:#ECF0F1;max-width:960px;margin:50px auto;text-align:center}h1{font-size:48px;font-size:4.8rem;letter-spacing:-.025em;color:#2E3C44;margin:0 0 20px;line-height:1.2}p{margin:0 0 20px} \ No newline at end of file diff --git a/dist/css/simple-player.css b/dist/css/simple-player.css new file mode 100644 index 00000000..5199f5f3 --- /dev/null +++ b/dist/css/simple-player.css @@ -0,0 +1 @@ +.player,.player *,.player ::after,.player ::before{box-sizing:border-box}.sr-only{position:absolute!important;clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}.hide{display:none}.show-inline{display:inline-block}.player{position:relative;max-width:100%;overflow:hidden}.player video{width:100%;height:auto;vertical-align:middle}.player svg{width:18px;height:18px}.player .controls{zoom:1;position:absolute;bottom:0;left:0;right:0;padding:10px 5px;background:rgba(0,0,0,.75);transition:-webkit-transform .3s ease;transition:transform .3s ease;line-height:1}.player .controls:after,.player .controls:before{content:"";display:table}.player .controls:after{clear:both}.player .controls button{border:0;background:0 0;overflow:hidden}.player .controls button,.player .controls label{display:inline-block;vertical-align:middle;margin:0 2px;padding:5px 10px;color:#ddd;transition:background .3s ease;border-radius:3px}.player .controls button svg,.player .controls label svg{display:block;fill:currentColor;transition:fill .3s ease}.player .controls button:focus,.player .controls label:focus{background:#000;outline:0}.player .controls button:hover,.player .controls label:hover{background:#3498db}.player .controls button:focus svg,.player .controls button:hover svg,.player .controls label:focus svg,.player .controls label:hover svg{fill:#fff}.player .controls .px-video-time{display:inline-block;vertical-align:middle;padding-top:3px;margin-left:10px;color:#fff;font-weight:600;font-size:14px;-webkit-font-smoothing:antialiased}.player progress{position:absolute;top:-10px;left:0;right:0;width:100%;height:10px;margin:0;vertical-align:top}.player progress[value]{-webkit-appearance:none;border:none}.player progress[value]::-webkit-progress-bar{background-color:#eee}.player progress[value]::-webkit-progress-value{background-color:#3498db}.player .play-controls{float:left}.player .sound-controls{float:right}.px-video-img-captions-container *{box-sizing:border-box}.px-video-img-captions-container{position:relative}.px-video-captions{position:absolute;top:0;left:0;width:100%;padding:.5em;min-height:2.5em;background-color:#000;color:#fff;font-size:1.1em;text-align:center;opacity:.75;-webkit-font-smoothing:antialiased;font-weight:500}.px-video-captions-btn-container label{display:inline-block;width:25px;height:20px;margin-left:25px;background:url(../images/px-video-sprite.png) -6px -835px no-repeat}.px-video-captions-btn-container input[type=checkbox]:hover+label{background-position:-6px -799px;cursor:pointer}.px-video-captions-btn-container input[type=checkbox]:focus+label{outline:#999 dotted 1px;background-position:-6px -799px}.px-video-captions-btn-container input[type=checkbox]:checked+label{background-position:-6px -871px}.px-video-mute-btn-container label{display:inline-block;width:25px;height:20px;margin-left:240px;margin-top:2px;background:url(../images/px-video-sprite.png) -6px -476px no-repeat}.px-video-mute-btn-container input[type=checkbox]:hover+label{background-position:-6px -440px;cursor:pointer}.px-video-mute-btn-container input[type=checkbox]:focus+label{outline:#999 dotted 1px;background-position:-6px -440px}.px-video-mute-btn-container input[type=checkbox]:checked+label{background-position:-6px -692px}.px-video-mute-btn-container input[type=checkbox]:checked:focus+label,.px-video-mute-btn-container input[type=checkbox]:checked:hover+label{background-position:-6px -656px}.px-video-controls input[type=range]{-webkit-appearance:none;height:6px;width:100px;margin-top:8px;background-color:#E6E6E6;outline:0}.px-video-controls input[type=range]:focus::-webkit-slider-thumb{outline:#999 dotted 1px}.px-video-controls input[type=range]::-moz-range-track{-moz-appearance:none;height:6px;background-color:#E6E6E6;border:none}.px-video-controls input[type=range]::-webkit-slider-thumb{-webkit-appearance:none!important;height:10px;width:6px;background-color:#666}.px-video-controls input[type=range]::-moz-range-thumb{height:12px;width:8px}@media screen and (-ms-high-contrast:active),(-ms-high-contrast:none){.px-video-controls input[type=range]{position:relative;padding:0;height:8px;top:-3px}.px-video-time{margin-top:4px}.px-video-captions{padding:8px;min-height:36px}} \ No newline at end of file diff --git a/dist/js/docs.js b/dist/js/docs.js new file mode 100644 index 00000000..98c30afa --- /dev/null +++ b/dist/js/docs.js @@ -0,0 +1 @@ +var Hogan={};!function(t){function n(t,n,e){var s;return n&&"object"==typeof n&&(void 0!==n[t]?s=n[t]:e&&n.get&&"function"==typeof n.get&&(s=n.get(t))),s}function e(t,n,e,s,i,r){function a(){}function o(){}a.prototype=t,o.prototype=t.subs;var l,u=new a;u.subs=new o,u.subsText={},u.buf="",s=s||{},u.stackSubs=s,u.subsText=r;for(l in n)s[l]||(s[l]=n[l]);for(l in s)u.subs[l]=s[l];i=i||{},u.stackPartials=i;for(l in e)i[l]||(i[l]=e[l]);for(l in i)u.partials[l]=i[l];return u}function s(t){return String(null===t||void 0===t?"":t)}function i(t){return t=s(t),c.test(t)?t.replace(r,"&").replace(a,"<").replace(o,">").replace(l,"'").replace(u,"""):t}t.Template=function(t,n,e,s){t=t||{},this.r=t.code||this.r,this.c=e,this.options=s||{},this.text=n||"",this.partials=t.partials||{},this.subs=t.subs||{},this.buf=""},t.Template.prototype={r:function(){return""},v:i,t:s,render:function(t,n,e){return this.ri([t],n||{},e)},ri:function(t,n,e){return this.r(t,n,e)},ep:function(t,n){var s=this.partials[t],i=n[s.name];if(s.instance&&s.base==i)return s.instance;if("string"==typeof i){if(!this.c)throw new Error("No compiler available.");i=this.c.compile(i,this.options)}if(!i)return null;if(this.partials[t].base=i,s.subs){n.stackText||(n.stackText={});for(key in s.subs)n.stackText[key]||(n.stackText[key]=void 0!==this.activeSub&&n.stackText[this.activeSub]?n.stackText[this.activeSub]:this.text);i=e(i,s.subs,s.partials,this.stackSubs,this.stackPartials,n.stackText)}return this.partials[t].instance=i,i},rp:function(t,n,e,s){var i=this.ep(t,e);return i?i.ri(n,e,s):""},rs:function(t,n,e){var s=t[t.length-1];if(!p(s))return e(t,n,this),void 0;for(var i=0;i=0;u--)if(a=e[u],r=n(t,a,l),void 0!==r){o=!0;break}return o?(i||"function"!=typeof r||(r=this.mv(r,e,s)),r):i?!1:""},ls:function(t,n,e,i,r){var a=this.options.delimiters;return this.options.delimiters=r,this.b(this.ct(s(t.call(n,i)),n,e)),this.options.delimiters=a,!1},ct:function(t,n,e){if(this.options.disableLambda)throw new Error("Lambda features disabled.");return this.c.compile(t,this.options).render(n,e)},b:function(t){this.buf+=t},fl:function(){var t=this.buf;return this.buf="",t},ms:function(t,n,e,s,i,r,a){var o,l=n[n.length-1],u=t.call(l);return"function"==typeof u?s?!0:(o=this.activeSub&&this.subsText&&this.subsText[this.activeSub]?this.subsText[this.activeSub]:this.text,this.ls(u,l,e,o.substring(i,r),a)):u},mv:function(t,n,e){var i=n[n.length-1],r=t.call(i);return"function"==typeof r?this.ct(s(r.call(i)),i,e):r},sub:function(t,n,e,s){var i=this.subs[t];i&&(this.activeSub=t,i(n,e,this,s),this.activeSub=!1)}};var r=/&/g,a=//g,l=/\'/g,u=/\"/g,c=/[&<>\"\']/,p=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)}}("undefined"!=typeof exports?exports:Hogan),function(t){function n(t){"}"===t.n.substr(t.n.length-1)&&(t.n=t.n.substring(0,t.n.length-1))}function e(t){return t.trim?t.trim():t.replace(/^\s*|\s*$/g,"")}function s(t,n,e){if(n.charAt(e)!=t.charAt(0))return!1;for(var s=1,i=t.length;i>s;s++)if(n.charAt(e+s)!=t.charAt(s))return!1;return!0}function i(n,e,s,o){var l=[],u=null,c=null,p=null;for(c=s[s.length-1];n.length>0;){if(p=n.shift(),c&&"<"==c.tag&&!(p.tag in w))throw new Error("Illegal content in < super tag.");if(t.tags[p.tag]<=t.tags.$||r(p,o))s.push(p),p.nodes=i(n,p.tag,s,o);else{if("/"==p.tag){if(0===s.length)throw new Error("Closing tag without opener: /"+p.n);if(u=s.pop(),p.n!=u.n&&!a(p.n,u.n,o))throw new Error("Nesting error: "+u.n+" vs. "+p.n);return u.end=p.i,l}"\n"==p.tag&&(p.last=0==n.length||"\n"==n[0].tag)}l.push(p)}if(s.length>0)throw new Error("missing closing tag: "+s.pop().n);return l}function r(t,n){for(var e=0,s=n.length;s>e;e++)if(n[e].o==t.n)return t.tag="#",!0}function a(t,n,e){for(var s=0,i=e.length;i>s;s++)if(e[s].c==t&&e[s].o==n)return!0}function o(t){var n=[];for(var e in t)n.push('"'+u(e)+'": function(c,p,t,i) {'+t[e]+"}");return"{ "+n.join(",")+" }"}function l(t){var n=[];for(var e in t.partials)n.push('"'+u(e)+'":{name:"'+u(t.partials[e].name)+'", '+l(t.partials[e])+"}");return"partials: {"+n.join(",")+"}, subs: "+o(t.subs)}function u(t){return t.replace(m,"\\\\").replace(d,'\\"').replace(v,"\\n").replace(g,"\\r").replace(x,"\\u2028").replace(y,"\\u2029")}function c(t){return~t.indexOf(".")?"d":"f"}function p(t,n){var e="<"+(n.prefix||""),s=e+t.n+k++;return n.partials[s]={name:t.n,partials:{}},n.code+='t.b(t.rp("'+u(s)+'",c,p,"'+(t.indent||"")+'"));',s}function b(t,n){n.code+="t.b(t.t(t."+c(t.n)+'("'+u(t.n)+'",c,p,0)));'}function f(t){return"t.b("+t+");"}var h=/\S/,d=/\"/g,v=/\n/g,g=/\r/g,m=/\\/g,x=/\u2028/,y=/\u2029/;t.tags={"#":1,"^":2,"<":3,$:4,"/":5,"!":6,">":7,"=":8,_v:9,"{":10,"&":11,_t:12},t.scan=function(i,r){function a(){m.length>0&&(x.push({tag:"_t",text:new String(m)}),m="")}function o(){for(var n=!0,e=k;e"==e.tag&&(e.indent=x[s].text.toString()),x.splice(s,1));else n||x.push({tag:"\n"});y=!1,k=x.length}function u(t,n){var s="="+S,i=t.indexOf(s,n),r=e(t.substring(t.indexOf("=",n)+1,i)).split(" ");return T=r[0],S=r[r.length-1],i+s.length-1}var c=i.length,p=0,b=1,f=2,d=p,v=null,g=null,m="",x=[],y=!1,w=0,k=0,T="{{",S="}}";for(r&&(r=r.split(" "),T=r[0],S=r[1]),w=0;c>w;w++)d==p?s(T,i,w)?(--w,a(),d=b):"\n"==i.charAt(w)?l(y):m+=i.charAt(w):d==b?(w+=T.length-1,g=t.tags[i.charAt(w+1)],v=g?i.charAt(w+1):"_v","="==v?(w=u(i,w),d=p):(g&&w++,d=f),y=w):s(S,i,w)?(x.push({tag:v,n:e(m),otag:T,ctag:S,i:"/"==v?y-T.length:w+S.length}),m="",w+=S.length-1,d=p,"{"==v&&("}}"==S?w++:n(x[x.length-1]))):m+=i.charAt(w);return l(y,!0),x};var w={_t:!0,"\n":!0,$:!0,"/":!0};t.stringify=function(n){return"{code: function (c,p,i) { "+t.wrapMain(n.code)+" },"+l(n)+"}"};var k=0;t.generate=function(n,e,s){k=0;var i={code:"",subs:{},partials:{}};return t.walk(n,i),s.asString?this.stringify(i,e,s):this.makeTemplate(i,e,s)},t.wrapMain=function(t){return'var t=this;t.b(i=i||"");'+t+"return t.fl();"},t.template=t.Template,t.makeTemplate=function(t,n,e){var s=this.makePartials(t);return s.code=new Function("c","p","i",this.wrapMain(t.code)),new this.template(s,n,this,e)},t.makePartials=function(t){var n,e={subs:{},partials:t.partials,name:t.name};for(n in e.partials)e.partials[n]=this.makePartials(e.partials[n]);for(n in t.subs)e.subs[n]=new Function("c","p","t","i",t.subs[n]);return e},t.codegen={"#":function(n,e){e.code+="if(t.s(t."+c(n.n)+'("'+u(n.n)+'",c,p,1),c,p,0,'+n.i+","+n.end+',"'+n.otag+" "+n.ctag+'")){t.rs(c,p,function(c,p,t){',t.walk(n.nodes,e),e.code+="});c.pop();}"},"^":function(n,e){e.code+="if(!t.s(t."+c(n.n)+'("'+u(n.n)+'",c,p,1),c,p,1,0,0,"")){',t.walk(n.nodes,e),e.code+="};"},">":p,"<":function(n,e){var s={partials:{},code:"",subs:{},inPartial:!0};t.walk(n.nodes,s);var i=e.partials[p(n,e)];i.subs=s.subs,i.partials=s.partials},$:function(n,e){var s={subs:{},code:"",partials:e.partials,prefix:n.n};t.walk(n.nodes,s),e.subs[n.n]=s.code,e.inPartial||(e.code+='t.sub("'+u(n.n)+'",c,p,i);')},"\n":function(t,n){n.code+=f('"\\n"'+(t.last?"":" + i"))},_v:function(t,n){n.code+="t.b(t.v(t."+c(t.n)+'("'+u(t.n)+'",c,p,0)));'},_t:function(t,n){n.code+=f('"'+u(t.text)+'"')},"{":b,"&":b},t.walk=function(n,e){for(var s,i=0,r=n.length;r>i;i++)s=t.codegen[n[i].tag],s&&s(n[i],e);return e},t.parse=function(t,n,e){return e=e||{},i(t,"",[],e.sectionTags||[])},t.cache={},t.cacheKey=function(t,n){return[t,!!n.asString,!!n.disableLambda,n.delimiters,!!n.modelGet].join("||")},t.compile=function(n,e){e=e||{};var s=t.cacheKey(n,e),i=this.cache[s];if(i){var r=i.partials;for(var a in r)delete r[a].instance;return i}return i=this.generate(this.parse(this.scan(n,e.delimiters),n,e),n,e),this.cache[s]=i}}("undefined"!=typeof exports?exports:Hogan);var Mustache=function(t){function n(n,e,s,i){var r=this.f(n,e,s,0),a=e;return r&&(a=a.concat(r)),t.Template.prototype.rp.call(this,n,a,s,i)}var e=function(e,s,i){this.rp=n,t.Template.call(this,e,s,i)};e.prototype=t.Template.prototype;var s,i=function(){this.cache={},this.generate=function(t,n){return new e(new Function("c","p","i",t),n,s)}};return i.prototype=t,s=new i,{to_html:function(t,n,e,i){var r=s.compile(t),a=r.render(n,e);return i?(i(a),void 0):a}}}(Hogan),templates={};templates.controls=new Hogan.Template({code:function(t,n,e){var s=this;return s.b(e=e||""),s.b('
'),s.b("\n"+e),s.b(' 0% played'),s.b("\n"),s.b("\n"+e),s.b('
'),s.b("\n"+e),s.b(' "),s.b("\n"+e),s.b(' "),s.b("\n"+e),s.b(' "),s.b("\n"+e),s.b(' "),s.b("\n"+e),s.b(' "),s.b("\n"+e),s.b('
'),s.b("\n"+e),s.b(' Time'),s.b("\n"+e),s.b(' 00:00'),s.b("\n"+e),s.b("
"),s.b("\n"+e),s.b("
"),s.b("\n"),s.b("\n"+e),s.b('
'),s.b("\n"+e),s.b(' '),s.b("\n"+e),s.b(' '),s.b("\n"+e),s.b(' "),s.b("\n"+e),s.b(" "),s.b("\n"),s.b("\n"+e),s.b(' '),s.b("\n"+e),s.b(' '),s.b("\n"),s.b("\n"+e),s.b(' '),s.b("\n"+e),s.b(' '),s.b("\n"+e),s.b(' "),s.b("\n"+e),s.b(" "),s.b("\n"+e),s.b("
"),s.b("\n"+e),s.b("
"),s.b("\n"),s.fl()},partials:{},subs:{}});var video=new InitPxVideo({videoId:"myvid",captionsOnDefault:!0,seekInterval:20,videoTitle:"PayPal Austin promo",debug:!0,html:templates.controls.render({})});console.log(video); \ No newline at end of file diff --git a/dist/js/simple-player.js b/dist/js/simple-player.js new file mode 100644 index 00000000..26c3968b --- /dev/null +++ b/dist/js/simple-player.js @@ -0,0 +1 @@ +function InitPxVideo(e){"use strict";function t(e){var t=[];return t=e.split(" --> "),o(t[0])}function n(e){var t=[];return t=e.split(" --> "),o(t[1])}function o(e){if(null===e||void 0===e)return 0;var t,n=[],o=[];return n=e.split(","),o=n[0].split(":"),t=Math.floor(60*o[0]*60)+Math.floor(60*o[1])+Math.floor(o[2])}function a(e){for(e.subcount=0;n(e.captions[e.subcount][0])e.captions.length-1){e.subcount=e.captions.length-1;break}}function i(e){e.isCaptionDefault&&(e.captionsContainer.className="px-video-captions show",e.captionsBtn.setAttribute("checked","checked"))}function s(){var e,t,n,o=navigator.userAgent,a=navigator.appName,i=""+parseFloat(navigator.appVersion),s=parseInt(navigator.appVersion,10);return-1!==navigator.appVersion.indexOf("Windows NT")&&-1!==navigator.appVersion.indexOf("rv:11")?(a="IE",i="11;"):-1!==(t=o.indexOf("MSIE"))?(a="IE",i=o.substring(t+5)):-1!==(t=o.indexOf("Chrome"))?(a="Chrome",i=o.substring(t+7)):-1!==(t=o.indexOf("Safari"))?(a="Safari",i=o.substring(t+7),-1!==(t=o.indexOf("Version"))&&(i=o.substring(t+8))):-1!==(t=o.indexOf("Firefox"))?(a="Firefox",i=o.substring(t+8)):(e=o.lastIndexOf(" ")+1)<(t=o.lastIndexOf("/"))&&(a=o.substring(e,t),i=o.substring(t+1),a.toLowerCase()==a.toUpperCase()&&(a=navigator.appName)),-1!==(n=i.indexOf(";"))&&(i=i.substring(0,n)),-1!==(n=i.indexOf(" "))&&(i=i.substring(0,n)),s=parseInt(""+i,10),isNaN(s)&&(i=""+parseFloat(navigator.appVersion),s=parseInt(navigator.appVersion,10)),[a,s]}String.prototype.replaceAll||Object.defineProperty(String.prototype,"replaceAll",{value:function(e,t){return this.replace(new RegExp(e.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),t)}});var r={};if(r.arBrowserInfo=s(),r.browserName=r.arBrowserInfo[0],r.browserMajorVersion=r.arBrowserInfo[1],"IE"===r.browserName&&(8===r.browserMajorVersion||9===r.browserMajorVersion))return!1;if(r.isSmartphoneOrTablet=/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent),r.isSmartphoneOrTablet)return!1;"undefined"==typeof e.debug&&(e.debug=!1),r.debug=e.debug,e.debug&&console.log(r.browserName+" "+r.browserMajorVersion),r.playAriaLabel="undefined"==typeof e.videoTitle||""===e.videoTitle?"Play":"Play video, "+e.videoTitle,r.container=document.getElementById(e.videoId),r.container.className=r.container.className+" stopped",r.movie=r.container.getElementsByTagName("video")[0],r.controls=r.container.getElementsByClassName("px-video-controls")[0],r.movie.removeAttribute("controls"),r.randomNum=Math.floor(1e4*Math.random()),e.debug&&console.log("Inserting custom video controls"),r.controls.innerHTML=e.html.replaceAll("{aria-label}",r.playAriaLabel).replaceAll("{id}",r.randomNum),r.labelMute=document.getElementById("labelMute"+r.randomNum),r.labelMuteOffset=r.movieWidth-390,r.labelMuteOffset<0&&(r.labelMuteOffset=0),r.labelMute.setAttribute("style","margin-left:"+r.labelMuteOffset+"px");for(var c,l="",d=r.movie.childNodes,p=0;pe?0:e,r.isTextTracks||a(r)},!1),r.btnForward.addEventListener("click",function(){var e=r.movie.currentTime+r.seekInterval;r.movie.currentTime=e>r.movie.duration?r.movie.duration:e,r.isTextTracks||a(r)},!1),r.btnVolume.addEventListener("change",function(){r.movie.volume=parseFloat(this.value/10)},!1),r.btnMute.addEventListener("click",function(){r.movie.muted=r.movie.muted===!0?!1:!0},!1),r.movie.addEventListener("timeupdate",function(){r.secs=parseInt(r.movie.currentTime%60),r.mins=parseInt(r.movie.currentTime/60%60),r.secs=("0"+r.secs).slice(-2),r.mins=("0"+r.mins).slice(-2),r.duration.innerHTML=r.mins+":"+r.secs},!1),r.movie.addEventListener("timeupdate",function(){r.percent=100/r.movie.duration*r.movie.currentTime,r.percent>0&&(r.progressBar.value=r.percent,r.progressBarSpan.innerHTML=r.percent)},!1),r.progressBar.addEventListener("click",function(e){r.pos=(e.pageX-this.offsetLeft)/this.offsetWidth,r.movie.currentTime=r.pos*r.movie.duration,r.isTextTracks||a(r)}),r.movie.addEventListener("ended",function(){r.captionsContainer.innerHTML=""}),r.captionsBtn.addEventListener("click",function(){r.captionsContainer.className=this.checked?"px-video-captions show":"px-video-captions hide"},!1),r.captionExists){if("IE"===r.browserName&&10===r.browserMajorVersion||"IE"===r.browserName&&11===r.browserMajorVersion||"Firefox"===r.browserName&&r.browserMajorVersion>=31||"Safari"===r.browserName&&r.browserMajorVersion>=7){e.debug&&console.log("Detected IE 10/11 or Firefox 31+ or Safari 7+"),r.isTextTracks=!1;for(var u={},m=r.movie.textTracks,v=0;vt(r.captions[r.subcount][0])&&r.movie.currentTime.toFixed(1)n(r.captions[r.subcount][0])&&r.subcount");t.b("\n" + i);t.b(" 0% played");t.b("\n");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" Time");t.b("\n" + i);t.b(" 00:00");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b(" ");t.b("\n" + i);t.b("
");t.b("\n" + i);t.b("
");t.b("\n");return t.fl(); },partials: {}, subs: { }}); \ No newline at end of file diff --git a/dist/svg/sprite.svg b/dist/svg/sprite.svg new file mode 100644 index 00000000..b6a35931 --- /dev/null +++ b/dist/svg/sprite.svg @@ -0,0 +1 @@ +collapseexpandpauserewind \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..1afbd70a --- /dev/null +++ b/docs/index.html @@ -0,0 +1,52 @@ + + + + + Simple HTML5 Video Player + + + + + + + + + +
+

HTML5 Media Player

+

A simple HTML5 media player

+
+ +
+
+
+ +
+ +
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 00000000..600b384b --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,139 @@ +// ========================================================================== +// Gulp build script +// ========================================================================== +/*global require, __dirname*/ + +var fs = require("fs"), + path = require("path"), + gulp = require("gulp"), + gutil = require("gulp-util"), + concat = require("gulp-concat"), + uglify = require("gulp-uglify"), + less = require("gulp-less"), + minifyCss = require("gulp-minify-css"), + runSequence = require("run-sequence"), + prefix = require("gulp-autoprefixer"), + svgstore = require("gulp-svgstore"), + svgmin = require("gulp-svgmin"), + hogan = require("gulp-hogan-compile"); + +var projectPath = __dirname; +var paths = { + project: projectPath, + + // Watch paths + watchless: path.join(projectPath, "assets/less/**/*"), + watchjs: path.join(projectPath, "assets/js/**/*"), + watchicons: path.join(projectPath, "assets/icons/**/*"), + watchtemplates: path.join(projectPath, "assets/templates/**/*"), + + // SVG Icons + svg: path.join(projectPath, "assets/icons/*.svg"), + + // Output paths + js: path.join(projectPath, "dist/js/"), + css: path.join(projectPath, "dist/css/"), + icons: path.join(projectPath, "dist/svg/") +}, + +// Task names +taskNames = { + jsAll: "js-all", + lessBuild: "less-", + jsBuild: "js-", + iconBuild: "icon-build", + templates: "templates" +}, +// Task arrays +lessBuildTasks = [], +jsBuildTasks = [], + +// Fetch bundles from JSON +bundles = loadJSON(path.join(paths.project, "bundles.json")); + +// Load json +function loadJSON(path) { + return JSON.parse(fs.readFileSync(path)); +} + +// Build templates +gulp.task(taskNames.templates, function () { + return gulp + .src(paths.watchtemplates) + .pipe(hogan("templates.js", { + wrapper: false, + templateName: function (file) { + return path.basename(file.relative.replace(/\\/g, "-"), path.extname(file.relative)); + } + })) + .pipe(gulp.dest(paths.js)); +}); + +// Process JS +for (var key in bundles.js) { + (function(key) { + var taskName = taskNames.jsBuild + key; + jsBuildTasks.push(taskName); + + gulp.task(taskName, function () { + return gulp + .src(bundles.js[key]) + .pipe(concat(key)) + .pipe(uglify()) + .pipe(gulp.dest(paths.js)); + }); + })(key); +} + +// Process CSS +for (var key in bundles.less) { + (function (key) { + var taskName = taskNames.lessBuild + key; + lessBuildTasks.push(taskName); + + gulp.task(taskName, function () { + return gulp + .src(bundles.less[key]) + .pipe(less()) + .on("error", gutil.log) + .pipe(concat(key)) + .pipe(prefix(["last 2 versions", "> 1%", "ie 9"], { cascade: true })) + .pipe(minifyCss()) + .pipe(gulp.dest(paths.css)); + }); + })(key); +} + +// Process Icons +gulp.task(taskNames.iconBuild, function () { + return gulp + .src(paths.svg) + .pipe(svgmin({ + plugins: [{ + removeDesc: true + }] + })) + .pipe(svgstore({ + prefix: "icon-", + fileName: "sprite.svg" + })) + .pipe(gulp.dest(paths.icons)); +}); + +// Default gulp task +gulp.task("default", function(){ + runSequence(taskNames.jsAll, lessBuildTasks.concat(taskNames.iconBuild, "watch")); +}); + +// Build all JS (inc. templates) +gulp.task(taskNames.jsAll, function(){ + runSequence(taskNames.templates, jsBuildTasks); +}); + +// Watch for file changes +gulp.task("watch", function () { + gulp.watch(paths.watchtemplates, taskNames.jsAll); + gulp.watch(paths.watchjs, taskNames.jsAll); + gulp.watch(paths.watchless, lessBuildTasks); + gulp.watch(paths.watchicons, taskNames.iconBuild); +}); \ No newline at end of file diff --git a/media/captions_PayPal_Austin_en.vtt.txt b/media/captions_PayPal_Austin_en.vtt.txt new file mode 100644 index 00000000..284f1cd9 --- /dev/null +++ b/media/captions_PayPal_Austin_en.vtt.txt @@ -0,0 +1,145 @@ +WEBVTT + +00:00:00.000 --> 00:00:00.500 + + +00:00:00.501 --> 00:00:06.000 +[ music ] + +00:00:06.001 --> 00:00:09.500 +Austin is an absolutely thriving place + +00:00:09.501 --> 00:00:12.000 +for small business. And for locally owned businesses. + +00:00:12.001 --> 00:00:15.000 +We have more locally owned businesses per capita + +00:00:15.001 --> 00:00:17.500 +than any other city our size in the nation. + +00:00:17.501 --> 00:00:19.000 +I'm Marsha Lane, the owner of + +00:00:19.001 --> 00:00:22.000 +Ragalicious and Flashback in Austin, Texas. + +00:00:22.001 --> 00:00:23.000 +Everybody in Austin it seems like + +00:00:23.001 --> 00:00:25.000 +is a potential entrepreneur. + +00:00:25.001 --> 00:00:27.000 +I moved here in 1982. I thought I had a job. + +00:00:27.001 --> 00:00:31.500 +It fell through, so I started my own business then. + +00:00:31.501 --> 00:00:34.500 + + +00:00:34.501 --> 00:00:38.500 +Well Tom made a cash box out of a shoe box. + +00:00:38.501 --> 00:00:40.500 +I didn't want to throw the money in a drawer. + +00:00:41.501 --> 00:00:44.500 +But I just cut a shoebox and made it dividers + +00:00:44.501 --> 00:00:48.000 +and put in the cash and the change. [laughs] + +00:00:48.001 --> 00:00:51.500 + + +00:00:51.501 --> 00:00:54.000 +Today we installed PayPal Here. + +00:00:54.001 --> 00:00:57.000 +And we're really looking forward to using it in the future. + +00:00:57.001 --> 00:01:01.000 +[music] + +00:01:01.001 --> 00:01:03.000 +One of the things that excites me the most + +00:01:03.001 --> 00:01:05.500 +is that PayPal didn't come in and say, + +00:01:05.501 --> 00:01:07.000 +"Here's what we want you to buy." + +00:01:07.001 --> 00:01:08.500 +They've come in to say, + +00:01:08.501 --> 00:01:10.000 +"How can we help you?" + +00:01:10.001 --> 00:01:13.500 +"How can we be a partner to you as a local business?" + +00:01:13.501 --> 00:01:16.500 +[music] + +00:01:16.501 --> 00:01:18.500 +I'm really pleased to be one of the first people in Austin + +00:01:18.501 --> 00:01:21.000 +using the new cash for registers program + +00:01:21.001 --> 00:01:24.000 +and especially because we get free processing + +00:01:24.001 --> 00:01:27.000 +for 6 whole months and that is huge. + +00:01:27.001 --> 00:01:29.000 +I used PayPal Here for the first time this morning + +00:01:29.001 --> 00:01:33.000 +and I really like that it's really user friendly, self-explanatory + +00:01:33.001 --> 00:01:35.000 +I think customers will appreciate that + +00:01:35.001 --> 00:01:39.000 +it won't take me as long to add up their total. + +00:01:39.001 --> 00:01:43.000 +You just put in the amount; it figures the sales tax for you + +00:01:43.001 --> 00:01:46.000 +and everything goes into the bank account daily. + +00:01:46.001 --> 00:01:49.000 +One of the important things for a local business + +00:01:49.001 --> 00:01:51.000 +is to get as many customers as they can and + +00:01:51.001 --> 00:01:54.000 +make it easy for those customers to come do business with them. + +00:01:54.001 --> 00:01:59.000 +Being able to use PayPal in a retail situation like that + +00:01:59.001 --> 00:02:02.000 +just gives them one more option. + +00:02:02.001 --> 00:02:05.000 +Everything's very exciting; I'm really looking forward to it. + +00:02:05.001 --> 00:02:09.000 +I so appreciate especially the support PayPal is giving us. + +00:02:09.001 --> 00:02:12.000 +I would definitely recommend PayPal to other small businesses. + +00:02:12.001 --> 00:02:16.000 +Thanks to PayPal I found a better use for my shoe box. + +00:02:16.001 --> 00:02:30.000 +[music] diff --git a/media/poster_PayPal_Austin2.jpg b/media/poster_PayPal_Austin2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..21131a1c59df40c657b4351e1de1b90bafdaf592 GIT binary patch literal 39528 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 literal 0 HcmV?d00001 diff --git a/package.json b/package.json new file mode 100644 index 00000000..5c44f95a --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "name": "simple-media", + "version": "1.0.0", + "description": "A simple HTML5 media player using custom controls", + "main": "gulpfile.js", + "dependencies": {}, + "devDependencies": { + "gulp": "~3.8.6", + "gulp-autoprefixer": "^0.0.8", + "gulp-concat": "~2.3.3", + "gulp-hogan-compile": "^0.4.1", + "gulp-less": "~1.3.1", + "gulp-minify-css": "~0.3.6", + "gulp-svgmin": "^1.0.0", + "gulp-svgstore": "^4.0.1", + "gulp-uglify": "~0.3.1", + "gulp-util": "~2.2.20", + "run-sequence": "^0.3.6" + }, + "scripts": { + "preinstall": "npm install -g gulp" + }, + "keywords": [ + "HTML5 Video", + "HTML5 Audio", + "Media Player" + ], + "repository": { + "type": "git", + "url": "git://github.com/sampotts/simple-media.git" + }, + "authors": [ + "Sam Potts " + ], + "license": "MIT" +} diff --git a/readme.md b/readme.md new file mode 100644 index 00000000..f6b9b5ea --- /dev/null +++ b/readme.md @@ -0,0 +1,12 @@ +# Useful links + +- [http://www.w3.org/2010/05/video/mediaevents.html](http://www.w3.org/2010/05/video/mediaevents.html) +- [http://www.osmf.org/strobe_mediaplayback.html](http://www.osmf.org/strobe_mediaplayback.html) +- [http://osmf.org/dev/2.0gm/](http://osmf.org/dev/2.0gm/) +- [http://stackoverflow.com/questions/4763042/html5-video-fallback-to-flash-if-no-ogv-file](http://stackoverflow.com/questions/4763042/html5-video-fallback-to-flash-if-no-ogv-file) +- [http://css-tricks.com/snippets/html/video-for-everybody-html5-video-with-flash-fallback/](http://css-tricks.com/snippets/html/video-for-everybody-html5-video-with-flash-fallback/) +- [http://stackoverflow.com/questions/21552914/flash-fallback-in-html5-video-tag-does-not-work-in-opera](http://stackoverflow.com/questions/21552914/flash-fallback-in-html5-video-tag-does-not-work-in-opera) +- [http://osmf.org/configurator/fmp/#](http://osmf.org/configurator/fmp/#) +- [http://stackoverflow.com/questions/5138077/html5-video-file-loading-complete-event](http://stackoverflow.com/questions/5138077/html5-video-file-loading-complete-event) +- [http://www.sitepoint.com/essential-audio-and-video-events-for-html5/](http://www.sitepoint.com/essential-audio-and-video-events-for-html5/) +- [http://dev.opera.com/articles/view/simple-html5-video-flash-fallback-custom-controls/](http://dev.opera.com/articles/view/simple-html5-video-flash-fallback-custom-controls/) \ No newline at end of file