flowtime-rails 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ })();