Created
April 30, 2020 08:21
-
-
Save frontenddeveloping/a532a0f88f4a1e8ebf47ecdd6ed09cb0 to your computer and use it in GitHub Desktop.
Assignment 3 part 1 // source https://jsbin.com/noqi/21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html xmlns='http://www.w3.org/1999/xhtml' lang='en'> | |
<head> | |
<meta charset='utf-8'/> | |
<meta name="HandheldFriendly" content="True"> | |
<meta name="MobileOptimized" content="320"> | |
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no, minimal-ui"> | |
<meta name="mobile-web-app-capable" content="yes"> | |
<meta name="apple-mobile-web-app-capable" content="yes"> | |
<meta name="apple-mobile-web-app-status-bar-style" content="black"> | |
<meta name="apple-mobile-web-app-title" content="My Diary Entries"> | |
<meta name="application-name" content="My Diary Entries"/> | |
<meta name="msapplication-TileColor" content="#1179bc"/> | |
<meta name="msapplication-tap-highlight" content="no" /> | |
<link rel="apple-touch-icon" href="data:image/png;base64,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"> | |
<title>Assignment 3 part 1</title> | |
<style id="jsbin-css"> | |
/*fix windows phone 8 viewport*/ | |
@media screen and (max-width:400px) { | |
@-ms-viewport{ | |
width:320px; | |
} | |
} | |
/*normilize css*/ | |
h1, h2, p, html, body { | |
font-size: 100%; | |
margin: 0; | |
padding: 0; | |
vertical-align: baseline; | |
} | |
article, section { | |
display: block; | |
} | |
html, | |
body { | |
overflow: hidden; | |
min-height: 100%; | |
height: 100% | |
} | |
body { | |
word-wrap: break-word; | |
-webkit-text-size-adjust: none; | |
-ms-text-size-adjust: none; | |
text-size-adjust: none; | |
background-color: #fff; | |
color: #444; | |
} | |
h1, h2 { | |
font-weight: normal; | |
} | |
/* common */ | |
.hidden { | |
visibility: hidden !important; | |
} | |
/* My theme */ | |
body, | |
h1, | |
.entries p, | |
.entries h2 { | |
font: 400 14px/normal "Helvetica", "Arial", sans-serif; | |
} | |
html.has-posts-switcher body:before { | |
background: #444; | |
bottom: 19px; | |
-webkit-box-shadow: 0 6px 0 #444, 0 12px 0 #444; | |
box-shadow: 0 6px 0 #444, 0 12px 0 #444; | |
content: ''; | |
display: block; | |
height: 3px; | |
left: 10px; | |
position: fixed; | |
width: 20px; | |
z-index: 100; | |
} | |
html.has-posts-switcher body:after { | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fefefe), color-stop(100%, #cfcfcf)); | |
background: -webkit-linear-gradient(top, #fefefe 0%, #cfcfcf 100%); | |
background: linear-gradient(to bottom, #fefefe 0%, #cfcfcf 100%); | |
-webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
content: 'Show all articles'; | |
bottom: 0; | |
font-weight: bold; | |
left: 0; | |
line-height: 30px; | |
height: 30px; | |
padding-left: 40px; | |
position: fixed; | |
right:0; | |
z-index: 9; | |
} | |
h1 { | |
background-color: #3DC8FF; | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3DC8FF), color-stop(100%, #008CC3)); | |
background: -webkit-linear-gradient(top, #3DC8FF 0%, #008CC3 100%); | |
background: linear-gradient(to bottom, #3DC8FF 0%, #008CC3 100%); | |
-webkit-box-shadow: inset 0 -1px 0 0 #0A385C; | |
box-shadow: inset 0 -1px 0 0 #0A385C; | |
color: #fff; | |
font-family: "Myriad Pro", "Helvetica", "Arial", sans-serif; | |
font-size: 24px; | |
line-height: 18px; | |
padding: 20px; | |
position: relative; | |
text-align: center; | |
/*prevent user select*/ | |
-ms-user-select: none; | |
-moz-user-select: none; | |
-webkit-touch-callout: none; | |
-webkit-user-select: none; | |
user-select: none; | |
z-index: 99; | |
} | |
h1:after, | |
h1:before { | |
content: ''; | |
position: absolute; | |
height: 0; | |
border: 0; | |
overflow: hidden; | |
border: 10px solid transparent; | |
margin-top: -10px; | |
top: 50%; | |
pointer-events: none; | |
} | |
h1:before { | |
left: 10px; | |
border-right-color: #fff; | |
} | |
h1:after { | |
right: 10px; | |
border-left-color: #fff; | |
} | |
h1.first-post:before, | |
h1.last-post:after { | |
/* Android 2 Mobile Safari don't hide pseudo elements if content is none, using display*/ | |
display: none; | |
} | |
.entries { | |
font: 0/0 a;/* Android 2 needs reset and a font-family to hide the space*/ | |
height: 100%; | |
min-height: 100%; | |
overflow: hidden; | |
padding-bottom: 5px; | |
position: relative; | |
width: 100%; | |
white-space: nowrap; | |
/* enable GPU using */ | |
-webkit-transform: translateZ(0); | |
-webkit-perspective: 1000; | |
-webkit-backface-visibility: hidden; | |
/* animate by transitions */ | |
-webkit-transition: -webkit-transform 0.3s ease; | |
transition: transform 0.3s ease; | |
} | |
.entries article { | |
background: #cfcfcf; | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #cfcfcf), color-stop(10%, #fefefe)); | |
background: -webkit-linear-gradient(top, #cfcfcf 0%, #fefefe 100px); | |
background: linear-gradient(to bottom, #cfcfcf 0%, #fefefe 100px); | |
display: inline-block; | |
min-height: 100%; | |
position: relative; | |
vertical-align: top; | |
width: 100%; | |
white-space: normal; | |
} | |
.entries h2 { | |
font-size: 16px; | |
font-weight: bold; | |
line-height: 1; | |
height: 16px; | |
overflow: hidden; | |
padding: 10px 10px 5px; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
} | |
.entries p { | |
line-height: 21px; | |
padding: 0 10px 10px; | |
} | |
/* layouts */ | |
.small-layout .entries { | |
width: 20000px; | |
} | |
.small-layout .entries article:before { | |
background: #bbb; | |
content: ''; | |
height: 1px; | |
left: 10px; | |
overflow: hidden; | |
width: auto; | |
position: absolute; | |
right: 10px; | |
top: 27px; | |
} | |
/* animate header */ | |
/* http://daneden.github.io/animate.css/ */ | |
@-webkit-keyframes bounceInRight { | |
0% { | |
opacity: 0; | |
-webkit-transform: translateX(1000px); | |
transform: translateX(1000px); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translateX(-30px); | |
transform: translateX(-30px); | |
} | |
80% { | |
-webkit-transform: translateX(10px); | |
transform: translateX(10px); | |
} | |
100% { | |
-webkit-transform: translateX(0); | |
transform: translateX(0); | |
} | |
} | |
@keyframes bounceInRight { | |
0% { | |
opacity: 0; | |
-webkit-transform: translateX(1000px); | |
-ms-transform: translateX(1000px); | |
transform: translateX(1000px); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translateX(-30px); | |
-ms-transform: translateX(-30px); | |
transform: translateX(-30px); | |
} | |
80% { | |
-webkit-transform: translateX(10px); | |
-ms-transform: translateX(10px); | |
transform: translateX(10px); | |
} | |
100% { | |
-webkit-transform: translateX(0); | |
-ms-transform: translateX(0); | |
transform: translateX(0); | |
} | |
} | |
.small-layout .animated-header { | |
display: block; | |
-webkit-animation: bounceInRight 0.5s ease-in-out; | |
animation: bounceInRight 0.5s ease-in-out; | |
} | |
/* medium screen */ | |
html.middle-layout body { | |
overflow-y: auto; | |
} | |
html.middle-layout h1:before, | |
html.middle-layout h1:after, | |
html.middle-layout body:before { | |
display: none; | |
} | |
html.has-posts-switcher.middle-layout body:after { | |
content: 'Back to post'; | |
padding-left: 10px; | |
} | |
html.middle-layout .entries { | |
background: #fff; | |
white-space: normal; | |
-webkit-transition: none; | |
transition: none; | |
} | |
html.middle-layout .entries article { | |
background: #fff; | |
overflow: hidden; | |
min-height: 1px; | |
} | |
html.middle-layout .entries article.open { | |
border-bottom: 1px solid #bbb; | |
} | |
html.middle-layout .entries article p { | |
height: 0; | |
position: absolute; | |
-webkit-transition: height 0.5s ease; | |
transition: height 0.5s ease; | |
} | |
html.middle-layout .entries article.open p { | |
height: 100px; | |
position: static; | |
} | |
html.middle-layout .entries article h2 { | |
border-bottom: 1px solid #bbb; | |
font-size: 24px; | |
height: auto; | |
line-height: 32px; | |
overflow: auto; | |
text-decoration: underline; | |
text-overflow: clip; | |
-webkit-transition: color 0.5s ease; | |
transition: color 0.5s ease; | |
white-space: normal; | |
} | |
html.middle-layout .entries article.open h2 { | |
color: #666; | |
margin-bottom: 10px; | |
text-decoration: none; | |
} | |
/* big screen */ | |
html.full-layout h1:after, | |
html.full-layout body:before { | |
display: none; | |
} | |
html.full-layout, | |
html.full-layout body { | |
overflow: auto; | |
height: auto; | |
min-height: 1px; | |
} | |
html.full-layout body { | |
background: #efefef; | |
padding: 40px; | |
} | |
html.full-layout h1 { | |
-webkit-border-radius: 20px 20px 0 0; | |
border-radius: 20px 20px 0 0; | |
-webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
} | |
html.full-layout .entries { | |
background: #fff; | |
-webkit-border-radius: 0 0 20px 20px; | |
border-radius: 0 0 20px 20px; | |
-webkit-box-shadow: 0 3px 6px rgba(0,0,0,0.5); | |
box-shadow: 0 3px 6px rgba(0,0,0,0.5); | |
height: auto; | |
min-height: 1px; | |
min-width: 500px; | |
position: relative; | |
white-space: normal; | |
} | |
html.full-layout .entries article { | |
background: none; | |
padding: 20px; | |
position: static; | |
width: auto; | |
} | |
html.full-layout .entries article:after { | |
border-bottom: 1px solid #bbb; | |
content : ''; | |
height: 20px; | |
left: 0; | |
overflow: hidden; | |
position: absolute; | |
right: 0; | |
} | |
html.full-layout .entries article:last-child:after { | |
display: none; | |
} | |
html.full-layout .entries article:last-child { | |
-webkit-border-radius: 0 0 20px 20px; | |
border-radius: 0 0 20px 20px; | |
} | |
html.full-layout .entries h2 { | |
background: none; | |
font-size: 21px; | |
height: auto; | |
line-height: normal; | |
overflow: auto; | |
padding: 0; | |
white-space: normal; | |
} | |
html.full-layout .entries p { | |
font-size: 16px; | |
padding: 12px 0 0; | |
} | |
/* js bin fix */ | |
#edit-with-js-bin { | |
display: none !important; | |
} | |
/* | |
Icon(s) | |
*/ | |
html.full-layout h1 { | |
font-size: 33px; | |
line-height: 66px; | |
min-width: 500px; | |
padding: 0; | |
} | |
html.full-layout h1:before { | |
background: #fff; | |
border: 0; | |
-webkit-box-shadow: 0 10px 0 #fff, 0 20px 0 #fff; | |
box-shadow: 0 10px 0 #fff, 0 20px 0 #fff; | |
display: inline-block; | |
height: 4px; | |
margin: 18px 10px 0 0; | |
opacity: 0.9; | |
position: static; | |
vertical-align: top; | |
width: 30px; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>My Diary Entries</h1> | |
<section class='entries'> | |
<article> | |
<h2>Wrote my first mobile application</h2> | |
<p> | |
Today I wrote my first mobile application. It was great! I had huge amounts of fun, it was | |
a lot easier than I expected, and I was so happy I spent the rest of the day celebrating. | |
</p> | |
</article> | |
<article> | |
<h2>Wrote another mobile application</h2> | |
<p> | |
I am on such a roll with these mobile Web applications that I went crazy and wrote a second | |
one. I am so happy I cannot stop singing at the top of my lungs. My cat seems worried that | |
I've finally lost it completely, but I don't care — it's mobile Web all the way from now on! | |
</p> | |
</article> | |
<article> | |
<h2>Must stop writing mobile applications</h2> | |
<p> | |
My fingers are sore from writing so many great mobile Web applications. I know that I should | |
stop and take a break, but there are so many great things to do with this technology that I | |
really don't know how to stop! | |
</p> | |
</article> | |
</section> | |
<script id="jsbin-javascript"> | |
/* | |
Mmmmmm! Spaghetti! | |
────────────▀▄───█───▄▀ | |
───────────▄▄▄█▄▄█▄▄█▄▄▄ | |
────────▄▀▀═════════════▀▀▄ | |
───────█═══════════════════█ | |
──────█═════════════════════█ | |
─────█═══▄▄▄▄▄▄▄═══▄▄▄▄▄▄▄═══█ | |
────█═══█████████═█████████═══█ | |
────█══██▀────▀█████▀────▀██══█ | |
───██████───█▀█─███───█▀█─██████ | |
───██████───▀▀▀─███───▀▀▀─██████ | |
────█══▀█▄────▄██─██▄────▄█▀══█ | |
────█════▀█████▀───▀█████▀════█ | |
────█═════════════════════════█ | |
────█═════════════════════════█ | |
────█═══════█▀█▀█▀█▀█▀█═══════█ | |
────█═══════▀▄───────▄▀═══════█ | |
───▐▓▓▌═══════▀▄█▄█▄▀═══════▐▓▓▌ | |
───▐▐▓▓▌▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▐▓▓▌▌ | |
───█══▐▓▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄▓▌══█ | |
──█══▌═▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌═▐══█ | |
──█══█═▐▓▓▓▓▓▓▄▄▄▄▄▄▄▓▓▓▓▓▓▌═█══█ | |
──█══█═▐▓▓▓▓▓▓▐██▀██▌▓▓▓▓▓▓▌═█══█ | |
──█══█═▐▓▓▓▓▓▓▓▀▀▀▀▀▓▓▓▓▓▓▓▌═█══█ | |
──█══█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█══█ | |
─▄█══█▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌█══█▄ | |
─█████▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌─█████ | |
─██████▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌─██████ | |
──▀█▀█──▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌───█▀█▀ | |
─────────▐▓▓▓▓▓▓▌▐▓▓▓▓▓▓▌ | |
──────────▐▓▓▓▓▌──▐▓▓▓▓▌ | |
─────────▄████▀────▀████▄ | |
─────────▀▀▀▀────────▀▀▀▀ | |
*/ | |
document.addEventListener('DOMContentLoaded', function(){ | |
var App = {};//Application namespace | |
//Constants | |
var | |
VIEWPORT_SIZE, | |
HEADER_WIDTH, | |
HEADER_NODE = document.querySelector('h1'), | |
POSTS_NODE = document.querySelector('.entries'), | |
POSTS_NODES_ARRAY = [].slice.call(POSTS_NODE.getElementsByTagName('article')), | |
HEADER_HEIGHT = 58, | |
CURRENT_POST = 0, | |
TRANSFORM_STYLE_NAME; | |
//check transform support for -webkit prefix | |
if (document.body.style.transform !== undefined) { | |
TRANSFORM_STYLE_NAME = 'transform'; | |
} else if (document.body.style.webkitTransform !== undefined) { | |
TRANSFORM_STYLE_NAME = 'webkitTransform'; | |
} else { | |
TRANSFORM_STYLE_NAME = 'marginLeft'; | |
} | |
//Helerps module | |
App.Helpers = { | |
getCoords : function (e) { | |
var hasTouches = e.touches && e.touches[0]; | |
return { | |
x: hasTouches ? e.touches[0].pageX : e.pageX, | |
y: hasTouches ? e.touches[0].pageY : e.pageY | |
}; | |
}, | |
matchMedia : function (width) { | |
var isNormalLayout; | |
if (window.matchMedia) { | |
isNormalLayout = window.matchMedia('(min-width: '+ width +'px)').matches; | |
} else { | |
isNormalLayout = VIEWPORT_SIZE > width; | |
} | |
return isNormalLayout; | |
}, | |
hasClass : function (el, className) { | |
var result; | |
if (el.classList) { | |
result = el.classList.contains(className); | |
} else { | |
result = el.className.indexOf(className) > -1; | |
} | |
return result; | |
}, | |
addClass : function (el, className) { | |
if (el.classList) { | |
el.classList.add(className); | |
} else { | |
el.className += ' ' + className; | |
} | |
}, | |
removeClass : function (el, className) { | |
if (el.classList) { | |
el.classList.remove(className); | |
} else if(el.className) { | |
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); | |
} | |
}, | |
addUniqueListener : function (node, event, listener) { | |
node.removeEventListener(event, listener); | |
node.addEventListener(event, listener); | |
} | |
}; | |
//Layout module | |
App.Layout = (function () { | |
var currentType = 'small'; | |
return { | |
init : function () { | |
if (App.Helpers.matchMedia(1300)) { | |
this.set('full'); | |
} else if (App.Helpers.matchMedia(700)) { | |
this.set('middle'); | |
} else { | |
this.set('small'); | |
} | |
}, | |
set : function (type) { | |
this.clear(); | |
currentType = type; | |
App.Helpers.addClass(document.documentElement, type+'-layout'); | |
if (type === 'small') { | |
//Android 2 fix | |
//document.body.style.height = window.innerHeight + 'px'; | |
//fix for Windows Phone | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.style.width = VIEWPORT_SIZE + 'px'; | |
}); | |
} | |
}, | |
get : function () { | |
return currentType; | |
}, | |
clear : function () { | |
App.Helpers.removeClass(document.documentElement, 'small-layout'); | |
App.Helpers.removeClass(document.documentElement, 'middle-layout'); | |
App.Helpers.removeClass(document.documentElement, 'full-layout'); | |
document.body.style.height = null; | |
//clear after small | |
POSTS_NODE.removeAttribute('style'); | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.removeAttribute('style'); | |
//clear after medium | |
App.Helpers.removeClass(postNode, 'open'); | |
App.Helpers.removeClass(postNode.firstElementChild, 'hidden'); | |
}); | |
} | |
}; | |
})(); | |
//Animation module | |
App.Animation = (function (){ | |
var isTransitionEnabled = !window.operamini && (function () { | |
var style = document.body.style; | |
return 'transition' in style || | |
'WebkitTransition' in style || | |
'msTransition' in style; | |
})(); | |
function headerAnimationHandler() { | |
var post = POSTS_NODES_ARRAY[CURRENT_POST], | |
postHeader = post.firstElementChild; | |
App.Helpers.removeClass(postHeader, 'hidden'); | |
App.Helpers.addClass(postHeader, 'animated-header'); | |
setTimeout( function () { | |
App.Helpers.removeClass(postHeader, 'animated-header'); | |
postHeader = null; | |
}, 600); | |
} | |
return { | |
isEnabled : function () { | |
return isTransitionEnabled; | |
}, | |
init : function () { | |
if (!this.isEnabled()) { | |
return; | |
} | |
['webkitTransitionEnd', 'transitionend', 'msTransitionEnd'].forEach(function (eventName) { | |
if (eventName.slice(0, -3) in document.body.style) { | |
App.Helpers.addUniqueListener(POSTS_NODE, eventName, headerAnimationHandler); | |
} | |
}); | |
} | |
}; | |
})(); | |
App.Handlers = (function () { | |
//Event listerners vars | |
var | |
wasTouchMoved = false, | |
isTouchEnabled = 'ontouchend' in document.documentElement, | |
touchEndEvent = isTouchEnabled ? 'touchend' : 'click', | |
touchStartCoords = {}; | |
function navigationHandler(e) { | |
if (isTouchEnabled && wasTouchMoved) { | |
return; | |
} | |
if (!isTouchEnabled) { | |
touchStartCoords = App.Helpers.getCoords(e); | |
} | |
if (touchStartCoords.y > HEADER_HEIGHT) { | |
//it's out of needed y coord | |
return; | |
} | |
if (touchStartCoords.x > HEADER_WIDTH/2 && touchStartCoords.x < HEADER_WIDTH) { | |
//if the event point on the left part of app header | |
App.Handlers.showNextPost(); | |
} else if (touchStartCoords.x > 0 && touchStartCoords.x <= HEADER_WIDTH/2) { | |
//point on the right part of app header | |
App.Handlers.showPrevPost(); | |
} | |
touchStartCoords = {}; | |
} | |
function openPostHandler() { | |
var isOpened = App.Helpers.hasClass(this.parentNode, 'open'); | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
App.Helpers.removeClass(postNode, 'open'); | |
}); | |
if (!isOpened) { | |
App.Helpers.addClass(this.parentNode, 'open'); | |
} | |
} | |
function touchMovedHandler() { | |
wasTouchMoved = true; | |
} | |
function touchStartHandler(e) { | |
touchStartCoords = App.Helpers.getCoords(e); | |
wasTouchMoved = false; | |
} | |
function showAllPostsHandler(e) { | |
var layoutType = App.Layout.get(); | |
if (isTouchEnabled && wasTouchMoved) { | |
return; | |
} | |
if (!isTouchEnabled) { | |
touchStartCoords = App.Helpers.getCoords(e); | |
} | |
if (touchStartCoords.y - window.innerHeight - window.pageYOffset > -40 && App.Layout.hasSwitcher) { | |
//40 is bottom clickable zone | |
if (layoutType == 'small') { | |
App.Layout.set('middle'); | |
initCurrentLayoutHandlers(); | |
} else if (layoutType == 'middle') { | |
App.Layout.set('small'); | |
App.Handlers.showCurrentPost(); | |
initCurrentLayoutHandlers(); | |
} | |
} | |
touchStartCoords = {}; | |
} | |
function initCurrentLayoutHandlers () { | |
var layoutType = App.Layout.get(); | |
if (layoutType === 'small') { | |
App.Helpers.addUniqueListener(HEADER_NODE, touchEndEvent, navigationHandler); | |
if (isTouchEnabled) { | |
App.Helpers.addUniqueListener(document, 'touchstart', touchStartHandler); | |
App.Helpers.addUniqueListener(document, 'touchmoved', touchMovedHandler); | |
} | |
App.Helpers.addUniqueListener(document, touchEndEvent, showAllPostsHandler); | |
} else { | |
HEADER_NODE.removeEventListener(touchEndEvent, navigationHandler); | |
if (isTouchEnabled) { | |
document.removeEventListener('touchstart', touchStartHandler); | |
document.removeEventListener('touchmoved', touchMovedHandler); | |
} | |
} | |
if (layoutType === 'middle') { | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
App.Helpers.addUniqueListener(postNode.firstElementChild, touchEndEvent, openPostHandler); | |
}); | |
if (isTouchEnabled) { | |
App.Helpers.addUniqueListener(document, 'touchstart', touchStartHandler); | |
App.Helpers.addUniqueListener(document, 'touchmoved', touchMovedHandler); | |
} | |
App.Helpers.addUniqueListener(document, touchEndEvent, showAllPostsHandler); | |
} else { | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.firstElementChild.removeEventListener(touchEndEvent, openPostHandler); | |
}); | |
if (isTouchEnabled) { | |
document.removeEventListener('touchstart', touchStartHandler); | |
document.removeEventListener('touchmoved', touchMovedHandler); | |
} | |
} | |
if (layoutType === 'full') { | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.firstElementChild.removeEventListener(touchEndEvent, openPostHandler); | |
}); | |
if (isTouchEnabled) { | |
document.body.removeEventListener('touchstart', touchStartHandler); | |
document.body.removeEventListener('touchmoved', touchMovedHandler); | |
} | |
document.removeEventListener(touchEndEvent, showAllPostsHandler); | |
} | |
} | |
function checkAppState() { | |
VIEWPORT_SIZE = HEADER_WIDTH = window.innerWidth; | |
initCurrentLayoutHandlers(); | |
App.Layout.init(); | |
App.Handlers.showCurrentPost(); | |
} | |
return { | |
showCurrentPost : function (noEffects) { | |
var layoutType = App.Layout.get(), | |
xCoord, | |
currentPost, | |
currentPostHeader; | |
if (layoutType === 'small') { | |
//fix small layout navigation arrows | |
if (CURRENT_POST === 0) { | |
App.Helpers.addClass(HEADER_NODE, 'first-post'); | |
} else { | |
App.Helpers.removeClass(HEADER_NODE, 'first-post'); | |
} | |
if (CURRENT_POST === POSTS_NODES_ARRAY.length -1) { | |
App.Helpers.addClass(HEADER_NODE, 'last-post'); | |
} else { | |
App.Helpers.removeClass(HEADER_NODE, 'last-post'); | |
} | |
//calculate current x delta | |
xCoord = -CURRENT_POST * VIEWPORT_SIZE; | |
//start moving | |
if (TRANSFORM_STYLE_NAME === 'marginLeft') { | |
POSTS_NODE.style[TRANSFORM_STYLE_NAME] = xCoord + 'px'; | |
} else { | |
POSTS_NODE.style[TRANSFORM_STYLE_NAME] = 'translateX(' + xCoord + 'px)'; | |
} | |
if (!noEffects) { | |
currentPost = POSTS_NODES_ARRAY[CURRENT_POST]; | |
currentPostHeader = currentPost.firstElementChild; | |
//hide current post header before animation | |
App.Helpers.addClass(currentPostHeader, 'hidden'); | |
} | |
} else if (layoutType === 'middle') { | |
//TODO effects | |
} else if (layoutType === 'full') { | |
//TODO effects | |
} | |
}, | |
showNextPost : function () { | |
if (CURRENT_POST < POSTS_NODES_ARRAY.length - 1) { | |
CURRENT_POST++; | |
this.showCurrentPost(); | |
} | |
}, | |
showPrevPost : function () { | |
if (CURRENT_POST > 0) { | |
CURRENT_POST--; | |
this.showCurrentPost(); | |
} | |
}, | |
init : function () { | |
initCurrentLayoutHandlers(); | |
this.showCurrentPost(); | |
//Yes, double checkAppState makes a lot of work, | |
//but making sync orientationchange and resize order hell adds a lot of code | |
window.addEventListener('orientationchange', checkAppState); | |
window.addEventListener('resize', checkAppState); | |
} | |
}; | |
})(); | |
App.init = function () { | |
VIEWPORT_SIZE = HEADER_WIDTH = window.innerWidth; | |
this.Layout.init(); | |
this.Handlers.init(); | |
this.Animation.init(); | |
if (this.Layout.get() === 'small') { | |
this.Helpers.addClass(document.documentElement,'has-posts-switcher'); | |
this.Layout.hasSwitcher = true; | |
} | |
}; | |
App.init(); | |
}); | |
//standalone support | |
( function() { | |
if (window.navigator.standalone || window.navigator.userAgent.match(/androidwebapp/i)) { | |
document.addEventListener('click', function(e) { | |
var | |
element = e.target, | |
href = ''; | |
while (!/^(a|html)$/i.test(element.nodeName)) { | |
element = element.parentNode; | |
} | |
if (element.getAttribute) { | |
href = element.getAttribute('href'); | |
if ('' !== href && '#' !== href && null !== href && (!element.protocol || element.protocol !== 'tel:')) { | |
e.preventDefault(); | |
window.location = element.href; | |
} | |
} | |
}, false); | |
} | |
}() ); | |
</script> | |
<script id="jsbin-source-css" type="text/css">/*fix windows phone 8 viewport*/ | |
@media screen and (max-width:400px) { | |
@-ms-viewport{ | |
width:320px; | |
} | |
} | |
/*normilize css*/ | |
h1, h2, p, html, body { | |
font-size: 100%; | |
margin: 0; | |
padding: 0; | |
vertical-align: baseline; | |
} | |
article, section { | |
display: block; | |
} | |
html, | |
body { | |
overflow: hidden; | |
min-height: 100%; | |
height: 100% | |
} | |
body { | |
word-wrap: break-word; | |
-webkit-text-size-adjust: none; | |
-ms-text-size-adjust: none; | |
text-size-adjust: none; | |
background-color: #fff; | |
color: #444; | |
} | |
h1, h2 { | |
font-weight: normal; | |
} | |
/* common */ | |
.hidden { | |
visibility: hidden !important; | |
} | |
/* My theme */ | |
body, | |
h1, | |
.entries p, | |
.entries h2 { | |
font: 400 14px/normal "Helvetica", "Arial", sans-serif; | |
} | |
html.has-posts-switcher body:before { | |
background: #444; | |
bottom: 19px; | |
-webkit-box-shadow: 0 6px 0 #444, 0 12px 0 #444; | |
box-shadow: 0 6px 0 #444, 0 12px 0 #444; | |
content: ''; | |
display: block; | |
height: 3px; | |
left: 10px; | |
position: fixed; | |
width: 20px; | |
z-index: 100; | |
} | |
html.has-posts-switcher body:after { | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fefefe), color-stop(100%, #cfcfcf)); | |
background: -webkit-linear-gradient(top, #fefefe 0%, #cfcfcf 100%); | |
background: linear-gradient(to bottom, #fefefe 0%, #cfcfcf 100%); | |
-webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
content: 'Show all articles'; | |
bottom: 0; | |
font-weight: bold; | |
left: 0; | |
line-height: 30px; | |
height: 30px; | |
padding-left: 40px; | |
position: fixed; | |
right:0; | |
z-index: 9; | |
} | |
h1 { | |
background-color: #3DC8FF; | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3DC8FF), color-stop(100%, #008CC3)); | |
background: -webkit-linear-gradient(top, #3DC8FF 0%, #008CC3 100%); | |
background: linear-gradient(to bottom, #3DC8FF 0%, #008CC3 100%); | |
-webkit-box-shadow: inset 0 -1px 0 0 #0A385C; | |
box-shadow: inset 0 -1px 0 0 #0A385C; | |
color: #fff; | |
font-family: "Myriad Pro", "Helvetica", "Arial", sans-serif; | |
font-size: 24px; | |
line-height: 18px; | |
padding: 20px; | |
position: relative; | |
text-align: center; | |
/*prevent user select*/ | |
-ms-user-select: none; | |
-moz-user-select: none; | |
-webkit-touch-callout: none; | |
-webkit-user-select: none; | |
user-select: none; | |
z-index: 99; | |
} | |
h1:after, | |
h1:before { | |
content: ''; | |
position: absolute; | |
height: 0; | |
border: 0; | |
overflow: hidden; | |
border: 10px solid transparent; | |
margin-top: -10px; | |
top: 50%; | |
pointer-events: none; | |
} | |
h1:before { | |
left: 10px; | |
border-right-color: #fff; | |
} | |
h1:after { | |
right: 10px; | |
border-left-color: #fff; | |
} | |
h1.first-post:before, | |
h1.last-post:after { | |
/* Android 2 Mobile Safari don't hide pseudo elements if content is none, using display*/ | |
display: none; | |
} | |
.entries { | |
font: 0/0 a;/* Android 2 needs reset and a font-family to hide the space*/ | |
height: 100%; | |
min-height: 100%; | |
overflow: hidden; | |
padding-bottom: 5px; | |
position: relative; | |
width: 100%; | |
white-space: nowrap; | |
/* enable GPU using */ | |
-webkit-transform: translateZ(0); | |
-webkit-perspective: 1000; | |
-webkit-backface-visibility: hidden; | |
/* animate by transitions */ | |
-webkit-transition: -webkit-transform 0.3s ease; | |
transition: transform 0.3s ease; | |
} | |
.entries article { | |
background: #cfcfcf; | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #cfcfcf), color-stop(10%, #fefefe)); | |
background: -webkit-linear-gradient(top, #cfcfcf 0%, #fefefe 100px); | |
background: linear-gradient(to bottom, #cfcfcf 0%, #fefefe 100px); | |
display: inline-block; | |
min-height: 100%; | |
position: relative; | |
vertical-align: top; | |
width: 100%; | |
white-space: normal; | |
} | |
.entries h2 { | |
font-size: 16px; | |
font-weight: bold; | |
line-height: 1; | |
height: 16px; | |
overflow: hidden; | |
padding: 10px 10px 5px; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
} | |
.entries p { | |
line-height: 21px; | |
padding: 0 10px 10px; | |
} | |
/* layouts */ | |
.small-layout .entries { | |
width: 20000px; | |
} | |
.small-layout .entries article:before { | |
background: #bbb; | |
content: ''; | |
height: 1px; | |
left: 10px; | |
overflow: hidden; | |
width: auto; | |
position: absolute; | |
right: 10px; | |
top: 27px; | |
} | |
/* animate header */ | |
/* http://daneden.github.io/animate.css/ */ | |
@-webkit-keyframes bounceInRight { | |
0% { | |
opacity: 0; | |
-webkit-transform: translateX(1000px); | |
transform: translateX(1000px); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translateX(-30px); | |
transform: translateX(-30px); | |
} | |
80% { | |
-webkit-transform: translateX(10px); | |
transform: translateX(10px); | |
} | |
100% { | |
-webkit-transform: translateX(0); | |
transform: translateX(0); | |
} | |
} | |
@keyframes bounceInRight { | |
0% { | |
opacity: 0; | |
-webkit-transform: translateX(1000px); | |
-ms-transform: translateX(1000px); | |
transform: translateX(1000px); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translateX(-30px); | |
-ms-transform: translateX(-30px); | |
transform: translateX(-30px); | |
} | |
80% { | |
-webkit-transform: translateX(10px); | |
-ms-transform: translateX(10px); | |
transform: translateX(10px); | |
} | |
100% { | |
-webkit-transform: translateX(0); | |
-ms-transform: translateX(0); | |
transform: translateX(0); | |
} | |
} | |
.small-layout .animated-header { | |
display: block; | |
-webkit-animation: bounceInRight 0.5s ease-in-out; | |
animation: bounceInRight 0.5s ease-in-out; | |
} | |
/* medium screen */ | |
html.middle-layout body { | |
overflow-y: auto; | |
} | |
html.middle-layout h1:before, | |
html.middle-layout h1:after, | |
html.middle-layout body:before { | |
display: none; | |
} | |
html.has-posts-switcher.middle-layout body:after { | |
content: 'Back to post'; | |
padding-left: 10px; | |
} | |
html.middle-layout .entries { | |
background: #fff; | |
white-space: normal; | |
-webkit-transition: none; | |
transition: none; | |
} | |
html.middle-layout .entries article { | |
background: #fff; | |
overflow: hidden; | |
min-height: 1px; | |
} | |
html.middle-layout .entries article.open { | |
border-bottom: 1px solid #bbb; | |
} | |
html.middle-layout .entries article p { | |
height: 0; | |
position: absolute; | |
-webkit-transition: height 0.5s ease; | |
transition: height 0.5s ease; | |
} | |
html.middle-layout .entries article.open p { | |
height: 100px; | |
position: static; | |
} | |
html.middle-layout .entries article h2 { | |
border-bottom: 1px solid #bbb; | |
font-size: 24px; | |
height: auto; | |
line-height: 32px; | |
overflow: auto; | |
text-decoration: underline; | |
text-overflow: clip; | |
-webkit-transition: color 0.5s ease; | |
transition: color 0.5s ease; | |
white-space: normal; | |
} | |
html.middle-layout .entries article.open h2 { | |
color: #666; | |
margin-bottom: 10px; | |
text-decoration: none; | |
} | |
/* big screen */ | |
html.full-layout h1:after, | |
html.full-layout body:before { | |
display: none; | |
} | |
html.full-layout, | |
html.full-layout body { | |
overflow: auto; | |
height: auto; | |
min-height: 1px; | |
} | |
html.full-layout body { | |
background: #efefef; | |
padding: 40px; | |
} | |
html.full-layout h1 { | |
-webkit-border-radius: 20px 20px 0 0; | |
border-radius: 20px 20px 0 0; | |
-webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
} | |
html.full-layout .entries { | |
background: #fff; | |
-webkit-border-radius: 0 0 20px 20px; | |
border-radius: 0 0 20px 20px; | |
-webkit-box-shadow: 0 3px 6px rgba(0,0,0,0.5); | |
box-shadow: 0 3px 6px rgba(0,0,0,0.5); | |
height: auto; | |
min-height: 1px; | |
min-width: 500px; | |
position: relative; | |
white-space: normal; | |
} | |
html.full-layout .entries article { | |
background: none; | |
padding: 20px; | |
position: static; | |
width: auto; | |
} | |
html.full-layout .entries article:after { | |
border-bottom: 1px solid #bbb; | |
content : ''; | |
height: 20px; | |
left: 0; | |
overflow: hidden; | |
position: absolute; | |
right: 0; | |
} | |
html.full-layout .entries article:last-child:after { | |
display: none; | |
} | |
html.full-layout .entries article:last-child { | |
-webkit-border-radius: 0 0 20px 20px; | |
border-radius: 0 0 20px 20px; | |
} | |
html.full-layout .entries h2 { | |
background: none; | |
font-size: 21px; | |
height: auto; | |
line-height: normal; | |
overflow: auto; | |
padding: 0; | |
white-space: normal; | |
} | |
html.full-layout .entries p { | |
font-size: 16px; | |
padding: 12px 0 0; | |
} | |
/* js bin fix */ | |
#edit-with-js-bin { | |
display: none !important; | |
} | |
/* | |
Icon(s) | |
*/ | |
html.full-layout h1 { | |
font-size: 33px; | |
line-height: 66px; | |
min-width: 500px; | |
padding: 0; | |
} | |
html.full-layout h1:before { | |
background: #fff; | |
border: 0; | |
-webkit-box-shadow: 0 10px 0 #fff, 0 20px 0 #fff; | |
box-shadow: 0 10px 0 #fff, 0 20px 0 #fff; | |
display: inline-block; | |
height: 4px; | |
margin: 18px 10px 0 0; | |
opacity: 0.9; | |
position: static; | |
vertical-align: top; | |
width: 30px; | |
}</script> | |
<script id="jsbin-source-javascript" type="text/javascript">/* | |
Mmmmmm! Spaghetti! | |
────────────▀▄───█───▄▀ | |
───────────▄▄▄█▄▄█▄▄█▄▄▄ | |
────────▄▀▀═════════════▀▀▄ | |
───────█═══════════════════█ | |
──────█═════════════════════█ | |
─────█═══▄▄▄▄▄▄▄═══▄▄▄▄▄▄▄═══█ | |
────█═══█████████═█████████═══█ | |
────█══██▀────▀█████▀────▀██══█ | |
───██████───█▀█─███───█▀█─██████ | |
───██████───▀▀▀─███───▀▀▀─██████ | |
────█══▀█▄────▄██─██▄────▄█▀══█ | |
────█════▀█████▀───▀█████▀════█ | |
────█═════════════════════════█ | |
────█═════════════════════════█ | |
────█═══════█▀█▀█▀█▀█▀█═══════█ | |
────█═══════▀▄───────▄▀═══════█ | |
───▐▓▓▌═══════▀▄█▄█▄▀═══════▐▓▓▌ | |
───▐▐▓▓▌▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▐▓▓▌▌ | |
───█══▐▓▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄▓▌══█ | |
──█══▌═▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌═▐══█ | |
──█══█═▐▓▓▓▓▓▓▄▄▄▄▄▄▄▓▓▓▓▓▓▌═█══█ | |
──█══█═▐▓▓▓▓▓▓▐██▀██▌▓▓▓▓▓▓▌═█══█ | |
──█══█═▐▓▓▓▓▓▓▓▀▀▀▀▀▓▓▓▓▓▓▓▌═█══█ | |
──█══█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█══█ | |
─▄█══█▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌█══█▄ | |
─█████▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌─█████ | |
─██████▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌─██████ | |
──▀█▀█──▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌───█▀█▀ | |
─────────▐▓▓▓▓▓▓▌▐▓▓▓▓▓▓▌ | |
──────────▐▓▓▓▓▌──▐▓▓▓▓▌ | |
─────────▄████▀────▀████▄ | |
─────────▀▀▀▀────────▀▀▀▀ | |
*/ | |
document.addEventListener('DOMContentLoaded', function(){ | |
var App = {};//Application namespace | |
//Constants | |
var | |
VIEWPORT_SIZE, | |
HEADER_WIDTH, | |
HEADER_NODE = document.querySelector('h1'), | |
POSTS_NODE = document.querySelector('.entries'), | |
POSTS_NODES_ARRAY = [].slice.call(POSTS_NODE.getElementsByTagName('article')), | |
HEADER_HEIGHT = 58, | |
CURRENT_POST = 0, | |
TRANSFORM_STYLE_NAME; | |
//check transform support for -webkit prefix | |
if (document.body.style.transform !== undefined) { | |
TRANSFORM_STYLE_NAME = 'transform'; | |
} else if (document.body.style.webkitTransform !== undefined) { | |
TRANSFORM_STYLE_NAME = 'webkitTransform'; | |
} else { | |
TRANSFORM_STYLE_NAME = 'marginLeft'; | |
} | |
//Helerps module | |
App.Helpers = { | |
getCoords : function (e) { | |
var hasTouches = e.touches && e.touches[0]; | |
return { | |
x: hasTouches ? e.touches[0].pageX : e.pageX, | |
y: hasTouches ? e.touches[0].pageY : e.pageY | |
}; | |
}, | |
matchMedia : function (width) { | |
var isNormalLayout; | |
if (window.matchMedia) { | |
isNormalLayout = window.matchMedia('(min-width: '+ width +'px)').matches; | |
} else { | |
isNormalLayout = VIEWPORT_SIZE > width; | |
} | |
return isNormalLayout; | |
}, | |
hasClass : function (el, className) { | |
var result; | |
if (el.classList) { | |
result = el.classList.contains(className); | |
} else { | |
result = el.className.indexOf(className) > -1; | |
} | |
return result; | |
}, | |
addClass : function (el, className) { | |
if (el.classList) { | |
el.classList.add(className); | |
} else { | |
el.className += ' ' + className; | |
} | |
}, | |
removeClass : function (el, className) { | |
if (el.classList) { | |
el.classList.remove(className); | |
} else if(el.className) { | |
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); | |
} | |
}, | |
addUniqueListener : function (node, event, listener) { | |
node.removeEventListener(event, listener); | |
node.addEventListener(event, listener); | |
} | |
}; | |
//Layout module | |
App.Layout = (function () { | |
var currentType = 'small'; | |
return { | |
init : function () { | |
if (App.Helpers.matchMedia(1300)) { | |
this.set('full'); | |
} else if (App.Helpers.matchMedia(700)) { | |
this.set('middle'); | |
} else { | |
this.set('small'); | |
} | |
}, | |
set : function (type) { | |
this.clear(); | |
currentType = type; | |
App.Helpers.addClass(document.documentElement, type+'-layout'); | |
if (type === 'small') { | |
//Android 2 fix | |
//document.body.style.height = window.innerHeight + 'px'; | |
//fix for Windows Phone | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.style.width = VIEWPORT_SIZE + 'px'; | |
}); | |
} | |
}, | |
get : function () { | |
return currentType; | |
}, | |
clear : function () { | |
App.Helpers.removeClass(document.documentElement, 'small-layout'); | |
App.Helpers.removeClass(document.documentElement, 'middle-layout'); | |
App.Helpers.removeClass(document.documentElement, 'full-layout'); | |
document.body.style.height = null; | |
//clear after small | |
POSTS_NODE.removeAttribute('style'); | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.removeAttribute('style'); | |
//clear after medium | |
App.Helpers.removeClass(postNode, 'open'); | |
App.Helpers.removeClass(postNode.firstElementChild, 'hidden'); | |
}); | |
} | |
}; | |
})(); | |
//Animation module | |
App.Animation = (function (){ | |
var isTransitionEnabled = !window.operamini && (function () { | |
var style = document.body.style; | |
return 'transition' in style || | |
'WebkitTransition' in style || | |
'msTransition' in style; | |
})(); | |
function headerAnimationHandler() { | |
var post = POSTS_NODES_ARRAY[CURRENT_POST], | |
postHeader = post.firstElementChild; | |
App.Helpers.removeClass(postHeader, 'hidden'); | |
App.Helpers.addClass(postHeader, 'animated-header'); | |
setTimeout( function () { | |
App.Helpers.removeClass(postHeader, 'animated-header'); | |
postHeader = null; | |
}, 600); | |
} | |
return { | |
isEnabled : function () { | |
return isTransitionEnabled; | |
}, | |
init : function () { | |
if (!this.isEnabled()) { | |
return; | |
} | |
['webkitTransitionEnd', 'transitionend', 'msTransitionEnd'].forEach(function (eventName) { | |
if (eventName.slice(0, -3) in document.body.style) { | |
App.Helpers.addUniqueListener(POSTS_NODE, eventName, headerAnimationHandler); | |
} | |
}); | |
} | |
}; | |
})(); | |
App.Handlers = (function () { | |
//Event listerners vars | |
var | |
wasTouchMoved = false, | |
isTouchEnabled = 'ontouchend' in document.documentElement, | |
touchEndEvent = isTouchEnabled ? 'touchend' : 'click', | |
touchStartCoords = {}; | |
function navigationHandler(e) { | |
if (isTouchEnabled && wasTouchMoved) { | |
return; | |
} | |
if (!isTouchEnabled) { | |
touchStartCoords = App.Helpers.getCoords(e); | |
} | |
if (touchStartCoords.y > HEADER_HEIGHT) { | |
//it's out of needed y coord | |
return; | |
} | |
if (touchStartCoords.x > HEADER_WIDTH/2 && touchStartCoords.x < HEADER_WIDTH) { | |
//if the event point on the left part of app header | |
App.Handlers.showNextPost(); | |
} else if (touchStartCoords.x > 0 && touchStartCoords.x <= HEADER_WIDTH/2) { | |
//point on the right part of app header | |
App.Handlers.showPrevPost(); | |
} | |
touchStartCoords = {}; | |
} | |
function openPostHandler() { | |
var isOpened = App.Helpers.hasClass(this.parentNode, 'open'); | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
App.Helpers.removeClass(postNode, 'open'); | |
}); | |
if (!isOpened) { | |
App.Helpers.addClass(this.parentNode, 'open'); | |
} | |
} | |
function touchMovedHandler() { | |
wasTouchMoved = true; | |
} | |
function touchStartHandler(e) { | |
touchStartCoords = App.Helpers.getCoords(e); | |
wasTouchMoved = false; | |
} | |
function showAllPostsHandler(e) { | |
var layoutType = App.Layout.get(); | |
if (isTouchEnabled && wasTouchMoved) { | |
return; | |
} | |
if (!isTouchEnabled) { | |
touchStartCoords = App.Helpers.getCoords(e); | |
} | |
if (touchStartCoords.y - window.innerHeight - window.pageYOffset > -40 && App.Layout.hasSwitcher) { | |
//40 is bottom clickable zone | |
if (layoutType == 'small') { | |
App.Layout.set('middle'); | |
initCurrentLayoutHandlers(); | |
} else if (layoutType == 'middle') { | |
App.Layout.set('small'); | |
App.Handlers.showCurrentPost(); | |
initCurrentLayoutHandlers(); | |
} | |
} | |
touchStartCoords = {}; | |
} | |
function initCurrentLayoutHandlers () { | |
var layoutType = App.Layout.get(); | |
if (layoutType === 'small') { | |
App.Helpers.addUniqueListener(HEADER_NODE, touchEndEvent, navigationHandler); | |
if (isTouchEnabled) { | |
App.Helpers.addUniqueListener(document, 'touchstart', touchStartHandler); | |
App.Helpers.addUniqueListener(document, 'touchmoved', touchMovedHandler); | |
} | |
App.Helpers.addUniqueListener(document, touchEndEvent, showAllPostsHandler); | |
} else { | |
HEADER_NODE.removeEventListener(touchEndEvent, navigationHandler); | |
if (isTouchEnabled) { | |
document.removeEventListener('touchstart', touchStartHandler); | |
document.removeEventListener('touchmoved', touchMovedHandler); | |
} | |
} | |
if (layoutType === 'middle') { | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
App.Helpers.addUniqueListener(postNode.firstElementChild, touchEndEvent, openPostHandler); | |
}); | |
if (isTouchEnabled) { | |
App.Helpers.addUniqueListener(document, 'touchstart', touchStartHandler); | |
App.Helpers.addUniqueListener(document, 'touchmoved', touchMovedHandler); | |
} | |
App.Helpers.addUniqueListener(document, touchEndEvent, showAllPostsHandler); | |
} else { | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.firstElementChild.removeEventListener(touchEndEvent, openPostHandler); | |
}); | |
if (isTouchEnabled) { | |
document.removeEventListener('touchstart', touchStartHandler); | |
document.removeEventListener('touchmoved', touchMovedHandler); | |
} | |
} | |
if (layoutType === 'full') { | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.firstElementChild.removeEventListener(touchEndEvent, openPostHandler); | |
}); | |
if (isTouchEnabled) { | |
document.body.removeEventListener('touchstart', touchStartHandler); | |
document.body.removeEventListener('touchmoved', touchMovedHandler); | |
} | |
document.removeEventListener(touchEndEvent, showAllPostsHandler); | |
} | |
} | |
function checkAppState() { | |
VIEWPORT_SIZE = HEADER_WIDTH = window.innerWidth; | |
initCurrentLayoutHandlers(); | |
App.Layout.init(); | |
App.Handlers.showCurrentPost(); | |
} | |
return { | |
showCurrentPost : function (noEffects) { | |
var layoutType = App.Layout.get(), | |
xCoord, | |
currentPost, | |
currentPostHeader; | |
if (layoutType === 'small') { | |
//fix small layout navigation arrows | |
if (CURRENT_POST === 0) { | |
App.Helpers.addClass(HEADER_NODE, 'first-post'); | |
} else { | |
App.Helpers.removeClass(HEADER_NODE, 'first-post'); | |
} | |
if (CURRENT_POST === POSTS_NODES_ARRAY.length -1) { | |
App.Helpers.addClass(HEADER_NODE, 'last-post'); | |
} else { | |
App.Helpers.removeClass(HEADER_NODE, 'last-post'); | |
} | |
//calculate current x delta | |
xCoord = -CURRENT_POST * VIEWPORT_SIZE; | |
//start moving | |
if (TRANSFORM_STYLE_NAME === 'marginLeft') { | |
POSTS_NODE.style[TRANSFORM_STYLE_NAME] = xCoord + 'px'; | |
} else { | |
POSTS_NODE.style[TRANSFORM_STYLE_NAME] = 'translateX(' + xCoord + 'px)'; | |
} | |
if (!noEffects) { | |
currentPost = POSTS_NODES_ARRAY[CURRENT_POST]; | |
currentPostHeader = currentPost.firstElementChild; | |
//hide current post header before animation | |
App.Helpers.addClass(currentPostHeader, 'hidden'); | |
} | |
} else if (layoutType === 'middle') { | |
//TODO effects | |
} else if (layoutType === 'full') { | |
//TODO effects | |
} | |
}, | |
showNextPost : function () { | |
if (CURRENT_POST < POSTS_NODES_ARRAY.length - 1) { | |
CURRENT_POST++; | |
this.showCurrentPost(); | |
} | |
}, | |
showPrevPost : function () { | |
if (CURRENT_POST > 0) { | |
CURRENT_POST--; | |
this.showCurrentPost(); | |
} | |
}, | |
init : function () { | |
initCurrentLayoutHandlers(); | |
this.showCurrentPost(); | |
//Yes, double checkAppState makes a lot of work, | |
//but making sync orientationchange and resize order hell adds a lot of code | |
window.addEventListener('orientationchange', checkAppState); | |
window.addEventListener('resize', checkAppState); | |
} | |
}; | |
})(); | |
App.init = function () { | |
VIEWPORT_SIZE = HEADER_WIDTH = window.innerWidth; | |
this.Layout.init(); | |
this.Handlers.init(); | |
this.Animation.init(); | |
if (this.Layout.get() === 'small') { | |
this.Helpers.addClass(document.documentElement,'has-posts-switcher'); | |
this.Layout.hasSwitcher = true; | |
} | |
}; | |
App.init(); | |
}); | |
//standalone support | |
( function() { | |
if (window.navigator.standalone || window.navigator.userAgent.match(/androidwebapp/i)) { | |
document.addEventListener('click', function(e) { | |
var | |
element = e.target, | |
href = ''; | |
while (!/^(a|html)$/i.test(element.nodeName)) { | |
element = element.parentNode; | |
} | |
if (element.getAttribute) { | |
href = element.getAttribute('href'); | |
if ('' !== href && '#' !== href && null !== href && (!element.protocol || element.protocol !== 'tel:')) { | |
e.preventDefault(); | |
window.location = element.href; | |
} | |
} | |
}, false); | |
} | |
}() ); | |
</script></body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*fix windows phone 8 viewport*/ | |
@media screen and (max-width:400px) { | |
@-ms-viewport{ | |
width:320px; | |
} | |
} | |
/*normilize css*/ | |
h1, h2, p, html, body { | |
font-size: 100%; | |
margin: 0; | |
padding: 0; | |
vertical-align: baseline; | |
} | |
article, section { | |
display: block; | |
} | |
html, | |
body { | |
overflow: hidden; | |
min-height: 100%; | |
height: 100% | |
} | |
body { | |
word-wrap: break-word; | |
-webkit-text-size-adjust: none; | |
-ms-text-size-adjust: none; | |
text-size-adjust: none; | |
background-color: #fff; | |
color: #444; | |
} | |
h1, h2 { | |
font-weight: normal; | |
} | |
/* common */ | |
.hidden { | |
visibility: hidden !important; | |
} | |
/* My theme */ | |
body, | |
h1, | |
.entries p, | |
.entries h2 { | |
font: 400 14px/normal "Helvetica", "Arial", sans-serif; | |
} | |
html.has-posts-switcher body:before { | |
background: #444; | |
bottom: 19px; | |
-webkit-box-shadow: 0 6px 0 #444, 0 12px 0 #444; | |
box-shadow: 0 6px 0 #444, 0 12px 0 #444; | |
content: ''; | |
display: block; | |
height: 3px; | |
left: 10px; | |
position: fixed; | |
width: 20px; | |
z-index: 100; | |
} | |
html.has-posts-switcher body:after { | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fefefe), color-stop(100%, #cfcfcf)); | |
background: -webkit-linear-gradient(top, #fefefe 0%, #cfcfcf 100%); | |
background: linear-gradient(to bottom, #fefefe 0%, #cfcfcf 100%); | |
-webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
content: 'Show all articles'; | |
bottom: 0; | |
font-weight: bold; | |
left: 0; | |
line-height: 30px; | |
height: 30px; | |
padding-left: 40px; | |
position: fixed; | |
right:0; | |
z-index: 9; | |
} | |
h1 { | |
background-color: #3DC8FF; | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #3DC8FF), color-stop(100%, #008CC3)); | |
background: -webkit-linear-gradient(top, #3DC8FF 0%, #008CC3 100%); | |
background: linear-gradient(to bottom, #3DC8FF 0%, #008CC3 100%); | |
-webkit-box-shadow: inset 0 -1px 0 0 #0A385C; | |
box-shadow: inset 0 -1px 0 0 #0A385C; | |
color: #fff; | |
font-family: "Myriad Pro", "Helvetica", "Arial", sans-serif; | |
font-size: 24px; | |
line-height: 18px; | |
padding: 20px; | |
position: relative; | |
text-align: center; | |
/*prevent user select*/ | |
-ms-user-select: none; | |
-moz-user-select: none; | |
-webkit-touch-callout: none; | |
-webkit-user-select: none; | |
user-select: none; | |
z-index: 99; | |
} | |
h1:after, | |
h1:before { | |
content: ''; | |
position: absolute; | |
height: 0; | |
border: 0; | |
overflow: hidden; | |
border: 10px solid transparent; | |
margin-top: -10px; | |
top: 50%; | |
pointer-events: none; | |
} | |
h1:before { | |
left: 10px; | |
border-right-color: #fff; | |
} | |
h1:after { | |
right: 10px; | |
border-left-color: #fff; | |
} | |
h1.first-post:before, | |
h1.last-post:after { | |
/* Android 2 Mobile Safari don't hide pseudo elements if content is none, using display*/ | |
display: none; | |
} | |
.entries { | |
font: 0/0 a;/* Android 2 needs reset and a font-family to hide the space*/ | |
height: 100%; | |
min-height: 100%; | |
overflow: hidden; | |
padding-bottom: 5px; | |
position: relative; | |
width: 100%; | |
white-space: nowrap; | |
/* enable GPU using */ | |
-webkit-transform: translateZ(0); | |
-webkit-perspective: 1000; | |
-webkit-backface-visibility: hidden; | |
/* animate by transitions */ | |
-webkit-transition: -webkit-transform 0.3s ease; | |
transition: transform 0.3s ease; | |
} | |
.entries article { | |
background: #cfcfcf; | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #cfcfcf), color-stop(10%, #fefefe)); | |
background: -webkit-linear-gradient(top, #cfcfcf 0%, #fefefe 100px); | |
background: linear-gradient(to bottom, #cfcfcf 0%, #fefefe 100px); | |
display: inline-block; | |
min-height: 100%; | |
position: relative; | |
vertical-align: top; | |
width: 100%; | |
white-space: normal; | |
} | |
.entries h2 { | |
font-size: 16px; | |
font-weight: bold; | |
line-height: 1; | |
height: 16px; | |
overflow: hidden; | |
padding: 10px 10px 5px; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
} | |
.entries p { | |
line-height: 21px; | |
padding: 0 10px 10px; | |
} | |
/* layouts */ | |
.small-layout .entries { | |
width: 20000px; | |
} | |
.small-layout .entries article:before { | |
background: #bbb; | |
content: ''; | |
height: 1px; | |
left: 10px; | |
overflow: hidden; | |
width: auto; | |
position: absolute; | |
right: 10px; | |
top: 27px; | |
} | |
/* animate header */ | |
/* http://daneden.github.io/animate.css/ */ | |
@-webkit-keyframes bounceInRight { | |
0% { | |
opacity: 0; | |
-webkit-transform: translateX(1000px); | |
transform: translateX(1000px); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translateX(-30px); | |
transform: translateX(-30px); | |
} | |
80% { | |
-webkit-transform: translateX(10px); | |
transform: translateX(10px); | |
} | |
100% { | |
-webkit-transform: translateX(0); | |
transform: translateX(0); | |
} | |
} | |
@keyframes bounceInRight { | |
0% { | |
opacity: 0; | |
-webkit-transform: translateX(1000px); | |
-ms-transform: translateX(1000px); | |
transform: translateX(1000px); | |
} | |
60% { | |
opacity: 1; | |
-webkit-transform: translateX(-30px); | |
-ms-transform: translateX(-30px); | |
transform: translateX(-30px); | |
} | |
80% { | |
-webkit-transform: translateX(10px); | |
-ms-transform: translateX(10px); | |
transform: translateX(10px); | |
} | |
100% { | |
-webkit-transform: translateX(0); | |
-ms-transform: translateX(0); | |
transform: translateX(0); | |
} | |
} | |
.small-layout .animated-header { | |
display: block; | |
-webkit-animation: bounceInRight 0.5s ease-in-out; | |
animation: bounceInRight 0.5s ease-in-out; | |
} | |
/* medium screen */ | |
html.middle-layout body { | |
overflow-y: auto; | |
} | |
html.middle-layout h1:before, | |
html.middle-layout h1:after, | |
html.middle-layout body:before { | |
display: none; | |
} | |
html.has-posts-switcher.middle-layout body:after { | |
content: 'Back to post'; | |
padding-left: 10px; | |
} | |
html.middle-layout .entries { | |
background: #fff; | |
white-space: normal; | |
-webkit-transition: none; | |
transition: none; | |
} | |
html.middle-layout .entries article { | |
background: #fff; | |
overflow: hidden; | |
min-height: 1px; | |
} | |
html.middle-layout .entries article.open { | |
border-bottom: 1px solid #bbb; | |
} | |
html.middle-layout .entries article p { | |
height: 0; | |
position: absolute; | |
-webkit-transition: height 0.5s ease; | |
transition: height 0.5s ease; | |
} | |
html.middle-layout .entries article.open p { | |
height: 100px; | |
position: static; | |
} | |
html.middle-layout .entries article h2 { | |
border-bottom: 1px solid #bbb; | |
font-size: 24px; | |
height: auto; | |
line-height: 32px; | |
overflow: auto; | |
text-decoration: underline; | |
text-overflow: clip; | |
-webkit-transition: color 0.5s ease; | |
transition: color 0.5s ease; | |
white-space: normal; | |
} | |
html.middle-layout .entries article.open h2 { | |
color: #666; | |
margin-bottom: 10px; | |
text-decoration: none; | |
} | |
/* big screen */ | |
html.full-layout h1:after, | |
html.full-layout body:before { | |
display: none; | |
} | |
html.full-layout, | |
html.full-layout body { | |
overflow: auto; | |
height: auto; | |
min-height: 1px; | |
} | |
html.full-layout body { | |
background: #efefef; | |
padding: 40px; | |
} | |
html.full-layout h1 { | |
-webkit-border-radius: 20px 20px 0 0; | |
border-radius: 20px 20px 0 0; | |
-webkit-box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
box-shadow: 0 1px 6px rgba(0,0,0,0.5); | |
} | |
html.full-layout .entries { | |
background: #fff; | |
-webkit-border-radius: 0 0 20px 20px; | |
border-radius: 0 0 20px 20px; | |
-webkit-box-shadow: 0 3px 6px rgba(0,0,0,0.5); | |
box-shadow: 0 3px 6px rgba(0,0,0,0.5); | |
height: auto; | |
min-height: 1px; | |
min-width: 500px; | |
position: relative; | |
white-space: normal; | |
} | |
html.full-layout .entries article { | |
background: none; | |
padding: 20px; | |
position: static; | |
width: auto; | |
} | |
html.full-layout .entries article:after { | |
border-bottom: 1px solid #bbb; | |
content : ''; | |
height: 20px; | |
left: 0; | |
overflow: hidden; | |
position: absolute; | |
right: 0; | |
} | |
html.full-layout .entries article:last-child:after { | |
display: none; | |
} | |
html.full-layout .entries article:last-child { | |
-webkit-border-radius: 0 0 20px 20px; | |
border-radius: 0 0 20px 20px; | |
} | |
html.full-layout .entries h2 { | |
background: none; | |
font-size: 21px; | |
height: auto; | |
line-height: normal; | |
overflow: auto; | |
padding: 0; | |
white-space: normal; | |
} | |
html.full-layout .entries p { | |
font-size: 16px; | |
padding: 12px 0 0; | |
} | |
/* js bin fix */ | |
#edit-with-js-bin { | |
display: none !important; | |
} | |
/* | |
Icon(s) | |
*/ | |
html.full-layout h1 { | |
font-size: 33px; | |
line-height: 66px; | |
min-width: 500px; | |
padding: 0; | |
} | |
html.full-layout h1:before { | |
background: #fff; | |
border: 0; | |
-webkit-box-shadow: 0 10px 0 #fff, 0 20px 0 #fff; | |
box-shadow: 0 10px 0 #fff, 0 20px 0 #fff; | |
display: inline-block; | |
height: 4px; | |
margin: 18px 10px 0 0; | |
opacity: 0.9; | |
position: static; | |
vertical-align: top; | |
width: 30px; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Mmmmmm! Spaghetti! | |
────────────▀▄───█───▄▀ | |
───────────▄▄▄█▄▄█▄▄█▄▄▄ | |
────────▄▀▀═════════════▀▀▄ | |
───────█═══════════════════█ | |
──────█═════════════════════█ | |
─────█═══▄▄▄▄▄▄▄═══▄▄▄▄▄▄▄═══█ | |
────█═══█████████═█████████═══█ | |
────█══██▀────▀█████▀────▀██══█ | |
───██████───█▀█─███───█▀█─██████ | |
───██████───▀▀▀─███───▀▀▀─██████ | |
────█══▀█▄────▄██─██▄────▄█▀══█ | |
────█════▀█████▀───▀█████▀════█ | |
────█═════════════════════════█ | |
────█═════════════════════════█ | |
────█═══════█▀█▀█▀█▀█▀█═══════█ | |
────█═══════▀▄───────▄▀═══════█ | |
───▐▓▓▌═══════▀▄█▄█▄▀═══════▐▓▓▌ | |
───▐▐▓▓▌▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▐▓▓▌▌ | |
───█══▐▓▄▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄▓▌══█ | |
──█══▌═▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌═▐══█ | |
──█══█═▐▓▓▓▓▓▓▄▄▄▄▄▄▄▓▓▓▓▓▓▌═█══█ | |
──█══█═▐▓▓▓▓▓▓▐██▀██▌▓▓▓▓▓▓▌═█══█ | |
──█══█═▐▓▓▓▓▓▓▓▀▀▀▀▀▓▓▓▓▓▓▓▌═█══█ | |
──█══█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█══█ | |
─▄█══█▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌█══█▄ | |
─█████▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌─█████ | |
─██████▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌─██████ | |
──▀█▀█──▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▌───█▀█▀ | |
─────────▐▓▓▓▓▓▓▌▐▓▓▓▓▓▓▌ | |
──────────▐▓▓▓▓▌──▐▓▓▓▓▌ | |
─────────▄████▀────▀████▄ | |
─────────▀▀▀▀────────▀▀▀▀ | |
*/ | |
document.addEventListener('DOMContentLoaded', function(){ | |
var App = {};//Application namespace | |
//Constants | |
var | |
VIEWPORT_SIZE, | |
HEADER_WIDTH, | |
HEADER_NODE = document.querySelector('h1'), | |
POSTS_NODE = document.querySelector('.entries'), | |
POSTS_NODES_ARRAY = [].slice.call(POSTS_NODE.getElementsByTagName('article')), | |
HEADER_HEIGHT = 58, | |
CURRENT_POST = 0, | |
TRANSFORM_STYLE_NAME; | |
//check transform support for -webkit prefix | |
if (document.body.style.transform !== undefined) { | |
TRANSFORM_STYLE_NAME = 'transform'; | |
} else if (document.body.style.webkitTransform !== undefined) { | |
TRANSFORM_STYLE_NAME = 'webkitTransform'; | |
} else { | |
TRANSFORM_STYLE_NAME = 'marginLeft'; | |
} | |
//Helerps module | |
App.Helpers = { | |
getCoords : function (e) { | |
var hasTouches = e.touches && e.touches[0]; | |
return { | |
x: hasTouches ? e.touches[0].pageX : e.pageX, | |
y: hasTouches ? e.touches[0].pageY : e.pageY | |
}; | |
}, | |
matchMedia : function (width) { | |
var isNormalLayout; | |
if (window.matchMedia) { | |
isNormalLayout = window.matchMedia('(min-width: '+ width +'px)').matches; | |
} else { | |
isNormalLayout = VIEWPORT_SIZE > width; | |
} | |
return isNormalLayout; | |
}, | |
hasClass : function (el, className) { | |
var result; | |
if (el.classList) { | |
result = el.classList.contains(className); | |
} else { | |
result = el.className.indexOf(className) > -1; | |
} | |
return result; | |
}, | |
addClass : function (el, className) { | |
if (el.classList) { | |
el.classList.add(className); | |
} else { | |
el.className += ' ' + className; | |
} | |
}, | |
removeClass : function (el, className) { | |
if (el.classList) { | |
el.classList.remove(className); | |
} else if(el.className) { | |
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); | |
} | |
}, | |
addUniqueListener : function (node, event, listener) { | |
node.removeEventListener(event, listener); | |
node.addEventListener(event, listener); | |
} | |
}; | |
//Layout module | |
App.Layout = (function () { | |
var currentType = 'small'; | |
return { | |
init : function () { | |
if (App.Helpers.matchMedia(1300)) { | |
this.set('full'); | |
} else if (App.Helpers.matchMedia(700)) { | |
this.set('middle'); | |
} else { | |
this.set('small'); | |
} | |
}, | |
set : function (type) { | |
this.clear(); | |
currentType = type; | |
App.Helpers.addClass(document.documentElement, type+'-layout'); | |
if (type === 'small') { | |
//Android 2 fix | |
//document.body.style.height = window.innerHeight + 'px'; | |
//fix for Windows Phone | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.style.width = VIEWPORT_SIZE + 'px'; | |
}); | |
} | |
}, | |
get : function () { | |
return currentType; | |
}, | |
clear : function () { | |
App.Helpers.removeClass(document.documentElement, 'small-layout'); | |
App.Helpers.removeClass(document.documentElement, 'middle-layout'); | |
App.Helpers.removeClass(document.documentElement, 'full-layout'); | |
document.body.style.height = null; | |
//clear after small | |
POSTS_NODE.removeAttribute('style'); | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.removeAttribute('style'); | |
//clear after medium | |
App.Helpers.removeClass(postNode, 'open'); | |
App.Helpers.removeClass(postNode.firstElementChild, 'hidden'); | |
}); | |
} | |
}; | |
})(); | |
//Animation module | |
App.Animation = (function (){ | |
var isTransitionEnabled = !window.operamini && (function () { | |
var style = document.body.style; | |
return 'transition' in style || | |
'WebkitTransition' in style || | |
'msTransition' in style; | |
})(); | |
function headerAnimationHandler() { | |
var post = POSTS_NODES_ARRAY[CURRENT_POST], | |
postHeader = post.firstElementChild; | |
App.Helpers.removeClass(postHeader, 'hidden'); | |
App.Helpers.addClass(postHeader, 'animated-header'); | |
setTimeout( function () { | |
App.Helpers.removeClass(postHeader, 'animated-header'); | |
postHeader = null; | |
}, 600); | |
} | |
return { | |
isEnabled : function () { | |
return isTransitionEnabled; | |
}, | |
init : function () { | |
if (!this.isEnabled()) { | |
return; | |
} | |
['webkitTransitionEnd', 'transitionend', 'msTransitionEnd'].forEach(function (eventName) { | |
if (eventName.slice(0, -3) in document.body.style) { | |
App.Helpers.addUniqueListener(POSTS_NODE, eventName, headerAnimationHandler); | |
} | |
}); | |
} | |
}; | |
})(); | |
App.Handlers = (function () { | |
//Event listerners vars | |
var | |
wasTouchMoved = false, | |
isTouchEnabled = 'ontouchend' in document.documentElement, | |
touchEndEvent = isTouchEnabled ? 'touchend' : 'click', | |
touchStartCoords = {}; | |
function navigationHandler(e) { | |
if (isTouchEnabled && wasTouchMoved) { | |
return; | |
} | |
if (!isTouchEnabled) { | |
touchStartCoords = App.Helpers.getCoords(e); | |
} | |
if (touchStartCoords.y > HEADER_HEIGHT) { | |
//it's out of needed y coord | |
return; | |
} | |
if (touchStartCoords.x > HEADER_WIDTH/2 && touchStartCoords.x < HEADER_WIDTH) { | |
//if the event point on the left part of app header | |
App.Handlers.showNextPost(); | |
} else if (touchStartCoords.x > 0 && touchStartCoords.x <= HEADER_WIDTH/2) { | |
//point on the right part of app header | |
App.Handlers.showPrevPost(); | |
} | |
touchStartCoords = {}; | |
} | |
function openPostHandler() { | |
var isOpened = App.Helpers.hasClass(this.parentNode, 'open'); | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
App.Helpers.removeClass(postNode, 'open'); | |
}); | |
if (!isOpened) { | |
App.Helpers.addClass(this.parentNode, 'open'); | |
} | |
} | |
function touchMovedHandler() { | |
wasTouchMoved = true; | |
} | |
function touchStartHandler(e) { | |
touchStartCoords = App.Helpers.getCoords(e); | |
wasTouchMoved = false; | |
} | |
function showAllPostsHandler(e) { | |
var layoutType = App.Layout.get(); | |
if (isTouchEnabled && wasTouchMoved) { | |
return; | |
} | |
if (!isTouchEnabled) { | |
touchStartCoords = App.Helpers.getCoords(e); | |
} | |
if (touchStartCoords.y - window.innerHeight - window.pageYOffset > -40 && App.Layout.hasSwitcher) { | |
//40 is bottom clickable zone | |
if (layoutType == 'small') { | |
App.Layout.set('middle'); | |
initCurrentLayoutHandlers(); | |
} else if (layoutType == 'middle') { | |
App.Layout.set('small'); | |
App.Handlers.showCurrentPost(); | |
initCurrentLayoutHandlers(); | |
} | |
} | |
touchStartCoords = {}; | |
} | |
function initCurrentLayoutHandlers () { | |
var layoutType = App.Layout.get(); | |
if (layoutType === 'small') { | |
App.Helpers.addUniqueListener(HEADER_NODE, touchEndEvent, navigationHandler); | |
if (isTouchEnabled) { | |
App.Helpers.addUniqueListener(document, 'touchstart', touchStartHandler); | |
App.Helpers.addUniqueListener(document, 'touchmoved', touchMovedHandler); | |
} | |
App.Helpers.addUniqueListener(document, touchEndEvent, showAllPostsHandler); | |
} else { | |
HEADER_NODE.removeEventListener(touchEndEvent, navigationHandler); | |
if (isTouchEnabled) { | |
document.removeEventListener('touchstart', touchStartHandler); | |
document.removeEventListener('touchmoved', touchMovedHandler); | |
} | |
} | |
if (layoutType === 'middle') { | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
App.Helpers.addUniqueListener(postNode.firstElementChild, touchEndEvent, openPostHandler); | |
}); | |
if (isTouchEnabled) { | |
App.Helpers.addUniqueListener(document, 'touchstart', touchStartHandler); | |
App.Helpers.addUniqueListener(document, 'touchmoved', touchMovedHandler); | |
} | |
App.Helpers.addUniqueListener(document, touchEndEvent, showAllPostsHandler); | |
} else { | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.firstElementChild.removeEventListener(touchEndEvent, openPostHandler); | |
}); | |
if (isTouchEnabled) { | |
document.removeEventListener('touchstart', touchStartHandler); | |
document.removeEventListener('touchmoved', touchMovedHandler); | |
} | |
} | |
if (layoutType === 'full') { | |
POSTS_NODES_ARRAY.forEach(function (postNode) { | |
postNode.firstElementChild.removeEventListener(touchEndEvent, openPostHandler); | |
}); | |
if (isTouchEnabled) { | |
document.body.removeEventListener('touchstart', touchStartHandler); | |
document.body.removeEventListener('touchmoved', touchMovedHandler); | |
} | |
document.removeEventListener(touchEndEvent, showAllPostsHandler); | |
} | |
} | |
function checkAppState() { | |
VIEWPORT_SIZE = HEADER_WIDTH = window.innerWidth; | |
initCurrentLayoutHandlers(); | |
App.Layout.init(); | |
App.Handlers.showCurrentPost(); | |
} | |
return { | |
showCurrentPost : function (noEffects) { | |
var layoutType = App.Layout.get(), | |
xCoord, | |
currentPost, | |
currentPostHeader; | |
if (layoutType === 'small') { | |
//fix small layout navigation arrows | |
if (CURRENT_POST === 0) { | |
App.Helpers.addClass(HEADER_NODE, 'first-post'); | |
} else { | |
App.Helpers.removeClass(HEADER_NODE, 'first-post'); | |
} | |
if (CURRENT_POST === POSTS_NODES_ARRAY.length -1) { | |
App.Helpers.addClass(HEADER_NODE, 'last-post'); | |
} else { | |
App.Helpers.removeClass(HEADER_NODE, 'last-post'); | |
} | |
//calculate current x delta | |
xCoord = -CURRENT_POST * VIEWPORT_SIZE; | |
//start moving | |
if (TRANSFORM_STYLE_NAME === 'marginLeft') { | |
POSTS_NODE.style[TRANSFORM_STYLE_NAME] = xCoord + 'px'; | |
} else { | |
POSTS_NODE.style[TRANSFORM_STYLE_NAME] = 'translateX(' + xCoord + 'px)'; | |
} | |
if (!noEffects) { | |
currentPost = POSTS_NODES_ARRAY[CURRENT_POST]; | |
currentPostHeader = currentPost.firstElementChild; | |
//hide current post header before animation | |
App.Helpers.addClass(currentPostHeader, 'hidden'); | |
} | |
} else if (layoutType === 'middle') { | |
//TODO effects | |
} else if (layoutType === 'full') { | |
//TODO effects | |
} | |
}, | |
showNextPost : function () { | |
if (CURRENT_POST < POSTS_NODES_ARRAY.length - 1) { | |
CURRENT_POST++; | |
this.showCurrentPost(); | |
} | |
}, | |
showPrevPost : function () { | |
if (CURRENT_POST > 0) { | |
CURRENT_POST--; | |
this.showCurrentPost(); | |
} | |
}, | |
init : function () { | |
initCurrentLayoutHandlers(); | |
this.showCurrentPost(); | |
//Yes, double checkAppState makes a lot of work, | |
//but making sync orientationchange and resize order hell adds a lot of code | |
window.addEventListener('orientationchange', checkAppState); | |
window.addEventListener('resize', checkAppState); | |
} | |
}; | |
})(); | |
App.init = function () { | |
VIEWPORT_SIZE = HEADER_WIDTH = window.innerWidth; | |
this.Layout.init(); | |
this.Handlers.init(); | |
this.Animation.init(); | |
if (this.Layout.get() === 'small') { | |
this.Helpers.addClass(document.documentElement,'has-posts-switcher'); | |
this.Layout.hasSwitcher = true; | |
} | |
}; | |
App.init(); | |
}); | |
//standalone support | |
( function() { | |
if (window.navigator.standalone || window.navigator.userAgent.match(/androidwebapp/i)) { | |
document.addEventListener('click', function(e) { | |
var | |
element = e.target, | |
href = ''; | |
while (!/^(a|html)$/i.test(element.nodeName)) { | |
element = element.parentNode; | |
} | |
if (element.getAttribute) { | |
href = element.getAttribute('href'); | |
if ('' !== href && '#' !== href && null !== href && (!element.protocol || element.protocol !== 'tel:')) { | |
e.preventDefault(); | |
window.location = element.href; | |
} | |
} | |
}, false); | |
} | |
}() ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment