flowtime-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in flowtime-rails.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2012-2013 Marco Lago, http://marcolago.com
2
+ Copyright (c) 2013 Julien 'Lta' BALLET
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
+ Copyright (c) 2013 Julien 'Lta' BALLET
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # flowtime-rails
2
+
3
+ This gems includes flowtime.js (https://github.com/marcolago/flowtime.js) into Rails/MiddleMan assets pipeline.
4
+ Add the time of writing, Rails support is untested yet, although it is simpler enough to work OOTB
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'flowtime-rails'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install flowtime-rails
19
+
20
+ ## Usage
21
+
22
+ This gem works as usual with assets gems. Simply add these line to your application.{js|css}. Replaces 'application' with the correct name for your project (all.{js|css} under MiddleMan for example)
23
+
24
+ ### application.js
25
+
26
+ //= require 'flowtime'
27
+
28
+ ### application.css
29
+
30
+ /*
31
+ *= require 'flowtime'
32
+ */
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'flowtime-rails/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "flowtime-rails"
8
+ gem.version = Flowtime::Rails::VERSION
9
+ gem.authors = ["Julien 'Lta' BALLET"]
10
+ gem.email = ["elthariel@gmail.com"]
11
+ gem.description = %q{Adds flowtime.js to rails/middleman assets Pipeline}
12
+ gem.summary = %q{Adds flowtime.js to rails/middleman assets Pipeline}
13
+ gem.homepage = "http://github.com/elthariel/flowtime-rails"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,28 @@
1
+ require "flowtime-rails/version"
2
+
3
+ module FlowtimeRails
4
+ class FrameworkNotFound < StandardError; end
5
+
6
+ # Inspired by Kaminari
7
+ def self.load!
8
+ if asset_pipeline?
9
+ register_rails_engine
10
+ elsif middleman?
11
+ # There's nothing to do for MiddleMan, it just checks for vendor/assets
12
+ else
13
+ raise FlowtimeRails::FrameworkNotFound, "flowtime-rails requires Rails > 3.1"
14
+ end
15
+ end
16
+
17
+ private
18
+ def self.asset_pipeline?
19
+ defined?(::Rails) && ::Rails.version >= '3.1.0'
20
+ end
21
+ def self.middleman?
22
+ defined?(::Middleman)
23
+ end
24
+
25
+ def self.register_rails_engine
26
+ require 'flowtime-rails/engine'
27
+ end
28
+ end
@@ -0,0 +1,19 @@
1
+ ##
2
+ ## engine.rb
3
+ ## Login : <lta@still>
4
+ ## Started on Tue Apr 16 12:50:13 2013 Lta Akr
5
+ ## $Id$
6
+ ##
7
+ ## Author(s):
8
+ ## - Lta Akr <>
9
+ ##
10
+ ## Copyright (C) 2013 Lta Akr
11
+ ## See LICENSE
12
+
13
+ module Flowtime
14
+ module Rails
15
+ class Engine < ::Rails::Engine
16
+ # Rails, will you please look in our vendor? kthx
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ module Flowtime
2
+ module Rails
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,201 @@
1
+ /*!
2
+ * Brav1Toolbox.js - common utility scripts and polyfills
3
+ * http://marcolago.com/
4
+ * MIT licensed
5
+ *
6
+ * Copyright (C) 2012-2013 Marco Lago, http://marcolago.com
7
+ */
8
+ var Brav1Toolbox = (function()
9
+ {
10
+ var cssPrefixes = ["", "-webkit-", "-moz-", "-ms-", "-o-"];
11
+ var styleObject;
12
+
13
+ /**
14
+ * cache a Style Collection Object for future use
15
+ */
16
+ if (window.getComputedStyle)
17
+ {
18
+ styleObject = window.getComputedStyle(document.body);
19
+ }
20
+ else
21
+ {
22
+ styleObject = document.documentElement.style;
23
+ }
24
+
25
+ /**
26
+ * shortcut to add a listener for modern browsers and IE8-
27
+ */
28
+ function _addListener(element, type, handler, useCapture)
29
+ {
30
+ if (element.addEventListener)
31
+ {
32
+ element.addEventListener(type, handler, useCapture);
33
+ }
34
+ else if (element.attachEvent)
35
+ {
36
+ element.attachEvent(type, handler);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * checks if a CSS property is supported
42
+ * including the prefixed ones
43
+ */
44
+ function _testCSS(prop)
45
+ {
46
+ return _getPrefixed(prop) != "";
47
+ }
48
+
49
+ /**
50
+ * returns the standard or the prefixed CSS property
51
+ * use: element[Brav1Toolbox.getPrefixed(CSSProperty)];
52
+ */
53
+ function _getPrefixed(prop)
54
+ {
55
+ for (var i = 0; i < cssPrefixes.length; i++)
56
+ {
57
+ var pre = cssPrefixes[i].replace(/-/g, "");
58
+ var p = prop;
59
+ if (pre.length > 0)
60
+ {
61
+ p = p.charAt(0).toUpperCase() + p.substr(1);
62
+ }
63
+ p = pre + p;
64
+ if (p in styleObject == true)
65
+ {
66
+ return p;
67
+ }
68
+ }
69
+ return "";
70
+ }
71
+
72
+ /**
73
+ * returns the type of the object passed
74
+ */
75
+ function _typeOf(obj)
76
+ {
77
+ return !!obj && Object.prototype.toString.call(obj).match(/(\w+)\]/)[1];
78
+ }
79
+
80
+ /**
81
+ * classList API polyfill
82
+ */
83
+
84
+ /**
85
+ * adds the specified class to the specified element
86
+ */
87
+ function _addClass(el, c)
88
+ {
89
+ if (el.classList)
90
+ {
91
+ el.classList.add(c);
92
+ }
93
+ else
94
+ {
95
+ if (_hasClass(el, c) == false)
96
+ {
97
+ var cl = el.className;
98
+ if (cl.length > 0)
99
+ {
100
+ cl += " ";
101
+ }
102
+ el.className = cl + c;
103
+ }
104
+ }
105
+ }
106
+
107
+ /**
108
+ * removes the specified class from the specified element
109
+ */
110
+ function _removeClass(el, c)
111
+ {
112
+ if (el.classList)
113
+ {
114
+ el.classList.remove(c);
115
+ }
116
+ else
117
+ {
118
+ var cl = el.className;
119
+ if (cl.indexOf(c) != -1)
120
+ {
121
+ if (cl.indexOf(" " + c) != -1)
122
+ {
123
+ cl = cl.replace(" " + c, "");
124
+ }
125
+ else if (cl.indexOf(c + " ") != -1)
126
+ {
127
+ cl = cl.replace(c + " ", "");
128
+ }
129
+ else
130
+ {
131
+ cl = cl.replace(c, "");
132
+ }
133
+ }
134
+ el.className = cl;
135
+ }
136
+ }
137
+
138
+ /**
139
+ * checks if the specified class is assigned to the specified element
140
+ */
141
+ function _hasClass(el, c)
142
+ {
143
+ if (el)
144
+ {
145
+ if (el.classList)
146
+ {
147
+ return el.classList.contains(c);
148
+ }
149
+ else if (el.className)
150
+ {
151
+ return el.className.indexOf(c) != -1;
152
+ }
153
+ }
154
+ return false;
155
+ }
156
+
157
+ /**
158
+ * creates and dispatch a custom event
159
+ */
160
+ function _dispatchEvent(t, ps)
161
+ {
162
+ if (document.createEvent)
163
+ {
164
+ var e = document.createEvent( "HTMLEvents");
165
+ e.initEvent(t, true, true);
166
+ for (var p in ps)
167
+ {
168
+ e[p] = ps[p];
169
+ }
170
+ document.dispatchEvent(e);
171
+ }
172
+ }
173
+
174
+ /**
175
+ * returns the absolute distance from two points
176
+ */
177
+ function _distance(pA, pB)
178
+ {
179
+ var cX;
180
+ var cY;
181
+ cX = pB.x - pA.x;
182
+ cX *= cX;
183
+ cY = pB.y - pA.y;
184
+ cY *= cY;
185
+
186
+ return Math.abs(Math.sqrt( cX + cY ));
187
+ }
188
+
189
+ return {
190
+ addListener: _addListener,
191
+ dispatchEvent: _dispatchEvent,
192
+ testCSS: _testCSS,
193
+ getPrefixed: _getPrefixed,
194
+ typeOf: _typeOf,
195
+ addClass: _addClass,
196
+ removeClass: _removeClass,
197
+ hasClass: _hasClass,
198
+ distance: _distance
199
+ }
200
+ })();
201
+
@@ -0,0 +1,2102 @@
1
+ /*!
2
+ * Flowtime.js
3
+ * http://marcolago.com/flowtime-js/
4
+ * MIT licensed
5
+ *
6
+ * Copyright (C) 2012-2013 Marco Lago, http://marcolago.com
7
+ */
8
+
9
+ var Flowtime = (function ()
10
+ {
11
+
12
+ /**
13
+ * test if the device is touch enbled
14
+ */
15
+ var isTouchDevice = 'ontouchstart' in document.documentElement;
16
+
17
+ /**
18
+ * test if the HTML History API's where available
19
+ * this value can be overridden to disable the History API
20
+ */
21
+ var pushHistory = window.history.pushState;
22
+
23
+ /**
24
+ * application constants
25
+ */
26
+ var SECTION_CLASS = "ft-section";
27
+ var SECTION_SELECTOR = "." + SECTION_CLASS;
28
+ var PAGE_CLASS = "ft-page";
29
+ var PAGE_SELECTOR = "." + PAGE_CLASS;
30
+ var FRAGMENT_CLASS = "ft-fragment";
31
+ var FRAGMENT_SELECTOR = "." + FRAGMENT_CLASS;
32
+ var FRAGMENT_REVEALED_CLASS = "revealed";
33
+ var FRAGMENT_ACTUAL_CLASS = "actual";
34
+ var FRAGMENT_REVEALED_TEMP_CLASS = "revealed-temp";
35
+ var DEFAULT_PROGRESS_CLASS = "ft-default-progress";
36
+ var DEFAULT_PROGRESS_SELECTOR = "." + DEFAULT_PROGRESS_CLASS;
37
+ var SECTION_THUMB_CLASS = "ft-section-thumb";
38
+ var SECTION_THUMB_SELECTOR = "." + SECTION_THUMB_CLASS;
39
+ var PAGE_THUMB_CLASS = "ft-page-thumb";
40
+ var PAGE_THUMB_SELECTOR = "." + PAGE_THUMB_CLASS;
41
+
42
+ /**
43
+ * events
44
+ */
45
+
46
+ var NAVIGATION_EVENT = "flowtimenavigation";
47
+ /**
48
+ * application variables
49
+ */
50
+ var ftContainer = document.querySelector(".flowtime"); // cached reference to .flowtime element
51
+ var html = document.querySelector("html"); // cached reference to html element
52
+ var body = document.querySelector("body"); // cached reference to body element
53
+ var useHash = false; // if true the engine uses only the hash change logic
54
+ var currentHash = ""; // the hash string of the current section / page pair
55
+ var pastIndex = { section:0, page:0 }; // section and page indexes of the past page
56
+ var isOverview = false; // Boolean status for the overview
57
+ var siteName = document.title; // cached base string for the site title
58
+ var overviewCachedDest; // caches the destination before performing an overview zoom out for navigation back purposes
59
+ var overviewFixedScaleFactor = 22; // fixed scale factor for overview variant
60
+ var defaultProgress = null; // default progress bar reference
61
+
62
+ var _fragmentsOnSide = false; // enable or disable fragments navigation when navigating from sections
63
+ var _fragmentsOnBack = true; // shows or hide fragments when navigating back to a page
64
+ var _slideInPx = false; // calculate the slide position in px instead of %, use in case the % mode does not works
65
+ var _sectionsSlideToTop = false; // if true navigation with right or left arrow go to the first page of the section
66
+ var _useOverviewVariant = false; // use an alternate overview layout and navigation (experimental - useful in case of rendering issues)
67
+ var _twoStepsSlide = false; // not yet implemented! slides up or down before, then slides to the page
68
+ var _showProgress = false; // show or hide the default progress indicator (leave false if you want to implement a custom progress indicator)
69
+ var _parallaxInPx = false; // if false the parallax movement is calulated in % values, if true in pixels
70
+ var defaultParallaxX = 50; // the default parallax horizontal value used when no data-parallax value were specified
71
+ var defaultParallaxY = 50; // the default parallax vertical value used when no data-parallax value were specified
72
+
73
+ var parallaxEnabled = document.querySelector(".parallax") != null; // performance tweak, if there is no elements with .parallax class disable the dom manipulation to boost performances
74
+
75
+
76
+ /**
77
+ * test the base support
78
+ */
79
+ var browserSupport = true;
80
+ try
81
+ {
82
+ var htmlClass = document.querySelector("html").className.toLowerCase();
83
+ if (htmlClass.indexOf("ie7") != -1 ||
84
+ htmlClass.indexOf("ie8") != -1 ||
85
+ htmlClass.indexOf("lt-ie9") != -1 )
86
+ {
87
+ browserSupport = false;
88
+ }
89
+ }
90
+ catch(e)
91
+ {
92
+ browserSupport = false;
93
+ }
94
+ /**
95
+ * add "ft-absolute-nav" hook class to body
96
+ * to set the CSS properties
97
+ * needed for application scrolling
98
+ */
99
+ if (browserSupport)
100
+ {
101
+ Brav1Toolbox.addClass(body, "ft-absolute-nav");
102
+ }
103
+
104
+ /*
105
+ ## ## ### ## ## #### ###### ### ######## #### ####### ## ## ## ## ### ######## ######## #### ## ##
106
+ ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ### ### ## ## ## ## ## ## ## ##
107
+ #### ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## #### #### ## ## ## ## ## ## ## ##
108
+ ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ######## ## ###
109
+ ## #### ######### ## ## ## ## ## ######### ## ## ## ## ## #### ## ## ######### ## ## ## ## ## ##
110
+ ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ##
111
+ ## ## ## ## ### #### ###### ## ## ## #### ####### ## ## ## ## ## ## ## ## ## #### ## ##
112
+ */
113
+
114
+ /**
115
+ * NavigationMatrix is the Object who store the navigation grid structure
116
+ * and which expose all the methods to get and set the navigation destinations
117
+ */
118
+
119
+ var NavigationMatrix = (function ()
120
+ {
121
+ var sections; // HTML Collection of .flowtime > .ft-section elements
122
+ var sectionsArray; // multi-dimensional array containing the pages' array
123
+ var allPages; // HTML Collection of .flowtime .ft-page elements
124
+ var fragments; // HTML Collection of .fragment elements
125
+ var fragmentsArray; // multi-dimensional array containing the per page fragments' array
126
+ var fr = []; // multi-dimensional array containing the index of the current active fragment per page
127
+ var parallaxElements = []; // array containing all elements with parrallax
128
+ var sectionsLength = 0; // cached total number of .ft-section elements
129
+ var pagesLength = 0; // cached max number of .page elements
130
+ var pagesTotalLength = 0; // cached total number of .page elements
131
+ var p = 0; // index of the current section viewved or higlighted
132
+ var sp = 0; // index of the current page viewved or higlighted
133
+ var pCache = 0; // cache index of the current section
134
+ var spCache = 0; // cache index of the current page
135
+ var hilited; // the current page higlighted, useful for overview mode
136
+
137
+ /**
138
+ * update the navigation matrix array
139
+ * this is a publicy exposed method
140
+ * useful for updating the matrix whne the site structure changes at runtime
141
+ */
142
+ function _updateMatrix()
143
+ {
144
+ sectionsArray = [];
145
+ parallaxElements = [];
146
+ fragments = document.querySelectorAll(FRAGMENT_SELECTOR);
147
+ fragmentsArray = [];
148
+ sections = ftContainer.querySelectorAll(".flowtime > " + SECTION_SELECTOR);
149
+ allPages = ftContainer.querySelectorAll(".flowtime " + PAGE_SELECTOR);
150
+ //
151
+ for (var i = 0; i < sections.length; i++)
152
+ {
153
+ var pagesArray = [];
154
+ var section = sections[i];
155
+ fragmentsArray[i] = [];
156
+ fr[i] = [];
157
+ //
158
+ if (section.getAttribute("data-id"))
159
+ {
160
+ section.setAttribute("data-id", "__" + unsafeAttr(section.getAttribute("data-id"))); // prevents attributes starting with a number
161
+ }
162
+ section.setAttribute("data-prog", "__" + (i + 1));
163
+ section.index = i;
164
+ section.setAttribute("id", "");
165
+ //
166
+ pages = section.querySelectorAll(PAGE_SELECTOR);
167
+ pagesTotalLength += pages.length;
168
+ pagesLength = Math.max(pagesLength, pages.length); // sets the pages max number for overview purposes
169
+ for (var ii = 0; ii < pages.length; ii++)
170
+ {
171
+ var _sp = pages[ii];
172
+ if (_sp.getAttribute("data-id"))
173
+ {
174
+ _sp.setAttribute("data-id", "__" + unsafeAttr(_sp.getAttribute("data-id"))); // prevents attributes starting with a number
175
+ }
176
+ _sp.setAttribute("data-prog", "__" + (ii + 1));
177
+ _sp.index = ii;
178
+ _sp.setAttribute("id", "");
179
+ // set data-title attributes to pages that doesn't have one and have at least an h1 heading element inside
180
+ if (!_sp.getAttribute("data-title"))
181
+ {
182
+ var heading = _sp.querySelector("h1");
183
+ if (heading != null && heading.textContent.lenght != "")
184
+ {
185
+ _sp.setAttribute("data-title", heading.textContent);
186
+ }
187
+ }
188
+ // store parallax data on elements
189
+ setParallax(_sp, i, ii);
190
+ //
191
+ pagesArray.push(_sp);
192
+ //
193
+ var subFragments = _sp.querySelectorAll(FRAGMENT_SELECTOR);
194
+ fragmentsArray[i][ii] = subFragments;
195
+ fr[i][ii] = -1;
196
+ }
197
+ sectionsArray.push(pagesArray);
198
+ }
199
+ //
200
+ sectionsLength = sections.length; // sets the sections max number for overview purposes
201
+ resetScroll();
202
+ _updateOffsets();
203
+ }
204
+
205
+ /**
206
+ * stores parallax data directly on the dome elements with a data-parallax attribute
207
+ * data are stored on a multi dimensional array ordered per section and per page to easily manage the position
208
+ */
209
+ function setParallax(page, sectionIndex, pageIndex)
210
+ {
211
+ if (parallaxEnabled)
212
+ {
213
+ if (parallaxElements[sectionIndex] == undefined)
214
+ {
215
+ parallaxElements[sectionIndex] = [];
216
+ }
217
+ if (parallaxElements[sectionIndex][pageIndex] == undefined)
218
+ {
219
+ parallaxElements[sectionIndex][pageIndex] = [];
220
+ }
221
+ //
222
+ var pxs = page.querySelectorAll(".parallax");
223
+ if (pxs.length > 0)
224
+ {
225
+ for (var i = 0; i < pxs.length; i++)
226
+ {
227
+ var el = pxs[i];
228
+ var pX = defaultParallaxX;
229
+ var pY = defaultParallaxY;
230
+ if (el.getAttribute("data-parallax") != null)
231
+ {
232
+ var pValues = el.getAttribute("data-parallax").split(",");
233
+ pX = pY = pValues[0];
234
+ if (pValues.length > 1)
235
+ {
236
+ pY = pValues[1];
237
+ }
238
+ }
239
+ el.pX = pX;
240
+ el.pY = pY;
241
+ parallaxElements[sectionIndex][pageIndex].push(el);
242
+ }
243
+ }
244
+ }
245
+ }
246
+
247
+ function _getParallaxElements()
248
+ {
249
+ return parallaxElements;
250
+ }
251
+
252
+ /**
253
+ * cache the position for every page, useful when navigatin in pixels or when attaching a page after scrolling
254
+ */
255
+ function _updateOffsets ()
256
+ {
257
+ for (var i = 0; i < allPages.length; i++)
258
+ {
259
+ var _sp = allPages[i];
260
+ _sp.x = _sp.offsetLeft + _sp.parentNode.offsetLeft;
261
+ _sp.y = _sp.offsetTop + _sp.parentNode.offsetTop;
262
+ }
263
+ };
264
+
265
+ /**
266
+ * returns the next section in navigation
267
+ * @param top Boolean if true the next page will be the first page in the next array; if false the next section will be the same index page in the next array
268
+ * @param fos Boolean value of _fragmentsOnSide
269
+ * @param io Boolean value of isOverview
270
+ */
271
+ function _getNextSection(top, fos, io)
272
+ {
273
+ var sub = sp;
274
+ var toTop = top == !_sectionsSlideToTop;
275
+ if (fos == true && fragmentsArray[p][sp].length > 0 && fr[p][sp] < fragmentsArray[p][sp].length - 1 && toTop != true && io == false)
276
+ {
277
+ _showFragment(p, sp);
278
+ }
279
+ else
280
+ {
281
+ sub = 0;
282
+ if (toTop == true && p + 1 < sectionsArray.length - 1)
283
+ {
284
+ sub = 0;
285
+ }
286
+ else if (toTop != true || _fragmentsOnBack == true || p + 1 > sectionsArray.length - 1)
287
+ {
288
+ sub = sp;
289
+ }
290
+ p = Math.min(p + 1, sectionsArray.length - 1);
291
+ return _getNearestPage(sectionsArray[p], sub, io);
292
+ }
293
+ return hiliteOrNavigate(sectionsArray[p][sp], io);
294
+ }
295
+
296
+ /**
297
+ * returns the prev section in navigation
298
+ * @param top Boolean if true the next section will be the first page in the prev array; if false the prev section will be the same index page in the prev array
299
+ * @param fos Boolean value of _fragmentsOnSide
300
+ * @param io Boolean value of isOverview
301
+ */
302
+ function _getPrevSection(top, fos, io)
303
+ {
304
+ var sub = sp;
305
+ var toTop = top == !_sectionsSlideToTop;
306
+ if (fos == true && fragmentsArray[p][sp].length > 0 && fr[p][sp] >= 0 && toTop != true && io == false)
307
+ {
308
+ _hideFragment(p, sp);
309
+ }
310
+ else
311
+ {
312
+ var sub = 0;
313
+ sub = 0;
314
+ if (toTop == true && p - 1 >= 0)
315
+ {
316
+ sub = 0;
317
+ }
318
+ else if (toTop != true || _fragmentsOnBack == true || p - 1 < 0)
319
+ {
320
+ sub = sp;
321
+ }
322
+ p = Math.max(p - 1, 0);
323
+ return _getNearestPage(sectionsArray[p], sub, io);
324
+ }
325
+ return hiliteOrNavigate(sectionsArray[p][sp], io);
326
+ }
327
+
328
+ /**
329
+ * checks if there is a valid page in the current section array
330
+ * if the passed page is not valid thne check which is the first valid page in the array
331
+ * then returns the page
332
+ * @param p Number the section index in the sections array
333
+ * @param sub Number the page index in the sections->page array
334
+ * @param io Boolean value of isOverview
335
+ */
336
+ function _getNearestPage(pg, sub, io)
337
+ {
338
+ var nsp = pg[sub];
339
+ if (nsp == undefined)
340
+ {
341
+ for (var i = sub; i >= 0; i--)
342
+ {
343
+ if (pg[i] != undefined)
344
+ {
345
+ nsp = pg[i];
346
+ sub = i;
347
+ break;
348
+ }
349
+ }
350
+ }
351
+ sp = sub;
352
+ if (!isOverview)
353
+ {
354
+ _updateFragments();
355
+ }
356
+ return hiliteOrNavigate(nsp, io);
357
+ }
358
+
359
+ /**
360
+ * returns the next page in navigation
361
+ * if the next page is not in the current section array returns the first page in the next section array
362
+ * @param jump Boolean if true jumps over the fragments directly to the next page
363
+ * @param io Boolean value of isOverview
364
+ */
365
+ function _getNextPage(jump, io)
366
+ {
367
+ if (fragmentsArray[p][sp].length > 0 && fr[p][sp] < fragmentsArray[p][sp].length - 1 && jump != true && io == false)
368
+ {
369
+ _showFragment(p, sp);
370
+ }
371
+ else
372
+ {
373
+ if (sectionsArray[p][sp + 1] == undefined && sectionsArray[p + 1] != undefined)
374
+ {
375
+ p += 1;
376
+ sp = 0;
377
+ }
378
+ else
379
+ {
380
+ sp = Math.min(sp + 1, sectionsArray[p].length - 1);
381
+ }
382
+ }
383
+ return hiliteOrNavigate(sectionsArray[p][sp], io);
384
+ }
385
+
386
+ /**
387
+ * returns the prev page in navigation
388
+ * if the prev page is not in the current section array returns the last page in the prev section array
389
+ * @param jump Boolean if true jumps over the fragments directly to the prev page
390
+ * @param io Boolean value of isOverview
391
+ */
392
+ function _getPrevPage(jump, io)
393
+ {
394
+ if (fragmentsArray[p][sp].length > 0 && fr[p][sp] >= 0 && jump != true && io == false)
395
+ {
396
+ _hideFragment(p, sp);
397
+ }
398
+ else
399
+ {
400
+ if (sp == 0 && sectionsArray[p - 1] != undefined)
401
+ {
402
+ p -= 1;
403
+ sp = sectionsArray[p].length - 1;
404
+ }
405
+ else
406
+ {
407
+ sp = Math.max(sp - 1, 0);
408
+ }
409
+ }
410
+ return hiliteOrNavigate(sectionsArray[p][sp], io);
411
+ }
412
+
413
+ /**
414
+ * returns the destination page or
415
+ * if the application is in overview mode
416
+ * switch the active page without returning a destination
417
+ * @param d HTMLElement the candidate destination
418
+ * @param io Boolean value of isOverview
419
+ */
420
+ function hiliteOrNavigate(d, io)
421
+ {
422
+ if (io == true)
423
+ {
424
+ _switchActivePage(d);
425
+ return;
426
+ }
427
+ else
428
+ {
429
+ return d;
430
+ }
431
+ }
432
+
433
+ /**
434
+ * show a single fragment inside the specified section / page
435
+ * the fragment index parameter is optional, if passed force the specified fragment to show
436
+ * otherwise the method shows the current fragment
437
+ * @param fp Number the section index
438
+ * @param fsp Number the page index
439
+ * @param f Number the fragment index (optional)
440
+ */
441
+ function _showFragment(fp, fsp, f)
442
+ {
443
+ if (f != undefined)
444
+ {
445
+ fr[fp][fsp] = f;
446
+ }
447
+ else
448
+ {
449
+ f = fr[fp][fsp] += 1;
450
+ }
451
+ for (var i = 0; i <= f; i++)
452
+ {
453
+ Brav1Toolbox.addClass(fragmentsArray[fp][fsp][i], FRAGMENT_REVEALED_CLASS);
454
+ Brav1Toolbox.removeClass(fragmentsArray[fp][fsp][i], FRAGMENT_ACTUAL_CLASS);
455
+ }
456
+ Brav1Toolbox.addClass(fragmentsArray[fp][fsp][f], FRAGMENT_ACTUAL_CLASS);
457
+ }
458
+
459
+ /**
460
+ * hide a single fragment inside the specified section / page
461
+ * the fragment index parameter is optional, if passed force the specified fragment to hide
462
+ * otherwise the method hides the current fragment
463
+ * @param fp Number the section index
464
+ * @param fsp Number the page index
465
+ * @param f Number the fragment index (optional)
466
+ */
467
+ function _hideFragment(fp, fsp, f)
468
+ {
469
+ if (f != undefined)
470
+ {
471
+ fr[fp][fsp] = f;
472
+ }
473
+ else
474
+ {
475
+ f = fr[fp][fsp];
476
+ }
477
+ for (var i = 0; i < fragmentsArray[fp][fsp].length; i++)
478
+ {
479
+ if (i >= f)
480
+ {
481
+ Brav1Toolbox.removeClass(fragmentsArray[fp][fsp][i], FRAGMENT_REVEALED_CLASS);
482
+ Brav1Toolbox.removeClass(fragmentsArray[fp][fsp][i], FRAGMENT_REVEALED_TEMP_CLASS);
483
+ }
484
+ Brav1Toolbox.removeClass(fragmentsArray[fp][fsp][i], FRAGMENT_ACTUAL_CLASS);
485
+ }
486
+ f -= 1;
487
+ if (f >= 0)
488
+ {
489
+ Brav1Toolbox.addClass(fragmentsArray[fp][fsp][f], FRAGMENT_ACTUAL_CLASS);
490
+ }
491
+ fr[fp][fsp] = f;
492
+ }
493
+
494
+ /**
495
+ * show all the fragments or the fragments in the specified page
496
+ * adds a temporary class which does not override the current status of fragments
497
+ */
498
+ function _showFragments()
499
+ {
500
+ for (var i = 0; i < fragments.length; i++)
501
+ {
502
+ Brav1Toolbox.addClass(fragments[i], FRAGMENT_REVEALED_TEMP_CLASS);
503
+ }
504
+ }
505
+
506
+ /**
507
+ * hide all the fragments or the fragments in the specified page
508
+ * removes a temporary class which does not override the current status of fragments
509
+ */
510
+ function _hideFragments()
511
+ {
512
+ for (var i = 0; i < fragments.length; i++)
513
+ {
514
+ Brav1Toolbox.removeClass(fragments[i], FRAGMENT_REVEALED_TEMP_CLASS);
515
+ }
516
+ }
517
+
518
+ function _updateFragments()
519
+ {
520
+ for (var ip = 0; ip < fragmentsArray.length; ip++)
521
+ {
522
+ var frp = fragmentsArray[ip];
523
+ for (var isp = 0; isp < frp.length; isp++)
524
+ {
525
+ var frsp = frp[isp];
526
+ if (frsp.length > 0)
527
+ {
528
+ // there are fragments
529
+ if (ip > p)
530
+ {
531
+ // previous section
532
+ for (var f = frsp.length - 1; f >= 0; f--)
533
+ {
534
+ _hideFragment(ip, isp, f);
535
+ }
536
+ }
537
+ else if (ip < p)
538
+ {
539
+ // next section
540
+ for (var f = 0; f < frsp.length; f++)
541
+ {
542
+ _showFragment(ip, isp, f);
543
+ }
544
+ }
545
+ else if (ip == p)
546
+ {
547
+ // same section
548
+ if (isp > sp)
549
+ {
550
+ // previous page
551
+ for (var f = frsp.length - 1; f >= 0; f--)
552
+ {
553
+ _hideFragment(ip, isp, f);
554
+ }
555
+ }
556
+ else if (isp < sp)
557
+ {
558
+ // next page
559
+ for (var f = 0; f < frsp.length; f++)
560
+ {
561
+ _showFragment(ip, isp, f);
562
+ }
563
+ }
564
+ else if (isp == sp)
565
+ {
566
+ // same page
567
+ if (_fragmentsOnBack == true && (pastIndex.section > NavigationMatrix.getPageIndex().section || pastIndex.page > NavigationMatrix.getPageIndex().page))
568
+ {
569
+ for (var f = 0; f < frsp.length; f++)
570
+ {
571
+ _showFragment(ip, isp, f);
572
+ }
573
+ }
574
+ else
575
+ {
576
+ for (var f = frsp.length - 1; f >= 0; f--)
577
+ {
578
+ _hideFragment(ip, isp, f);
579
+ }
580
+ }
581
+ if (_fragmentsOnBack == false)
582
+ {
583
+ fr[ip][isp] = -1
584
+ }
585
+ else
586
+ {
587
+ if (pastIndex.section > NavigationMatrix.getPageIndex().section || pastIndex.page > NavigationMatrix.getPageIndex().page)
588
+ {
589
+ fr[ip][isp] = frsp.length - 1;
590
+ }
591
+ else
592
+ {
593
+ fr[ip][isp] = -1
594
+ }
595
+ }
596
+ }
597
+ }
598
+ }
599
+ }
600
+ }
601
+ }
602
+
603
+ /**
604
+ * returns the current section index
605
+ */
606
+ function _getSection(h)
607
+ {
608
+ if (h)
609
+ {
610
+ // TODO return the index of the section by hash
611
+ }
612
+ return p;
613
+ }
614
+
615
+ /**
616
+ * returns the current page index
617
+ */
618
+ function _getPage(h)
619
+ {
620
+ if (h)
621
+ {
622
+ // TODO return the index of the page by hash
623
+ }
624
+ return sp;
625
+ }
626
+
627
+ /**
628
+ * returns the sections collection
629
+ */
630
+ function _getSections()
631
+ {
632
+ return sections;
633
+ }
634
+
635
+ /**
636
+ * returns the pages collection inside the passed section index
637
+ */
638
+ function _getPages(i)
639
+ {
640
+ return sectionsArray[i];
641
+ }
642
+
643
+ /**
644
+ * returns the pages collection of all pages in the presentation
645
+ */
646
+ function _getAllPages()
647
+ {
648
+ return allPages;
649
+ }
650
+
651
+ /**
652
+ * returns the number of sections
653
+ */
654
+ function _getSectionsLength()
655
+ {
656
+ return sectionsLength;
657
+ }
658
+
659
+ /**
660
+ * returns the max number of pages
661
+ */
662
+ function _getPagesLength()
663
+ {
664
+ return pagesLength;
665
+ }
666
+
667
+ /**
668
+ * returns the total number of pages
669
+ */
670
+ function _getPagesTotalLength()
671
+ {
672
+ return pagesTotalLength;
673
+ }
674
+
675
+ /**
676
+ * returns a object with the index of the current section and page
677
+ */
678
+ function _getPageIndex(d)
679
+ {
680
+ var pIndex = p;
681
+ var spIndex = sp;
682
+ if (d != undefined)
683
+ {
684
+ pIndex = d.parentNode.index; //parseInt(d.parentNode.getAttribute("data-prog").replace(/__/, "")) - 1;
685
+ spIndex = d.index; //parseInt(d.getAttribute("data-prog").replace(/__/, "")) - 1;
686
+ }
687
+ return { section: pIndex, page: spIndex };
688
+ }
689
+
690
+ function _getSectionByIndex(i)
691
+ {
692
+ return sections[i];
693
+ }
694
+
695
+ function _getPageByIndex(i, pi)
696
+ {
697
+ return sectionsArray[pi][i];
698
+ }
699
+
700
+ function _getCurrentSection()
701
+ {
702
+ return sections[p];
703
+ }
704
+
705
+ function _getCurrentPage()
706
+ {
707
+ return sectionsArray[p][sp];
708
+ }
709
+
710
+ function _getCurrentFragment()
711
+ {
712
+ return fragmentsArray[p][sp][_getCurrentFragmentIndex()];
713
+ }
714
+
715
+ function _getCurrentFragmentIndex()
716
+ {
717
+ return fr[p][sp];
718
+ }
719
+
720
+ function _hasNextSection()
721
+ {
722
+ return p < sections.length - 1;
723
+ }
724
+
725
+ function _hasPrevSection()
726
+ {
727
+ return p > 0;
728
+ }
729
+
730
+ function _hasNextPage()
731
+ {
732
+ return sp < sectionsArray[p].length - 1;
733
+ }
734
+
735
+ function _hasPrevPage()
736
+ {
737
+ return sp > 0;
738
+ }
739
+
740
+ /**
741
+ * get a progress value calculated on the total number of pages
742
+ */
743
+ function _getProgress()
744
+ {
745
+ if (p == 0 && sp == 0)
746
+ {
747
+ return 0;
748
+ }
749
+ var c = 0;
750
+ for (var i = 0; i < p; i++)
751
+ {
752
+ c += sectionsArray[i].length;
753
+ }
754
+ c += sectionsArray[p][sp].index + 1;
755
+ return c;
756
+ }
757
+
758
+ /**
759
+ * get a composed hash based on current section and page
760
+ */
761
+ function _getHash(d)
762
+ {
763
+ if (d != undefined)
764
+ {
765
+ sp = _getPageIndex(d).page;
766
+ p = _getPageIndex(d).section;
767
+ }
768
+ var h = "";
769
+ // append to h the value of data-id attribute or, if data-id is not defined, the data-prog attribute
770
+ var _p = sections[p];
771
+ h += getPageId(_p);
772
+ if (sectionsArray[p].length > 1)
773
+ {
774
+ var _sp = sectionsArray[p][sp];
775
+ h += "/" + getPageId(_sp);
776
+ }
777
+ return h;
778
+ }
779
+
780
+ /**
781
+ * expose the method to set the page from a hash
782
+ */
783
+ function _setPage(h)
784
+ {
785
+ var elem = getElementByHash(h);
786
+ if (elem)
787
+ {
788
+ var pElem = elem.parentNode;
789
+ for (var i = 0; i < sectionsArray.length; i++)
790
+ {
791
+ var pa = sectionsArray[i];
792
+ if (sections[i] === pElem)
793
+ {
794
+ p = i;
795
+ for (var ii = 0; ii < pa.length; ii++)
796
+ {
797
+ if (pa[ii] === elem)
798
+ {
799
+ sp = ii;
800
+ break;
801
+ }
802
+ }
803
+ }
804
+ }
805
+ _updateFragments();
806
+ }
807
+ return elem;
808
+ }
809
+
810
+ function _switchActivePage(d, navigate)
811
+ {
812
+ var sIndex = d.parentNode.index;
813
+ for (var i = 0; i < sectionsArray.length; i++)
814
+ {
815
+ var pa = sectionsArray[i];
816
+ for (var ii = 0; ii < pa.length; ii++)
817
+ {
818
+ var spa = pa[ii];
819
+ //
820
+ Brav1Toolbox.removeClass(spa, "past-section");
821
+ Brav1Toolbox.removeClass(spa, "future-section");
822
+ Brav1Toolbox.removeClass(spa, "past-page");
823
+ Brav1Toolbox.removeClass(spa, "future-page");
824
+ //
825
+ if (spa !== d)
826
+ {
827
+ Brav1Toolbox.removeClass(spa, "hilite");
828
+ if (isOverview == false && spa !== _getCurrentPage())
829
+ {
830
+ Brav1Toolbox.removeClass(spa, "actual");
831
+ }
832
+ if (i < sIndex)
833
+ {
834
+ Brav1Toolbox.addClass(spa, "past-section");
835
+ }
836
+ else if (i > sIndex)
837
+ {
838
+ Brav1Toolbox.addClass(spa, "future-section");
839
+ }
840
+ if (spa.index < d.index)
841
+ {
842
+ Brav1Toolbox.addClass(spa, "past-page");
843
+ }
844
+ else if (spa.index > d.index)
845
+ {
846
+ Brav1Toolbox.addClass(spa, "future-page");
847
+ }
848
+ }
849
+ }
850
+ }
851
+ Brav1Toolbox.addClass(d, "hilite");
852
+ if (navigate)
853
+ {
854
+ setActual(d);
855
+ }
856
+ hilited = d;
857
+ }
858
+
859
+ function _getCurrentHilited()
860
+ {
861
+ return hilited;
862
+ }
863
+
864
+ function setActual(d)
865
+ {
866
+ Brav1Toolbox.addClass(d, "actual");
867
+ }
868
+
869
+ _updateMatrix(); // update the navigation matrix on the first run
870
+
871
+ return {
872
+ update: _updateMatrix,
873
+ updateFragments: _updateFragments,
874
+ showFragments: _showFragments,
875
+ hideFragments: _hideFragments,
876
+ getSection: _getSection,
877
+ getPage: _getPage,
878
+ getSections: _getSections,
879
+ getPages: _getPages,
880
+ getAllPages: _getAllPages,
881
+ getNextSection: _getNextSection,
882
+ getPrevSection: _getPrevSection,
883
+ getNextPage: _getNextPage,
884
+ getPrevPage: _getPrevPage,
885
+ getSectionsLength: _getSectionsLength,
886
+ getPagesLength: _getPagesLength,
887
+ getPagesTotalLength: _getPagesTotalLength,
888
+ getPageIndex: _getPageIndex,
889
+ getSectionByIndex: _getSectionByIndex,
890
+ getPageByIndex: _getPageByIndex,
891
+ getCurrentSection: _getCurrentSection,
892
+ getCurrentPage: _getCurrentPage,
893
+ getCurrentFragment: _getCurrentFragment,
894
+ getCurrentFragmentIndex: _getCurrentFragmentIndex,
895
+ getProgress: _getProgress,
896
+ getHash: _getHash,
897
+ setPage: _setPage,
898
+ switchActivePage: _switchActivePage,
899
+ getCurrentHilited: _getCurrentHilited,
900
+ hasNextSection: _hasNextSection,
901
+ hasPrevSection: _hasPrevSection,
902
+ hasNextPage: _hasNextPage,
903
+ hasPrevPage: _hasPrevPage,
904
+ updateOffsets: _updateOffsets,
905
+ getParallaxElements: _getParallaxElements
906
+ }
907
+ })();
908
+
909
+ /*
910
+ ## ## ### ## ## #### ###### ### ######## #### ####### ## ## ######## ## ## ######## ## ## ######## ######
911
+ ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ### ## ## ## ##
912
+ #### ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## #### ## ## ##
913
+ ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ###### ## ## ###### ## ## ## ## ######
914
+ ## #### ######### ## ## ## ## ## ######### ## ## ## ## ## #### ## ## ## ## ## #### ## ##
915
+ ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ### ## ## ##
916
+ ## ## ## ## ### #### ###### ## ## ## #### ####### ## ## ######## ### ######## ## ## ## ######
917
+ */
918
+ /**
919
+ * add a listener for event delegation
920
+ * used for navigation purposes
921
+ */
922
+ if (browserSupport)
923
+ {
924
+ if (isTouchDevice)
925
+ {
926
+ Brav1Toolbox.addListener(document, "touchend", onNavClick, false);
927
+ }
928
+ else
929
+ {
930
+ Brav1Toolbox.addListener(document, "click", onNavClick, false);
931
+ }
932
+ }
933
+
934
+ function onNavClick(e)
935
+ {
936
+ var href = e.target.getAttribute("href");
937
+ // links with href starting with #
938
+ if (href && href.substr(0,1) == "#")
939
+ {
940
+ e.target.blur();
941
+ e.preventDefault();
942
+ var h = href;
943
+ var dest = NavigationMatrix.setPage(h);
944
+ navigateTo(dest, true, true);
945
+ }
946
+ // pages in oveview mode
947
+ if (isOverview)
948
+ {
949
+ var dest = e.target;
950
+ while (dest && !Brav1Toolbox.hasClass(dest, PAGE_CLASS))
951
+ {
952
+ dest = dest.parentNode;
953
+ }
954
+ if (Brav1Toolbox.hasClass(dest, PAGE_CLASS))
955
+ {
956
+ e.preventDefault();
957
+ navigateTo(dest, null, true);
958
+ }
959
+ }
960
+ // thumbs in the default progress indicator
961
+ if (Brav1Toolbox.hasClass(e.target, PAGE_THUMB_CLASS))
962
+ {
963
+ e.preventDefault();
964
+ var pTo = Number(unsafeAttr(e.target.getAttribute("data-section")));
965
+ var spTo = Number(unsafeAttr(e.target.getAttribute("data-page")));
966
+ _gotoPage(pTo, spTo);
967
+ }
968
+ }
969
+
970
+ /**
971
+ * set callback for onpopstate event
972
+ * uses native history API to manage navigation
973
+ * but uses the # for client side navigation on return
974
+ */
975
+ if (useHash == false && window.history.pushState)
976
+ {
977
+ window.onpopstate = onPopState;
978
+ }
979
+ else
980
+ {
981
+ useHash = true;
982
+ }
983
+ //
984
+ function onPopState(e)
985
+ {
986
+ useHash = false;
987
+ var h;
988
+ if (e.state)
989
+ {
990
+ h = e.state.token.replace("#/", "");
991
+ }
992
+ else
993
+ {
994
+ h = document.location.hash.replace("#/", "");
995
+ }
996
+ var dest = NavigationMatrix.setPage(h);
997
+ navigateTo(dest, false);
998
+ }
999
+
1000
+ /**
1001
+ * set callback for hashchange event
1002
+ * this callback is used not only when onpopstate event wasn't available
1003
+ * but also when the user resize the window or for the firs visit on the site
1004
+ */
1005
+ Brav1Toolbox.addListener(window, "hashchange", onHashChange);
1006
+ //
1007
+ /**
1008
+ * @param e Event the hashChange Event
1009
+ * @param d Boolean force the hash change
1010
+ */
1011
+ function onHashChange(e, d)
1012
+ {
1013
+ if (useHash || d)
1014
+ {
1015
+ var h = document.location.hash.replace("#/", "");
1016
+ var dest = NavigationMatrix.setPage(h);
1017
+ navigateTo(dest, false);
1018
+ }
1019
+ }
1020
+
1021
+ /*
1022
+ ######## ####### ## ## ###### ## ##
1023
+ ## ## ## ## ## ## ## ## ##
1024
+ ## ## ## ## ## ## ## ##
1025
+ ## ## ## ## ## ## #########
1026
+ ## ## ## ## ## ## ## ##
1027
+ ## ## ## ## ## ## ## ## ##
1028
+ ## ####### ####### ###### ## ##
1029
+ */
1030
+
1031
+ var _ftX = ftContainer.offsetX;
1032
+ var _ftY = 0;
1033
+ var _touchStartX = 0;
1034
+ var _touchStartY = 0;
1035
+ var _deltaX = 0;
1036
+ var _deltaY = 0;
1037
+ var _dragging = 0;
1038
+ var _dragAxis = "x";
1039
+ var _swipeLimit = 100;
1040
+
1041
+ html.addEventListener("touchstart", onTouchStart, false);
1042
+ html.addEventListener("touchmove", onTouchMove, false);
1043
+ html.addEventListener("touchend", onTouchEnd, false);
1044
+
1045
+ function onTouchStart(e)
1046
+ {
1047
+ _deltaX = 0;
1048
+ _deltaY = 0;
1049
+ e.preventDefault();
1050
+ e = getTouchEvent(e);
1051
+ _touchStartX = e.clientX;
1052
+ _touchStartY = e.clientY;
1053
+ _dragging = 1;
1054
+ var initOffset = getInitOffset();
1055
+ _ftX = initOffset.x;
1056
+ _ftY = initOffset.y;
1057
+ }
1058
+
1059
+ function onTouchMove(e)
1060
+ {
1061
+ e.preventDefault();
1062
+ e = getTouchEvent(e);
1063
+ _deltaX = e.clientX - _touchStartX;
1064
+ _deltaY = e.clientY - _touchStartY;
1065
+ }
1066
+
1067
+ function onTouchEnd(e)
1068
+ {
1069
+ // e.preventDefault();
1070
+ e = getTouchEvent(e);
1071
+ _dragging = 0;
1072
+ _dragAxis = Math.abs(_deltaX) >= Math.abs(_deltaY) ? "x" : "y";
1073
+ if (_dragAxis == "x" && Math.abs(_deltaX) >= _swipeLimit)
1074
+ {
1075
+ if (_deltaX > 0)
1076
+ {
1077
+ _prevSection();
1078
+ return;
1079
+ }
1080
+ else if (_deltaX < 0)
1081
+ {
1082
+ _nextSection();
1083
+ return;
1084
+ }
1085
+ }
1086
+ else
1087
+ {
1088
+ if (_deltaY > 0 && Math.abs(_deltaY) >= _swipeLimit)
1089
+ {
1090
+ _prevPage();
1091
+ return;
1092
+ }
1093
+ else if (_deltaY < 0)
1094
+ {
1095
+ _nextPage();
1096
+ return;
1097
+ }
1098
+ }
1099
+
1100
+ }
1101
+
1102
+ function getTouchEvent(e)
1103
+ {
1104
+ if (e.touches)
1105
+ {
1106
+ e = e.touches[0];
1107
+ }
1108
+ return e;
1109
+ }
1110
+
1111
+ function getInitOffset()
1112
+ {
1113
+ var off = ftContainer.style[Brav1Toolbox.getPrefixed("transform")];
1114
+ // X
1115
+ var indexX = off.indexOf("translateX(") + 11;
1116
+ var offX = off.substring(indexX, off.indexOf(")", indexX));
1117
+ if (offX.indexOf("%") != -1)
1118
+ {
1119
+ offX = offX.replace("%", "");
1120
+ offX = (parseInt(offX) / 100) * window.innerWidth;
1121
+ }
1122
+ else if (offX.indexOf("px") != -1)
1123
+ {
1124
+ offX = parseInt(offX.replace("px", ""));
1125
+ }
1126
+ // Y
1127
+ var indexY = off.indexOf("translateY(") + 11;
1128
+ var offY = off.substring(indexY, off.indexOf(")", indexY));
1129
+ if (offY.indexOf("%") != -1)
1130
+ {
1131
+ offY = offY.replace("%", "");
1132
+ offY = (parseInt(offY) / 100) * window.innerHeight;
1133
+ }
1134
+ else if (offY.indexOf("px") != -1)
1135
+ {
1136
+ offY = parseInt(offY.replace("px", ""));
1137
+ }
1138
+ return { x:offX, y:offY };
1139
+ }
1140
+
1141
+ /*
1142
+ ###### ###### ######## ####### ## ##
1143
+ ## ## ## ## ## ## ## ## ## ##
1144
+ ## ## ## ## ## ## ## ##
1145
+ ###### ## ######## ## ## ## ##
1146
+ ## ## ## ## ## ## ## ##
1147
+ ## ## ## ## ## ## ## ## ## ##
1148
+ ###### ###### ## ## ####### ######## ########
1149
+ */
1150
+
1151
+ /**
1152
+ * native scroll management
1153
+ */
1154
+ var scrollEventEnabled = true;
1155
+
1156
+ Brav1Toolbox.addListener(window, "scroll", onNativeScroll);
1157
+
1158
+ function onNativeScroll(e)
1159
+ {
1160
+ e.preventDefault();
1161
+ resetScroll();
1162
+ }
1163
+
1164
+ /*
1165
+ ######## ######## ###### #### ######## ########
1166
+ ## ## ## ## ## ## ## ##
1167
+ ## ## ## ## ## ## ##
1168
+ ######## ###### ###### ## ## ######
1169
+ ## ## ## ## ## ## ##
1170
+ ## ## ## ## ## ## ## ##
1171
+ ## ## ######## ###### #### ######## ########
1172
+ */
1173
+
1174
+ /**
1175
+ * monitoring function that triggers hashChange when resizing window
1176
+ */
1177
+ var resizeMonitor = (function _resizeMonitor()
1178
+ {
1179
+ var ticker = NaN;
1180
+ function _enable()
1181
+ {
1182
+ _disable();
1183
+ if (!isOverview)
1184
+ {
1185
+ ticker = setTimeout(doResizeHandler, 300);
1186
+ }
1187
+ }
1188
+
1189
+ function _disable()
1190
+ {
1191
+ clearTimeout(ticker);
1192
+ }
1193
+
1194
+ function doResizeHandler()
1195
+ {
1196
+ NavigationMatrix.updateOffsets();
1197
+ navigateTo();
1198
+ }
1199
+
1200
+ Brav1Toolbox.addListener(window, "resize", _enable);
1201
+ window.addEventListener("orientationchange", _enable, false);
1202
+
1203
+ return {
1204
+ enable: _enable,
1205
+ disable: _disable,
1206
+ }
1207
+ })();
1208
+
1209
+ /*
1210
+ ## ## ######## #### ## ######
1211
+ ## ## ## ## ## ## ##
1212
+ ## ## ## ## ## ##
1213
+ ## ## ## ## ## ######
1214
+ ## ## ## ## ## ##
1215
+ ## ## ## ## ## ## ##
1216
+ ####### ## #### ######## ######
1217
+ */
1218
+
1219
+ /**
1220
+ * returns the element by parsing the hash
1221
+ * @param h String the hash string to evaluate
1222
+ */
1223
+ function getElementByHash(h)
1224
+ {
1225
+ if (h.length > 0)
1226
+ {
1227
+ var aHash = h.replace("#/", "").split("/"); // TODO considerare l'ultimo slash come nullo
1228
+ var p = document.querySelector(SECTION_SELECTOR + "[data-id=__" + aHash[0] + "]") || document.querySelector(SECTION_SELECTOR + "[data-prog=__" + aHash[0] + "]");
1229
+ if (p != null)
1230
+ {
1231
+ var sp = null;
1232
+ if (aHash.length > 1)
1233
+ {
1234
+ sp = p.querySelector(PAGE_SELECTOR + "[data-id=__" + aHash[1] + "]") || p.querySelector(PAGE_SELECTOR + "[data-prog=__" + aHash[1] + "]");
1235
+ }
1236
+ if (sp == null)
1237
+ {
1238
+ sp = p.querySelector(PAGE_SELECTOR);
1239
+ }
1240
+ return sp;
1241
+ }
1242
+ }
1243
+ return;
1244
+ }
1245
+
1246
+ /**
1247
+ * public method to force navigation updates
1248
+ */
1249
+ function _updateNavigation()
1250
+ {
1251
+ NavigationMatrix.update();
1252
+ onHashChange(null, true);
1253
+ }
1254
+
1255
+ /**
1256
+ * builds and sets the title of the document parsing the attributes of the current section
1257
+ * if a data-title is available in a page and or in a section then it will be used
1258
+ * otherwise it will be used a formatted version of the hash string
1259
+ */
1260
+ function setTitle(h)
1261
+ {
1262
+ var t = siteName;
1263
+ var ht = NavigationMatrix.getCurrentPage().getAttribute("data-title");
1264
+ if (ht == null)
1265
+ {
1266
+ var hs = h.split("/");
1267
+ for (var i = 0; i < hs.length; i++)
1268
+ {
1269
+ t += " | " + hs[i];
1270
+ }
1271
+ }
1272
+ else
1273
+ {
1274
+ if (NavigationMatrix.getCurrentSection().getAttribute("data-title") != null)
1275
+ {
1276
+ t += " | " + NavigationMatrix.getCurrentSection().getAttribute("data-title");
1277
+ }
1278
+ t += " | " + ht
1279
+ }
1280
+ document.title = t;
1281
+ }
1282
+
1283
+ /**
1284
+ * returns a clean string of navigation atributes of the passed page
1285
+ * if there is a data-id attribute it will be returned
1286
+ * otherwise will be returned the data-prog attribute
1287
+ */
1288
+ function getPageId(d)
1289
+ {
1290
+ return (d.getAttribute("data-id") != null ? d.getAttribute("data-id").replace(/__/, "") : d.getAttribute("data-prog").replace(/__/, ""));
1291
+ }
1292
+
1293
+ /**
1294
+ * returns a safe version of an attribute value
1295
+ * adding __ in front of the value
1296
+ */
1297
+ function safeAttr(a)
1298
+ {
1299
+ if (a.substr(0,2) != "__")
1300
+ {
1301
+ return "__" + a;
1302
+ }
1303
+ else
1304
+ {
1305
+ return a;
1306
+ }
1307
+ }
1308
+
1309
+ /**
1310
+ * clean the save value of an attribute
1311
+ * removing __ from the beginning of the value
1312
+ */
1313
+ function unsafeAttr(a)
1314
+ {
1315
+ if (a.substr(0,2) == "__")
1316
+ {
1317
+ return a.replace(/__/, "");
1318
+ }
1319
+ else
1320
+ {
1321
+ return a;
1322
+ }
1323
+ }
1324
+
1325
+ /*
1326
+ ## ## ### ## ## #### ###### ### ######## ######## ######## #######
1327
+ ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1328
+ #### ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1329
+ ## ## ## ## ## ## ## ## ## #### ## ## ## ###### ## ## ##
1330
+ ## #### ######### ## ## ## ## ## ######### ## ## ## ## ##
1331
+ ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1332
+ ## ## ## ## ### #### ###### ## ## ## ######## ## #######
1333
+ */
1334
+
1335
+ /**
1336
+ * navigation transition logic
1337
+ * @param dest HTMLElement the page to go to
1338
+ * @param push Boolean if true the hash string were pushed to the history API
1339
+ * @param linked Boolean if true triggers a forced update of all the fragments in the pages, used when navigating from links or overview
1340
+ */
1341
+ function navigateTo(dest, push, linked)
1342
+ {
1343
+ push = push == false ? push : true;
1344
+ // if dest doesn't exist then go to homepage
1345
+ if (!dest)
1346
+ {
1347
+ if (NavigationMatrix.getCurrentPage() != null)
1348
+ {
1349
+ dest = NavigationMatrix.getCurrentPage();
1350
+ }
1351
+ else
1352
+ {
1353
+ dest = document.querySelector(PAGE_SELECTOR);
1354
+ }
1355
+ push = true;
1356
+ }
1357
+ // checks what properties use for navigation and set the style
1358
+ navigate(dest);
1359
+ //
1360
+ moveParallax(dest);
1361
+ //
1362
+ if (isOverview)
1363
+ {
1364
+ _toggleOverview(false, false);
1365
+ }
1366
+ //
1367
+ var h = NavigationMatrix.getHash(dest);
1368
+ if (linked == true)
1369
+ {
1370
+ NavigationMatrix.updateFragments();
1371
+ }
1372
+ // set history properties
1373
+ var pageIndex = NavigationMatrix.getPageIndex(dest);
1374
+ if (pastIndex.section != pageIndex.section || pastIndex.page != pageIndex.page)
1375
+ {
1376
+ if (pushHistory != null && push != false && NavigationMatrix.getCurrentFragmentIndex() == -1)
1377
+ {
1378
+ var stateObj = { token: h };
1379
+ var nextHash = "#/" + h;
1380
+ currentHash = nextHash;
1381
+ window.history.pushState(stateObj, null, currentHash);
1382
+ }
1383
+ else
1384
+ {
1385
+ document.location.hash = "/" + h;
1386
+ }
1387
+ }
1388
+ // set the title
1389
+ setTitle(h);
1390
+ //
1391
+ // dispatches an event populated with navigation data
1392
+ fireNavigationEvent();
1393
+ // cache the section and page index, useful to determine the direction of the next navigation
1394
+ pastIndex = pageIndex;
1395
+ NavigationMatrix.switchActivePage(dest, true);
1396
+ //
1397
+ if (_showProgress)
1398
+ {
1399
+ updateProgress();
1400
+ }
1401
+
1402
+ }
1403
+
1404
+ function fireNavigationEvent()
1405
+ {
1406
+ var pageIndex = NavigationMatrix.getPageIndex();
1407
+ Brav1Toolbox.dispatchEvent(NAVIGATION_EVENT, {
1408
+ section: NavigationMatrix.getCurrentSection(),
1409
+ page: NavigationMatrix.getCurrentPage(),
1410
+ sectionIndex: pageIndex.section,
1411
+ pageIndex: pageIndex.page,
1412
+ pastSectionIndex: pastIndex.section,
1413
+ pastPageIndex: pastIndex.page,
1414
+ prevSection: NavigationMatrix.hasPrevSection(),
1415
+ nextSection: NavigationMatrix.hasNextSection(),
1416
+ prevPage: NavigationMatrix.hasPrevPage(),
1417
+ nextPage: NavigationMatrix.hasNextPage(),
1418
+ fragment: NavigationMatrix.getCurrentFragment(),
1419
+ fragmentIndex: NavigationMatrix.getCurrentFragmentIndex(),
1420
+ isOverview: isOverview,
1421
+ progress: NavigationMatrix.getProgress(),
1422
+ total: NavigationMatrix.getPagesTotalLength()
1423
+ } );
1424
+ }
1425
+
1426
+ /**
1427
+ * check the availability of transform CSS property
1428
+ * if transform is not available then fallbacks to position absolute behaviour
1429
+ */
1430
+ function navigate(dest)
1431
+ {
1432
+ var x;
1433
+ var y;
1434
+ var pageIndex = NavigationMatrix.getPageIndex(dest);
1435
+ if (_slideInPx == true)
1436
+ {
1437
+ // calculate the coordinates of the destination
1438
+ x = dest.x;
1439
+ y = dest.y;
1440
+ }
1441
+ else
1442
+ {
1443
+ // calculate the index of the destination page
1444
+ x = pageIndex.section;
1445
+ y = pageIndex.page;
1446
+ }
1447
+ //
1448
+ if (Brav1Toolbox.testCSS("transform"))
1449
+ {
1450
+ if (_slideInPx)
1451
+ {
1452
+ ftContainer.style[Brav1Toolbox.getPrefixed("transform")] = "translateX(" + -x + "px) translateY(" + -y + "px)";
1453
+ }
1454
+ else
1455
+ {
1456
+ ftContainer.style[Brav1Toolbox.getPrefixed("transform")] = "translateX(" + -x * 100 + "%) translateY(" + -y * 100 + "%)";
1457
+ }
1458
+ }
1459
+ else
1460
+ {
1461
+ if (_slideInPx)
1462
+ {
1463
+ ftContainer.style.top = -y + "px";
1464
+ ftContainer.style.left = -x + "px";
1465
+ }
1466
+ else
1467
+ {
1468
+ ftContainer.style.top = -y * 100 + "%";
1469
+ ftContainer.style.left = -x * 100 + "%";
1470
+ }
1471
+ }
1472
+ resetScroll();
1473
+ }
1474
+
1475
+ function moveParallax(dest)
1476
+ {
1477
+ if (parallaxEnabled)
1478
+ {
1479
+ var pageIndex = NavigationMatrix.getPageIndex(dest);
1480
+
1481
+ var pxElements = NavigationMatrix.getParallaxElements();
1482
+ for (var i = 0; i < pxElements.length; i++)
1483
+ {
1484
+ var pxSection = pxElements[i];
1485
+ if (pxSection != undefined)
1486
+ {
1487
+ for (var ii = 0; ii < pxSection.length; ii++)
1488
+ {
1489
+ var pxPage = pxSection[ii];
1490
+ if (pxPage != undefined)
1491
+ {
1492
+ for (var iii = 0; iii < pxPage.length; iii++)
1493
+ {
1494
+ var pxElement = pxPage[iii]
1495
+ var pX = 0;
1496
+ var pY = 0;
1497
+ // sections
1498
+ if (pageIndex.section < i)
1499
+ {
1500
+ pX = pxElement.pX;
1501
+ }
1502
+ else if (pageIndex.section > i)
1503
+ {
1504
+ pX = -pxElement.pX;
1505
+ }
1506
+ // pages
1507
+ if (pageIndex.page < ii)
1508
+ {
1509
+ pY = pxElement.pY;
1510
+ }
1511
+ else if (pageIndex.page > ii)
1512
+ {
1513
+ pY = -pxElement.pY;
1514
+ }
1515
+ // animation
1516
+ if (_parallaxInPx)
1517
+ {
1518
+ pxElement.style[Brav1Toolbox.getPrefixed("transform")] = "translateX(" + pX + "px) translateY(" + pY + "px)";
1519
+ }
1520
+ else
1521
+ {
1522
+ pxElement.style[Brav1Toolbox.getPrefixed("transform")] = "translateX(" + pX + "%) translateY(" + pY + "%)";
1523
+ }
1524
+ }
1525
+ }
1526
+ }
1527
+ }
1528
+ }
1529
+ }
1530
+ }
1531
+
1532
+ function resetScroll()
1533
+ {
1534
+ window.scrollTo(0,0); // fix the eventually occurred page scrolling resetting the scroll values to 0
1535
+ }
1536
+
1537
+ /*
1538
+ ######## ######## ####### ###### ######## ######## ###### ######
1539
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1540
+ ## ## ## ## ## ## ## ## ## ## ## ##
1541
+ ######## ######## ## ## ## #### ######## ###### ###### ######
1542
+ ## ## ## ## ## ## ## ## ## ## ## ##
1543
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1544
+ ## ## ## ####### ###### ## ## ######## ###### ######
1545
+ */
1546
+ var defaultProgress = null;
1547
+ var progressFill = null;
1548
+
1549
+ function buildProgressIndicator()
1550
+ {
1551
+ var domFragment = document.createDocumentFragment();
1552
+ // create the progress container div
1553
+ defaultProgress = document.createElement("div");
1554
+ defaultProgress.className = DEFAULT_PROGRESS_CLASS;
1555
+ domFragment.appendChild(defaultProgress);
1556
+ // loop through sections
1557
+ for (var i = 0; i < NavigationMatrix.getSectionsLength(); i++)
1558
+ {
1559
+ var pDiv = document.createElement("div");
1560
+ pDiv.setAttribute("data-section", "__" + i);
1561
+ pDiv.className = SECTION_THUMB_CLASS;
1562
+ Brav1Toolbox.addClass(pDiv, "thumb-section-" + i);
1563
+ // loop through pages
1564
+ var spArray = NavigationMatrix.getPages(i)
1565
+ for (var ii = 0; ii < spArray.length; ii++) {
1566
+ var spDiv = document.createElement("div");
1567
+ spDiv.className = PAGE_THUMB_CLASS;
1568
+ spDiv.setAttribute("data-section", "__" + i);
1569
+ spDiv.setAttribute("data-page", "__" + ii);
1570
+ Brav1Toolbox.addClass(spDiv, "thumb-page-" + ii);
1571
+ pDiv.appendChild(spDiv);
1572
+ };
1573
+ defaultProgress.appendChild(pDiv);
1574
+ };
1575
+ body.appendChild(defaultProgress);
1576
+ }
1577
+
1578
+ function hideProgressIndicator()
1579
+ {
1580
+ if (defaultProgress != null)
1581
+ {
1582
+ body.removeChild(defaultProgress);
1583
+ defaultProgress = null;
1584
+ }
1585
+ }
1586
+
1587
+ function updateProgress()
1588
+ {
1589
+ if (defaultProgress != null)
1590
+ {
1591
+ var spts = defaultProgress.querySelectorAll(PAGE_THUMB_SELECTOR);
1592
+ for (var i = 0; i < spts.length; i++)
1593
+ {
1594
+ var spt = spts[i];
1595
+ var pTo = Number(unsafeAttr(spt.getAttribute("data-section")));
1596
+ var spTo = Number(unsafeAttr(spt.getAttribute("data-page")));
1597
+ if (pTo == NavigationMatrix.getPageIndex().section && spTo == NavigationMatrix.getPageIndex().page)
1598
+ {
1599
+ Brav1Toolbox.addClass(spts[i], "actual");
1600
+ }
1601
+ else
1602
+ {
1603
+ Brav1Toolbox.removeClass(spts[i], "actual");
1604
+ }
1605
+ }
1606
+
1607
+ }
1608
+ }
1609
+
1610
+ function _getDefaultProgress()
1611
+ {
1612
+ return defaultProgress;
1613
+ }
1614
+
1615
+ /*
1616
+ ####### ## ## ######## ######## ## ## #### ######## ## ## ## ## ### ## ## ### ###### ######## ## ## ######## ## ## ########
1617
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ### ## ## ### ## ## ## ## ## ## ### ### ## ### ## ##
1618
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### #### ## ## #### ## ## ## ## ## #### #### ## #### ## ##
1619
+ ## ## ## ## ###### ######## ## ## ## ###### ## ## ## ## ### ## ## ## ## ## ## ## ## ## #### ###### ## ### ## ###### ## ## ## ##
1620
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ######### ## #### ######### ## ## ## ## ## ## ## #### ##
1621
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ### ##
1622
+ ####### ### ######## ## ## ### #### ######## ### ### ## ## ## ## ## ## ## ## ###### ######## ## ## ######## ## ## ##
1623
+ */
1624
+
1625
+ /**
1626
+ * switch from the overview states
1627
+ */
1628
+ function _toggleOverview(back, navigate)
1629
+ {
1630
+ if (isOverview)
1631
+ {
1632
+ zoomIn(back, navigate);
1633
+ }
1634
+ else
1635
+ {
1636
+ overviewCachedDest = NavigationMatrix.getCurrentPage();
1637
+ zoomOut();
1638
+ }
1639
+ }
1640
+
1641
+ /**
1642
+ * zoom in the view to focus on the current section / page
1643
+ */
1644
+ function zoomIn(back, navigate)
1645
+ {
1646
+ isOverview = false;
1647
+ Brav1Toolbox.removeClass(body, "ft-overview");
1648
+ NavigationMatrix.hideFragments();
1649
+ navigate = navigate === false ? false : true;
1650
+ if (navigate == true)
1651
+ {
1652
+ if (back == true)
1653
+ {
1654
+ navigateTo(overviewCachedDest);
1655
+ }
1656
+ else
1657
+ {
1658
+ navigateTo();
1659
+ }
1660
+ }
1661
+ }
1662
+
1663
+ /**
1664
+ * zoom out the view for an overview of all the sections / pages
1665
+ */
1666
+ function zoomOut()
1667
+ {
1668
+ isOverview = true;
1669
+ Brav1Toolbox.addClass(body, "ft-overview");
1670
+ NavigationMatrix.showFragments();
1671
+ //
1672
+ if (_useOverviewVariant == false)
1673
+ {
1674
+ overviewZoomTypeA(true);
1675
+ }
1676
+ else
1677
+ {
1678
+ overviewZoomTypeB(true);
1679
+ }
1680
+ fireNavigationEvent();
1681
+ }
1682
+
1683
+ function overviewZoomTypeA(out)
1684
+ {
1685
+ // ftContainer scale version
1686
+ if (out)
1687
+ {
1688
+ var scaleX = 100 / NavigationMatrix.getSectionsLength();
1689
+ var scaleY = 100 / NavigationMatrix.getPagesLength();
1690
+ var scale = Math.min(scaleX, scaleY) * 0.9;
1691
+ var offsetX = (100 - NavigationMatrix.getSectionsLength() * scale) / 2;
1692
+ var offsetY = (100 - NavigationMatrix.getPagesLength() * scale) / 2;
1693
+ ftContainer.style[Brav1Toolbox.getPrefixed("transform")] = "translate(" + offsetX + "%, " + offsetY + "%) scale(" + scale/100 + ", " + scale/100 + ")";
1694
+ }
1695
+ }
1696
+
1697
+ function overviewZoomTypeB(out)
1698
+ {
1699
+ // ftContainer scale alternative version
1700
+ if (out)
1701
+ {
1702
+ var scale = overviewFixedScaleFactor // Math.min(scaleX, scaleY) * 0.9;
1703
+ var pIndex = NavigationMatrix.getPageIndex();
1704
+ var offsetX = 50 - (scale * pIndex.section) - (scale / 2);
1705
+ var offsetY = 50 - (scale * pIndex.page) - (scale / 2);
1706
+ ftContainer.style[Brav1Toolbox.getPrefixed("transform")] = "translate(" + offsetX + "%, " + offsetY + "%) scale(" + scale/100 + ", " + scale/100 + ")";
1707
+ }
1708
+ }
1709
+
1710
+ /*
1711
+ ## ## ######## ## ## ######## ####### ### ######## ######## ## ## ### ## ## #### ###### ### ######## #### ####### ## ##
1712
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ##
1713
+ ## ## ## #### ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ## ## ## ## ## #### ##
1714
+ ##### ###### ## ######## ## ## ## ## ######## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ## ## ## ## ## ## ##
1715
+ ## ## ## ## ## ## ## ## ######### ## ## ## ## ## #### ######### ## ## ## ## ## ######### ## ## ## ## ## ####
1716
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###
1717
+ ## ## ######## ## ######## ####### ## ## ## ## ######## ## ## ## ## ### #### ###### ## ## ## #### ####### ## ##
1718
+ */
1719
+
1720
+ /**
1721
+ * KEYBOARD NAVIGATION
1722
+ */
1723
+ Brav1Toolbox.addListener(window, "keydown", onKeyDown);
1724
+ Brav1Toolbox.addListener(window, "keyup", onKeyUp);
1725
+
1726
+ function onKeyDown(e)
1727
+ {
1728
+ var tag = e.target.tagName;
1729
+ if (tag != "INPUT" && tag != "TEXTAREA" && tag != "SELECT")
1730
+ {
1731
+ if (e.keyCode >= 37 && e.keyCode <= 40)
1732
+ {
1733
+ e.preventDefault();
1734
+ }
1735
+ }
1736
+ }
1737
+
1738
+ function onKeyUp(e)
1739
+ {
1740
+ var tag = e.target.tagName;
1741
+ var elem;
1742
+ if (tag != "INPUT" && tag != "TEXTAREA" && tag != "SELECT")
1743
+ {
1744
+ e.preventDefault();
1745
+ switch (e.keyCode)
1746
+ {
1747
+ case 27 : // esc
1748
+ _toggleOverview(true);
1749
+ break;
1750
+ case 33 : // pag up
1751
+ _gotoTop();
1752
+ break;
1753
+ case 34 : // pag down
1754
+ _gotoBottom();
1755
+ break;
1756
+ case 35 : // end
1757
+ _gotoEnd();
1758
+ break;
1759
+ case 36 : // home
1760
+ _gotoHome();
1761
+ break;
1762
+ case 37 : // left
1763
+ _prevSection(e.shiftKey);
1764
+ break;
1765
+ case 39 : // right
1766
+ _nextSection(e.shiftKey);
1767
+ break;
1768
+ case 38 : // up
1769
+ _prevPage(e.shiftKey);
1770
+ break;
1771
+ case 40 : // down
1772
+ _nextPage(e.shiftKey);
1773
+ break;
1774
+ case 13 : // return
1775
+ {
1776
+ if (isOverview)
1777
+ {
1778
+ _gotoPage(NavigationMatrix.getCurrentHilited());
1779
+ }
1780
+ break;
1781
+ }
1782
+ default :
1783
+ break;
1784
+ }
1785
+ }
1786
+ }
1787
+
1788
+ /*
1789
+ ######## ## ## ######## ## #### ###### ### ######## ####
1790
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1791
+ ## ## ## ## ## ## ## ## ## ## ## ## ## ##
1792
+ ######## ## ## ######## ## ## ## ## ## ######## ##
1793
+ ## ## ## ## ## ## ## ## ######### ## ##
1794
+ ## ## ## ## ## ## ## ## ## ## ## ## ##
1795
+ ## ####### ######## ######## #### ###### ## ## ## ####
1796
+ */
1797
+
1798
+
1799
+ /**
1800
+ * triggers the first animation when visiting the site
1801
+ * if the hash is not empty
1802
+ */
1803
+ function _start()
1804
+ {
1805
+ // init and configuration
1806
+ if (_showProgress && defaultProgress == null)
1807
+ {
1808
+ buildProgressIndicator();
1809
+ }
1810
+ // start navigation
1811
+ if (document.location.hash.length > 0)
1812
+ {
1813
+ Brav1Toolbox.addClass(ftContainer, "no-transition");
1814
+ onHashChange(null, true);
1815
+ Brav1Toolbox.removeClass(ftContainer, "no-transition");
1816
+ }
1817
+ else
1818
+ {
1819
+ if (_start.arguments.length > 0)
1820
+ {
1821
+ _gotoPage.apply(this, _start.arguments);
1822
+ }
1823
+ else
1824
+ {
1825
+ _gotoPage(0,0);
1826
+ updateProgress();
1827
+ }
1828
+ }
1829
+ }
1830
+
1831
+ /*
1832
+ * Public API to go to the next section
1833
+ * @param top Boolean if true the next section will be the first page in the next array; if false the next section will be the same index page in the next array
1834
+ */
1835
+ function _nextSection(top)
1836
+ {
1837
+ var d = NavigationMatrix.getNextSection(top, _fragmentsOnSide, isOverview);
1838
+ if (d != undefined)
1839
+ {
1840
+ navigateTo(d);
1841
+ }
1842
+ else
1843
+ {
1844
+ if (isOverview && _useOverviewVariant)
1845
+ {
1846
+ zoomOut();
1847
+ }
1848
+ }
1849
+ }
1850
+
1851
+ /*
1852
+ * Public API to go to the prev section
1853
+ *
1854
+ */
1855
+ function _prevSection(top)
1856
+ {
1857
+ var d = NavigationMatrix.getPrevSection(top, _fragmentsOnSide, isOverview);
1858
+ if (d != undefined)
1859
+ {
1860
+ navigateTo(d);
1861
+ }
1862
+ else
1863
+ {
1864
+ if (isOverview && _useOverviewVariant)
1865
+ {
1866
+ zoomOut();
1867
+ }
1868
+ }
1869
+ }
1870
+
1871
+ /*
1872
+ * Public API to go to the next page
1873
+ */
1874
+ function _nextPage(jump)
1875
+ {
1876
+ var d = NavigationMatrix.getNextPage(jump, isOverview);
1877
+ if (d != undefined)
1878
+ {
1879
+ navigateTo(d);
1880
+ }
1881
+ else
1882
+ {
1883
+ if (isOverview && _useOverviewVariant)
1884
+ {
1885
+ zoomOut();
1886
+ }
1887
+ }
1888
+ }
1889
+
1890
+ /*
1891
+ * Public API to go to the prev page
1892
+ */
1893
+ function _prevPage(jump)
1894
+ {
1895
+ var d = NavigationMatrix.getPrevPage(jump, isOverview);
1896
+ if (d != undefined)
1897
+ {
1898
+ navigateTo(d);
1899
+ }
1900
+ else
1901
+ {
1902
+ if (isOverview && _useOverviewVariant)
1903
+ {
1904
+ zoomOut();
1905
+ }
1906
+ }
1907
+ }
1908
+
1909
+ /*
1910
+ * Public API to go to a specified section / page
1911
+ * the method accepts vary parameters:
1912
+ * if two numbers were passed it assumes that the first is the section index and the second is the page index;
1913
+ * if an object is passed it assumes that the object has a section property and a page property to get the indexes to navigate;
1914
+ * if an HTMLElement is passed it assumes the element is a destination page
1915
+ */
1916
+ function _gotoPage()
1917
+ {
1918
+ var args = _gotoPage.arguments;
1919
+ if (args.length > 0)
1920
+ {
1921
+ if (args.length == 1)
1922
+ {
1923
+
1924
+ if (Brav1Toolbox.typeOf(args[0]) === "Object")
1925
+ {
1926
+ var o = args[0];
1927
+ var p = o.section;
1928
+ var sp = o.page;
1929
+ if (p != null && p != undefined)
1930
+ {
1931
+ var pd = document.querySelector(SECTION_SELECTOR + "[data-id=" + safeAttr(p) + "]");
1932
+ if (sp != null && sp != undefined)
1933
+ {
1934
+ var spd = pd.querySelector(PAGE_SELECTOR + "[data-id=" + safeAttr(sp) + "]");
1935
+ if (spd != null)
1936
+ {
1937
+ navigateTo(spd);
1938
+ return;
1939
+ }
1940
+ }
1941
+ }
1942
+ }
1943
+ else if (args[0].nodeName != undefined)
1944
+ {
1945
+ navigateTo(args[0], null, true);
1946
+ }
1947
+ }
1948
+ if (Brav1Toolbox.typeOf(args[0]) === "Number" || args[0] === 0)
1949
+ {
1950
+ var spd = NavigationMatrix.getPageByIndex(args[1], args[0]);
1951
+ navigateTo(spd);
1952
+ return;
1953
+ }
1954
+ }
1955
+ }
1956
+
1957
+ function _gotoHome()
1958
+ {
1959
+ _gotoPage(0,0);
1960
+ }
1961
+
1962
+ function _gotoEnd()
1963
+ {
1964
+ var sl = NavigationMatrix.getSectionsLength() - 1;
1965
+ _gotoPage(sl, NavigationMatrix.getPages(sl).length - 1);
1966
+ }
1967
+
1968
+ function _gotoTop()
1969
+ {
1970
+ var pageIndex = NavigationMatrix.getPageIndex();
1971
+ _gotoPage(pageIndex.section, 0);
1972
+ }
1973
+
1974
+ function _gotoBottom()
1975
+ {
1976
+ var pageIndex = NavigationMatrix.getPageIndex();
1977
+ _gotoPage(pageIndex.section, NavigationMatrix.getPages(pageIndex.section).length - 1);
1978
+ }
1979
+
1980
+ function _addEventListener(type, handler, useCapture)
1981
+ {
1982
+ Brav1Toolbox.addListener(document, type, handler, useCapture);
1983
+ }
1984
+
1985
+ /*
1986
+ ###### ######## ######## ######## ######## ######## ######
1987
+ ## ## ## ## ## ## ## ## ## ##
1988
+ ## ## ## ## ## ## ## ##
1989
+ ###### ###### ## ## ###### ######## ######
1990
+ ## ## ## ## ## ## ## ##
1991
+ ## ## ## ## ## ## ## ## ## ##
1992
+ ###### ######## ## ## ######## ## ## ######
1993
+ */
1994
+
1995
+ function _setFragmentsOnSide(v)
1996
+ {
1997
+ _fragmentsOnSide = v;
1998
+ _setFragmentsOnBack(v);
1999
+ }
2000
+
2001
+ function _setFragmentsOnBack(v)
2002
+ {
2003
+ _fragmentsOnBack = v;
2004
+ }
2005
+
2006
+ function _setUseHistory(v)
2007
+ {
2008
+ pushHistory = v;
2009
+ }
2010
+
2011
+ function _setSlideInPx(v)
2012
+ {
2013
+ _slideInPx = v;
2014
+ navigateTo();
2015
+ }
2016
+
2017
+ function _setSectionsSlideToTop(v)
2018
+ {
2019
+ _sectionsSlideToTop = v;
2020
+ }
2021
+
2022
+ function _setGridNavigation(v)
2023
+ {
2024
+ _sectionsSlideToTop = !v;
2025
+ }
2026
+
2027
+ function _setUseOverviewVariant(v)
2028
+ {
2029
+ _useOverviewVariant = v;
2030
+ }
2031
+
2032
+ function _setTwoStepsSlide(v)
2033
+ {
2034
+ _twoStepsSlide = v;
2035
+ }
2036
+
2037
+ function _setShowProgress(v)
2038
+ {
2039
+ _showProgress = v;
2040
+ if (_showProgress)
2041
+ {
2042
+ if (defaultProgress == null)
2043
+ {
2044
+ buildProgressIndicator();
2045
+ }
2046
+ updateProgress();
2047
+ }
2048
+ else
2049
+ {
2050
+ if (defaultProgress != null)
2051
+ {
2052
+ hideProgressIndicator();
2053
+ }
2054
+ }
2055
+ }
2056
+
2057
+ function _setDefaultParallaxValues(x, y)
2058
+ {
2059
+ defaultParallaxX = x;
2060
+ defaultParallaxY = y == undefined ? defaultParallaxX : y;
2061
+ NavigationMatrix.update();
2062
+ }
2063
+
2064
+ function _setParallaxInPx(v)
2065
+ {
2066
+ _parallaxInPx = v;
2067
+ }
2068
+
2069
+ /**
2070
+ * return object for public methods
2071
+ */
2072
+ return {
2073
+ start: _start,
2074
+ updateNavigation: _updateNavigation,
2075
+ nextSection: _nextSection,
2076
+ prevSection: _prevSection,
2077
+ next: _nextPage,
2078
+ prev: _prevPage,
2079
+ nextFragment: _nextPage,
2080
+ prevFragment: _prevPage,
2081
+ gotoPage: _gotoPage,
2082
+ gotoHome: _gotoHome,
2083
+ gotoTop: _gotoTop,
2084
+ gotoBottom: _gotoBottom,
2085
+ gotoEnd: _gotoEnd,
2086
+ toggleOverview: _toggleOverview,
2087
+ fragmentsOnSide: _setFragmentsOnSide,
2088
+ fragmentsOnBack: _setFragmentsOnBack,
2089
+ useHistory: _setUseHistory,
2090
+ slideInPx: _setSlideInPx,
2091
+ sectionsSlideToTop: _setSectionsSlideToTop,
2092
+ gridNavigation: _setGridNavigation,
2093
+ useOverviewVariant: _setUseOverviewVariant,
2094
+ twoStepsSlide: _setTwoStepsSlide,
2095
+ showProgress: _setShowProgress,
2096
+ addEventListener: _addEventListener,
2097
+ defaultParallaxValues: _setDefaultParallaxValues,
2098
+ parallaxInPx: _setParallaxInPx,
2099
+ getDefaultProgress: _getDefaultProgress
2100
+ };
2101
+
2102
+ })();