From 731f5c491c911ca7a81f7ea44164adc19fb396f7 Mon Sep 17 00:00:00 2001 From: Oliver Schneider <oli@student.ethz.ch> Date: Fri, 15 Apr 2016 16:36:01 +0200 Subject: [PATCH] salvattore! --- public/css/cards.css | 3 +- public/css/dynamic.css | 21 ++ public/index.html | 13 +- public/js/main.js | 536 ++++++++++++++++++++++++++++ public/js/salvattore.min.js | 603 ++++++++++++++++++++++++++++++++ public/res/AMIV_Logo_150_50.svg | 35 ++ 6 files changed, 1202 insertions(+), 9 deletions(-) create mode 100644 public/css/dynamic.css create mode 100644 public/js/main.js create mode 100644 public/js/salvattore.min.js create mode 100644 public/res/AMIV_Logo_150_50.svg diff --git a/public/css/cards.css b/public/css/cards.css index a8f9fdd..0c71858 100644 --- a/public/css/cards.css +++ b/public/css/cards.css @@ -8,7 +8,8 @@ border-radius: 2px; background-clip: padding-box; } -.card span.card-title { + +#cardtitle.card span.card-title { color: #E8452B; font-size: 24px; font-weight: 300; diff --git a/public/css/dynamic.css b/public/css/dynamic.css new file mode 100644 index 0000000..59ae92e --- /dev/null +++ b/public/css/dynamic.css @@ -0,0 +1,21 @@ + @media screen and (min-width: 1px) and (max-width: 480px){ + #columns[data-columns]::before { + content: '1 .col-xs-12'; + } + } + + @media screen and (min-width: 481px) and (max-width: 767px){ + #columns[data-columns]::before { + content: '2 .col-xs-6'; + } + } + @media screen and (min-width:768px) and (max-width: 991px){ + #columns[data-columns]::before { + content: '3 .col-sm-4'; + } + } + @media screen and (min-width:992px) and (max-width: 9999px){ + #columns[data-columns]::before { + content: '4 .col-md-3'; + } + } \ No newline at end of file diff --git a/public/index.html b/public/index.html index 1470259..c69a39d 100644 --- a/public/index.html +++ b/public/index.html @@ -9,6 +9,7 @@ <link href="bs/css/bootstrap.min.css" rel="stylesheet"> <link href="css/logo-nav.css" rel="stylesheet"> <link href="css/cards.css" rel="stylesheet"> + <link href="css/dynamic.css" rel="stylesheet"> </head> @@ -26,7 +27,7 @@ <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#"> - <img src="https://www.amiv.ethz.ch/sites/all/themes/amiv15/logo.png" alt="AMIV" height="80%"> + <img src="file:///Volumes/Macintosh%20HD/Users/oli/Documents/ETH/amivwebsitefrontend/public/res/AMIV_Logo_150_50.svg" alt="AMIV" height="80%"> </a> </div> <!-- Collect the nav links, forms, and other content for toggling --> @@ -61,12 +62,9 @@ </nav> <!-- Page Content --> + <div class="container-fluid"> <div class="row"> - <div class="col-lg-12"> - <h1>Fluid Containers full of Events floating around</h1> - <p>Note: AMIV is awesome</p> - <!-- A Card --> <div class="col-xs-12 col-md-4 col-lg-3"> <div class="card"> @@ -76,7 +74,7 @@ </div> <div class="card-content"> - <p>This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself. </p> + <p>This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself. This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself.This is the best event like ever! You can bake some jarcakes and eat the afterwards all by yourself. </p> </div> <div class="card-action"> @@ -273,13 +271,12 @@ </script> </div> </div> - - </div> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <script src="bs/js/bootstrap.min.js"></script> + <script src="js/salvattore.js"></script> </body> diff --git a/public/js/main.js b/public/js/main.js new file mode 100644 index 0000000..d8af2b5 --- /dev/null +++ b/public/js/main.js @@ -0,0 +1,536 @@ +(function(root, factory) { + if(typeof exports === 'object') { + module.exports = factory(); + } + else if(typeof define === 'function' && define.amd) { + define('salvattore', [], factory); + } + else { + root.salvattore = factory(); + } +}(this, function() { +/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */ + +window.matchMedia || (window.matchMedia = function() { + "use strict"; + + // For browsers that support matchMedium api such as IE 9 and webkit + var styleMedia = (window.styleMedia || window.media); + + // For those that don't support matchMedium + if (!styleMedia) { + var style = document.createElement('style'), + script = document.getElementsByTagName('script')[0], + info = null; + + style.type = 'text/css'; + style.id = 'matchmediajs-test'; + + script.parentNode.insertBefore(style, script); + + // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers + info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; + + styleMedia = { + matchMedium: function(media) { + var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; + + // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers + if (style.styleSheet) { + style.styleSheet.cssText = text; + } else { + style.textContent = text; + } + + // Test if media query is true or false + return info.width === '1px'; + } + }; + } + + return function(media) { + return { + matches: styleMedia.matchMedium(media || 'all'), + media: media || 'all' + }; + }; +}()); +;/*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */ +(function(){ + // Bail out for browsers that have addListener support + if (window.matchMedia && window.matchMedia('all').addListener) { + return false; + } + + var localMatchMedia = window.matchMedia, + hasMediaQueries = localMatchMedia('only all').matches, + isListening = false, + timeoutID = 0, // setTimeout for debouncing 'handleChange' + queries = [], // Contains each 'mql' and associated 'listeners' if 'addListener' is used + handleChange = function(evt) { + // Debounce + clearTimeout(timeoutID); + + timeoutID = setTimeout(function() { + for (var i = 0, il = queries.length; i < il; i++) { + var mql = queries[i].mql, + listeners = queries[i].listeners || [], + matches = localMatchMedia(mql.media).matches; + // Update mql.matches value and call listeners + // Fire listeners only if transitioning to or from matched state + if (matches !== mql.matches) { + mql.matches = matches; + + for (var j = 0, jl = listeners.length; j < jl; j++) { + listeners[j].call(window, mql); + } + } + } + }, 30); + }; + + window.matchMedia = function(media) { + var mql = localMatchMedia(media), + listeners = [], + index = 0; + + mql.addListener = function(listener) { + // Changes would not occur to css media type so return now (Affects IE <= 8) + if (!hasMediaQueries) { + return; + } + + // Set up 'resize' listener for browsers that support CSS3 media queries (Not for IE <= 8) + // There should only ever be 1 resize listener running for performance + if (!isListening) { + isListening = true; + window.addEventListener('resize', handleChange, true); + } + + // Push object only if it has not been pushed already + if (index === 0) { + index = queries.push({ + mql : mql, + listeners : listeners + }); + } + + listeners.push(listener); + }; + + mql.removeListener = function(listener) { + for (var i = 0, il = listeners.length; i < il; i++){ + if (listeners[i] === listener){ + listeners.splice(i, 1); + } + } + }; + + return mql; + }; +}()); +;// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + +// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel + +// MIT license + +(function() { + var lastTime = 0; + var vendors = ['ms', 'moz', 'webkit', 'o']; + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] + || window[vendors[x]+'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) + window.requestAnimationFrame = function(callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function() { callback(currTime + timeToCall); }, + timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + + if (!window.cancelAnimationFrame) + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; +}()); +;var salvattore = (function (global, document, undefined) { +"use strict"; + +var self = {}, + grids = [], + add_to_dataset = function(element, key, value) { + // uses dataset function or a fallback for <ie10 + if (element.dataset) { + element.dataset[key] = value; + } else { + element.setAttribute("data-" + key, value); + } + return; + }; + +self.obtain_grid_settings = function obtain_grid_settings(element) { + // returns the number of columns and the classes a column should have, + // from computing the style of the ::before pseudo-element of the grid. + + var computedStyle = global.getComputedStyle(element, ":before") + , content = computedStyle.getPropertyValue("content").slice(1, -1) + , matchResult = content.match(/^\s*(\d+)(?:\s?\.(.+))?\s*$/) + , numberOfColumns + , columnClasses + ; + + if (matchResult) { + numberOfColumns = matchResult[1]; + columnClasses = matchResult[2]; + columnClasses = columnClasses? columnClasses.split(".") : ["column"]; + } else { + matchResult = content.match(/^\s*\.(.+)\s+(\d+)\s*$/); + columnClasses = matchResult[1]; + numberOfColumns = matchResult[2]; + if (numberOfColumns) { + numberOfColumns = numberOfColumns.split("."); + } + } + + return { + numberOfColumns: numberOfColumns, + columnClasses: columnClasses + }; +}; + + +self.add_columns = function add_columns(grid, items) { + // from the settings obtained, it creates columns with + // the configured classes and adds to them a list of items. + + var settings = self.obtain_grid_settings(grid) + , numberOfColumns = settings.numberOfColumns + , columnClasses = settings.columnClasses + , columnsItems = new Array(+numberOfColumns) + , columnsFragment = document.createDocumentFragment() + , i = numberOfColumns + , selector + ; + + while (i-- !== 0) { + selector = "[data-columns] > *:nth-child(" + numberOfColumns + "n-" + i + ")"; + columnsItems.push(items.querySelectorAll(selector)); + } + + columnsItems.forEach(function append_to_grid_fragment(rows) { + var column = document.createElement("div") + , rowsFragment = document.createDocumentFragment() + ; + + column.className = columnClasses.join(" "); + + Array.prototype.forEach.call(rows, function append_to_column(row) { + rowsFragment.appendChild(row); + }); + column.appendChild(rowsFragment); + columnsFragment.appendChild(column); + }); + + grid.appendChild(columnsFragment); + add_to_dataset(grid, 'columns', numberOfColumns); +}; + + +self.remove_columns = function remove_columns(grid) { + // removes all the columns from a grid, and returns a list + // of items sorted by the ordering of columns. + + var range = document.createRange(); + range.selectNodeContents(grid); + + var columns = Array.prototype.filter.call(range.extractContents().childNodes, function filter_elements(node) { + return node instanceof global.HTMLElement; + }); + + var numberOfColumns = columns.length + , numberOfRowsInFirstColumn = columns[0].childNodes.length + , sortedRows = new Array(numberOfRowsInFirstColumn * numberOfColumns) + ; + + Array.prototype.forEach.call(columns, function iterate_columns(column, columnIndex) { + Array.prototype.forEach.call(column.children, function iterate_rows(row, rowIndex) { + sortedRows[rowIndex * numberOfColumns + columnIndex] = row; + }); + }); + + var container = document.createElement("div"); + add_to_dataset(container, 'columns', 0); + + sortedRows.filter(function filter_non_null(child) { + return !!child; + }).forEach(function append_row(child) { + container.appendChild(child); + }); + + return container; +}; + + +self.recreate_columns = function recreate_columns(grid) { + // removes all the columns from the grid, and adds them again, + // it is used when the number of columns change. + + global.requestAnimationFrame(function render_after_css_media_query_change() { + self.add_columns(grid, self.remove_columns(grid)); + }); +}; + + +self.media_query_change = function media_query_change(mql) { + // recreates the columns when a media query matches the current state + // of the browser. + + if (mql.matches) { + Array.prototype.forEach.call(grids, self.recreate_columns); + } +}; + + +self.get_css_rules = function get_css_rules(stylesheet) { + // returns a list of css rules from a stylesheet + + var cssRules; + try { + cssRules = stylesheet.sheet.cssRules || stylesheet.sheet.rules; + } catch (e) { + return []; + } + + return cssRules || []; +}; + + +self.get_stylesheets = function get_stylesheets() { + // returns a list of all the styles in the document (that are accessible). + + return Array.prototype.concat.call( + Array.prototype.slice.call(document.querySelectorAll("style[type='text/css']")), + Array.prototype.slice.call(document.querySelectorAll("link[rel='stylesheet']")) + ); +}; + + +self.media_rule_has_columns_selector = function media_rule_has_columns_selector(rules) { + // checks if a media query css rule has in its contents a selector that + // styles the grid. + + var i = rules.length + , rule + ; + + while (i--) { + rule = rules[i]; + if (rule.selectorText && rule.selectorText.match(/\[data-columns\](.*)::?before$/)) { + return true; + } + } + + return false; +}; + + +self.scan_media_queries = function scan_media_queries() { + // scans all the stylesheets for selectors that style grids, + // if the matchMedia API is supported. + + + var mediaQueries = []; + + if (!global.matchMedia) { + return; + } + + self.get_stylesheets().forEach(function extract_rules(stylesheet) { + Array.prototype.forEach.call(self.get_css_rules(stylesheet), function filter_by_column_selector(rule) { + if (rule.media && self.media_rule_has_columns_selector(rule.cssRules)) { + mediaQueries.push(global.matchMedia(rule.media.mediaText)); + } + }); + }); + + mediaQueries.forEach(function listen_to_changes(mql) { + mql.addListener(self.media_query_change); + }); +}; + + +self.next_element_column_index = function next_element_column_index(grid, fragments) { + // returns the index of the column where the given element must be added. + + var children = grid.children + , m = children.length + , lowestRowCount = 0 + , child + , currentRowCount + , i + , index = 0 + ; + for (i = 0; i < m; i++) { + child = children[i]; + currentRowCount = child.children.length + fragments[i].children.length; + if(lowestRowCount === 0) { + lowestRowCount = currentRowCount; + } + if(currentRowCount < lowestRowCount) { + index = i; + lowestRowCount = currentRowCount; + } + } + + return index; +}; + + +self.create_list_of_fragments = function create_list_of_fragments(quantity) { + // returns a list of fragments + + + var fragments = new Array(quantity) + , i = 0 + ; + + while (i !== quantity) { + fragments[i] = document.createDocumentFragment(); + i++; + } + + return fragments; +}; + + +self.append_elements = function append_elements(grid, elements) { + // adds a list of elements to the end of a grid + var columns = grid.children + , numberOfColumns = columns.length + , fragments = self.create_list_of_fragments(numberOfColumns) + ; + + elements.forEach(function append_to_next_fragment(element) { + var columnIndex = self.next_element_column_index(grid, fragments); + fragments[columnIndex].appendChild(element); + }); + + Array.prototype.forEach.call(columns, function insert_column(column, index) { + column.appendChild(fragments[index]); + }); +}; + + +self.prepend_elements = function prepend_elements(grid, elements) { + // adds a list of elements to the start of a grid + + var columns = grid.children + , numberOfColumns = columns.length + , fragments = self.create_list_of_fragments(numberOfColumns) + , columnIndex = numberOfColumns - 1 + ; + + elements.forEach(function append_to_next_fragment(element) { + var fragment = fragments[columnIndex]; + fragment.insertBefore(element, fragment.firstChild); + if (columnIndex === 0) { + columnIndex = numberOfColumns - 1; + } else { + columnIndex--; + } + }); + + Array.prototype.forEach.call(columns, function insert_column(column, index) { + column.insertBefore(fragments[index], column.firstChild); + }); + + // populates a fragment with n columns till the right + var fragment = document.createDocumentFragment() + , numberOfColumnsToExtract = elements.length % numberOfColumns + ; + + while (numberOfColumnsToExtract-- !== 0) { + fragment.appendChild(grid.lastChild); + } + + // adds the fragment to the left + grid.insertBefore(fragment, grid.firstChild); +}; + + +self.register_grid = function register_grid (grid) { + if (global.getComputedStyle(grid).display === "none") { + return; + } + + // retrieve the list of items from the grid itself + var range = document.createRange(); + range.selectNodeContents(grid); + + var items = document.createElement("div"); + items.appendChild(range.extractContents()); + + + add_to_dataset(items, 'columns', 0); + self.add_columns(grid, items); + grids.push(grid); +}; + + +self.init = function init() { + // adds required CSS rule to hide 'content' based + // configuration. + + var css = document.createElement("style"); + css.innerHTML = "[data-columns]::before{visibility:hidden;position:absolute;font-size:1px;}"; + document.head.appendChild(css); + + // scans all the grids in the document and generates + // columns from their configuration. + + var gridElements = document.querySelectorAll("[data-columns]"); + Array.prototype.forEach.call(gridElements, self.register_grid); + self.scan_media_queries(); +}; + + +self.init(); + +return { + append_elements: self.append_elements, + prepend_elements: self.prepend_elements, + register_grid: self.register_grid +}; + +})(window, window.document); + + return salvattore; +})); + + function append(title, content){ + var grid = document.querySelector('#columns'); + var item = document.createElement('div'); + var h = '<div class="panel panel-primary">'; + h += '<div class="panel-heading">'; + h += title; + h += '</div>'; + h += '<div class="panel-body">'; + h += content; + h += '</div>'; + h += '</div>'; + salvattore['append_elements'](grid, [item]) + item.outerHTML = h; + } + + $.getJSON("https://www.googleapis.com/books/v1/volumes?q=inauthor:Ernest+Hemingway&callback=?", function(data){ + $(data.items).each(function(i,book){ + append(i +'. '+ book.volumeInfo.title, book.volumeInfo.description); + }); + }); \ No newline at end of file diff --git a/public/js/salvattore.min.js b/public/js/salvattore.min.js new file mode 100644 index 0000000..d515c53 --- /dev/null +++ b/public/js/salvattore.min.js @@ -0,0 +1,603 @@ +/*! + * Salvattore 1.0.9 by @rnmp and @ppold + * https://github.com/rnmp/salvattore + */ +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define([], factory); + } else if (typeof exports === 'object') { + module.exports = factory(); + } else { + root.salvattore = factory(); + } +}(this, function() { +/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */ + +if (!window.matchMedia) { + window.matchMedia = function() { + "use strict"; + + // For browsers that support matchMedium api such as IE 9 and webkit + var styleMedia = (window.styleMedia || window.media); + + // For those that don't support matchMedium + if (!styleMedia) { + var style = document.createElement('style'), + script = document.getElementsByTagName('script')[0], + info = null; + + style.type = 'text/css'; + style.id = 'matchmediajs-test'; + + script.parentNode.insertBefore(style, script); + + // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers + info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; + + styleMedia = { + matchMedium: function(media) { + var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; + + // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers + if (style.styleSheet) { + style.styleSheet.cssText = text; + } else { + style.textContent = text; + } + + // Test if media query is true or false + return info.width === '1px'; + } + }; + } + + return function(media) { + return { + matches: styleMedia.matchMedium(media || 'all'), + media: media || 'all' + }; + }; + }(); +} + +/*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */ +(function(){ + "use strict"; + + // Bail out for browsers that have addListener support + if (window.matchMedia && window.matchMedia('all').addListener) { + return false; + } + + var localMatchMedia = window.matchMedia, + hasMediaQueries = localMatchMedia('only all').matches, + isListening = false, + timeoutID = 0, // setTimeout for debouncing 'handleChange' + queries = [], // Contains each 'mql' and associated 'listeners' if 'addListener' is used + handleChange = function(evt) { + // Debounce + clearTimeout(timeoutID); + + timeoutID = setTimeout(function() { + for (var i = 0, il = queries.length; i < il; i++) { + var mql = queries[i].mql, + listeners = queries[i].listeners || [], + matches = localMatchMedia(mql.media).matches; + + // Update mql.matches value and call listeners + // Fire listeners only if transitioning to or from matched state + if (matches !== mql.matches) { + mql.matches = matches; + + for (var j = 0, jl = listeners.length; j < jl; j++) { + listeners[j].call(window, mql); + } + } + } + }, 30); + }; + + window.matchMedia = function(media) { + var mql = localMatchMedia(media), + listeners = [], + index = 0; + + mql.addListener = function(listener) { + // Changes would not occur to css media type so return now (Affects IE <= 8) + if (!hasMediaQueries) { + return; + } + + // Set up 'resize' listener for browsers that support CSS3 media queries (Not for IE <= 8) + // There should only ever be 1 resize listener running for performance + if (!isListening) { + isListening = true; + window.addEventListener('resize', handleChange, true); + } + + // Push object only if it has not been pushed already + if (index === 0) { + index = queries.push({ + mql : mql, + listeners : listeners + }); + } + + listeners.push(listener); + }; + + mql.removeListener = function(listener) { + for (var i = 0, il = listeners.length; i < il; i++){ + if (listeners[i] === listener){ + listeners.splice(i, 1); + } + } + }; + + return mql; + }; +}()); + +// http://paulirish.com/2011/requestanimationframe-for-smart-animating/ +// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating + +// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel + +// MIT license + +(function() { + "use strict"; + + var lastTime = 0; + var vendors = ['ms', 'moz', 'webkit', 'o']; + for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || + window[vendors[x]+'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) + window.requestAnimationFrame = function(callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16 - (currTime - lastTime)); + var id = window.setTimeout(function() { callback(currTime + timeToCall); }, + timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + + if (!window.cancelAnimationFrame) + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; +}()); + +// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent + +if (typeof window.CustomEvent !== "function") { + (function() { + "use strict"; + function CustomEvent(event, params) { + params = params || { bubbles: false, cancelable: false, detail: undefined }; + var evt = document.createEvent('CustomEvent'); + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); + return evt; + } + + CustomEvent.prototype = window.Event.prototype; + + window.CustomEvent = CustomEvent; + })(); +} + +/* jshint laxcomma: true */ +var salvattore = (function (global, document, undefined) { +"use strict"; + +var self = {}, + grids = [], + mediaRules = [], + mediaQueries = [], + add_to_dataset = function(element, key, value) { + // uses dataset function or a fallback for <ie10 + if (element.dataset) { + element.dataset[key] = value; + } else { + element.setAttribute("data-" + key, value); + } + return; + }; + +self.obtainGridSettings = function obtainGridSettings(element) { + // returns the number of columns and the classes a column should have, + // from computing the style of the ::before pseudo-element of the grid. + + var computedStyle = global.getComputedStyle(element, ":before") + , content = computedStyle.getPropertyValue("content").slice(1, -1) + , matchResult = content.match(/^\s*(\d+)(?:\s?\.(.+))?\s*$/) + , numberOfColumns = 1 + , columnClasses = [] + ; + + if (matchResult) { + numberOfColumns = matchResult[1]; + columnClasses = matchResult[2]; + columnClasses = columnClasses? columnClasses.split(".") : ["column"]; + } else { + matchResult = content.match(/^\s*\.(.+)\s+(\d+)\s*$/); + if (matchResult) { + columnClasses = matchResult[1]; + numberOfColumns = matchResult[2]; + if (numberOfColumns) { + numberOfColumns = numberOfColumns.split("."); + } + } + } + + return { + numberOfColumns: numberOfColumns, + columnClasses: columnClasses + }; +}; + + +self.addColumns = function addColumns(grid, items) { + // from the settings obtained, it creates columns with + // the configured classes and adds to them a list of items. + + var settings = self.obtainGridSettings(grid) + , numberOfColumns = settings.numberOfColumns + , columnClasses = settings.columnClasses + , columnsItems = new Array(+numberOfColumns) + , columnsFragment = document.createDocumentFragment() + , i = numberOfColumns + , selector + ; + + while (i-- !== 0) { + selector = "[data-columns] > *:nth-child(" + numberOfColumns + "n-" + i + ")"; + columnsItems.push(items.querySelectorAll(selector)); + } + + columnsItems.forEach(function append_to_grid_fragment(rows) { + var column = document.createElement("div") + , rowsFragment = document.createDocumentFragment() + ; + + column.className = columnClasses.join(" "); + + Array.prototype.forEach.call(rows, function append_to_column(row) { + rowsFragment.appendChild(row); + }); + column.appendChild(rowsFragment); + columnsFragment.appendChild(column); + }); + + grid.appendChild(columnsFragment); + add_to_dataset(grid, 'columns', numberOfColumns); +}; + + +self.removeColumns = function removeColumns(grid) { + // removes all the columns from a grid, and returns a list + // of items sorted by the ordering of columns. + + var range = document.createRange(); + range.selectNodeContents(grid); + + var columns = Array.prototype.filter.call(range.extractContents().childNodes, function filter_elements(node) { + return node instanceof global.HTMLElement; + }); + + var numberOfColumns = columns.length + , numberOfRowsInFirstColumn = columns[0].childNodes.length + , sortedRows = new Array(numberOfRowsInFirstColumn * numberOfColumns) + ; + + Array.prototype.forEach.call(columns, function iterate_columns(column, columnIndex) { + Array.prototype.forEach.call(column.children, function iterate_rows(row, rowIndex) { + sortedRows[rowIndex * numberOfColumns + columnIndex] = row; + }); + }); + + var container = document.createElement("div"); + add_to_dataset(container, 'columns', 0); + + sortedRows.filter(function filter_non_null(child) { + return !!child; + }).forEach(function append_row(child) { + container.appendChild(child); + }); + + return container; +}; + + +self.recreateColumns = function recreateColumns(grid) { + // removes all the columns from the grid, and adds them again, + // it is used when the number of columns change. + + global.requestAnimationFrame(function render_after_css_mediaQueryChange() { + self.addColumns(grid, self.removeColumns(grid)); + var columnsChange = new CustomEvent("columnsChange"); + grid.dispatchEvent(columnsChange); + }); +}; + + +self.mediaQueryChange = function mediaQueryChange(mql) { + // recreates the columns when a media query matches the current state + // of the browser. + + if (mql.matches) { + Array.prototype.forEach.call(grids, self.recreateColumns); + } +}; + + +self.getCSSRules = function getCSSRules(stylesheet) { + // returns a list of css rules from a stylesheet + + var cssRules; + try { + cssRules = stylesheet.sheet.cssRules || stylesheet.sheet.rules; + } catch (e) { + return []; + } + + return cssRules || []; +}; + + +self.getStylesheets = function getStylesheets() { + // returns a list of all the styles in the document (that are accessible). + + var inlineStyleBlocks = Array.prototype.slice.call(document.querySelectorAll("style")); + inlineStyleBlocks.forEach(function(stylesheet, idx) { + if (stylesheet.type !== 'text/css' && stylesheet.type !== '') { + inlineStyleBlocks.splice(idx, 1); + } + }); + + return Array.prototype.concat.call( + inlineStyleBlocks, + Array.prototype.slice.call(document.querySelectorAll("link[rel='stylesheet']")) + ); +}; + + +self.mediaRuleHasColumnsSelector = function mediaRuleHasColumnsSelector(rules) { + // checks if a media query css rule has in its contents a selector that + // styles the grid. + + var i, rule; + + try { + i = rules.length; + } + catch (e) { + i = 0; + } + + while (i--) { + rule = rules[i]; + if (rule.selectorText && rule.selectorText.match(/\[data-columns\](.*)::?before$/)) { + return true; + } + } + + return false; +}; + + +self.scanMediaQueries = function scanMediaQueries() { + // scans all the stylesheets for selectors that style grids, + // if the matchMedia API is supported. + + var newMediaRules = []; + + if (!global.matchMedia) { + return; + } + + self.getStylesheets().forEach(function extract_rules(stylesheet) { + Array.prototype.forEach.call(self.getCSSRules(stylesheet), function filter_by_column_selector(rule) { + // rule.media throws an 'not implemented error' in ie9 for import rules occasionally + try { + if (rule.media && rule.cssRules && self.mediaRuleHasColumnsSelector(rule.cssRules)) { + newMediaRules.push(rule); + } + } catch (e) {} + }); + }); + + // remove matchMedia listeners from the old rules + var oldRules = mediaRules.filter(function (el) { + return newMediaRules.indexOf(el) === -1; + }); + mediaQueries.filter(function (el) { + return oldRules.indexOf(el.rule) !== -1; + }).forEach(function (el) { + el.mql.removeListener(self.mediaQueryChange); + }); + mediaQueries = mediaQueries.filter(function (el) { + return oldRules.indexOf(el.rule) === -1; + }); + + // add matchMedia listeners to the new rules + newMediaRules.filter(function (el) { + return mediaRules.indexOf(el) == -1; + }).forEach(function (rule) { + var mql = global.matchMedia(rule.media.mediaText); + mql.addListener(self.mediaQueryChange); + mediaQueries.push({rule: rule, mql:mql}); + }); + + // swap mediaRules with the new set + mediaRules.length = 0; + mediaRules = newMediaRules; +}; + + +self.rescanMediaQueries = function rescanMediaQueries() { + self.scanMediaQueries(); + Array.prototype.forEach.call(grids, self.recreateColumns); +}; + + +self.nextElementColumnIndex = function nextElementColumnIndex(grid, fragments) { + // returns the index of the column where the given element must be added. + + var children = grid.children + , m = children.length + , lowestRowCount = 0 + , child + , currentRowCount + , i + , index = 0 + ; + for (i = 0; i < m; i++) { + child = children[i]; + currentRowCount = child.children.length + (fragments[i].children || fragments[i].childNodes).length; + if(lowestRowCount === 0) { + lowestRowCount = currentRowCount; + } + if(currentRowCount < lowestRowCount) { + index = i; + lowestRowCount = currentRowCount; + } + } + + return index; +}; + + +self.createFragmentsList = function createFragmentsList(quantity) { + // returns a list of fragments + + var fragments = new Array(quantity) + , i = 0 + ; + + while (i !== quantity) { + fragments[i] = document.createDocumentFragment(); + i++; + } + + return fragments; +}; + + +self.appendElements = function appendElements(grid, elements) { + // adds a list of elements to the end of a grid + + var columns = grid.children + , numberOfColumns = columns.length + , fragments = self.createFragmentsList(numberOfColumns) + ; + + Array.prototype.forEach.call(elements, function append_to_next_fragment(element) { + var columnIndex = self.nextElementColumnIndex(grid, fragments); + fragments[columnIndex].appendChild(element); + }); + + Array.prototype.forEach.call(columns, function insert_column(column, index) { + column.appendChild(fragments[index]); + }); +}; + + +self.prependElements = function prependElements(grid, elements) { + // adds a list of elements to the start of a grid + + var columns = grid.children + , numberOfColumns = columns.length + , fragments = self.createFragmentsList(numberOfColumns) + , columnIndex = numberOfColumns - 1 + ; + + elements.forEach(function append_to_next_fragment(element) { + var fragment = fragments[columnIndex]; + fragment.insertBefore(element, fragment.firstChild); + if (columnIndex === 0) { + columnIndex = numberOfColumns - 1; + } else { + columnIndex--; + } + }); + + Array.prototype.forEach.call(columns, function insert_column(column, index) { + column.insertBefore(fragments[index], column.firstChild); + }); + + // populates a fragment with n columns till the right + var fragment = document.createDocumentFragment() + , numberOfColumnsToExtract = elements.length % numberOfColumns + ; + + while (numberOfColumnsToExtract-- !== 0) { + fragment.appendChild(grid.lastChild); + } + + // adds the fragment to the left + grid.insertBefore(fragment, grid.firstChild); +}; + + +self.registerGrid = function registerGrid (grid) { + if (global.getComputedStyle(grid).display === "none") { + return; + } + + // retrieve the list of items from the grid itself + var range = document.createRange(); + range.selectNodeContents(grid); + + var items = document.createElement("div"); + items.appendChild(range.extractContents()); + + + add_to_dataset(items, 'columns', 0); + self.addColumns(grid, items); + grids.push(grid); +}; + + +self.init = function init() { + // adds required CSS rule to hide 'content' based + // configuration. + + var css = document.createElement("style"); + css.innerHTML = "[data-columns]::before{display:block;visibility:hidden;position:absolute;font-size:1px;}"; + document.head.appendChild(css); + + // scans all the grids in the document and generates + // columns from their configuration. + + var gridElements = document.querySelectorAll("[data-columns]"); + Array.prototype.forEach.call(gridElements, self.registerGrid); + self.scanMediaQueries(); +}; + +self.init(); + +return { + appendElements: self.appendElements, + prependElements: self.prependElements, + registerGrid: self.registerGrid, + recreateColumns: self.recreateColumns, + rescanMediaQueries: self.rescanMediaQueries, + init: self.init, + + // maintains backwards compatibility with underscore style method names + append_elements: self.appendElements, + prepend_elements: self.prependElements, + register_grid: self.registerGrid, + recreate_columns: self.recreateColumns, + rescan_media_queries: self.rescanMediaQueries +}; + +})(window, window.document); + +return salvattore; +})); \ No newline at end of file diff --git a/public/res/AMIV_Logo_150_50.svg b/public/res/AMIV_Logo_150_50.svg new file mode 100644 index 0000000..fe9ee50 --- /dev/null +++ b/public/res/AMIV_Logo_150_50.svg @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + width="150px" height="50px" viewBox="0 0 150 50" enable-background="new 0 0 150 50" xml:space="preserve"> +<path fill="#E7462B" d="M65.288,29.247h-4.975c-2.271,0-3.526,1.063-3.526,2.852c0,1.739,1.159,2.897,3.623,2.897 + c1.739,0,2.85-0.145,3.961-1.207c0.676-0.629,0.917-1.643,0.917-3.189V29.247z M65.434,39.876v-2.174 + c-1.691,1.689-3.285,2.415-6.183,2.415c-2.851,0-4.928-0.726-6.425-2.222c-1.353-1.401-2.077-3.431-2.077-5.652 + c0-4.009,2.753-7.294,8.598-7.294h5.941v-1.256c0-2.753-1.352-3.961-4.686-3.961c-2.415,0-3.526,0.581-4.83,2.078l-4.009-3.913 + c2.463-2.705,4.878-3.478,9.081-3.478c7.053,0,10.724,2.995,10.724,8.888v16.569H65.434z"/> +<path fill="#E7462B" d="M105.588,39.876V24.66c0-3.43-2.175-4.589-4.154-4.589c-1.934,0-4.202,1.159-4.202,4.444v15.361H90.95V24.66 + c0-3.43-2.173-4.589-4.153-4.589s-4.201,1.159-4.201,4.589v15.216h-6.279V14.709h6.134v2.318c1.643-1.69,3.961-2.608,6.278-2.608 + c2.802,0,5.072,1.014,6.667,3.188c2.125-2.223,4.396-3.188,7.535-3.188c2.511,0,4.782,0.821,6.183,2.222 + c2.029,2.028,2.754,4.396,2.754,7.148v16.086H105.588z"/> +<rect x="116.614" y="14.709" fill="#E7462B" width="6.279" height="25.167"/> +<polygon fill="#E7462B" points="143.407,14.709 138.339,30.255 133.222,14.709 126.608,14.709 135.875,39.861 140.802,39.861 + 150.021,14.711 150.021,14.709 "/> +<path fill="#E7462B" d="M46.613,28.72c0.135-1.021,0.211-2.06,0.211-3.116c0-1.058-0.077-2.095-0.211-3.116l-5.509-0.855 + c-0.247-1.1-0.594-2.177-1.041-3.218l3.95-3.926c-0.49-0.904-1.038-1.79-1.659-2.645c-0.621-0.855-1.294-1.651-2.003-2.396 + l-4.954,2.542c-0.419-0.368-0.855-0.722-1.316-1.056c-0.464-0.336-0.939-0.645-1.422-0.931l0.887-5.498 + c-0.928-0.444-1.892-0.838-2.898-1.165c-1.004-0.327-2.017-0.574-3.027-0.761l-2.517,4.977c-1.125-0.103-2.254-0.099-3.374,0.006 + l-2.521-4.983c-1.012,0.187-2.023,0.435-3.029,0.761c-1.005,0.327-1.97,0.721-2.897,1.164l0.888,5.505 + c-0.962,0.569-1.877,1.233-2.733,1.985l-4.96-2.545c-0.71,0.745-1.382,1.54-2.003,2.396c-0.623,0.855-1.171,1.741-1.661,2.645 + l3.955,3.931c-0.452,1.047-0.801,2.122-1.044,3.212l-5.509,0.856c-0.137,1.02-0.213,2.059-0.213,3.116 + c0,1.057,0.076,2.095,0.213,3.116l5.517,0.856c0.246,1.098,0.591,2.172,1.038,3.211l-3.956,3.931 + c0.49,0.905,1.038,1.791,1.661,2.646c0.621,0.855,1.292,1.651,2.003,2.397l4.954-2.543c0.422,0.371,0.862,0.728,1.326,1.064 + c0.46,0.334,0.932,0.641,1.411,0.926l-0.887,5.495c0.928,0.445,1.893,0.839,2.898,1.166c1.006,0.326,2.017,0.573,3.029,0.76 + l2.514-4.97c1.128,0.105,2.259,0.103,3.382-0.003l2.515,4.973c1.011-0.187,2.024-0.434,3.028-0.76 + c1.007-0.327,1.97-0.721,2.898-1.165l-0.886-5.491c0.966-0.57,1.883-1.236,2.743-1.992l4.948,2.54 + c0.709-0.746,1.381-1.542,2.003-2.397c0.622-0.854,1.169-1.74,1.659-2.646l-3.944-3.921c0.454-1.051,0.803-2.128,1.048-3.225 + L46.613,28.72z M11.481,31.085c-1.906-4.176-1.582-9.233,1.304-13.205c4.26-5.864,12.497-7.168,18.361-2.908 + c0.417,0.303,0.804,0.63,1.174,0.971l-4.002,2.908l-3.888-5.35l-4.288,3.115l3.888,5.351l-0.006,0.005l-12.243,1.193l3.662,5.04 + L11.481,31.085z M34.054,33.334c-4.261,5.864-12.497,7.169-18.361,2.908c-0.38-0.277-0.74-0.571-1.082-0.881l3.948-2.867 + l3.925,5.404l4.921-11.284l3.612,4.971l4.287-3.115l-3.871-5.33l3.975-2.888C37.254,24.404,36.912,29.4,34.054,33.334"/> +</svg> -- GitLab