diff --git a/static/js.cookie.js b/static/js.cookie.js new file mode 100644 index 0000000000000000000000000000000000000000..12fa0eebf46b07d7c79926b67af75ccdd381d30e --- /dev/null +++ b/static/js.cookie.js @@ -0,0 +1,156 @@ +/*! + * JavaScript Cookie v2.1.3 + * https://github.com/js-cookie/js-cookie + * + * Copyright 2006, 2015 Klaus Hartl & Fagner Brack + * Released under the MIT license + */ +;(function (factory) { + var registeredInModuleLoader = false; + if (typeof define === 'function' && define.amd) { + define(factory); + registeredInModuleLoader = true; + } + if (typeof exports === 'object') { + module.exports = factory(); + registeredInModuleLoader = true; + } + if (!registeredInModuleLoader) { + var OldCookies = window.Cookies; + var api = window.Cookies = factory(); + api.noConflict = function () { + window.Cookies = OldCookies; + return api; + }; + } +}(function () { + function extend () { + var i = 0; + var result = {}; + for (; i < arguments.length; i++) { + var attributes = arguments[ i ]; + for (var key in attributes) { + result[key] = attributes[key]; + } + } + return result; + } + + function init (converter) { + function api (key, value, attributes) { + var result; + if (typeof document === 'undefined') { + return; + } + + // Write + + if (arguments.length > 1) { + attributes = extend({ + path: '/' + }, api.defaults, attributes); + + if (typeof attributes.expires === 'number') { + var expires = new Date(); + expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); + attributes.expires = expires; + } + + try { + result = JSON.stringify(value); + if (/^[\{\[]/.test(result)) { + value = result; + } + } catch (e) {} + + if (!converter.write) { + value = encodeURIComponent(String(value)) + .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); + } else { + value = converter.write(value, key); + } + + key = encodeURIComponent(String(key)); + key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); + key = key.replace(/[\(\)]/g, escape); + + return (document.cookie = [ + key, '=', value, + attributes.expires ? '; expires=' + attributes.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE + attributes.path ? '; path=' + attributes.path : '', + attributes.domain ? '; domain=' + attributes.domain : '', + attributes.secure ? '; secure' : '' + ].join('')); + } + + // Read + + if (!key) { + result = {}; + } + + // To prevent the for loop in the first place assign an empty array + // in case there are no cookies at all. Also prevents odd result when + // calling "get()" + var cookies = document.cookie ? document.cookie.split('; ') : []; + var rdecode = /(%[0-9A-Z]{2})+/g; + var i = 0; + + for (; i < cookies.length; i++) { + var parts = cookies[i].split('='); + var cookie = parts.slice(1).join('='); + + if (cookie.charAt(0) === '"') { + cookie = cookie.slice(1, -1); + } + + try { + var name = parts[0].replace(rdecode, decodeURIComponent); + cookie = converter.read ? + converter.read(cookie, name) : converter(cookie, name) || + cookie.replace(rdecode, decodeURIComponent); + + if (this.json) { + try { + cookie = JSON.parse(cookie); + } catch (e) {} + } + + if (key === name) { + result = cookie; + break; + } + + if (!key) { + result[name] = cookie; + } + } catch (e) {} + } + + return result; + } + + api.set = api; + api.get = function (key) { + return api.call(api, key); + }; + api.getJSON = function () { + return api.apply({ + json: true + }, [].slice.call(arguments)); + }; + api.defaults = {}; + + api.remove = function (key, attributes) { + api(key, '', extend(attributes, { + expires: -1 + })); + }; + + api.withConverter = init; + + return api; + } + + return init(function () {}); +})); diff --git a/templates/base.html b/templates/base.html index 0b5d4caae7ea805bafabd07e5fe24413b580f39d..079d5cff5fad096052542bbf37f38665cd30bf41 100644 --- a/templates/base.html +++ b/templates/base.html @@ -8,16 +8,19 @@ <head> <title>Video AG</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <script src="{{url_for('static', filename='jquery.js')}}"></script> - <link rel="stylesheet" type="text/css" href="{{url_for('static', filename='style.css')}}"> - <link rel="stylesheet" href="{{url_for('static', filename='font-awesome/css/font-awesome.min.css')}}"> <link rel="icon" type="image/png" href="{{url_for('static', filename='favicon.png')}}"> <meta http-equiv="content-language" content="de-DE"> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> + <link href="{{url_for('static', filename='bootstrap/bootstrap.css')}}" rel="stylesheet"> + <link rel="stylesheet" type="text/css" href="{{url_for('static', filename='style.css')}}"> + <link rel="stylesheet" href="{{url_for('static', filename='font-awesome/css/font-awesome.min.css')}}"> + + <script src="{{url_for('static', filename='jquery.js')}}"></script> <script src="{{url_for('static', filename='bootstrap/bootstrap.js')}}"></script> + <script src="{{url_for('static', filename='js.cookie.js')}}"></script> {%if ismod() %}<script src="{{url_for('static', filename='moderator.js')}}"></script>{% endif %} </head> <body> @@ -105,8 +108,10 @@ {% for msg in get_flashed_messages() %} <div class="alert alert-danger" role="alert">{{ msg }}</div> {% endfor %} - {% for msg in get_announcements(min_announcement_level) %} + {% for msg in get_announcements(min_announcement_level) if (not request.cookies['alert-info-'+msg.id|string]) or ismod() %} <div class="alert alert-{{announcement_levels.get(msg.level, 'info')}}" role="alert"> + <a href="#" class="close" data-dismiss="alert" aria-label="close" onclick="Cookies.set('alert-info-{{msg.id}}', '1');">×</a> + {{ valueeditor(('announcements',msg.id,'text'), msg.text|safe) }} {% if ismod() %} <div class="pull-right"> diff --git a/templates/lecture.html b/templates/lecture.html index 2f6ae671c3ce9ecb604cbb002d3d434c9a0d71ee..8c10cea3938669e9094248ef580cb99b44043028 100644 --- a/templates/lecture.html +++ b/templates/lecture.html @@ -7,7 +7,7 @@ {% block content %} <div class="panel panel-default"> <div class="panel-heading"> - <h1 class="panel-title"><strong>{{ course.title }}</strong>: {{ lecture.title}}</h1> + <h1 class="panel-title"><strong><a href="{{url_for('course', handle=course.handle)}}#lecture-{{lecture.id}}">{{ course.title }}</strong></a>: {{ lecture.title}}</h1> </div> <div class="panel-body"> <div class="row" style="padding: 0px;"> diff --git a/templates/macros.html b/templates/macros.html index f41dcb06f7a3c4c9e254eae809e6eb13dc6daddb..6e1b722e8e154c9b9bfc7c5113773e77233fdced 100644 --- a/templates/macros.html +++ b/templates/macros.html @@ -2,7 +2,7 @@ <li class="list-group-item"> <a class="hidden-xs" href="{{url_for('lecture', id=lecture['id'])}}" title="{{ lecture['coursetitle'] }}" style="color: #000"> <div class="row"> - <img class="col-xs-4" style="max-height: 100px; width: auto;" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'"> + <img class="col-xs-4" style="max-height: 100px; width: auto;" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'; this.onerror=''; "> <div class="col-xs-4"> <span><strong>{{ lecture['short'] }}</strong></span><br> <span>{{ lecture['time'] }}</span> @@ -19,7 +19,7 @@ <a class="visible-xs" href="{{url_for('lecture', id=lecture['id'])}}" title="{{ lecture['coursetitle'] }}" style="color: #000"> <ul class="list-unstyled"> <li> - <img style="width: 100%;" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'"> + <img style="width: 100%;" src="{{ config.VIDEOPREFIX }}/{{ lecture['titlefile'] }}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'; this.onerror=''; "> </li> <li> <strong>{{ lecture['short'] }}</strong> {{ lecture['time'] }} @@ -65,7 +65,6 @@ {% macro course_list_item(course,show_semester=False) %} <li class="list-group-item list-group-item-condensed {% if (not course.visible) or (not course.listed) %}list-group-item-danger{% endif %}"> <div class="row"> - <a href="{{url_for('course', handle=course.handle)}}"> {% if show_semester %} <span class="col-xs-2 col-md-1"> {{ course.semester }} @@ -74,7 +73,9 @@ {% else %} <span class="col-xs-12 col-md-7"> {% endif %} + <a href="{{url_for('course', handle=course.handle)}}"> {{ course.title }} + </a> </span> <span class="col-xs-8 col-md-3"> {{ course.organizer }} @@ -82,7 +83,6 @@ <span class="col-xs-4 col-md-2"> {{ course.subject }} </span> - </a> </div> </li> {% endmacro %} @@ -124,7 +124,7 @@ $('#embedcodebtn').popover( {% macro lecture_list_item(lecture,videos) %} <li class="list-group-item" id="lecture-{{lecture.id}}"> <div class="row"> - <img class="col-sm-2 col-xs-12"src="{{ config.VIDEOPREFIX }}/{{lecture.titlefile}}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'"> + <img class="col-sm-2 col-xs-12"src="{{ config.VIDEOPREFIX }}/{{lecture.titlefile}}" alt="Vorschaubild" onerror="this.src='{{url_for('static',filename='no-thumbnail.png')}}'; this.onerror=''; "> <span class="col-sm-3 col-xs-12"> <ul class="list-unstyled"> <li>{{ valueeditor(['lectures',lecture.id,'title'], lecture.title) }}</li>