summaryrefslogtreecommitdiff
path: root/deck.js/extensions/hash/deck.hash.js
diff options
context:
space:
mode:
Diffstat (limited to 'deck.js/extensions/hash/deck.hash.js')
-rw-r--r--deck.js/extensions/hash/deck.hash.js142
1 files changed, 142 insertions, 0 deletions
diff --git a/deck.js/extensions/hash/deck.hash.js b/deck.js/extensions/hash/deck.hash.js
new file mode 100644
index 0000000..879bc62
--- /dev/null
+++ b/deck.js/extensions/hash/deck.hash.js
@@ -0,0 +1,142 @@
+/*!
+Deck JS - deck.hash
+Copyright (c) 2011 Caleb Troughton
+Dual licensed under the MIT license and GPL license.
+https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
+https://github.com/imakewebthings/deck.js/blob/master/GPL-license.txt
+*/
+
+/*
+This module adds deep linking to individual slides, enables internal links
+to slides within decks, and updates the address bar with the hash as the user
+moves through the deck. A permalink anchor is also updated. Standard themes
+hide this link in browsers that support the History API, and show it for
+those that do not. Slides that do not have an id are assigned one according to
+the hashPrefix option. In addition to the on-slide container state class
+kept by core, this module adds an on-slide state class that uses the id of each
+slide.
+*/
+(function ($, deck, window, undefined) {
+ var $d = $(document),
+ $window = $(window),
+
+ /* Collection of internal fragment links in the deck */
+ $internals,
+
+ /*
+ Internal only function. Given a string, extracts the id from the hash,
+ matches it to the appropriate slide, and navigates there.
+ */
+ goByHash = function(str) {
+ var id = str.substr(str.indexOf("#") + 1),
+ slides = $[deck]('getSlides');
+
+ $.each(slides, function(i, $el) {
+ if ($el.attr('id') === id) {
+ $[deck]('go', i);
+ return false;
+ }
+ });
+
+ // If we don't set these to 0 the container scrolls due to hashchange
+ $[deck]('getContainer').scrollLeft(0).scrollTop(0);
+ };
+
+ /*
+ Extends defaults/options.
+
+ options.selectors.hashLink
+ The element matching this selector has its href attribute updated to
+ the hash of the current slide as the user navigates through the deck.
+
+ options.hashPrefix
+ Every slide that does not have an id is assigned one at initialization.
+ Assigned ids take the form of hashPrefix + slideIndex, e.g., slide-0,
+ slide-12, etc.
+
+ options.preventFragmentScroll
+ When deep linking to a hash of a nested slide, this scrolls the deck
+ container to the top, undoing the natural browser behavior of scrolling
+ to the document fragment on load.
+ */
+ $.extend(true, $[deck].defaults, {
+ selectors: {
+ hashLink: '.deck-permalink'
+ },
+
+ hashPrefix: 'slide-',
+ preventFragmentScroll: true
+ });
+
+
+ $d.bind('deck.init', function() {
+ var opts = $[deck]('getOptions');
+ $internals = $(),
+ slides = $[deck]('getSlides');
+
+ $.each(slides, function(i, $el) {
+ var hash;
+
+ /* Hand out ids to the unfortunate slides born without them */
+ if (!$el.attr('id') || $el.data('deckAssignedId') === $el.attr('id')) {
+ $el.attr('id', opts.hashPrefix + i);
+ $el.data('deckAssignedId', opts.hashPrefix + i);
+ }
+
+ hash ='#' + $el.attr('id');
+
+ /* Deep link to slides on init */
+ if (hash === window.location.hash) {
+ setTimeout(function() {$[deck]('go', i)}, 1);
+ }
+
+ /* Add internal links to this slide */
+ $internals = $internals.add('a[href="' + hash + '"]');
+ });
+
+ if (!Modernizr.hashchange) {
+ /* Set up internal links using click for the poor browsers
+ without a hashchange event. */
+ $internals.unbind('click.deckhash').bind('click.deckhash', function(e) {
+ goByHash($(this).attr('href'));
+ });
+ }
+
+ /* Set up first id container state class */
+ if (slides.length) {
+ $[deck]('getContainer').addClass(opts.classes.onPrefix + $[deck]('getSlide').attr('id'));
+ };
+ })
+ /* Update permalink, address bar, and state class on a slide change */
+ .bind('deck.change', function(e, from, to) {
+ var hash = '#' + $[deck]('getSlide', to).attr('id'),
+ hashPath = window.location.href.replace(/#.*/, '') + hash,
+ opts = $[deck]('getOptions'),
+ osp = opts.classes.onPrefix,
+ $c = $[deck]('getContainer');
+
+ $c.removeClass(osp + $[deck]('getSlide', from).attr('id'));
+ $c.addClass(osp + $[deck]('getSlide', to).attr('id'));
+
+ $(opts.selectors.hashLink).attr('href', hashPath);
+ if (Modernizr.history) {
+ window.history.replaceState({}, "", hashPath);
+ }
+ });
+
+ /* Deals with internal links in modern browsers */
+ $window.bind('hashchange.deckhash', function(e) {
+ if (e.originalEvent && e.originalEvent.newURL) {
+ goByHash(e.originalEvent.newURL);
+ }
+ else {
+ goByHash(window.location.hash);
+ }
+ })
+ /* Prevent scrolling on deep links */
+ .bind('load', function() {
+ if ($[deck]('getOptions').preventFragmentScroll) {
+ $[deck]('getContainer').scrollLeft(0).scrollTop(0);
+ }
+ });
+})(jQuery, 'deck', this); \ No newline at end of file