Initial commit.

This commit is contained in:
Greg 2020-06-25 12:43:58 -04:00
commit fbe9009d23
50 changed files with 8804 additions and 0 deletions

BIN
accel.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
ble.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

60
core/deck.core.css Normal file
View File

@ -0,0 +1,60 @@
html, body {
height: 100%;
padding: 0;
margin: 0;
}
.deck-container {
position: relative;
min-height: 100%;
margin: 0 auto;
overflow: hidden;
overflow-y: auto;
}
.js .deck-container {
visibility: hidden;
}
.ready .deck-container {
visibility: visible;
}
.touch .deck-container {
-webkit-text-size-adjust: none;
-moz-text-size-adjust: none;
}
.deck-loading {
display: none;
}
.slide {
width: auto;
min-height: 100%;
position: relative;
}
.deck-before, .deck-previous, .deck-next, .deck-after {
position: absolute;
left: -999em;
top: -999em;
}
.deck-current {
z-index: 2;
}
.slide .slide {
visibility: hidden;
position: static;
min-height: 0;
}
.deck-child-current {
position: static;
z-index: 2;
}
.deck-child-current .slide {
visibility: hidden;
}
.deck-child-current .deck-previous, .deck-child-current .deck-before, .deck-child-current .deck-current {
visibility: visible;
}

748
core/deck.core.js Normal file
View File

@ -0,0 +1,748 @@
/*!
Deck JS - deck.core
Copyright (c) 2011-2014 Caleb Troughton
Dual licensed under the MIT license.
https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
*/
/*
The deck.core module provides all the basic functionality for creating and
moving through a deck. It does so by applying classes to indicate the state of
the deck and its slides, allowing CSS to take care of the visual representation
of each state. It also provides methods for navigating the deck and inspecting
its state, as well as basic key bindings for going to the next and previous
slides. More functionality is provided by wholly separate extension modules
that use the API provided by core.
*/
(function($, undefined) {
var slides, currentIndex, $container, $fragmentLinks;
var events = {
/*
This event fires at the beginning of a slide change, before the actual
change occurs. Its purpose is to give extension authors a way to prevent
the slide change from occuring. This is done by calling preventDefault
on the event object within this event. If that is done, the deck.change
event will never be fired and the slide will not change.
*/
beforeChange: 'deck.beforeChange',
/*
This event fires whenever the current slide changes, whether by way of
next, prev, or go. The callback function is passed two parameters, from
and to, equal to the indices of the old slide and the new slide
respectively. If preventDefault is called on the event within this handler
the slide change does not occur.
$(document).bind('deck.change', function(event, from, to) {
alert('Moving from slide ' + from + ' to ' + to);
});
*/
change: 'deck.change',
/*
This event fires at the beginning of deck initialization. This event makes
a good hook for preprocessing extensions looking to modify the DOM before
the deck is fully initialized. It is also possible to halt the deck.init
event from firing while you do things in beforeInit. This can be done by
calling lockInit on the event object passed to this event. The init can be
released by calling releaseInit.
$(document).bind('deck.beforeInit', function(event) {
event.lockInit(); // halts deck.init event
window.setTimeout(function() {
event.releaseInit(); // deck.init will now fire 2 seconds later
}, 2000);
});
The init event will be fired regardless of locks after
options.initLockTimeout milliseconds.
*/
beforeInitialize: 'deck.beforeInit',
/*
This event fires at the end of deck initialization. Extensions should
implement any code that relies on user extensible options (key bindings,
element selectors, classes) within a handler for this event. Native
events associated with Deck JS should be scoped under a .deck event
namespace, as with the example below:
var $d = $(document);
$.deck.defaults.keys.myExtensionKeycode = 70; // 'h'
$d.bind('deck.init', function() {
$d.bind('keydown.deck', function(event) {
if (event.which === $.deck.getOptions().keys.myExtensionKeycode) {
// Rock out
}
});
});
*/
initialize: 'deck.init'
};
var options = {};
var $document = $(document);
var $window = $(window);
var stopPropagation = function(event) {
event.stopPropagation();
};
var updateContainerState = function() {
var oldIndex = $container.data('onSlide');
$container.removeClass(options.classes.onPrefix + oldIndex);
$container.addClass(options.classes.onPrefix + currentIndex);
$container.data('onSlide', currentIndex);
};
var updateChildCurrent = function() {
var $oldCurrent = $('.' + options.classes.current);
var $oldParents = $oldCurrent.parentsUntil(options.selectors.container);
var $newCurrent = slides[currentIndex];
var $newParents = $newCurrent.parentsUntil(options.selectors.container);
$oldParents.removeClass(options.classes.childCurrent);
$newParents.addClass(options.classes.childCurrent);
};
var removeOldSlideStates = function() {
var $all = $();
$.each(slides, function(i, el) {
$all = $all.add(el);
});
$all.removeClass([
options.classes.before,
options.classes.previous,
options.classes.current,
options.classes.next,
options.classes.after
].join(' '));
};
var addNewSlideStates = function() {
slides[currentIndex].addClass(options.classes.current);
if (currentIndex > 0) {
slides[currentIndex-1].addClass(options.classes.previous);
}
if (currentIndex + 1 < slides.length) {
slides[currentIndex+1].addClass(options.classes.next);
}
if (currentIndex > 1) {
$.each(slides.slice(0, currentIndex - 1), function(i, $slide) {
$slide.addClass(options.classes.before);
});
}
if (currentIndex + 2 < slides.length) {
$.each(slides.slice(currentIndex+2), function(i, $slide) {
$slide.addClass(options.classes.after);
});
}
};
var setAriaHiddens = function() {
$(options.selectors.slides).each(function() {
var $slide = $(this);
var isSub = $slide.closest('.' + options.classes.childCurrent).length;
var isBefore = $slide.hasClass(options.classes.before) && !isSub;
var isPrevious = $slide.hasClass(options.classes.previous) && !isSub;
var isNext = $slide.hasClass(options.classes.next);
var isAfter = $slide.hasClass(options.classes.after);
var ariaHiddenValue = isBefore || isPrevious || isNext || isAfter;
$slide.attr('aria-hidden', ariaHiddenValue);
});
};
var updateStates = function() {
updateContainerState();
updateChildCurrent();
removeOldSlideStates();
addNewSlideStates();
if (options.setAriaHiddens) {
setAriaHiddens();
}
};
var initSlidesArray = function(elements) {
if ($.isArray(elements)) {
$.each(elements, function(i, element) {
slides.push($(element));
});
}
else {
$(elements).each(function(i, element) {
slides.push($(element));
});
}
};
var bindKeyEvents = function() {
var editables = [
'input',
'textarea',
'select',
'button',
'meter',
'progress',
'[contentEditable]'
].join(', ');
$document.unbind('keydown.deck').bind('keydown.deck', function(event) {
var isNext = event.which === options.keys.next;
var isPrev = event.which === options.keys.previous;
isNext = isNext || $.inArray(event.which, options.keys.next) > -1;
isPrev = isPrev || $.inArray(event.which, options.keys.previous) > -1;
if (isNext) {
methods.next();
event.preventDefault();
}
else if (isPrev) {
methods.prev();
event.preventDefault();
}
});
$document.undelegate(editables, 'keydown.deck', stopPropagation);
$document.delegate(editables, 'keydown.deck', stopPropagation);
};
var bindTouchEvents = function() {
var startTouch;
var direction = options.touch.swipeDirection;
var tolerance = options.touch.swipeTolerance;
var listenToHorizontal = ({ both: true, horizontal: true })[direction];
var listenToVertical = ({ both: true, vertical: true })[direction];
$container.unbind('touchstart.deck');
$container.bind('touchstart.deck', function(event) {
if (!startTouch) {
startTouch = $.extend({}, event.originalEvent.targetTouches[0]);
}
});
$container.unbind('touchmove.deck');
$container.bind('touchmove.deck', function(event) {
$.each(event.originalEvent.changedTouches, function(i, touch) {
if (!startTouch || touch.identifier !== startTouch.identifier) {
return true;
}
var xDistance = touch.screenX - startTouch.screenX;
var yDistance = touch.screenY - startTouch.screenY;
var leftToRight = xDistance > tolerance && listenToHorizontal;
var rightToLeft = xDistance < -tolerance && listenToHorizontal;
var topToBottom = yDistance > tolerance && listenToVertical;
var bottomToTop = yDistance < -tolerance && listenToVertical;
if (leftToRight || topToBottom) {
$.deck('prev');
startTouch = undefined;
}
else if (rightToLeft || bottomToTop) {
$.deck('next');
startTouch = undefined;
}
return false;
});
if (listenToVertical) {
event.preventDefault();
}
});
$container.unbind('touchend.deck');
$container.bind('touchend.deck', function(event) {
$.each(event.originalEvent.changedTouches, function(i, touch) {
if (startTouch && touch.identifier === startTouch.identifier) {
startTouch = undefined;
}
});
});
};
var indexInBounds = function(index) {
return typeof index === 'number' && index >=0 && index < slides.length;
};
var createBeforeInitEvent = function() {
var event = $.Event(events.beforeInitialize);
event.locks = 0;
event.done = $.noop;
event.lockInit = function() {
++event.locks;
};
event.releaseInit = function() {
--event.locks;
if (!event.locks) {
event.done();
}
};
return event;
};
var goByHash = function(str) {
var id = str.substr(str.indexOf("#") + 1);
$.each(slides, function(i, $slide) {
if ($slide.attr('id') === id) {
$.deck('go', i);
return false;
}
});
// If we don't set these to 0 the container scrolls due to hashchange
if (options.preventFragmentScroll) {
$.deck('getContainer').scrollLeft(0).scrollTop(0);
}
};
var assignSlideId = function(i, $slide) {
var currentId = $slide.attr('id');
var previouslyAssigned = $slide.data('deckAssignedId') === currentId;
if (!currentId || previouslyAssigned) {
$slide.attr('id', options.hashPrefix + i);
$slide.data('deckAssignedId', options.hashPrefix + i);
}
};
var removeContainerHashClass = function(id) {
$container.removeClass(options.classes.onPrefix + id);
};
var addContainerHashClass = function(id) {
$container.addClass(options.classes.onPrefix + id);
};
var setupHashBehaviors = function() {
$fragmentLinks = $();
$.each(slides, function(i, $slide) {
var hash;
assignSlideId(i, $slide);
hash = '#' + $slide.attr('id');
if (hash === window.location.hash) {
setTimeout(function() {
$.deck('go', i);
}, 1);
}
$fragmentLinks = $fragmentLinks.add('a[href="' + hash + '"]');
});
if (slides.length) {
addContainerHashClass($.deck('getSlide').attr('id'));
};
};
var changeHash = function(from, to) {
var hash = '#' + $.deck('getSlide', to).attr('id');
var hashPath = window.location.href.replace(/#.*/, '') + hash;
removeContainerHashClass($.deck('getSlide', from).attr('id'));
addContainerHashClass($.deck('getSlide', to).attr('id'));
if (Modernizr.history) {
window.history.replaceState({}, "", hashPath);
}
};
/* Methods exposed in the jQuery.deck namespace */
var methods = {
/*
jQuery.deck(selector, options)
selector: string | jQuery | array
options: object, optional
Initializes the deck, using each element matched by selector as a slide.
May also be passed an array of string selectors or jQuery objects, in
which case each selector in the array is considered a slide. The second
parameter is an optional options object which will extend the default
values.
Users may also pass only an options object to init. In this case the slide
selector will be options.selectors.slides which defaults to .slide.
$.deck('.slide');
or
$.deck([
'#first-slide',
'#second-slide',
'#etc'
]);
*/
init: function(opts) {
var beforeInitEvent = createBeforeInitEvent();
var overrides = opts;
if (!$.isPlainObject(opts)) {
overrides = arguments[1] || {};
$.extend(true, overrides, {
selectors: {
slides: arguments[0]
}
});
}
options = $.extend(true, {}, $.deck.defaults, overrides);
slides = [];
currentIndex = 0;
$container = $(options.selectors.container);
// Hide the deck while states are being applied to kill transitions
$container.addClass(options.classes.loading);
// populate the array of slides for pre-init
initSlidesArray(options.selectors.slides);
// Pre init event for preprocessing hooks
beforeInitEvent.done = function() {
// re-populate the array of slides
slides = [];
initSlidesArray(options.selectors.slides);
setupHashBehaviors();
bindKeyEvents();
bindTouchEvents();
$container.scrollLeft(0).scrollTop(0);
if (slides.length) {
updateStates();
}
// Show deck again now that slides are in place
$container.removeClass(options.classes.loading);
$document.trigger(events.initialize);
};
$document.trigger(beforeInitEvent);
if (!beforeInitEvent.locks) {
beforeInitEvent.done();
}
window.setTimeout(function() {
if (beforeInitEvent.locks) {
if (window.console) {
window.console.warn('Something locked deck initialization\
without releasing it before the timeout. Proceeding with\
initialization anyway.');
}
beforeInitEvent.done();
}
}, options.initLockTimeout);
},
/*
jQuery.deck('go', index)
index: integer | string
Moves to the slide at the specified index if index is a number. Index is
0-based, so $.deck('go', 0); will move to the first slide. If index is a
string this will move to the slide with the specified id. If index is out
of bounds or doesn't match a slide id the call is ignored.
*/
go: function(indexOrId) {
var beforeChangeEvent = $.Event(events.beforeChange);
var index;
/* Number index, easy. */
if (indexInBounds(indexOrId)) {
index = indexOrId;
}
/* Id string index, search for it and set integer index */
else if (typeof indexOrId === 'string') {
$.each(slides, function(i, $slide) {
if ($slide.attr('id') === indexOrId) {
index = i;
return false;
}
});
}
if (typeof index === 'undefined') {
return;
}
/* Trigger beforeChange. If nothing prevents the change, trigger
the slide change. */
$document.trigger(beforeChangeEvent, [currentIndex, index]);
if (!beforeChangeEvent.isDefaultPrevented()) {
$document.trigger(events.change, [currentIndex, index]);
changeHash(currentIndex, index);
currentIndex = index;
updateStates();
}
},
/*
jQuery.deck('next')
Moves to the next slide. If the last slide is already active, the call
is ignored.
*/
next: function() {
methods.go(currentIndex+1);
},
/*
jQuery.deck('prev')
Moves to the previous slide. If the first slide is already active, the
call is ignored.
*/
prev: function() {
methods.go(currentIndex-1);
},
/*
jQuery.deck('getSlide', index)
index: integer, optional
Returns a jQuery object containing the slide at index. If index is not
specified, the current slide is returned.
*/
getSlide: function(index) {
index = typeof index !== 'undefined' ? index : currentIndex;
if (!indexInBounds(index)) {
return null;
}
return slides[index];
},
/*
jQuery.deck('getSlides')
Returns all slides as an array of jQuery objects.
*/
getSlides: function() {
return slides;
},
/*
jQuery.deck('getTopLevelSlides')
Returns all slides that are not subslides.
*/
getTopLevelSlides: function() {
var topLevelSlides = [];
var slideSelector = options.selectors.slides;
var subSelector = [slideSelector, slideSelector].join(' ');
$.each(slides, function(i, $slide) {
if (!$slide.is(subSelector)) {
topLevelSlides.push($slide);
}
});
return topLevelSlides;
},
/*
jQuery.deck('getNestedSlides', index)
index: integer, optional
Returns all the nested slides of the current slide. If index is
specified it returns the nested slides of the slide at that index.
If there are no nested slides this will return an empty array.
*/
getNestedSlides: function(index) {
var targetIndex = index == null ? currentIndex : index;
var $targetSlide = $.deck('getSlide', targetIndex);
var $nesteds = $targetSlide.find(options.selectors.slides);
var nesteds = $nesteds.get();
return $.map(nesteds, function(slide, i) {
return $(slide);
});
},
/*
jQuery.deck('getContainer')
Returns a jQuery object containing the deck container as defined by the
container option.
*/
getContainer: function() {
return $container;
},
/*
jQuery.deck('getOptions')
Returns the options object for the deck, including any overrides that
were defined at initialization.
*/
getOptions: function() {
return options;
},
/*
jQuery.deck('extend', name, method)
name: string
method: function
Adds method to the deck namespace with the key of name. This doesnt
give access to any private member data public methods must still be
used within method but lets extension authors piggyback on the deck
namespace rather than pollute jQuery.
$.deck('extend', 'alert', function(msg) {
alert(msg);
});
// Alerts 'boom'
$.deck('alert', 'boom');
*/
extend: function(name, method) {
methods[name] = method;
}
};
/* jQuery extension */
$.deck = function(method, arg) {
var args = Array.prototype.slice.call(arguments, 1);
if (methods[method]) {
return methods[method].apply(this, args);
}
else {
return methods.init(method, arg);
}
};
/*
The default settings object for a deck. All deck extensions should extend
this object to add defaults for any of their options.
options.classes.after
This class is added to all slides that appear after the 'next' slide.
options.classes.before
This class is added to all slides that appear before the 'previous'
slide.
options.classes.childCurrent
This class is added to all elements in the DOM tree between the
'current' slide and the deck container. For standard slides, this is
mostly seen and used for nested slides.
options.classes.current
This class is added to the current slide.
options.classes.loading
This class is applied to the deck container during loading phases and is
primarily used as a way to short circuit transitions between states
where such transitions are distracting or unwanted. For example, this
class is applied during deck initialization and then removed to prevent
all the slides from appearing stacked and transitioning into place
on load.
options.classes.next
This class is added to the slide immediately following the 'current'
slide.
options.classes.onPrefix
This prefix, concatenated with the current slide index, is added to the
deck container as you change slides.
options.classes.previous
This class is added to the slide immediately preceding the 'current'
slide.
options.selectors.container
Elements matched by this CSS selector will be considered the deck
container. The deck container is used to scope certain states of the
deck, as with the onPrefix option, or with extensions such as deck.goto
and deck.menu.
options.selectors.slides
Elements matched by this selector make up the individual deck slides.
If a user chooses to pass the slide selector as the first argument to
$.deck() on initialization it does the same thing as passing in this
option and this option value will be set to the value of that parameter.
options.keys.next
The numeric keycode used to go to the next slide.
options.keys.previous
The numeric keycode used to go to the previous slide.
options.touch.swipeDirection
The direction swipes occur to cause slide changes. Can be 'horizontal',
'vertical', or 'both'. Any other value or a falsy value will disable
swipe gestures for navigation.
options.touch.swipeTolerance
The number of pixels the users finger must travel to produce a swipe
gesture.
options.initLockTimeout
The number of milliseconds the init event will wait for BeforeInit event
locks to be released before firing the init event regardless.
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.
options.setAriaHiddens
When set to true, deck.js will set aria hidden attributes for slides
that do not appear onscreen according to a typical heirarchical
deck structure. You may want to turn this off if you are using a theme
where slides besides the current slide are visible on screen and should
be accessible to screenreaders.
*/
$.deck.defaults = {
classes: {
after: 'deck-after',
before: 'deck-before',
childCurrent: 'deck-child-current',
current: 'deck-current',
loading: 'deck-loading',
next: 'deck-next',
onPrefix: 'on-slide-',
previous: 'deck-previous'
},
selectors: {
container: '.deck-container',
slides: '.slide'
},
keys: {
// enter, space, page down, right arrow, down arrow,
next: [13, 32, 34, 39, 40],
// backspace, page up, left arrow, up arrow
previous: [8, 33, 37, 38]
},
touch: {
swipeDirection: 'horizontal',
swipeTolerance: 60
},
initLockTimeout: 10000,
hashPrefix: 'slide-',
preventFragmentScroll: true,
setAriaHiddens: true
};
$document.ready(function() {
$('html').addClass('ready');
});
$window.bind('hashchange.deck', function(event) {
if (event.originalEvent && event.originalEvent.newURL) {
goByHash(event.originalEvent.newURL);
}
else {
goByHash(window.location.hash);
}
});
$window.bind('load.deck', function() {
if (options.preventFragmentScroll) {
$container.scrollLeft(0).scrollTop(0);
}
});
})(jQuery);

65
core/deck.core.scss Executable file
View File

@ -0,0 +1,65 @@
html, body {
height:100%;
padding:0;
margin:0;
}
.deck-container {
position:relative;
min-height:100%;
margin:0 auto;
overflow:hidden;
overflow-y:auto;
.js & {
visibility:hidden;
}
.ready & {
visibility:visible;
}
.touch & {
-webkit-text-size-adjust:none;
-moz-text-size-adjust:none;
}
}
.deck-loading {
display:none;
}
.slide {
width:auto;
min-height:100%;
position:relative;
}
.deck-before, .deck-previous, .deck-next, .deck-after {
position:absolute;
left:-999em;
top:-999em;
}
.deck-current {
z-index:2;
}
.slide .slide {
visibility:hidden;
position:static;
min-height:0;
}
.deck-child-current {
position:static;
z-index:2;
.slide {
visibility:hidden;
}
.deck-previous, .deck-before, .deck-current {
visibility:visible;
}
}

25
core/print.css Normal file
View File

@ -0,0 +1,25 @@
body {
font-size: 18pt;
}
h1 {
font-size: 48pt;
}
h2 {
font-size: 36pt;
}
h3 {
font-size: 28pt;
}
pre {
border: 1px solid #000;
padding: 10px;
white-space: pre-wrap;
}
.deck-container > .slide {
page-break-after: always;
}

14
core/print.scss Normal file
View File

@ -0,0 +1,14 @@
body { font-size:18pt; }
h1 { font-size:48pt; }
h2 { font-size:36pt; }
h3 { font-size:28pt; }
pre {
border:1px solid #000;
padding:10px;
white-space:pre-wrap;
}
.deck-container > .slide {
page-break-after: always;
}

View File

@ -0,0 +1,36 @@
.goto-form {
position: absolute;
z-index: 3;
bottom: 10px;
left: 50%;
height: 1.75em;
margin: 0 0 0 -9.125em;
line-height: 1.75em;
padding: 0.625em;
display: none;
background: #ccc;
overflow: hidden;
border-radius: 10px;
}
.goto-form label {
font-weight: bold;
}
.goto-form label, .goto-form input {
display: inline-block;
font-family: inherit;
}
.deck-goto .goto-form {
display: block;
}
#goto-slide {
width: 8.375em;
margin: 0 0.625em;
height: 1.4375em;
}
@media print {
.goto-form, #goto-slide {
display: none;
}
}

View File

@ -0,0 +1,7 @@
<!-- Place the following snippet at the bottom of the deck container. -->
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="text" name="slidenum" id="goto-slide" list="goto-datalist">
<datalist id="goto-datalist"></datalist>
<input type="submit" value="Go">
</form>

View File

@ -0,0 +1,190 @@
/*!
Deck JS - deck.goto
Copyright (c) 2011-2014 Caleb Troughton
Dual licensed under the MIT license.
https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
*/
/*
This module adds the necessary methods and key bindings to show and hide a form
for jumping to any slide number/id in the deck (and processes that form
accordingly). The form-showing state is indicated by the presence of a class on
the deck container.
*/
(function($, undefined) {
var $document = $(document);
var rootCounter;
var bindKeyEvents = function() {
$document.unbind('keydown.deckgoto');
$document.bind('keydown.deckgoto', function(event) {
var key = $.deck('getOptions').keys.goto;
if (event.which === key || $.inArray(event.which, key) > -1) {
event.preventDefault();
$.deck('toggleGoTo');
}
});
};
var populateDatalist = function() {
var options = $.deck('getOptions');
var $datalist = $(options.selectors.gotoDatalist);
$.each($.deck('getSlides'), function(i, $slide) {
var id = $slide.attr('id');
if (id) {
$datalist.append('<option value="' + id + '">');
}
});
};
var markRootSlides = function() {
var options = $.deck('getOptions');
var slideTest = $.map([
options.classes.before,
options.classes.previous,
options.classes.current,
options.classes.next,
options.classes.after
], function(el, i) {
return '.' + el;
}).join(', ');
rootCounter = 0;
$.each($.deck('getSlides'), function(i, $slide) {
var $parentSlides = $slide.parentsUntil(
options.selectors.container,
slideTest
);
if ($parentSlides.length) {
$slide.removeData('rootIndex');
}
else if (!options.countNested) {
++rootCounter;
$slide.data('rootIndex', rootCounter);
}
});
};
var handleFormSubmit = function() {
var options = $.deck('getOptions');
var $form = $(options.selectors.gotoForm);
$form.unbind('submit.deckgoto');
$form.bind('submit.deckgoto', function(event) {
var $field = $(options.selectors.gotoInput);
var indexOrId = $field.val();
var index = parseInt(indexOrId, 10);
if (!options.countNested) {
if (!isNaN(index) && index >= rootCounter) {
return false;
}
$.each($.deck('getSlides'), function(i, $slide) {
if ($slide.data('rootIndex') === index) {
index = i + 1;
return false;
}
});
}
$.deck('go', isNaN(index) ? indexOrId : index - 1);
$.deck('hideGoTo');
$field.val('');
event.preventDefault();
});
};
/*
Extends defaults/options.
options.classes.goto
This class is added to the deck container when showing the Go To Slide
form.
options.selectors.gotoDatalist
The element that matches this selector is the datalist element that will
be populated with options for each of the slide ids. In browsers that
support the datalist element, this provides a drop list of slide ids to
aid the user in selecting a slide.
options.selectors.gotoForm
The element that matches this selector is the form that is submitted
when a user hits enter after typing a slide number/id in the gotoInput
element.
options.selectors.gotoInput
The element that matches this selector is the text input field for
entering a slide number/id in the Go To Slide form.
options.keys.goto
The numeric keycode used to show the Go To Slide form.
options.countNested
If false, only top level slides will be counted when entering a
slide number.
*/
$.extend(true, $.deck.defaults, {
classes: {
goto: 'deck-goto'
},
selectors: {
gotoDatalist: '#goto-datalist',
gotoForm: '.goto-form',
gotoInput: '#goto-slide'
},
keys: {
goto: 71 // g
},
countNested: true
});
/*
jQuery.deck('showGoTo')
Shows the Go To Slide form by adding the class specified by the goto class
option to the deck container.
*/
$.deck('extend', 'showGoTo', function() {
var options = $.deck('getOptions');
$.deck('getContainer').addClass(options.classes.goto);
$(options.selectors.gotoForm).attr('aria-hidden', false);
$(options.selectors.gotoInput).focus();
});
/*
jQuery.deck('hideGoTo')
Hides the Go To Slide form by removing the class specified by the goto class
option from the deck container.
*/
$.deck('extend', 'hideGoTo', function() {
var options = $.deck('getOptions');
$(options.selectors.gotoInput).blur();
$.deck('getContainer').removeClass(options.classes.goto);
$(options.selectors.gotoForm).attr('aria-hidden', true);
});
/*
jQuery.deck('toggleGoTo')
Toggles between showing and hiding the Go To Slide form.
*/
$.deck('extend', 'toggleGoTo', function() {
var options = $.deck('getOptions');
var hasGotoClass = $.deck('getContainer').hasClass(options.classes.goto);
$.deck(hasGotoClass ? 'hideGoTo' : 'showGoTo');
});
$document.bind('deck.init', function() {
bindKeyEvents();
populateDatalist();
markRootSlides();
handleFormSubmit();
});
})(jQuery);

39
extensions/goto/deck.goto.scss Executable file
View File

@ -0,0 +1,39 @@
.goto-form {
position:absolute;
z-index:3;
bottom:10px;
left:50%;
height:1.75em;
margin:0 0 0 -9.125em;
line-height:1.75em;
padding:0.625em;
display:none;
background:#ccc;
overflow:hidden;
border-radius:10px;
label {
font-weight:bold;
}
label, input {
display:inline-block;
font-family:inherit;
}
.deck-goto & {
display:block;
}
}
#goto-slide {
width:8.375em;
margin:0 0.625em;
height:1.4375em;
}
@media print {
.goto-form, #goto-slide {
display:none;
}
}

View File

@ -0,0 +1,45 @@
.deck-menu {
overflow: auto;
}
.deck-menu .slide {
background: #eee;
position: relative;
left: 0;
top: 0;
visibility: visible;
cursor: pointer;
}
.no-csstransforms .deck-menu > .slide {
float: left;
width: 22%;
height: 22%;
min-height: 0;
margin: 1%;
font-size: 0.22em;
overflow: hidden;
padding: 0 0.5%;
}
.csstransforms .deck-menu > .slide {
-webkit-transform: scale(0.22) !important;
-ms-transform: scale(0.22) !important;
transform: scale(0.22) !important;
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
height: 100%;
overflow: hidden;
padding: 0 48px;
margin: 12px;
}
.deck-menu iframe, .deck-menu img, .deck-menu video {
max-width: 100%;
}
.deck-menu .deck-current, .no-touch .deck-menu .slide:hover {
background: #ddf;
}
.deck-menu.deck-container:hover .deck-prev-link, .deck-menu.deck-container:hover .deck-next-link {
display: none;
}

View File

@ -0,0 +1,225 @@
/*!
Deck JS - deck.menu
Copyright (c) 2011-2014 Caleb Troughton
Dual licensed under the MIT license.
https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
*/
/*
This module adds the methods and key binding to show and hide a menu of all
slides in the deck. The deck menu state is indicated by the presence of a class
on the deck container.
*/
(function($, undefined) {
var $document = $(document);
var $html = $('html');
var rootSlides;
var populateRootSlidesArray = function() {
var options = $.deck('getOptions');
var slideTest = $.map([
options.classes.before,
options.classes.previous,
options.classes.current,
options.classes.next,
options.classes.after
], function(el, i) {
return '.' + el;
}).join(', ');
rootSlides = [];
$.each($.deck('getSlides'), function(i, $slide) {
var $parentSlides = $slide.parentsUntil(
options.selectors.container,
slideTest
);
if (!$parentSlides.length) {
rootSlides.push($slide);
}
});
};
var bindKeyEvents = function() {
var options = $.deck('getOptions');
$document.unbind('keydown.deckmenu');
$document.bind('keydown.deckmenu', function(event) {
var isMenuKey = event.which === options.keys.menu;
isMenuKey = isMenuKey || $.inArray(event.which, options.keys.menu) > -1;
if (isMenuKey && !event.ctrlKey) {
$.deck('toggleMenu');
event.preventDefault();
}
});
};
var bindTouchEvents = function() {
var $container = $.deck('getContainer');
var options = $.deck('getOptions');
var touchEndTime = 0;
var currentSlide;
$container.unbind('touchstart.deckmenu');
$container.bind('touchstart.deckmenu', function() {
currentSlide = $.deck('getSlide');
});
$container.unbind('touchend.deckmenu');
$container.bind('touchend.deckmenu', function(event) {
var now = Date.now();
var isDoubletap = now - touchEndTime < options.touch.doubletapWindow;
// Ignore this touch event if it caused a nav change (swipe)
if (currentSlide !== $.deck('getSlide')) {
return;
}
if (isDoubletap) {
$.deck('toggleMenu');
event.preventDefault();
}
touchEndTime = now;
});
};
var setupMenuSlideSelection = function() {
var options = $.deck('getOptions');
$.each($.deck('getSlides'), function(i, $slide) {
$slide.unbind('click.deckmenu');
$slide.bind('click.deckmenu', function(event) {
if (!$.deck('getContainer').hasClass(options.classes.menu)) {
return;
}
$.deck('go', i);
$.deck('hideMenu');
event.stopPropagation();
event.preventDefault();
});
});
};
/*
Extends defaults/options.
options.classes.menu
This class is added to the deck container when showing the slide menu.
options.keys.menu
The numeric keycode used to toggle between showing and hiding the slide
menu.
options.touch.doubletapWindow
Two consecutive touch events within this number of milliseconds will
be considered a double tap, and will toggle the menu on touch devices.
*/
$.extend(true, $.deck.defaults, {
classes: {
menu: 'deck-menu'
},
keys: {
menu: 77 // m
},
touch: {
doubletapWindow: 400
}
});
/*
jQuery.deck('showMenu')
Shows the slide menu by adding the class specified by the menu class option
to the deck container.
*/
$.deck('extend', 'showMenu', function() {
var $container = $.deck('getContainer');
var options = $.deck('getOptions');
if ($container.hasClass(options.classes.menu)) {
return;
}
// Hide through loading class to short-circuit transitions (perf)
$container.addClass([
options.classes.loading,
options.classes.menu
].join(' '));
/* Forced to do this in JS until CSS learns second-grade math. Save old
style value for restoration when menu is hidden. */
if (Modernizr.csstransforms) {
$.each(rootSlides, function(i, $slide) {
$slide.data('oldStyle', $slide.attr('style'));
$slide.css({
'position': 'absolute',
'left': ((i % 4) * 25) + '%',
'top': (Math.floor(i / 4) * 25) + '%'
});
});
}
// Need to ensure the loading class renders first, then remove
window.setTimeout(function() {
$container.removeClass(options.classes.loading);
$container.scrollTop($.deck('getSlide').position().top);
}, 0);
});
/*
jQuery.deck('hideMenu')
Hides the slide menu by removing the class specified by the menu class
option from the deck container.
*/
$.deck('extend', 'hideMenu', function() {
var $container = $.deck('getContainer');
var options = $.deck('getOptions');
if (!$container.hasClass(options.classes.menu)) {
return;
}
$container.removeClass(options.classes.menu);
$container.addClass(options.classes.loading);
/* Restore old style value */
if (Modernizr.csstransforms) {
$.each(rootSlides, function(i, $slide) {
var oldStyle = $slide.data('oldStyle');
$slide.attr('style', oldStyle ? oldStyle : '');
});
}
window.setTimeout(function() {
$container.removeClass(options.classes.loading);
$container.scrollTop(0);
}, 0);
});
/*
jQuery.deck('toggleMenu')
Toggles between showing and hiding the slide menu.
*/
$.deck('extend', 'toggleMenu', function() {
$.deck('getContainer').hasClass($.deck('getOptions').classes.menu) ?
$.deck('hideMenu') : $.deck('showMenu');
});
$document.bind('deck.init', function() {
populateRootSlidesArray();
bindKeyEvents();
bindTouchEvents();
setupMenuSlideSelection();
});
$document.bind('deck.change', function(event, from, to) {
var $container = $.deck('getContainer');
var containerScroll, slideTop;
if ($container.hasClass($.deck('getOptions').classes.menu)) {
containerScroll = $container.scrollTop();
slideTop = $.deck('getSlide', to).position().top;
$container.scrollTop(containerScroll + slideTop);
}
});
})(jQuery);

55
extensions/menu/deck.menu.scss Executable file
View File

@ -0,0 +1,55 @@
.deck-menu {
overflow:auto;
.slide {
background:#eee;
position:relative;
left:0;
top:0;
visibility:visible;
cursor:pointer;
}
> .slide {
.no-csstransforms & {
float:left;
width:22%;
height:22%;
min-height:0;
margin:1%;
font-size:0.22em;
overflow:hidden;
padding:0 0.5%;
}
.csstransforms & {
-webkit-transform:scale(.22) !important;
-ms-transform:scale(.22) !important;
transform:scale(.22) !important;
-webkit-transform-origin:0 0;
-ms-transform-origin:0 0;
transform-origin:0 0;
-moz-box-sizing: border-box;
box-sizing: border-box;
width:100%;
height:100%;
overflow:hidden;
padding:0 48px;
margin:12px;
}
}
iframe, img, video {
max-width:100%;
}
.deck-current, .no-touch & .slide:hover {
background:#ddf;
}
&.deck-container:hover {
.deck-prev-link, .deck-next-link {
display:none;
}
}
}

View File

@ -0,0 +1,42 @@
.deck-prev-link, .deck-next-link {
display: none;
position: absolute;
z-index: 3;
top: 50%;
width: 32px;
height: 32px;
margin-top: -16px;
font-size: 20px;
font-weight: bold;
line-height: 32px;
vertical-align: middle;
text-align: center;
text-decoration: none;
color: #fff;
background: #888;
border-radius: 16px;
}
.deck-prev-link:hover, .deck-prev-link:focus, .deck-prev-link:active, .deck-prev-link:visited, .deck-next-link:hover, .deck-next-link:focus, .deck-next-link:active, .deck-next-link:visited {
color: #fff;
}
.deck-prev-link {
left: 8px;
}
.deck-next-link {
right: 8px;
}
.deck-container:hover .deck-prev-link, .deck-container:hover .deck-next-link {
display: block;
}
.deck-container:hover .deck-prev-link.deck-nav-disabled, .touch .deck-container:hover .deck-prev-link, .deck-container:hover .deck-next-link.deck-nav-disabled, .touch .deck-container:hover .deck-next-link {
display: none;
}
@media print {
.deck-prev-link, .deck-next-link {
display: none !important;
}
}

View File

@ -0,0 +1,5 @@
<!-- Place the following snippet at the bottom of the deck container. -->
<div aria-role="navigation">
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
<a href="#" class="deck-next-link" title="Next">&#8594;</a>
</div>

View File

@ -0,0 +1,94 @@
/*!
Deck JS - deck.navigation
Copyright (c) 2011-2014 Caleb Troughton
Dual licensed under the MIT license.
https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
*/
/*
This module adds clickable previous and next links to the deck.
*/
(function($, undefined) {
var $document = $(document);
/* Updates link hrefs, and disabled states if last/first slide */
var updateButtons = function(event, from, to) {
var options = $.deck('getOptions');
var lastIndex = $.deck('getSlides').length - 1;
var $prevSlide = $.deck('getSlide', to - 1);
var $nextSlide = $.deck('getSlide', to + 1);
var hrefBase = window.location.href.replace(/#.*/, '');
var prevId = $prevSlide ? $prevSlide.attr('id') : undefined;
var nextId = $nextSlide ? $nextSlide.attr('id') : undefined;
var $prevButton = $(options.selectors.previousLink);
var $nextButton = $(options.selectors.nextLink);
$prevButton.toggleClass(options.classes.navDisabled, to === 0);
$prevButton.attr('aria-disabled', to === 0);
$prevButton.attr('href', hrefBase + '#' + (prevId ? prevId : ''));
$nextButton.toggleClass(options.classes.navDisabled, to === lastIndex);
$nextButton.attr('aria-disabled', to === lastIndex);
$nextButton.attr('href', hrefBase + '#' + (nextId ? nextId : ''));
};
/*
Extends defaults/options.
options.classes.navDisabled
This class is added to a navigation link when that action is disabled.
It is added to the previous link when on the first slide, and to the
next link when on the last slide.
options.selectors.nextLink
The elements that match this selector will move the deck to the next
slide when clicked.
options.selectors.previousLink
The elements that match this selector will move to deck to the previous
slide when clicked.
*/
$.extend(true, $.deck.defaults, {
classes: {
navDisabled: 'deck-nav-disabled'
},
selectors: {
nextLink: '.deck-next-link',
previousLink: '.deck-prev-link'
}
});
$document.bind('deck.init', function() {
var options = $.deck('getOptions');
var slides = $.deck('getSlides');
var $current = $.deck('getSlide');
var $prevButton = $(options.selectors.previousLink);
var $nextButton = $(options.selectors.nextLink);
var index;
// Setup prev/next link events
$prevButton.unbind('click.decknavigation');
$prevButton.bind('click.decknavigation', function(event) {
$.deck('prev');
event.preventDefault();
});
$nextButton.unbind('click.decknavigation');
$nextButton.bind('click.decknavigation', function(event) {
$.deck('next');
event.preventDefault();
});
// Find where we started in the deck and set initial states
$.each(slides, function(i, $slide) {
if ($slide === $current) {
index = i;
return false;
}
});
updateButtons(null, index, index);
});
$document.bind('deck.change', updateButtons);
})(jQuery);

View File

@ -0,0 +1,44 @@
.deck-prev-link, .deck-next-link {
display:none;
position:absolute;
z-index:3;
top:50%;
width:32px;
height:32px;
margin-top:-16px;
font-size:20px;
font-weight:bold;
line-height:32px;
vertical-align:middle;
text-align:center;
text-decoration:none;
color:#fff;
background:#888;
border-radius:16px;
&:hover, &:focus, &:active, &:visited {
color:#fff;
}
}
.deck-prev-link {
left:8px;
}
.deck-next-link {
right:8px;
}
.deck-container:hover .deck-prev-link, .deck-container:hover .deck-next-link {
display:block;
&.deck-nav-disabled, .touch & {
display:none;
}
}
@media print {
.deck-prev-link, .deck-next-link {
display:none !important;
}
}

View File

@ -0,0 +1,20 @@
.csstransforms .deck-container.deck-scale:not(.deck-menu) {
overflow: hidden;
}
.csstransforms .deck-container.deck-scale:not(.deck-menu) > .slide {
-moz-box-sizing: padding-box;
box-sizing: padding-box;
width: 100%;
padding-bottom: 20px;
}
.csstransforms .deck-container.deck-scale:not(.deck-menu) > .slide > .deck-slide-scaler {
-webkit-transform-origin: 50% 0;
-ms-transform-origin: 50% 0;
transform-origin: 50% 0;
}
.csstransforms .deck-container.deck-menu .deck-slide-scaler {
-webkit-transform: none !important;
-ms-transform: none !important;
transform: none !important;
}

View File

@ -0,0 +1,190 @@
/*!
Deck JS - deck.scale
Copyright (c) 2011-2014 Caleb Troughton
Dual licensed under the MIT license.
https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
*/
/*
This module adds automatic scaling to the deck. Slides are scaled down
using CSS transforms to fit within the deck container. If the container is
big enough to hold the slides without scaling, no scaling occurs. The user
can disable and enable scaling with a keyboard shortcut.
Note: CSS transforms may make Flash videos render incorrectly. Presenters
that need to use video may want to disable scaling to play them. HTML5 video
works fine.
*/
(function($, undefined) {
var $document = $(document);
var $window = $(window);
var baseHeight, timer, rootSlides;
/*
Internal function to do all the dirty work of scaling the slides.
*/
var scaleDeck = function() {
var options = $.deck('getOptions');
var $container = $.deck('getContainer');
var baseHeight = options.baseHeight;
if (!baseHeight) {
baseHeight = $container.height();
}
// Scale each slide down if necessary (but don't scale up)
$.each(rootSlides, function(i, $slide) {
var slideHeight = $slide.innerHeight();
var $scaler = $slide.find('.' + options.classes.scaleSlideWrapper);
var shouldScale = $container.hasClass(options.classes.scale);
var scale = shouldScale ? baseHeight / slideHeight : 1;
if (scale === 1) {
$scaler.css('transform', '');
}
else {
$scaler.css('transform', 'scale(' + scale + ')');
window.setTimeout(function() {
$container.scrollTop(0)
}, 1);
}
});
};
var populateRootSlides = function() {
var options = $.deck('getOptions');
var slideTest = $.map([
options.classes.before,
options.classes.previous,
options.classes.current,
options.classes.next,
options.classes.after
], function(el, i) {
return '.' + el;
}).join(', ');
rootSlides = [];
$.each($.deck('getSlides'), function(i, $slide) {
var $parentSlides = $slide.parentsUntil(
options.selectors.container,
slideTest
);
if (!$parentSlides.length) {
rootSlides.push($slide);
}
});
};
var wrapRootSlideContent = function() {
var options = $.deck('getOptions');
var wrap = '<div class="' + options.classes.scaleSlideWrapper + '"/>';
$.each(rootSlides, function(i, $slide) {
$slide.children().wrapAll(wrap);
});
};
var scaleOnResizeAndLoad = function() {
var options = $.deck('getOptions');
$window.unbind('resize.deckscale');
$window.bind('resize.deckscale', function() {
window.clearTimeout(timer);
timer = window.setTimeout(scaleDeck, options.scaleDebounce);
});
$.deck('enableScale');
$window.unbind('load.deckscale');
$window.bind('load.deckscale', scaleDeck);
};
var bindKeyEvents = function() {
var options = $.deck('getOptions');
$document.unbind('keydown.deckscale');
$document.bind('keydown.deckscale', function(event) {
var isKey = event.which === options.keys.scale;
isKey = isKey || $.inArray(event.which, options.keys.scale) > -1;
if (isKey) {
$.deck('toggleScale');
event.preventDefault();
}
});
};
/*
Extends defaults/options.
options.classes.scale
This class is added to the deck container when scaling is enabled.
It is enabled by default when the module is included.
options.classes.scaleSlideWrapper
Scaling is done using a wrapper around the contents of each slide. This
class is applied to that wrapper.
options.keys.scale
The numeric keycode used to toggle enabling and disabling scaling.
options.baseHeight
When baseHeight is falsy, as it is by default, the deck is scaled in
proportion to the height of the deck container. You may instead specify
a height as a number of px, and slides will be scaled against this
height regardless of the container size.
options.scaleDebounce
Scaling on the browser resize event is debounced. This number is the
threshold in milliseconds. You can learn more about debouncing here:
http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
*/
$.extend(true, $.deck.defaults, {
classes: {
scale: 'deck-scale',
scaleSlideWrapper: 'deck-slide-scaler'
},
keys: {
scale: 83 // s
},
baseHeight: null,
scaleDebounce: 200
});
/*
jQuery.deck('disableScale')
Disables scaling and removes the scale class from the deck container.
*/
$.deck('extend', 'disableScale', function() {
$.deck('getContainer').removeClass($.deck('getOptions').classes.scale);
scaleDeck();
});
/*
jQuery.deck('enableScale')
Enables scaling and adds the scale class to the deck container.
*/
$.deck('extend', 'enableScale', function() {
$.deck('getContainer').addClass($.deck('getOptions').classes.scale);
scaleDeck();
});
/*
jQuery.deck('toggleScale')
Toggles between enabling and disabling scaling.
*/
$.deck('extend', 'toggleScale', function() {
var $container = $.deck('getContainer');
var isScaled = $container.hasClass($.deck('getOptions').classes.scale);
$.deck(isScaled? 'disableScale' : 'enableScale');
});
$document.bind('deck.init', function() {
populateRootSlides();
wrapRootSlideContent();
scaleOnResizeAndLoad();
bindKeyEvents();
});
})(jQuery, 'deck', this);

View File

@ -0,0 +1,22 @@
.csstransforms .deck-container.deck-scale:not(.deck-menu) {
overflow:hidden;
> .slide {
-moz-box-sizing: padding-box;
box-sizing: padding-box;
width:100%;
padding-bottom:20px;
> .deck-slide-scaler {
-webkit-transform-origin: 50% 0;
-ms-transform-origin: 50% 0;
transform-origin: 50% 0;
}
}
}
.csstransforms .deck-container.deck-menu .deck-slide-scaler {
-webkit-transform:none !important;
-ms-transform:none !important;
transform:none !important;
}

View File

@ -0,0 +1,18 @@
.deck-status {
position: absolute;
bottom: 10px;
right: 5px;
color: #888;
z-index: 3;
margin: 0;
}
body > .deck-container .deck-status {
position: fixed;
}
@media print {
.deck-status {
display: none;
}
}

View File

@ -0,0 +1,6 @@
<!-- Place the following snippet at the bottom of the deck container. -->
<p class="deck-status" aria-role="status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>

View File

@ -0,0 +1,108 @@
/*!
Deck JS - deck.status
Copyright (c) 2011-2014 Caleb Troughton
Dual licensed under the MIT license.
https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
*/
/*
This module adds a (current)/(total) style status indicator to the deck.
*/
(function($, undefined) {
var $document = $(document);
var rootCounter;
var updateCurrent = function(event, from, to) {
var options = $.deck('getOptions');
var currentSlideNumber = to + 1;
if (!options.countNested) {
currentSlideNumber = $.deck('getSlide', to).data('rootSlide');
}
$(options.selectors.statusCurrent).text(currentSlideNumber);
};
var markRootSlides = function() {
var options = $.deck('getOptions');
var slideTest = $.map([
options.classes.before,
options.classes.previous,
options.classes.current,
options.classes.next,
options.classes.after
], function(el, i) {
return '.' + el;
}).join(', ');
rootCounter = 0;
$.each($.deck('getSlides'), function(i, $slide) {
var $parentSlides = $slide.parentsUntil(
options.selectors.container,
slideTest
);
if ($parentSlides.length) {
$slide.data('rootSlide', $parentSlides.last().data('rootSlide'));
}
else {
++rootCounter;
$slide.data('rootSlide', rootCounter);
}
});
};
var setInitialSlideNumber = function() {
var slides = $.deck('getSlides');
var $currentSlide = $.deck('getSlide');
var index;
$.each(slides, function(i, $slide) {
if ($slide === $currentSlide) {
index = i;
return false;
}
});
updateCurrent(null, index, index);
};
var setTotalSlideNumber = function() {
var options = $.deck('getOptions');
var slides = $.deck('getSlides');
if (options.countNested) {
$(options.selectors.statusTotal).text(slides.length);
}
else {
$(options.selectors.statusTotal).text(rootCounter);
}
};
/*
Extends defaults/options.
options.selectors.statusCurrent
The element matching this selector displays the current slide number.
options.selectors.statusTotal
The element matching this selector displays the total number of slides.
options.countNested
If false, only top level slides will be counted in the current and
total numbers.
*/
$.extend(true, $.deck.defaults, {
selectors: {
statusCurrent: '.deck-status-current',
statusTotal: '.deck-status-total'
},
countNested: true
});
$document.bind('deck.init', function() {
markRootSlides();
setInitialSlideNumber();
setTotalSlideNumber();
});
$document.bind('deck.change', updateCurrent);
})(jQuery, 'deck');

View File

@ -0,0 +1,18 @@
.deck-status {
position:absolute;
bottom:10px;
right:5px;
color:#888;
z-index:3;
margin:0;
}
body > .deck-container .deck-status {
position:fixed;
}
@media print {
.deck-status {
display:none;
}
}

BIN
fragment.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 KiB

407
godoc-style.css Normal file
View File

@ -0,0 +1,407 @@
@charset "utf-8";
body { margin: 0px; font-family: Arial, sans-serif; background-color: rgb(2=
55, 255, 255); line-height: 1.3; text-align: center; color: rgb(34, 34, 34)=
; }
textarea { color: inherit; }
pre, code { font-family: Menlo, monospace; font-size: 0.875rem; }
pre { line-height: 1.4; overflow-x: auto; }
pre .comment { color: rgb(0, 102, 0); }
pre .highlight, pre .highlight-comment, pre .selection-highlight, pre .sele=
ction-highlight-comment { background: rgb(255, 255, 0); }
pre .selection, pre .selection-comment { background: rgb(255, 150, 50); }
pre .ln { color: rgb(153, 153, 153); background: rgb(239, 239, 239); }
.ln { user-select: none; display: inline-block; width: 8ch; }
.search-nav { margin-left: 1.25rem; font-size: 0.875rem; column-gap: 1.25re=
m; column-fill: auto; column-width: 14rem; }
.search-nav .indent { margin-left: 1.25rem; }
a, .exampleHeading .text, .expandAll { color: rgb(55, 94, 171); text-decora=
tion: none; }
a:hover, .exampleHeading .text:hover, .expandAll:hover { text-decoration: u=
nderline; }
.article a { text-decoration: underline; }
.article .title a { text-decoration: none; }
.permalink { display: none; }
:hover > .permalink { display: inline; }
p, li { max-width: 50rem; overflow-wrap: break-word; }
p, pre, ul, ol { margin: 1.25rem; }
pre { background: rgb(239, 239, 239); padding: 0.625rem; border-radius: 0.3=
125rem; }
h1, h2, h3, h4, .rootHeading { margin: 1.25rem 0px; padding: 0px; color: rg=
b(55, 94, 171); font-weight: bold; }
h1 { font-size: 1.75rem; line-height: 1; }
h1 .text-muted { color: rgb(119, 119, 119); }
h2 { font-size: 1.25rem; background: rgb(224, 235, 245); padding: 0.5rem; l=
ine-height: 1.25; font-weight: normal; overflow: auto; overflow-wrap: break=
-word; }
h2 a { font-weight: bold; }
h3 { font-size: 1.25rem; line-height: 1.25; overflow: auto; overflow-wrap: =
break-word; }
h3, h4 { margin: 1.25rem 0.3125rem; }
h4 { font-size: 1rem; }
.rootHeading { font-size: 1.25rem; margin: 0px; }
h2 > span, h3 > span { float: right; margin: 0px 25px 0px 0px; font-weight:=
normal; color: rgb(82, 121, 199); }
dl { margin: 1.25rem; }
dd { margin: 0px 0px 0px 1.25rem; }
dl, dd { font-size: 0.875rem; }
div#nav table td { vertical-align: top; }
#pkg-index h3 { font-size: 1rem; }
.pkg-dir { padding: 0px 0.625rem; }
.pkg-dir table { border-collapse: collapse; border-spacing: 0px; }
.pkg-name { padding-right: 0.625rem; }
.alert { color: rgb(170, 0, 0); }
.top-heading { float: left; padding: 1.313rem 0px; font-size: 1.25rem; font=
-weight: normal; }
.top-heading a { color: rgb(34, 34, 34); text-decoration: none; }
#pkg-examples h3 { float: left; }
#pkg-examples dl { clear: both; }
.expandAll { cursor: pointer; float: left; margin: 1.25rem 0px; }
div#topbar { background: rgb(224, 235, 245); height: 4rem; overflow: hidden=
; }
div#page { width: 100%; }
div#page > .container, div#topbar > .container { text-align: left; margin-l=
eft: auto; margin-right: auto; padding: 0px 1.25rem; }
div#topbar > .container, div#page > .container { max-width: 59.38rem; }
div#page.wide > .container, div#topbar.wide > .container { max-width: none;=
}
div#plusone { float: right; clear: right; margin-top: 0.3125rem; }
div#footer { text-align: center; color: rgb(102, 102, 102); font-size: 0.87=
5rem; margin: 2.5rem 0px; }
div#menu > a, input#search, div#learn .buttons a, div.play .buttons a, div#=
blog .read a, #menu-button { padding: 0.625rem; text-decoration: none; font=
-size: 1rem; border-radius: 0.3125rem; }
div#playground .buttons a, div#menu > a, input#search, #menu-button { borde=
r: 0.0625rem solid rgb(55, 94, 171); }
div#playground .buttons a, div#menu > a, #menu-button { color: white; backg=
round: rgb(55, 94, 171); }
#playgroundButton.active { background: white; color: rgb(55, 94, 171); }
a#start, div#learn .buttons a, div.play .buttons a, div#blog .read a { colo=
r: rgb(34, 34, 34); border: 0.0625rem solid rgb(55, 94, 171); background: r=
gb(224, 235, 245); }
.download { width: 9.375rem; }
div#menu { text-align: right; padding: 0.625rem; white-space: nowrap; max-h=
eight: 0px; transition: max-height 0.25s linear 0s; width: 100%; }
div#menu.menu-visible { max-height: 31.25rem; }
div#menu > a, #menu-button { margin: 0.625rem 0.125rem; padding: 0.625rem; =
}
::-webkit-input-placeholder { color: rgb(127, 127, 127); opacity: 1; }
::placeholder { color: rgb(127, 127, 127); opacity: 1; }
#menu .search-box { display: inline-flex; width: 8.75rem; }
input#search { background: white; color: rgb(34, 34, 34); box-sizing: borde=
r-box; -webkit-appearance: none; border-top-right-radius: 0px; border-botto=
m-right-radius: 0px; border-right: 0px; margin-right: 0px; flex-grow: 1; ma=
x-width: 100%; min-width: 5.625rem; }
input#search + button { display: inline; font-size: 1em; background-color: =
rgb(55, 94, 171); color: white; border: 0.0625rem solid rgb(55, 94, 171); b=
order-radius: 0px 0.3125rem 0.3125rem 0px; margin-left: 0px; cursor: pointe=
r; }
input#search + button span { display: flex; }
input#search + button svg { fill: white; }
#menu-button { display: none; position: absolute; right: 0.3125rem; top: 0p=
x; margin-right: 0.3125rem; }
#menu-button-arrow { display: inline-block; }
.vertical-flip { transform: rotate(-180deg); }
div.left { float: left; clear: left; margin-right: 2.5%; }
div.right { float: right; clear: right; margin-left: 2.5%; }
div.left, div.right { width: 45%; }
div#learn, div#about { padding-top: 1.25rem; }
div#learn h2, div#about { margin: 0px; }
div#about { font-size: 1.25rem; margin: 0px auto 1.875rem; }
div#gopher { background: url("/doc/gopher/frontpage.png") center top no-rep=
eat; height: 9.688rem; max-height: 200px; }
a#start { display: block; padding: 0.625rem; text-align: center; text-decor=
ation: none; border-radius: 0.3125rem; }
a#start .big { display: block; font-weight: bold; font-size: 1.25rem; }
a#start .desc { display: block; font-size: 0.875rem; font-weight: normal; m=
argin-top: 0.3125rem; }
div#learn .popout { float: right; display: block; cursor: pointer; font-siz=
e: 0.75rem; background: url("/doc/share.png") right center no-repeat; paddi=
ng: 0.375rem 1.688rem; }
div#learn pre, div#learn textarea { padding: 0px; margin: 0px; font-family:=
Menlo, monospace; font-size: 0.875rem; }
div#learn .input { padding: 0.625rem; margin-top: 0.625rem; height: 9.375re=
m; border-top-left-radius: 0.3125rem; border-top-right-radius: 0.3125rem; }
div#learn .input textarea { width: 100%; height: 100%; border: none; outlin=
e: none; resize: none; }
div#learn .output { padding: 0.625rem; height: 3.688rem; overflow: auto; bo=
rder-bottom-right-radius: 0.3125rem; border-bottom-left-radius: 0.3125rem; =
border-top: none !important; }
div#learn .output pre { padding: 0px; border-radius: 0px; }
div#learn .input, div#learn .input textarea, div#learn .output, div#learn .=
output pre { background: rgb(255, 255, 216); }
div#learn .input, div#learn .output { border: 0.0625rem solid rgb(55, 94, 1=
71); }
div#learn .buttons { float: right; padding: 1.25rem 0px 0.625rem; text-alig=
n: right; }
div#learn .buttons a { height: 1rem; margin-left: 0.3125rem; padding: 0.625=
rem; }
div#learn .toys { margin-top: 0.5rem; }
div#learn .toys select { font-size: 0.875rem; border: 0.0625rem solid rgb(5=
5, 94, 171); margin: 0px; }
div#learn .output .exit { display: none; }
div#video { max-width: 100%; }
div#blog, div#video { margin-top: 2.5rem; }
div#blog > a, div#blog > div, div#blog > h2, div#video > a, div#video > div=
, div#video > h2 { margin-bottom: 0.625rem; }
div#blog .title, div#video .title { display: block; font-size: 1.25rem; }
div#blog .when { color: rgb(102, 102, 102); font-size: 0.875rem; }
div#blog .read { text-align: right; }
@supports (--c: 0) {
[style*=3D"--aspect-ratio-padding:"] { position: relative; overflow: hidd=
en; padding-top: var(--aspect-ratio-padding); }
[style*=3D"--aspect-ratio-padding:"] > * { position: absolute; top: 0px; =
left: 0px; width: 100%; height: 100%; }
}
.toggleButton { cursor: pointer; }
.toggle > .collapsed { display: block; }
.toggle > .expanded { display: none; }
.toggleVisible > .collapsed { display: none; }
.toggleVisible > .expanded { display: block; }
table.codetable { margin-left: auto; margin-right: auto; border-style: none=
; }
table.codetable td { padding-right: 0.625rem; }
hr { border-style: solid none none; border-top-width: 0.0625rem; border-top=
-color: black; }
img.gopher { float: right; margin-left: 0.625rem; margin-bottom: 0.625rem; =
z-index: -1; }
h2 { clear: right; }
div.play { padding: 0px 1.25rem 2.5rem; }
div.play pre, div.play textarea, div.play .lines { padding: 0px; margin: 0p=
x; font-family: Menlo, monospace; font-size: 0.875rem; }
div.play .input { padding: 0.625rem; margin-top: 0.625rem; border-top-left-=
radius: 0.3125rem; border-top-right-radius: 0.3125rem; overflow: hidden; }
div.play .input textarea { width: 100%; height: 100%; border: none; outline=
: none; resize: none; overflow: hidden; }
div#playground .input textarea { overflow: auto; resize: auto; }
div.play .output { padding: 0.625rem; max-height: 12.5rem; overflow: auto; =
border-bottom-right-radius: 0.3125rem; border-bottom-left-radius: 0.3125rem=
; border-top: none !important; }
div.play .output pre { padding: 0px; border-radius: 0px; }
div.play .input, div.play .input textarea, div.play .output, div.play .outp=
ut pre { background: rgb(255, 255, 216); }
div.play .input, div.play .output { border: 0.0625rem solid rgb(55, 94, 171=
); }
div.play .buttons { float: right; padding: 1.25rem 0px 0.625rem; text-align=
: right; }
div.play .buttons a { height: 1rem; margin-left: 0.3125rem; padding: 0.625r=
em; cursor: pointer; }
.output .stderr { color: rgb(153, 51, 51); }
.output .system { color: rgb(153, 153, 153); }
div#playground { display: none; }
div#playground { position: absolute; top: 3.938rem; right: 1.25rem; padding=
: 0px 0.625rem 0.625rem; z-index: 1; text-align: left; background: rgb(224,=
235, 245); border-right: 0.0625rem solid rgb(176, 187, 197); border-bottom=
: 0.0625rem solid rgb(176, 187, 197); border-left: 0.0625rem solid rgb(176,=
187, 197); border-image: initial; border-top: none; border-bottom-left-rad=
ius: 0.3125rem; border-bottom-right-radius: 0.3125rem; }
div#playground .code { width: 32.5rem; height: 12.5rem; }
div#playground .output { height: 6.25rem; }
#content .code pre, #content .playground pre, #content .output pre { margin=
: 0px; padding: 0px; background: none; border: none; outline: transparent s=
olid 0px; overflow: auto; }
#content .playground .number, #content .code .number { color: rgb(153, 153,=
153); }
#content .code, #content .playground, #content .output { width: auto; margi=
n: 1.25rem; padding: 0.625rem; border-radius: 0.3125rem; }
#content .code, #content .playground { background: rgb(233, 233, 233); }
#content .output { background: rgb(32, 32, 32); }
#content .output .stdout, #content .output pre { color: rgb(230, 230, 230);=
}
#content .output .stderr, #content .output .error { color: rgb(244, 74, 63)=
; }
#content .output .system, #content .output .exit { color: rgb(255, 209, 77)=
; }
#content .buttons { position: relative; float: right; top: -3.125rem; right=
: 1.875rem; }
#content .output .buttons { top: -3.75rem; right: 0px; height: 0px; }
#content .buttons .kill { display: none; visibility: hidden; }
a.error { font-weight: bold; color: white; background-color: darkred; borde=
r-radius: 0.25rem; padding: 0.125rem 0.25rem; }
#heading-narrow { display: none; }
.downloading { background: rgb(249, 249, 190); padding: 0.625rem; text-alig=
n: center; border-radius: 0.3125rem; }
@media (max-width: 58.125em) {
#heading-wide { display: none; }
#heading-narrow { display: block; }
}
@media (max-width: 47.5em) {
.container .left, .container .right { width: auto; float: none; }
div#about { max-width: 31.25rem; text-align: center; }
}
@media (max-width: 62.5em) and (min-width: 43.75em) {
div#menu > a { margin: 0.3125rem 0px; font-size: 0.875rem; }
input#search { font-size: 0.875rem; }
}
@media (max-width: 43.75em) {
body { font-size: 0.9375rem; }
div#playground { left: 0px; right: 0px; }
pre, code { font-size: 0.866rem; }
div#page > .container { padding: 0px 0.625rem; }
div#topbar { height: auto; padding: 0.625rem; }
div#topbar > .container { padding: 0px; }
#heading-wide { display: block; }
#heading-narrow { display: none; }
.top-heading { float: none; display: inline-block; padding: 0.75rem; }
div#menu { padding: 0px; min-width: 0px; text-align: left; float: left; }
div#menu > a { display: block; margin-left: 0px; margin-right: 0px; }
#menu .search-box { display: flex; width: 100%; }
#menu-button { display: inline-block; }
p, pre, ul, ol { margin: 0.625rem; }
.pkg-synopsis { display: none; }
img.gopher { display: none; }
}
@media (max-width: 30em) {
#heading-wide { display: none; }
#heading-narrow { display: block; }
}
@media print {
pre { background: rgb(255, 255, 255); border: 0.0625rem solid rgb(187, 18=
7, 187); white-space: pre-wrap; }
}

215
introduction/index.html Normal file
View File

@ -0,0 +1,215 @@
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie6" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Getting Started with deck.js</title>
<meta name="description" content="A jQuery library for modern HTML presentations">
<meta name="author" content="Caleb Troughton">
<meta name="viewport" content="width=1024, user-scalable=no">
<!-- Core and extension CSS files -->
<link rel="stylesheet" media="screen" href="../core/deck.core.css">
<link rel="stylesheet" media="screen" href="../extensions/goto/deck.goto.css">
<link rel="stylesheet" media="screen" href="../extensions/menu/deck.menu.css">
<link rel="stylesheet" media="screen" href="../extensions/navigation/deck.navigation.css">
<link rel="stylesheet" media="screen" href="../extensions/status/deck.status.css">
<link rel="stylesheet" media="screen" href="../extensions/scale/deck.scale.css">
<!-- Style theme. More available in /themes/style/ or create your own. -->
<link rel="stylesheet" media="screen" href="../themes/style/web-2.0.css">
<!-- Transition theme. More available in /themes/transition/ or create your own. -->
<link rel="stylesheet" media="screen" href="../themes/transition/horizontal-slide.css">
<!-- Basic black and white print styles -->
<link rel="stylesheet" media="print" href="../core/print.css">
<script src="../modernizr.custom.js"></script>
</head>
<body>
<div class="deck-container">
<!-- Begin slides -->
<section class="slide" id="title-slide">
<h1>Getting Started with deck.js</h1>
</section>
<section class="slide" id="how-to-overview">
<h2>How to Make a Deck</h2>
<ol>
<li>
<h3>Write Slides</h3>
<p>Slide content is simple&nbsp;HTML.</p>
</li>
<li>
<h3>Choose Themes</h3>
<p>One for slide styles and one for deck&nbsp;transitions.</p>
</li>
<li>
<h3>Include Extensions</h3>
<p>Add extra functionality to your deck, or leave it stripped&nbsp;down.</p>
</li>
</ol>
</section>
<section class="slide" id="quick-start">
<h2>Quick Start</h2>
<p>When you <a href="https://github.com/imakewebthings/deck.js/archive/latest.zip">download</a> deck.js, it will include a file named <code>boilerplate.html</code>. You can immediately start editing slides in this page and viewing them in your web browser. Later on, when you are comfortable customizing the deck, you can edit the various pieces of the boilerplate or make your own to suit your needs.</p>
</section>
<section class="slide" id="markup">
<h2>The Markup</h2>
<p>Slides are just HTML elements with a class of <code>slide</code>.</p>
<pre><code>&lt;section class=&quot;slide&quot;&gt;
&lt;h2&gt;How to Make a Deck&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;Write Slides&lt;/h3&gt;
&lt;p&gt;Slide content is simple HTML.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;Choose Themes&lt;/h3&gt;
&lt;p&gt;One for slide styles and one for deck transitions.&lt;/p&gt;
&lt;/li&gt;
&hellip;
&lt;/ol&gt;
&lt;/section&gt;</code></pre>
</section>
<section class="slide" id="themes">
<h2>Style Themes</h2>
<p>Customizes the colors, typography, and layout of slide&nbsp;content.</p>
<pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;/path/to/css/style-theme.css&quot;&gt;</code></pre>
<h2>Transition Themes</h2>
<p>Defines transitions between slides using CSS3 transitions. Less capable browsers fall back to cutaways. But <strong>you</strong> aren&rsquo;t using <em>those</em> browsers to give your presentations, are&nbsp;you&hellip;</p>
<pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;/path/to/css/transition-theme.css&quot;&gt;</code></pre>
</section>
<section class="slide" id="extensions">
<h2>Extensions</h2>
<p>Core gives you basic slide functionality with left and right arrow navigation, but you may want more. Here are the ones included in this&nbsp;deck:</p>
<ul>
<li class="slide" id="extensions-goto">
<strong>deck.goto</strong>: Adds a shortcut key to jump to any slide number. Hit g, type in the slide number, and hit&nbsp;enter.
</li>
<li class="slide" id="extensions-menu">
<strong>deck.menu</strong>: Adds a menu view, letting you see all slides in a grid. Hit m to toggle to menu view, continue navigating your deck, and hit m to return to normal view. Touch devices can double-tap the deck to switch between&nbsp;views.
</li>
<li class="slide" id="extensions-navigation">
<strong>deck.navigation</strong>: Adds clickable left and right buttons for the less keyboard&nbsp;inclined.
</li>
<li class="slide" id="extensions-status">
<strong>deck.status</strong>: Adds a page number indicator. (current/total)
</li>
<li class="slide" id="extensions-scale">
<strong>deck.scale</strong>: Scales each slide to fit within the deck container using CSS Transforms for those browsers that support them.
</li>
</ul>
<p class="slide" id="extension-folders">Each extension folder in the download package contains the necessary JavaScript, CSS, and HTML&nbsp;files. For a complete list of extension modules included in deck.js, check out the&nbsp;<a href="http://imakewebthings.github.com/deck.js/docs">documentation</a>.</p>
</section>
<section class="slide" id="nested">
<h2>Nested Slides</h2>
<p>That last slide had a few steps. To create substeps in slides, just nest them:</p>
<pre><code>&lt;section class=&quot;slide&quot;&gt;
&lt;h2&gt;Extensions&lt;/h2&gt;
&lt;p&gt;Core gives you basic slide functionality...&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;slide&quot;&gt;
&lt;h3&gt;deck.goto&lt;/h3&gt;
&lt;p&gt;Adds a shortcut key to jump to any slide number...&lt;/p&gt;
&lt;/li&gt;
&lt;li class=&quot;slide&quot;&gt;...&lt;/li&gt;
&lt;li class=&quot;slide&quot;&gt;...&lt;/li&gt;
&lt;li class=&quot;slide&quot;&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;</code></pre>
</section>
<section class="slide" id="elements-images">
<h2>Other Elements: Images</h2>
<img src="http://placekitten.com/600/375" alt="Kitties">
<pre><code>&lt;img src=&quot;http://placekitten.com/600/375&quot; alt=&quot;Kitties&quot;&gt;</code></pre>
</section>
<section class="slide" id="elements-blockquotes">
<h2>Other Elements: Blockquotes</h2>
<blockquote cite="http://example.org">
<p>Food is an important part of a balanced diet.</p>
<p><cite>Fran Lebowitz</cite></p>
</blockquote>
<pre><code>&lt;blockquote cite=&quot;http://example.org&quot;&gt;
&lt;p&gt;Food is an important part of a balanced diet.&lt;/p&gt;
&lt;p&gt;&lt;cite&gt;Fran Lebowitz&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;</code></pre>
</section>
<section class="slide" id="elements-videos">
<h2>Other Elements: Video Embeds</h2>
<p>Embed videos from your favorite online video service or with an HTML5 video&nbsp;element.</p>
<iframe src="http://player.vimeo.com/video/1063136?title=0&amp;byline=0&amp;portrait=0" width="400" height="225" frameborder="0"></iframe>
<pre><code>&lt;iframe src=&quot;http://player.vimeo.com/video/1063136?title=0&amp;amp;byline=0&amp;amp;portrait=0&quot; width=&quot;400&quot; height=&quot;225&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;</code></pre>
</section>
<section class="slide" id="digging-deeper">
<h2>Digging Deeper</h2>
<p>If you want to learn about making your own themes, extending deck.js, and more, check out the&nbsp;<a href="../docs/">documentation</a>.</p>
</section>
<!-- deck.navigation snippet -->
<div aria-role="navigation">
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
<a href="#" class="deck-next-link" title="Next">&#8594;</a>
</div>
<!-- deck.status snippet -->
<p class="deck-status" aria-role="status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<!-- deck.goto snippet -->
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="text" name="slidenum" id="goto-slide" list="goto-datalist">
<datalist id="goto-datalist"></datalist>
<input type="submit" value="Go">
</form>
</div>
<script src="../jquery.min.js"></script>
<!-- Deck Core and extensions -->
<script src="../core/deck.core.js"></script>
<script src="../extensions/menu/deck.menu.js"></script>
<script src="../extensions/goto/deck.goto.js"></script>
<script src="../extensions/status/deck.status.js"></script>
<script src="../extensions/navigation/deck.navigation.js"></script>
<script src="../extensions/scale/deck.scale.js"></script>
<!-- Initialize the deck -->
<script>
$(function() {
$.deck('.slide');
});
</script>
</body>
</html>

BIN
jni.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

View File

@ -0,0 +1,640 @@
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/* A little code to ease navigation of these documents.
*
* On window load we:
* + Generate a table of contents (generateTOC)
* + Bind foldable sections (bindToggles)
* + Bind links to foldable sections (bindToggleLinks)
*/
(function() {
'use strict';
// Mobile-friendly topbar menu
$(function() {
var menu = $('#menu');
var menuButton = $('#menu-button');
var menuButtonArrow = $('#menu-button-arrow');
menuButton.click(function(event) {
menu.toggleClass('menu-visible');
menuButtonArrow.toggleClass('vertical-flip');
event.preventDefault();
return false;
});
});
/* Generates a table of contents: looks for h2 and h3 elements and generates
* links. "Decorates" the element with id=="nav" with this table of contents.
*/
function generateTOC() {
if ($('#manual-nav').length > 0) {
return;
}
// For search, we send the toc precomputed from server-side.
// TODO: Ideally, this should always be precomputed for all pages, but then
// we need to do HTML parsing on the server-side.
if (location.pathname === '/search') {
return;
}
var nav = $('#nav');
if (nav.length === 0) {
return;
}
var toc_items = [];
$(nav).nextAll('h2, h3').each(function() {
var node = this;
if (node.id == '')
node.id = 'tmp_' + toc_items.length;
var link = $('<a/>').attr('href', '#' + node.id).text($(node).text());
var item;
if ($(node).is('h2')) {
item = $('<dt/>');
} else { // h3
item = $('<dd class="indent"/>');
}
item.append(link);
toc_items.push(item);
});
if (toc_items.length <= 1) {
return;
}
var dl1 = $('<dl/>');
var dl2 = $('<dl/>');
var split_index = (toc_items.length / 2) + 1;
if (split_index < 8) {
split_index = toc_items.length;
}
for (var i = 0; i < split_index; i++) {
dl1.append(toc_items[i]);
}
for (/* keep using i */; i < toc_items.length; i++) {
dl2.append(toc_items[i]);
}
var tocTable = $('<table class="unruled"/>').appendTo(nav);
var tocBody = $('<tbody/>').appendTo(tocTable);
var tocRow = $('<tr/>').appendTo(tocBody);
// 1st column
$('<td class="first"/>').appendTo(tocRow).append(dl1);
// 2nd column
$('<td/>').appendTo(tocRow).append(dl2);
}
function bindToggle(el) {
$('.toggleButton', el).click(function() {
if ($(this).closest(".toggle, .toggleVisible")[0] != el) {
// Only trigger the closest toggle header.
return;
}
if ($(el).is('.toggle')) {
$(el).addClass('toggleVisible').removeClass('toggle');
} else {
$(el).addClass('toggle').removeClass('toggleVisible');
}
});
}
function bindToggles(selector) {
$(selector).each(function(i, el) {
bindToggle(el);
});
}
function bindToggleLink(el, prefix) {
$(el).click(function() {
var href = $(el).attr('href');
var i = href.indexOf('#'+prefix);
if (i < 0) {
return;
}
var id = '#' + prefix + href.slice(i+1+prefix.length);
if ($(id).is('.toggle')) {
$(id).find('.toggleButton').first().click();
}
});
}
function bindToggleLinks(selector, prefix) {
$(selector).each(function(i, el) {
bindToggleLink(el, prefix);
});
}
function setupDropdownPlayground() {
if (!$('#page').is('.wide')) {
return; // don't show on front page
}
var button = $('#playgroundButton');
var div = $('#playground');
var setup = false;
button.toggle(function() {
button.addClass('active');
div.show();
if (setup) {
return;
}
setup = true;
playground({
'codeEl': $('.code', div),
'outputEl': $('.output', div),
'runEl': $('.run', div),
'fmtEl': $('.fmt', div),
'shareEl': $('.share', div),
'shareRedirect': '//play.golang.org/p/'
});
},
function() {
button.removeClass('active');
div.hide();
});
$('#menu').css('min-width', '+=60');
// Hide inline playground if we click somewhere on the page.
// This is needed in mobile devices, where the "Play" button
// is not clickable once the playground opens up.
$("#page").click(function() {
if (button.hasClass('active')) {
button.click();
}
});
}
function setupInlinePlayground() {
'use strict';
// Set up playground when each element is toggled.
$('div.play').each(function (i, el) {
// Set up playground for this example.
var setup = function() {
var code = $('.code', el);
playground({
'codeEl': code,
'outputEl': $('.output', el),
'runEl': $('.run', el),
'fmtEl': $('.fmt', el),
'shareEl': $('.share', el),
'shareRedirect': '//play.golang.org/p/'
});
// Make the code textarea resize to fit content.
var resize = function() {
code.height(0);
var h = code[0].scrollHeight;
code.height(h+20); // minimize bouncing.
code.closest('.input').height(h);
};
code.on('keydown', resize);
code.on('keyup', resize);
code.keyup(); // resize now.
};
// If example already visible, set up playground now.
if ($(el).is(':visible')) {
setup();
return;
}
// Otherwise, set up playground when example is expanded.
var built = false;
$(el).closest('.toggle').click(function() {
// Only set up once.
if (!built) {
setup();
built = true;
}
});
});
}
// fixFocus tries to put focus to div#page so that keyboard navigation works.
function fixFocus() {
var page = $('div#page');
var topbar = $('div#topbar');
page.css('outline', 0); // disable outline when focused
page.attr('tabindex', -1); // and set tabindex so that it is focusable
$(window).resize(function (evt) {
// only focus page when the topbar is at fixed position (that is, it's in
// front of page, and keyboard event will go to the former by default.)
// by focusing page, keyboard event will go to page so that up/down arrow,
// space, etc. will work as expected.
if (topbar.css('position') == "fixed")
page.focus();
}).resize();
}
function toggleHash() {
var id = window.location.hash.substring(1);
// Open all of the toggles for a particular hash.
var els = $(
document.getElementById(id),
$('a[name]').filter(function() {
return $(this).attr('name') == id;
})
);
while (els.length) {
for (var i = 0; i < els.length; i++) {
var el = $(els[i]);
if (el.is('.toggle')) {
el.find('.toggleButton').first().click();
}
}
els = el.parent();
}
}
function personalizeInstallInstructions() {
var prefix = '?download=';
var s = window.location.search;
if (s.indexOf(prefix) != 0) {
// No 'download' query string; detect "test" instructions from User Agent.
if (navigator.platform.indexOf('Win') != -1) {
$('.testUnix').hide();
$('.testWindows').show();
} else {
$('.testUnix').show();
$('.testWindows').hide();
}
return;
}
var filename = s.substr(prefix.length);
var filenameRE = /^go1\.\d+(\.\d+)?([a-z0-9]+)?\.([a-z0-9]+)(-[a-z0-9]+)?(-osx10\.[68])?\.([a-z.]+)$/;
var m = filenameRE.exec(filename);
if (!m) {
// Can't interpret file name; bail.
return;
}
$('.downloadFilename').text(filename);
$('.hideFromDownload').hide();
var os = m[3];
var ext = m[6];
if (ext != 'tar.gz') {
$('#tarballInstructions').hide();
}
if (os != 'darwin' || ext != 'pkg') {
$('#darwinPackageInstructions').hide();
}
if (os != 'windows') {
$('#windowsInstructions').hide();
$('.testUnix').show();
$('.testWindows').hide();
} else {
if (ext != 'msi') {
$('#windowsInstallerInstructions').hide();
}
if (ext != 'zip') {
$('#windowsZipInstructions').hide();
}
$('.testUnix').hide();
$('.testWindows').show();
}
var download = "https://dl.google.com/go/" + filename;
var message = $('<p class="downloading">'+
'Your download should begin shortly. '+
'If it does not, click <a>this link</a>.</p>');
message.find('a').attr('href', download);
message.insertAfter('#nav');
window.location = download;
}
function updateVersionTags() {
var v = window.goVersion;
if (/^go[0-9.]+$/.test(v)) {
$(".versionTag").empty().text(v);
$(".whereTag").hide();
}
}
function addPermalinks() {
function addPermalink(source, parent) {
var id = source.attr("id");
if (id == "" || id.indexOf("tmp_") === 0) {
// Auto-generated permalink.
return;
}
if (parent.find("> .permalink").length) {
// Already attached.
return;
}
parent.append(" ").append($("<a class='permalink'>&#xb6;</a>").attr("href", "#" + id));
}
$("#page .container").find("h2[id], h3[id]").each(function() {
var el = $(this);
addPermalink(el, el);
});
$("#page .container").find("dl[id]").each(function() {
var el = $(this);
// Add the anchor to the "dt" element.
addPermalink(el, el.find("> dt").first());
});
}
$(".js-expandAll").click(function() {
if ($(this).hasClass("collapsed")) {
toggleExamples('toggle');
$(this).text("(Collapse All)");
} else {
toggleExamples('toggleVisible');
$(this).text("(Expand All)");
}
$(this).toggleClass("collapsed")
});
function toggleExamples(className) {
// We need to explicitly iterate through divs starting with "example_"
// to avoid toggling Overview and Index collapsibles.
$("[id^='example_']").each(function() {
// Check for state and click it only if required.
if ($(this).hasClass(className)) {
$(this).find('.toggleButton').first().click();
}
});
}
$(document).ready(function() {
generateTOC();
addPermalinks();
bindToggles(".toggle");
bindToggles(".toggleVisible");
bindToggleLinks(".exampleLink", "example_");
bindToggleLinks(".overviewLink", "");
bindToggleLinks(".examplesLink", "");
bindToggleLinks(".indexLink", "");
setupDropdownPlayground();
setupInlinePlayground();
fixFocus();
setupTypeInfo();
setupCallgraphs();
toggleHash();
personalizeInstallInstructions();
updateVersionTags();
// godoc.html defines window.initFuncs in the <head> tag, and root.html and
// codewalk.js push their on-page-ready functions to the list.
// We execute those functions here, to avoid loading jQuery until the page
// content is loaded.
for (var i = 0; i < window.initFuncs.length; i++) window.initFuncs[i]();
});
// -- analysis ---------------------------------------------------------
// escapeHTML returns HTML for s, with metacharacters quoted.
// It is safe for use in both elements and attributes
// (unlike the "set innerText, read innerHTML" trick).
function escapeHTML(s) {
return s.replace(/&/g, '&amp;').
replace(/\"/g, '&quot;').
replace(/\'/g, '&#39;').
replace(/</g, '&lt;').
replace(/>/g, '&gt;');
}
// makeAnchor returns HTML for an <a> element, given an anchorJSON object.
function makeAnchor(json) {
var html = escapeHTML(json.Text);
if (json.Href != "") {
html = "<a href='" + escapeHTML(json.Href) + "'>" + html + "</a>";
}
return html;
}
function showLowFrame(html) {
var lowframe = document.getElementById('lowframe');
lowframe.style.height = "200px";
lowframe.innerHTML = "<p style='text-align: left;'>" + html + "</p>\n" +
"<div onclick='hideLowFrame()' style='position: absolute; top: 0; right: 0; cursor: pointer;'>✘</div>"
};
document.hideLowFrame = function() {
var lowframe = document.getElementById('lowframe');
lowframe.style.height = "0px";
}
// onClickCallers is the onclick action for the 'func' tokens of a
// function declaration.
document.onClickCallers = function(index) {
var data = document.ANALYSIS_DATA[index]
if (data.Callers.length == 1 && data.Callers[0].Sites.length == 1) {
document.location = data.Callers[0].Sites[0].Href; // jump to sole caller
return;
}
var html = "Callers of <code>" + escapeHTML(data.Callee) + "</code>:<br/>\n";
for (var i = 0; i < data.Callers.length; i++) {
var caller = data.Callers[i];
html += "<code>" + escapeHTML(caller.Func) + "</code>";
var sites = caller.Sites;
if (sites != null && sites.length > 0) {
html += " at line ";
for (var j = 0; j < sites.length; j++) {
if (j > 0) {
html += ", ";
}
html += "<code>" + makeAnchor(sites[j]) + "</code>";
}
}
html += "<br/>\n";
}
showLowFrame(html);
};
// onClickCallees is the onclick action for the '(' token of a function call.
document.onClickCallees = function(index) {
var data = document.ANALYSIS_DATA[index]
if (data.Callees.length == 1) {
document.location = data.Callees[0].Href; // jump to sole callee
return;
}
var html = "Callees of this " + escapeHTML(data.Descr) + ":<br/>\n";
for (var i = 0; i < data.Callees.length; i++) {
html += "<code>" + makeAnchor(data.Callees[i]) + "</code><br/>\n";
}
showLowFrame(html);
};
// onClickTypeInfo is the onclick action for identifiers declaring a named type.
document.onClickTypeInfo = function(index) {
var data = document.ANALYSIS_DATA[index];
var html = "Type <code>" + data.Name + "</code>: " +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<small>(size=" + data.Size + ", align=" + data.Align + ")</small><br/>\n";
html += implementsHTML(data);
html += methodsetHTML(data);
showLowFrame(html);
};
// implementsHTML returns HTML for the implements relation of the
// specified TypeInfoJSON value.
function implementsHTML(info) {
var html = "";
if (info.ImplGroups != null) {
for (var i = 0; i < info.ImplGroups.length; i++) {
var group = info.ImplGroups[i];
var x = "<code>" + escapeHTML(group.Descr) + "</code> ";
for (var j = 0; j < group.Facts.length; j++) {
var fact = group.Facts[j];
var y = "<code>" + makeAnchor(fact.Other) + "</code>";
if (fact.ByKind != null) {
html += escapeHTML(fact.ByKind) + " type " + y + " implements " + x;
} else {
html += x + " implements " + y;
}
html += "<br/>\n";
}
}
}
return html;
}
// methodsetHTML returns HTML for the methodset of the specified
// TypeInfoJSON value.
function methodsetHTML(info) {
var html = "";
if (info.Methods != null) {
for (var i = 0; i < info.Methods.length; i++) {
html += "<code>" + makeAnchor(info.Methods[i]) + "</code><br/>\n";
}
}
return html;
}
// onClickComm is the onclick action for channel "make" and "<-"
// send/receive tokens.
document.onClickComm = function(index) {
var ops = document.ANALYSIS_DATA[index].Ops
if (ops.length == 1) {
document.location = ops[0].Op.Href; // jump to sole element
return;
}
var html = "Operations on this channel:<br/>\n";
for (var i = 0; i < ops.length; i++) {
html += makeAnchor(ops[i].Op) + " by <code>" + escapeHTML(ops[i].Fn) + "</code><br/>\n";
}
if (ops.length == 0) {
html += "(none)<br/>\n";
}
showLowFrame(html);
};
$(window).load(function() {
// Scroll window so that first selection is visible.
// (This means we don't need to emit id='L%d' spans for each line.)
// TODO(adonovan): ideally, scroll it so that it's under the pointer,
// but I don't know how to get the pointer y coordinate.
var elts = document.getElementsByClassName("selection");
if (elts.length > 0) {
elts[0].scrollIntoView()
}
});
// setupTypeInfo populates the "Implements" and "Method set" toggle for
// each type in the package doc.
function setupTypeInfo() {
for (var i in document.ANALYSIS_DATA) {
var data = document.ANALYSIS_DATA[i];
var el = document.getElementById("implements-" + i);
if (el != null) {
// el != null => data is TypeInfoJSON.
if (data.ImplGroups != null) {
el.innerHTML = implementsHTML(data);
el.parentNode.parentNode.style.display = "block";
}
}
var el = document.getElementById("methodset-" + i);
if (el != null) {
// el != null => data is TypeInfoJSON.
if (data.Methods != null) {
el.innerHTML = methodsetHTML(data);
el.parentNode.parentNode.style.display = "block";
}
}
}
}
function setupCallgraphs() {
if (document.CALLGRAPH == null) {
return
}
document.getElementById("pkg-callgraph").style.display = "block";
var treeviews = document.getElementsByClassName("treeview");
for (var i = 0; i < treeviews.length; i++) {
var tree = treeviews[i];
if (tree.id == null || tree.id.indexOf("callgraph-") != 0) {
continue;
}
var id = tree.id.substring("callgraph-".length);
$(tree).treeview({collapsed: true, animated: "fast"});
document.cgAddChildren(tree, tree, [id]);
tree.parentNode.parentNode.style.display = "block";
}
}
document.cgAddChildren = function(tree, ul, indices) {
if (indices != null) {
for (var i = 0; i < indices.length; i++) {
var li = cgAddChild(tree, ul, document.CALLGRAPH[indices[i]]);
if (i == indices.length - 1) {
$(li).addClass("last");
}
}
}
$(tree).treeview({animated: "fast", add: ul});
}
// cgAddChild adds an <li> element for document.CALLGRAPH node cgn to
// the parent <ul> element ul. tree is the tree's root <ul> element.
function cgAddChild(tree, ul, cgn) {
var li = document.createElement("li");
ul.appendChild(li);
li.className = "closed";
var code = document.createElement("code");
if (cgn.Callees != null) {
$(li).addClass("expandable");
// Event handlers and innerHTML updates don't play nicely together,
// hence all this explicit DOM manipulation.
var hitarea = document.createElement("div");
hitarea.className = "hitarea expandable-hitarea";
li.appendChild(hitarea);
li.appendChild(code);
var childUL = document.createElement("ul");
li.appendChild(childUL);
childUL.setAttribute('style', "display: none;");
var onClick = function() {
document.cgAddChildren(tree, childUL, cgn.Callees);
hitarea.removeEventListener('click', onClick)
};
hitarea.addEventListener('click', onClick);
} else {
li.appendChild(code);
}
code.innerHTML += "&nbsp;" + makeAnchor(cgn.Func);
return li
}
})();

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,872 @@
body {
margin: 0;
font-family: Arial, sans-serif;
background-color: #fff;
line-height: 1.3;
text-align: center;
color: #222;
}
textarea {
/* Inherit text color from body avoiding illegible text in the case where the
* user has inverted the browsers custom text and background colors. */
color: inherit;
}
pre,
code {
font-family: Menlo, monospace;
font-size: 0.875rem;
}
pre {
line-height: 1.4;
overflow-x: auto;
}
pre .comment {
color: #006600;
}
pre .highlight,
pre .highlight-comment,
pre .selection-highlight,
pre .selection-highlight-comment {
background: #FFFF00;
}
pre .selection,
pre .selection-comment {
background: #FF9632;
}
pre .ln {
color: #999;
background: #efefef;
}
.ln {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
/* Ensure 8 characters in the document - which due to floating
* point rendering issues, might have a width of less than 1 each - are 8
* characters wide, so a tab in the 9th position indents properly. See
* https://github.com/webcompat/web-bugs/issues/17530#issuecomment-402675091
* for more information. */
display: inline-block;
width: 8ch;
}
.search-nav{
margin-left: 1.25rem;
font-size: 0.875rem;
column-gap: 1.25rem;
column-fill: auto;
column-width: 14rem;
}
.search-nav .indent {
margin-left: 1.25rem;
}
a,
.exampleHeading .text,
.expandAll {
color: #375EAB;
text-decoration: none;
}
a:hover,
.exampleHeading .text:hover,
.expandAll:hover {
text-decoration: underline;
}
.article a {
text-decoration: underline;
}
.article .title a {
text-decoration: none;
}
.permalink {
display: none;
}
:hover > .permalink {
display: inline;
}
p, li {
max-width: 50rem;
word-wrap: break-word;
}
p,
pre,
ul,
ol {
margin: 1.25rem;
}
pre {
background: #EFEFEF;
padding: 0.625rem;
border-radius: 0.3125rem;
}
h1,
h2,
h3,
h4,
.rootHeading {
margin: 1.25rem 0 1.25rem;
padding: 0;
color: #375EAB;
font-weight: bold;
}
h1 {
font-size: 1.75rem;
line-height: 1;
}
h1 .text-muted {
color:#777;
}
h2 {
font-size: 1.25rem;
background: #E0EBF5;
padding: 0.5rem;
line-height: 1.25;
font-weight: normal;
overflow: auto;
overflow-wrap: break-word;
}
h2 a {
font-weight: bold;
}
h3 {
font-size: 1.25rem;
line-height: 1.25;
overflow: auto;
overflow-wrap: break-word;
}
h3,
h4 {
margin: 1.25rem 0.3125rem;
}
h4 {
font-size: 1rem;
}
.rootHeading {
font-size: 1.25rem;
margin: 0;
}
h2 > span,
h3 > span {
float: right;
margin: 0 25px 0 0;
font-weight: normal;
color: #5279C7;
}
dl {
margin: 1.25rem;
}
dd {
margin: 0 0 0 1.25rem;
}
dl,
dd {
font-size: 0.875rem;
}
div#nav table td {
vertical-align: top;
}
#pkg-index h3 {
font-size: 1rem;
}
.pkg-dir {
padding: 0 0.625rem;
}
.pkg-dir table {
border-collapse: collapse;
border-spacing: 0;
}
.pkg-name {
padding-right: 0.625rem;
}
.alert {
color: #AA0000;
}
.top-heading {
float: left;
padding: 1.313rem 0;
font-size: 1.25rem;
font-weight: normal;
}
.top-heading a {
color: #222;
text-decoration: none;
}
#pkg-examples h3 {
float: left;
}
#pkg-examples dl {
clear: both;
}
.expandAll {
cursor: pointer;
float: left;
margin: 1.25rem 0;
}
div#topbar {
background: #E0EBF5;
height: 4rem;
overflow: hidden;
}
div#page {
width: 100%;
}
div#page > .container,
div#topbar > .container {
text-align: left;
margin-left: auto;
margin-right: auto;
padding: 0 1.25rem;
}
div#topbar > .container,
div#page > .container {
max-width: 59.38rem;
}
div#page.wide > .container,
div#topbar.wide > .container {
max-width: none;
}
div#plusone {
float: right;
clear: right;
margin-top: 0.3125rem;
}
div#footer {
text-align: center;
color: #666;
font-size: 0.875rem;
margin: 2.5rem 0;
}
div#menu > a,
input#search,
div#learn .buttons a,
div.play .buttons a,
div#blog .read a,
#menu-button {
padding: 0.625rem;
text-decoration: none;
font-size: 1rem;
border-radius: 0.3125rem;
}
div#playground .buttons a,
div#menu > a,
input#search,
#menu-button {
border: 0.0625rem solid #375EAB;
}
div#playground .buttons a,
div#menu > a,
#menu-button {
color: white;
background: #375EAB;
}
#playgroundButton.active {
background: white;
color: #375EAB;
}
a#start,
div#learn .buttons a,
div.play .buttons a,
div#blog .read a {
color: #222;
border: 0.0625rem solid #375EAB;
background: #E0EBF5;
}
.download {
width: 9.375rem;
}
div#menu {
text-align: right;
padding: 0.625rem;
white-space: nowrap;
max-height: 0;
-moz-transition: max-height .25s linear;
transition: max-height .25s linear;
width: 100%;
}
div#menu.menu-visible {
max-height: 31.25rem;
}
div#menu > a,
#menu-button {
margin: 0.625rem 0.125rem;
padding: 0.625rem;
}
::-webkit-input-placeholder {
color: #7f7f7f;
opacity: 1;
}
::placeholder {
color: #7f7f7f;
opacity: 1;
}
#menu .search-box {
display: inline-flex;
width: 8.75rem;
}
input#search {
background: white;
color: #222;
box-sizing: border-box;
-webkit-appearance: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 0;
margin-right: 0;
flex-grow: 1;
max-width: 100%;
min-width: 5.625rem;
}
input#search:-webkit-search-decoration {
-webkit-appearance: none;
}
input#search:-moz-ui-invalid {
box-shadow: unset;
}
input#search + button {
display: inline;
font-size: 1em;
background-color: #375EAB;
color: white;
border: 0.0625rem solid #375EAB;
border-top-left-radius: 0;
border-top-right-radius: 0.3125rem;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0.3125rem;
margin-left: 0;
cursor: pointer;
}
input#search + button span {
display: flex;
}
input#search + button svg {
fill: white
}
#menu-button {
display: none;
position: absolute;
right: 0.3125rem;
top: 0;
margin-right: 0.3125rem;
}
#menu-button-arrow {
display: inline-block;
}
.vertical-flip {
transform: rotate(-180deg);
}
div.left {
float: left;
clear: left;
margin-right: 2.5%;
}
div.right {
float: right;
clear: right;
margin-left: 2.5%;
}
div.left,
div.right {
width: 45%;
}
div#learn,
div#about {
padding-top: 1.25rem;
}
div#learn h2,
div#about {
margin: 0;
}
div#about {
font-size: 1.25rem;
margin: 0 auto 1.875rem;
}
div#gopher {
background: url(/doc/gopher/frontpage.png) no-repeat;
background-position: center top;
height: 9.688rem;
max-height: 200px; /* Setting in px to prevent the gopher from blowing up in very high default font-sizes */
}
a#start {
display: block;
padding: 0.625rem;
text-align: center;
text-decoration: none;
border-radius: 0.3125rem;
}
a#start .big {
display: block;
font-weight: bold;
font-size: 1.25rem;
}
a#start .desc {
display: block;
font-size: 0.875rem;
font-weight: normal;
margin-top: 0.3125rem;
}
div#learn .popout {
float: right;
display: block;
cursor: pointer;
font-size: 0.75rem;
background: url(/doc/share.png) no-repeat;
background-position: right center;
padding: 0.375rem 1.688rem;
}
div#learn pre,
div#learn textarea {
padding: 0;
margin: 0;
font-family: Menlo, monospace;
font-size: 0.875rem;
}
div#learn .input {
padding: 0.625rem;
margin-top: 0.625rem;
height: 9.375rem;
border-top-left-radius: 0.3125rem;
border-top-right-radius: 0.3125rem;
}
div#learn .input textarea {
width: 100%;
height: 100%;
border: none;
outline: none;
resize: none;
}
div#learn .output {
border-top: none !important;
padding: 0.625rem;
height: 3.688rem;
overflow: auto;
border-bottom-right-radius: 0.3125rem;
border-bottom-left-radius: 0.3125rem;
}
div#learn .output pre {
padding: 0;
border-radius: 0;
}
div#learn .input,
div#learn .input textarea,
div#learn .output,
div#learn .output pre {
background: #FFFFD8;
}
div#learn .input,
div#learn .output {
border: 0.0625rem solid #375EAB;
}
div#learn .buttons {
float: right;
padding: 1.25rem 0 0.625rem 0;
text-align: right;
}
div#learn .buttons a {
height: 1rem;
margin-left: 0.3125rem;
padding: 0.625rem;
}
div#learn .toys {
margin-top: 0.5rem;
}
div#learn .toys select {
font-size: 0.875rem;
border: 0.0625rem solid #375EAB;
margin: 0;
}
div#learn .output .exit {
display: none;
}
div#video {
max-width: 100%;
}
div#blog,
div#video {
margin-top: 2.5rem;
}
div#blog > a,
div#blog > div,
div#blog > h2,
div#video > a,
div#video > div,
div#video > h2 {
margin-bottom: 0.625rem;
}
div#blog .title,
div#video .title {
display: block;
font-size: 1.25rem;
}
div#blog .when {
color: #666;
font-size: 0.875rem;
}
div#blog .read {
text-align: right;
}
@supports (--c: 0) {
[style*="--aspect-ratio-padding:"] {
position: relative;
overflow: hidden;
padding-top: var(--aspect-ratio-padding);
}
[style*="--aspect-ratio-padding:"]>* {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
.toggleButton { cursor: pointer; }
.toggle > .collapsed { display: block; }
.toggle > .expanded { display: none; }
.toggleVisible > .collapsed { display: none; }
.toggleVisible > .expanded { display: block; }
table.codetable { margin-left: auto; margin-right: auto; border-style: none; }
table.codetable td { padding-right: 0.625rem; }
hr { border-style: none; border-top: 0.0625rem solid black; }
img.gopher {
float: right;
margin-left: 0.625rem;
margin-bottom: 0.625rem;
z-index: -1;
}
h2 { clear: right; }
/* example and drop-down playground */
div.play {
padding: 0 1.25rem 2.5rem 1.25rem;
}
div.play pre,
div.play textarea,
div.play .lines {
padding: 0;
margin: 0;
font-family: Menlo, monospace;
font-size: 0.875rem;
}
div.play .input {
padding: 0.625rem;
margin-top: 0.625rem;
border-top-left-radius: 0.3125rem;
border-top-right-radius: 0.3125rem;
overflow: hidden;
}
div.play .input textarea {
width: 100%;
height: 100%;
border: none;
outline: none;
resize: none;
overflow: hidden;
}
div#playground .input textarea {
overflow: auto;
resize: auto;
}
div.play .output {
border-top: none !important;
padding: 0.625rem;
max-height: 12.5rem;
overflow: auto;
border-bottom-right-radius: 0.3125rem;
border-bottom-left-radius: 0.3125rem;
}
div.play .output pre {
padding: 0;
border-radius: 0;
}
div.play .input,
div.play .input textarea,
div.play .output,
div.play .output pre {
background: #FFFFD8;
}
div.play .input,
div.play .output {
border: 0.0625rem solid #375EAB;
}
div.play .buttons {
float: right;
padding: 1.25rem 0 0.625rem 0;
text-align: right;
}
div.play .buttons a {
height: 1rem;
margin-left: 0.3125rem;
padding: 0.625rem;
cursor: pointer;
}
.output .stderr {
color: #933;
}
.output .system {
color: #999;
}
/* drop-down playground */
div#playground {
/* start hidden; revealed by javascript */
display: none;
}
div#playground {
position: absolute;
top: 3.938rem;
right: 1.25rem;
padding: 0 0.625rem 0.625rem 0.625rem;
z-index: 1;
text-align: left;
background: #E0EBF5;
border: 0.0625rem solid #B0BBC5;
border-top: none;
border-bottom-left-radius: 0.3125rem;
border-bottom-right-radius: 0.3125rem;
}
div#playground .code {
width: 32.5rem;
height: 12.5rem;
}
div#playground .output {
height: 6.25rem;
}
/* Inline runnable snippets (play.js/initPlayground) */
#content .code pre, #content .playground pre, #content .output pre {
margin: 0;
padding: 0;
background: none;
border: none;
outline: 0 solid transparent;
overflow: auto;
}
#content .playground .number, #content .code .number {
color: #999;
}
#content .code, #content .playground, #content .output {
width: auto;
margin: 1.25rem;
padding: 0.625rem;
border-radius: 0.3125rem;
}
#content .code, #content .playground {
background: #e9e9e9;
}
#content .output {
background: #202020;
}
#content .output .stdout, #content .output pre {
color: #e6e6e6;
}
#content .output .stderr, #content .output .error {
color: rgb(244, 74, 63);
}
#content .output .system, #content .output .exit {
color: rgb(255, 209, 77)
}
#content .buttons {
position: relative;
float: right;
top: -3.125rem;
right: 1.875rem;
}
#content .output .buttons {
top: -3.75rem;
right: 0;
height: 0;
}
#content .buttons .kill {
display: none;
visibility: hidden;
}
a.error {
font-weight: bold;
color: white;
background-color: darkred;
border-bottom-left-radius: 0.25rem;
border-bottom-right-radius: 0.25rem;
border-top-left-radius: 0.25rem;
border-top-right-radius: 0.25rem;
padding: 0.125rem 0.25rem 0.125rem 0.25rem; /* TRBL */
}
#heading-narrow {
display: none;
}
.downloading {
background: #F9F9BE;
padding: 0.625rem;
text-align: center;
border-radius: 0.3125rem;
}
@media (max-width: 58.125em) {
#heading-wide {
display: none;
}
#heading-narrow {
display: block;
}
}
@media (max-width: 47.5em) {
.container .left,
.container .right {
width: auto;
float: none;
}
div#about {
max-width: 31.25rem;
text-align: center;
}
}
@media (min-width: 43.75em) and (max-width: 62.5em) {
div#menu > a {
margin: 0.3125rem 0;
font-size: 0.875rem;
}
input#search {
font-size: 0.875rem;
}
}
@media (max-width: 43.75em) {
body {
font-size: 0.9375rem;
}
div#playground {
left: 0;
right: 0;
}
pre,
code {
font-size: 0.866rem;
}
div#page > .container {
padding: 0 0.625rem;
}
div#topbar {
height: auto;
padding: 0.625rem;
}
div#topbar > .container {
padding: 0;
}
#heading-wide {
display: block;
}
#heading-narrow {
display: none;
}
.top-heading {
float: none;
display: inline-block;
padding: 0.75rem;
}
div#menu {
padding: 0;
min-width: 0;
text-align: left;
float: left;
}
div#menu > a {
display: block;
margin-left: 0;
margin-right: 0;
}
#menu .search-box {
display: flex;
width: 100%;
}
#menu-button {
display: inline-block;
}
p,
pre,
ul,
ol {
margin: 0.625rem;
}
.pkg-synopsis {
display: none;
}
img.gopher {
display: none;
}
}
@media (max-width: 30em) {
#heading-wide {
display: none;
}
#heading-narrow {
display: block;
}
}
@media print {
pre {
background: #FFF;
border: 0.0625rem solid #BBB;
white-space: pre-wrap;
}
}

1377
jni/jni.html Normal file

File diff suppressed because it is too large Load Diff

6
jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

732
main.html Normal file
View File

@ -0,0 +1,732 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=1024, user-scalable=no">
<title>Your deck.js Presentation</title>
<!-- Required stylesheet -->
<link rel="stylesheet" media="screen" href="core/deck.core.css">
<!-- Extension CSS files go here. Remove or add as needed. -->
<link rel="stylesheet" media="screen" href="extensions/goto/deck.goto.css">
<link rel="stylesheet" media="screen" href="extensions/menu/deck.menu.css">
<link rel="stylesheet" media="screen" href="extensions/navigation/deck.navigation.css">
<link rel="stylesheet" media="screen" href="extensions/status/deck.status.css">
<!-- <link rel="stylesheet" media="screen" href="extensions/scale/deck.scale.css"> -->
<!-- Style theme. More available in /themes/style/ or create your own. -->
<link rel="stylesheet" media="screen" href="themes/style/swiss.css">
<!-- Transition theme. More available in /themes/transition/ or create your own. -->
<link rel="stylesheet" media="screen" href="themes/transition/horizontal-slide.css">
<!-- Basic black and white print styles -->
<link rel="stylesheet" media="print" href="core/print.css">
<!-- Required Modernizr file -->
<script src="modernizr.custom.js"></script>
</head>
<body style="margin:0px;padding:0px;overflow:hidden">
<div class="deck-container">
<!-- Begin slides. Just make elements with a class of slide. -->
<section class="slide">
<h2>Android for Gio programmers</h2> <br></br>
<h3>Native Development Kit (NDK): direct access from cgo</h3>
<ul><li>limited Android API access</li></ul>
<h3>Java Native Interface: call Java code via cgo</h3>
<ul><li>custom Java classes</li></ul>
<h3>Java fragments: extend the main Gio Activity</h3>
<ul><li>permissions and application lifecycle</li></ul>
</section>
<section class="slide">
<h2>NDK &mdash; sensor.h</h2>
<p>$ANDROID_HOME/ndk-bundle/sysroot/usr/include/android/sensor.h</p>
<pre style="font-size: 90%"><code># android/sensor.h
#if __ANDROID_API__ >= 26
/**
* Get a reference to the sensor manager. ASensorManager is a singleton
* per package as different packages may have access to different sensors.
*
* Example:
*
* ASensorManager* sensorManager = ASensorManager_getInstanceForPackage("foo.bar .baz");
*
*/
ASensorManager* ASensorManager_getInstanceForPackage(const char* packageName) __INTRODUCED_IN(26);
#endif
/**
* Returns the default sensor for the given type, or NULL if no sensor
* of that type exists.
*/
ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type);
/**
* {@link ASensorManager} is an opaque type to manage sensors and
* events queues.
*
* {@link ASensorManager} is a singleton that can be obtained using
* ASensorManager_getInstance().
*
* This file provides a set of functions that uses {@link
* ASensorManager} to access and list hardware sensors, and
* create and destroy event queues:
* - ASensorManager_getSensorList()
* - ASensorManager_getDefaultSensor()
* - ASensorManager_getDefaultSensorEx()
* - ASensorManager_createEventQueue()
* - ASensorManager_destroyEventQueue()
*/
typedef struct ASensorManager ASensorManager;
</code></pre>
</section>
<section class="slide">
<h2>NDK &mdash; nswrap</h2>
<img src="nswrap-git.png"></img>
</section>
<!--
<section class="slide">
<h2>NDK android27.yaml</h2>
<p>nswrap configuration: android27.yaml</p>
<pre style="font-size: 65%"><code>package: android27
libraries: [android, log, nativewindow, m]
inputfiles:
- $ANDROID_HOME/ndk-bundle/sysroot/usr/include/android/native_window.h
- $ANDROID_HOME/ndk-bundle/sysroot/usr/include/android/log.h
- $ANDROID_HOME/ndk-bundle/sysroot/usr/include/android/sensor.h
- $ANDROID_HOME/ndk-bundle/sysroot/usr/include/jni.h
- $ANDROID_HOME/ndk-bundle/sysroot/usr/include/sys/stat.h
sysimports:
- android/native_window.h
- android/log.h
- android/sensor.h
- jni.h
- stdlib.h
- sys/stat.h
functions:
- .*
functionignore:
- JNI_CreateJavaVM
- JNI_GetCreatedJavaVMs
- JNI_GetDefaultJavaVMInitArgs
- JNI_OnLoad
- JNI_OnUnload
- AHardwareBuffer_lockPlanes
- wcstoimax
- wcstoumax
- imaxdiv
# - __system_property_get
enums:
- .*
typesubs:
Stat: Stat_t
Stat64: Stat64_t
clang: $ANDROID_HOME/ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android27-clang
</code></pre>
</section>
<section class = "slide">
<h2>NDK &mdash; Clang AST</h2>
<p>nswrap reads the Clang ast</p>
<pre><code>...
|-TypedefDecl 0x7fac6e838220 &lt;line:480:1, col:31&gt; col:31 referenced ASensorManager 'struct ASensorManager':'struct ASensorManager'
| |-ElaboratedType 0x7fac6e8371d0 'struct ASensorManager' sugar
| | `-RecordType 0x7fac6e837180 'struct ASensorManager'
| | `-Record 0x7fac6e837100 'ASensorManager'
| `-FullComment 0x7fac6e8468a0 &lt;line:465:3, col:10&gt;
| |-ParagraphComment 0x7fac6e8465a0 &lt;col:3, col:4&gt;
| | `-TextComment 0x7fac6e846570 &lt;col:3, col:4&gt; Text=" {"
| `-VerbatimBlockComment 0x7fac6e8465c0 &lt;col:5, col:10&gt; Name="link" CloseName=""
| |-VerbatimBlockLineComment 0x7fac6e846610 &lt;col:10, col:66&gt; Text=" ASensorManager} is an opaque type to manage sensors and"
| |-VerbatimBlockLineComment 0x7fac6e846630 &lt;line:466:3, col:18&gt; Text=" events queues."
...
|-FunctionDecl 0x7fac6e838b28 &lt;line:568:1, versioning.h:19:89&gt; sensor.h:568:17 ASensorManager_getInstanceForPackage 'ASensorManager *(const char *)'
| |-ParmVarDecl 0x7fac6e838a00 &lt;col:54, col:66&gt; col:66 packageName 'const char *'
| |-AnnotateAttr 0x7fac6e838bc8 &lt;versioning.h:19:51, col:87&gt; "introduced_in=26"
</code></pre>
</section>
<section class="slide">
<h2>NDK &mdash; nswrap output</h2>
<p>nswrap generates 1270 lines of Go code</p>
<p>android27/main.go</p>
<pre style="font-size:75%"><code>package android27
...
type ASensorManager = C.struct_ASensorManager
const ASENSOR_TYPE_INVALID = C.ASENSOR_TYPE_INVALID
const ASENSOR_TYPE_ACCELEROMETER = C.ASENSOR_TYPE_ACCELEROMETER
const ASENSOR_TYPE_MAGNETIC_FIELD = C.ASENSOR_TYPE_MAGNETIC_FIELD
const ASENSOR_TYPE_GYROSCOPE = C.ASENSOR_TYPE_GYROSCOPE
...
func ASensorManagerGetInstanceForPackage(packageName *Char) *ASensorManager {
ret := (*ASensorManager)(unsafe.Pointer(C.ASensorManager_getInstanceForPackage((*C.char)(packageName))))
return ret
}
func ASensorManagerGetDefaultSensor(manager *ASensorManager, type_ Int) *ASensor {
ret := (*ASensor)(unsafe.Pointer(C.ASensorManager_getDefaultSensor((*C.ASensorManager)(manager), (C.int)(type_))))
return ret
}
</code></pre>
</section>
-->
<section class="slide">
<h2>NDK &mdash; Android-specific Go code</h2>
<p>os_android.go</p>
<pre style="font-size: 65%"><code>import ndk "git.wow.st/gmp/android-go/android27"
func sensorLoop() {
// the Android Looper is thread-local
runtime.LockOSThread()
pkg := ndk.CharWithGoString("st.wow.git.sensors")
manager := ndk.ASensorManagerGetInstanceForPackage(pkg)
pkg.Free()
sens := ndk.ASensorManagerGetDefaultSensor(manager, ndk.ASENSOR_TYPE_ACCELEROMETER)
stp := ndk.ASensorGetStringType(sens)
labchan <- "sensor" + stp.String()
var looper *ndk.ALooper
var queue *ndk.ASensorEventQueue
looper_id := 1
var rate ndk.Int32_t = 60
setup := func() {
looper = ndk.ALooperForThread()
if (looper == nil) {
labchan <- "no looper for thread"
looper = ndk.ALooperPrepare(ndk.ALOOPER_PREPARE_ALLOW_NON_CALLBACKS)
}
queue = ndk.ASensorManagerCreateEventQueue(manager, looper, looper_id)
ndk.ASensorEventQueueEnableSensor(queue, sens)
ndk.ASensorEventQueueSetEventRate(queue, sens, 1000000/rate) // microseconds
}
setup()
...
</code></pre>
</section>
<section class="slide">
<h2>NDK &mdash; Android main polling loop</h2>
<p>os_android.go (86 total lines)</p>
<pre style="font-size:75%"><code>func sensorLoop() {
...
for {
var zero ndk.Int
id := (int)(ndk.ALooperPollOnce(-1, &zero, &zero, (*unsafe.Pointer)(unsafe.Pointer(nil)))) // poll forever
if (id == ndk.ALOOPER_POLL_ERROR) { // set up a new looper
labchan <- "getting a new looper"
setup()
continue
}
if (id == looper_id) {
var event ndk.ASensorEvent
if (ndk.ASensorEventQueueGetEvents(queue, &event, 1) != 1) {
continue
}
accel := (&event).Acceleration()
senschan <- vector{float64(accel.X()), float64(accel.Y()), float64(accel.Z())}
}
}
</code></pre>
</section>
<section class="slide">
<h2>NDK &mdash; Gio app setup</h2>
<p>main.go</p>
<pre style="font-size: 70%"><code>func eventloop() {
w := app.NewWindow( app.Size(unit.Dp(400), unit.Dp(400)), app.Title("Hello"))
th := material.NewTheme(gofont.Collection())
var ops op.Ops
var accel vector
var cx, cy, cvx, cvy, cs float32 // circle position, velocity and radius
cx = 200
cy = 200
cs = 50 // circle size (radius)
circle := func(gtx C, width, height float32) D {
// clip circle position and bounce off of the edges
if (cx < cs) { cx = cs; cvx = (-0.5) * cvx }
if (cy < cs) { cy = cs; cvy = (-0.5) * cvy }
if (cx > width - cs) { cx = width - cs; cvx = (-0.5) * cvx }
if (cy > height - cs) { cy = height - cs; cvy = (-0.5) * cvy }
blue := color.RGBA{0x3f, 0x51, 0xb5, 0x80}
r1 := f32.Rectangle{f32.Point{cx - cs, cy - cs}, f32.Point{cx + cs, cy + cs}}
clip.Rect{ Rect: r1, NE: cs, NW: cs, SE: cs, SW: cs}.Op(gtx.Ops).Add(gtx.Ops)
paint.ColorOp{Color: blue}.Add(gtx.Ops)
paint.PaintOp{Rect: r1}.Add(gtx.Ops)
var ret D
ret.Size.X = int(cs * 2)
ret.Size.Y = int(cs * 2)
return ret
}
...
</code></pre>
</section>
<section class="slide">
<h2>NDK &mdash; Gio app main loop</h2>
<p>main.go (174 total lines)</p>
<pre style="font-size:65%"><code> ...
ticker := time.NewTicker(time.Second / 60)
var t, told int64
t = time.Now().UnixNano()
for {
select {
case <- ticker.C:
told = t
t = time.Now().UnixNano()
elapsed := float32((t - told) / 1000000)
cvx = cvx - float32(accel.x/1000) * elapsed
cvy = cvy + float32(accel.y/1000) * elapsed
cx = cx + cvx * elapsed
cy = cy + cvy * elapsed
w.Invalidate()
case x := <-senschan:
accel = x
case e := <-w.Events():
switch e := e.(type) {
case system.FrameEvent:
gtx := layout.NewContext(&ops, e)
... // draw everything
e.Frame(gtx.Ops)
}
}
}
</code></pre>
</section>
<section class="slide">
<h2>NDK &mdash; Building an APK</h2>
<pre><code>$ gogio -target android -minsdk 27 .
$ adb install sensors.apk
</code></pre>
<img src="accel.jpg" style="width:60%"></img>
</section>
<section class="slide">
<h2>JNI &mdash; Java Native Interface</h2>
<p>Use JNI from cgo to:</p>
<ul>
<li>Access Android Java APIs (with limitations)</li>
<li>Call methods on your own Java classes</li>
</ul>
<p>To use it:
<ul>
<li>create (or acquire) a Java Virtual Machine (JavaVM)</li>
<li>use the JavaVM to obtain a JNI Native Interface struct (JNIEnv)</li>
<li>call function pointers inside the JNIEnv struct</li>
</ul>
<p>$ANDROID_HOME/ndk-bundle/sysroot/usr/include/jni.h</p>
<pre style="font-size:65%"><code>typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
/*
* Table of interface function pointers.
*/
struct JNINativeInterface {
jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...);
jclass (*GetObjectClass)(JNIEnv*, jobject);
jboolean (*IsInstanceOf)(JNIEnv*, jobject, jclass);
jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
jboolean (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
jbyte (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
jchar (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
jshort (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
jlong (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
jfloat (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);
jdouble (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);
void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID);
jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID);
jbyte (*GetByteField)(JNIEnv*, jobject, jfieldID);
jchar (*GetCharField)(JNIEnv*, jobject, jfieldID);
jshort (*GetShortField)(JNIEnv*, jobject, jfieldID);
jint (*GetIntField)(JNIEnv*, jobject, jfieldID);
jlong (*GetLongField)(JNIEnv*, jobject, jfieldID);
jfloat (*GetFloatField)(JNIEnv*, jobject, jfieldID);
jdouble (*GetDoubleField)(JNIEnv*, jobject, jfieldID);
...
</code></pre>
</section>
<section class="slide">
<h2>JNI &mdash; git.wow.st/gmp/jni</h2>
<iframe frameborder="0" src="jni/jni.html" style="transform:scale(1.5); transform-origin: 50% 0%;" width=800 height=13300></iframe>
</section>
<section class="slide">
<h2>JNI &mdash; Basics</h2>
<p>my/java/AClass.java:</p>
<pre style="font-size:60%"><code>package my.java;
public class AClass {
public int Num() {
return 17;
}
}
</code></pre>
<p>main.go:</p>
<pre style="font-size:60%"><code>package main
//go:generate javac my/java/AClass.java
import (
"fmt"
"git.wow.st/gmp/jni"
)
func main() {
vm := jni.CreateJavaVM()
err := jni.Do(vm, func(env jni.Env) error {
cls := jni.FindClass(env, "my/java/AClass")
if cls == 0 {
return fmt.Errorf("Class not found")
}
mid := jni.GetMethodID(env, cls, "<init>", "()V")
if mid == nil {
return fmt.Errorf("Initializer not found")
}
inst, err := jni.NewObject(env, cls, mid)
if err != nil {
return err
}
mid = jni.GetMethodID(env, cls, "Num", "()I")
if mid == nil {
return fmt.Errorf("Method not found")
}
res, err := jni.CallIntMethod(env, inst, mid)
if err != nil {
return err
}
fmt.Printf("Result: %d\n", res)
return nil
})
if err != nil {
fmt.Printf(err.Error())
}
}
</code></pre>
</section>
<section class="slide">
<h2>JNI &mdash; Using JNI on Android</h2>
<p><code>gogio</code> looks for <code>.jar</code> files in your package
directory and across all imports. Every class from these <code>.jar</code> files
will be bundled with your <code>apk</code></p>
<pre style="font-size:65%"><code>$ apktool d hrm.apk
$ find hrm/smali -type f
hrm/smali/org/gioui/GioView$1.smali
hrm/smali/org/gioui/GioView.smali
hrm/smali/org/gioui/GioView$3.smali
hrm/smali/org/gioui/GioView$4.smali
hrm/smali/org/gioui/GioView$2.smali
hrm/smali/org/gioui/Gio.smali
hrm/smali/org/gioui/GioActivity.smali
hrm/smali/org/gioui/Gio$1.smali
hrm/smali/org/gioui/GioView$InputConnection.smali
hrm/smali/st/wow/git/ble/BlessedConnect$3.smali
hrm/smali/st/wow/git/ble/BlessedConnect$1.smali
hrm/smali/st/wow/git/ble/BlessedConnect$2.smali
hrm/smali/st/wow/git/ble/BlessedConnect.smali
hrm/smali/timber/log/Timber.smali
hrm/smali/timber/log/Timber$Tree.smali
hrm/smali/timber/log/Timber$DebugTree.smali
hrm/smali/timber/log/Timber$1.smali
hrm/smali/com/welie/blessed/BluetoothPeripheral$1$9.smali
hrm/smali/com/welie/blessed/BluetoothPeripheral$11.smali
hrm/smali/com/welie/blessed/BluetoothCentral$4.smali
...
</code></pre>
</section>
<section class="slide">
<h2>JNI &mdash; JNI Limitations on Android</h2>
<p>Key limitation: cannot override <code>Activity</code> methods:</p>
<ul>
<li><code>onActivityResult</code></li>
<li><code>onRequestPermissionResult</code></li>
<li>Lifecycle methods: <code>onCreate</code>, <code>onDestroy</code>, etc.</li>
</ul>
</section>
<section class="slide">
<h2>Java Fragments</h2>
<p>There are lots of gaps in the NDK and limitations with JNI.
Fragments can access the rest.</p>
<img src="fragment.png"></img>
</section>
<section class="slide">
<h2>Java Fragments &mdash; Basics</h2>
<p>os_android.go</p>
<pre style="font-size:61%"><code>import (
"gioui.org/app"
"git.wow.st/gmp/jni"
)
func registerFragment(w *app.Window) {
vm := jni.JVMFor(app.JavaVM())
w.Do(func(view uintptr) {
err := jni.Do(vm, func(env jni.Env) error {
cls := jni.FindClass(env, "st/wow/git/fragment/AFrag")
mth := jni.GetMethodID(env, cls, "<init>", "()V");
inst, err := jni.NewObject(env, cls, mth)
mth = jni.GetMethodID(env, cls, "register", "(Landroid/view/View;)V");
jni.CallVoidMethod(env, inst, mth, jni.Value(view))
return nil
})
if err != nil { ... }
})
}
</code></pre>
<p>AFrag.java</p>
<pre style="font-size:61%"><code>package com.afrag.AFrag;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.util.Log;
import android.view.View;
public class AFrag extends Fragment {
public void register(View view) {
Activity act = (Activity)view.getContext();
FragmentTransaction ft = act.getFragmentManager().beginTransaction();
ft.add(this, "AFrag");
ft.commitNow();
}
@Override public void onAttach(Context ctx) {
super.onAttach(ctx);
}
}
</code></pre>
</section>
<section class="slide">
<h2>Java Fragments &mdash; Permissions (Java)</h2>
<p>Here we are going to connect to Bluetooth low-energy peripherals using a
library called Blessed (<a href="https://github.com/weliem/blessed-android">https://github.com/weliem/blessed-android</a>)</p>
<p>We need permission to access Bluetooth hardware, which, on Android,
requies <code>ACCESS_FINE_LOCATION</code>, which is a "dangerous" permission. See:
<a href="https://developer.android.com/reference/android/Manifest.permission#ACCESS_FINE_LOCATION">developer.android.com/reference/android/Manifest.permission</a></p>
<p>We need to request access to this permission at runtime.</p>
<p>BlessedConnect.java:</p>
<pre style="font-size:57%"><code>package st.wow.git.ble;
import android.app.Fragment;
import com.welie.blessed.BluetoothCentral;
import com.welie.blessed.BluetoothCentralCallback;
import com.welie.blessed.BluetoothPeripheral;
import com.welie.blessed.BluetoothPeripheralCallback;
public class BlessedConnect extends Fragment {
final int PERMISSION_REQUEST = 1;
final int REQUEST_ENABLE_BT = 2;
@Override public void onAttach(Context ctx) {
super.onAttach(ctx);
if (ctx.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST);
}
System.loadLibrary("gio");
installComplete(this);
}
public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PERMISSION_REQUEST) {
boolean granted = true;
for (int x : grantResults) {
if (x == PackageManager.PERMISSION_DENIED) {
granted = false;
break;
}
}
}
}
static private native void installComplete(BlessedConnect p);
}
</code></pre>
</section>
<section class="slide">
<h2>Java Fragments &mdash; Permissions (Go)</h2>
<p>We need to ask <code>gogio</code> to add all required permissions to
AndroidManifest.xml</p>
<p>os_android.go:</p>
<pre style="font-size:70%"><code>import (
"gioui.org/app"
_ "gioui.org/app/permission/bluetooth"
)
</code></pre>
<p>AndroidManifest.xml:</p>
<pre style="font-size:70%"><code>
&lt;?xml version="1.0" encoding="utf-8" standalone="no"?&gt;&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" android:compileSdkVersion="29" android:compileSdkVersionCodename="10" package="git.wow.st.hrm" platformBuildVersionCode="29" platformBuildVersionName="10"&gt;
&lt;uses-permission android:name="android.permission.BLUETOOTH"/&gt;
&lt;uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/&gt;
&lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&gt;
&lt;uses-feature android:glEsVersion="0x00030000" android:required="false"/&gt;
&lt;uses-feature android:name="android.hardware.bluetooth" android:required="false"/&gt;
&lt;uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/&gt;
&lt;application android:icon="@mipmap/ic_launcher" android:label="Hrm"&gt;
&lt;activity android:configChanges="keyboardHidden|orientation" android:label="Hrm" android:name="org.gioui.GioActivity" android:theme="@style/Theme.GioApp" android:windowSoftInputMode="adjustResize"&gt;
&lt;intent-filter&gt;
&lt;action android:name="android.intent.action.MAIN"/&gt;
&lt;category android:name="android.intent.category.LAUNCHER"/&gt;
&lt;/intent-filter&gt;
&lt;/activity&gt;
&lt;/application&gt;
&lt;/manifest&gt;
</code></pre>
</section>
<section class ="slide">
<h2>Java Fragments &mdash; Gio app</h2>
<p>main.go is 482 lines. No platform-specific code is required in the Gio app.</p>
<pre style="font-size:65%"><code>import (
"gioui.org/app"
"git.wow.st/gmp/ble"
)
func eventloop()
w := app.NewWindow()
...
b := ble.NewBLE()
b.Enable(w)
select {
case e := <-b.Events():
switch e := e.(type) {
case ble.UpdateStateEvent: ...
case ble.DiscoverPeripheralEvent: ...
case ble.ConnectEvent: ...
case ble.ConnectTimeoutEvent: ...
case ble.DiscoverServiceEvent: ...
case ble.DiscoverCharacteristicEvent: ...
case ble.UpdateValueEvent: ...
}
w.Invalidate()
case e := <-w.Events():
switch e := e.(type) {
case system.DestroyEvent:
return
case system.FrameEvent:
gtx := layout.NewContext(&ops, e)
... // draw everything
e.Frame(gtx.Ops)
}
}
}
</code></pre>
</section>
<section class="slide">
<h2>Java Fragments &mdash; BLE API</h2>
<pre><code>func (b *BLE) Enable(w *app.Window)
func (b *BLE) State() string
func (b *BLE) Events() chan interface{}
func (b *BLE) Scan()
func (b *BLE) StopScan()
func (p Peripheral) DiscoverServices()
func (p Peripheral) DiscoverCharacteristics(serv Service)
func (p Peripheral) SetNotifyValue(c Characteristic)
func (b *BLE) Connect(p Peripheral) bool
func CancelConnection(p Peripheral)
func Disconnect(p Peripheral)
</code></pre>
<img src="ble.png" style="width:70%"></img>
</section>
<section class ="slide">
<h2>Links</h2>
<ol>
<p><a href="https://git.wow.st/gmp/nswrap">git.wow.st/gmp/nswrap</a></p>
<p><a href="https://git.wow.st/gmp/android-go">git.wow.st/gmp/android-go</a></p>
<p><a href="https://git.wow.st/gmp/hrm">git.wow.st/gmp/jni</a></p>
<p><a href="https://git.wow.st/gmp/ble">git.wow.st/gmp/ble</a></p>
<p><a href="https://git.wow.st/gmp/hrm">git.wow.st/gmp/hrm</a></p>
<p><a href="https://git.wow.st/gmp/passgo">git.wow.st/gmp/passgo</a></p>
</ol>
</section>
<!-- End slides. -->
<!-- Begin extension snippets. Add or remove as needed. -->
<!-- deck.navigation snippet -->
<div aria-role="navigation">
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
<a href="#" class="deck-next-link" title="Next">&#8594;</a>
</div>
<!-- deck.status snippet -->
<p class="deck-status" aria-role="status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<!-- deck.goto snippet -->
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="text" name="slidenum" id="goto-slide" list="goto-datalist">
<datalist id="goto-datalist"></datalist>
<input type="submit" value="Go">
</form>
<!-- End extension snippets. -->
</div>
<!-- Required JS files. -->
<script src="jquery.min.js"></script>
<script src="core/deck.core.js"></script>
<!-- Extension JS files. Add or remove as needed. -->
<script src="extensions/menu/deck.menu.js"></script>
<script src="extensions/goto/deck.goto.js"></script>
<script src="extensions/status/deck.status.js"></script>
<script src="extensions/navigation/deck.navigation.js"></script>
<!-- <script src="extensions/scale/deck.scale.js"></script> -->
<!-- Initialize the deck. You can put this in an external file if desired. -->
<script>
$(function() {
$.deck('.slide');
});
</script>
</body>
</html>

4
modernizr.custom.js Normal file

File diff suppressed because one or more lines are too long

BIN
nswrap-git.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

300
themes/style/_reset.scss Normal file
View File

@ -0,0 +1,300 @@
/* Resets and base styles from HTML5 Boilerplate */
div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
blockquote, q {
quotes:none;
&:before, &:after {
content:"";
content:none;
}
}
ins {
background-color:#ff9;
color:#000;
text-decoration:none;
}
mark {
background-color:#ff9;
color:#000;
font-style:italic;
font-weight:bold;
}
del {
text-decoration:line-through;
}
abbr[title], dfn[title] {
border-bottom:1px dotted;
cursor:help;
}
table {
border-collapse:collapse;
border-spacing:0;
}
hr {
display:block;
height:1px;
border:0;
border-top:1px solid #ccc;
margin:1em 0;
padding:0;
}
input, select {
vertical-align:middle;
}
select, input, textarea, button {
font:99% sans-serif;
}
pre, code, kbd, samp {
font-family:monospace, sans-serif;
}
a {
-webkit-tap-highlight-color:rgba(0,0,0,0);
&:hover, &:active {
outline:none;
}
}
ul, ol {
margin-left:2em;
vertical-align:top;
}
ol {
list-style-type:decimal;
}
nav {
ul, li {
margin:0;
list-style:none;
list-style-image:none;
}
}
small {
font-size:85%;
}
strong, th {
font-weight:bold;
}
td {
vertical-align:top;
}
sub, sup {
font-size:75%;
line-height:0;
position:relative;
}
sup {
top:-0.5em;
}
sub { bottom: -0.25em; }
textarea {
overflow:auto;
}
input[type="radio"] {
vertical-align:text-bottom;
}
input[type="checkbox"] {
vertical-align:bottom;
}
label,
input[type="button"],
input[type="submit"],
input[type="image"],
button {
cursor:pointer;
}
button, input, select, textarea {
margin: 0;
}
input, textarea {
&:invalid {
border-radius:1px;
-moz-box-shadow:0px 0px 5px red;
-webkit-box-shadow:0px 0px 5px red;
box-shadow: 0px 0px 5px red;
.no-boxshadow {
background-color: #f0dddd;
}
}
}
button {
width:auto;
overflow:visible;
}
select, input, textarea {
color: #444 ;
}
a {
color:#607890;
&:hover, &:focus {
color:#036;
}
&:link {
-webkit-tap-highlight-color: #fff;
}
}
/* End HTML5 Boilerplate adaptations */
h1 {
font-size:4.5em;
}
h1, .vcenter {
font-weight:bold;
text-align:center;
padding-top:1em;
max-height:100%;
.csstransforms & {
padding:0 48px;
position:absolute;
left:0;
right:0;
top:50%;
-webkit-transform:translate(0, -50%);
-moz-transform:translate(0, -50%);
-ms-transform:translate(0, -50%);
-o-transform:translate(0, -50%);
transform:translate(0, -50%);
}
}
.vcenter h1 {
position:relative;
top:auto;
padding:0;
-webkit-transform:none;
-moz-transform:none;
-ms-transform:none;
-o-transform:none;
transform:none;
}
h2 {
font-size:2.25em;
font-weight:bold;
padding-top:.5em;
margin:0 0 .66666em 0;
border-bottom:3px solid #888;
}
h3 {
font-size:1.4375em;
font-weight:bold;
margin-bottom:.30435em;
}
h4 {
font-size:1.25em;
font-weight:bold;
margin-bottom:.25em;
}
h5 {
font-size:1.125em;
font-weight:bold;
margin-bottom:.2222em;
}
h6 {
font-size:1em;
font-weight:bold;
}
img, iframe, video {
display:block;
max-width:100%;
}
video, iframe, img {
display:block;
margin:0 auto;
}
p, blockquote, iframe, img, ul, ol, pre, video {
margin-bottom:1em;
}
pre {
white-space:pre;
white-space:pre-wrap;
word-wrap:break-word;
padding: 1em;
border:1px solid #888;
}
em {
font-style:italic;
}
li {
padding:.25em 0;
vertical-align:middle;
> ol, > ul {
margin-bottom:inherit;
}
}
.deck-container {
font-size:16px;
line-height:1.25;
color:#444;
}
.slide {
-moz-box-sizing: border-box;
box-sizing: border-box;
width:100%;
}

421
themes/style/neon.css Normal file
View File

@ -0,0 +1,421 @@
/* Resets and base styles from HTML5 Boilerplate */
div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after, q:before, q:after {
content: "";
content: none;
}
ins {
background-color: #ff9;
color: #000;
text-decoration: none;
}
mark {
background-color: #ff9;
color: #000;
font-style: italic;
font-weight: bold;
}
del {
text-decoration: line-through;
}
abbr[title], dfn[title] {
border-bottom: 1px dotted;
cursor: help;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
input, select {
vertical-align: middle;
}
select, input, textarea, button {
font: 99% sans-serif;
}
pre, code, kbd, samp {
font-family: monospace, sans-serif;
}
a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
a:hover, a:active {
outline: none;
}
ul, ol {
margin-left: 2em;
vertical-align: top;
}
ol {
list-style-type: decimal;
}
nav ul, nav li {
margin: 0;
list-style: none;
list-style-image: none;
}
small {
font-size: 85%;
}
strong, th {
font-weight: bold;
}
td {
vertical-align: top;
}
sub, sup {
font-size: 75%;
line-height: 0;
position: relative;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
textarea {
overflow: auto;
}
input[type="radio"] {
vertical-align: text-bottom;
}
input[type="checkbox"] {
vertical-align: bottom;
}
label,
input[type="button"],
input[type="submit"],
input[type="image"],
button {
cursor: pointer;
}
button, input, select, textarea {
margin: 0;
}
input:invalid, textarea:invalid {
border-radius: 1px;
-moz-box-shadow: 0px 0px 5px red;
-webkit-box-shadow: 0px 0px 5px red;
box-shadow: 0px 0px 5px red;
}
input:invalid .no-boxshadow, textarea:invalid .no-boxshadow {
background-color: #f0dddd;
}
button {
width: auto;
overflow: visible;
}
select, input, textarea {
color: #444444;
}
a {
color: #607890;
}
a:hover, a:focus {
color: #036;
}
a:link {
-webkit-tap-highlight-color: #fff;
}
/* End HTML5 Boilerplate adaptations */
h1 {
font-size: 4.5em;
}
h1, .vcenter {
font-weight: bold;
text-align: center;
padding-top: 1em;
max-height: 100%;
}
.csstransforms h1, .csstransforms .vcenter {
padding: 0 48px;
position: absolute;
left: 0;
right: 0;
top: 50%;
-webkit-transform: translate(0, -50%);
-moz-transform: translate(0, -50%);
-ms-transform: translate(0, -50%);
-o-transform: translate(0, -50%);
transform: translate(0, -50%);
}
.vcenter h1 {
position: relative;
top: auto;
padding: 0;
-webkit-transform: none;
-moz-transform: none;
-ms-transform: none;
-o-transform: none;
transform: none;
}
h2 {
font-size: 2.25em;
font-weight: bold;
padding-top: .5em;
margin: 0 0 .66666em 0;
border-bottom: 3px solid #888;
}
h3 {
font-size: 1.4375em;
font-weight: bold;
margin-bottom: .30435em;
}
h4 {
font-size: 1.25em;
font-weight: bold;
margin-bottom: .25em;
}
h5 {
font-size: 1.125em;
font-weight: bold;
margin-bottom: .2222em;
}
h6 {
font-size: 1em;
font-weight: bold;
}
img, iframe, video {
display: block;
max-width: 100%;
}
video, iframe, img {
display: block;
margin: 0 auto;
}
p, blockquote, iframe, img, ul, ol, pre, video {
margin-bottom: 1em;
}
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
padding: 1em;
border: 1px solid #888;
}
em {
font-style: italic;
}
li {
padding: .25em 0;
vertical-align: middle;
}
li > ol, li > ul {
margin-bottom: inherit;
}
.deck-container {
font-size: 16px;
line-height: 1.25;
color: #444;
}
.slide {
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
}
h1 {
color: #0af;
font-weight: normal;
font-weight: 100;
text-shadow: 0 0 50px #0af, 0 0 3px #fff;
}
h2 {
color: #af0;
border-bottom-color: #ccc;
font-weight: normal;
font-weight: 100;
text-shadow: 0 0 15px #af0, 0 0 2px #fff;
border-bottom: 1px solid #333;
}
h3 {
color: #fff;
font-weight: normal;
font-weight: 100;
text-shadow: 0 0 10px #fff, 0 0 2px #fff;
}
pre {
border-color: #333;
}
pre code {
color: #fff;
}
code {
color: #f0a;
}
blockquote {
font-size: 2em;
padding: 1em 2em;
color: #fff;
border-left: 5px solid #fff;
}
blockquote p {
margin: 0;
}
blockquote cite {
font-size: .5em;
font-style: normal;
font-weight: normal;
font-weight: 100;
color: #aaa;
text-shadow: 0 0 15px #fff, 0 0 2px #fff;
}
::-moz-selection {
background: #a0f;
}
::selection {
background: #a0f;
}
a, a:hover, a:focus, a:active, a:visited {
color: #f0a;
text-decoration: none;
}
a:hover, a:focus {
text-decoration: underline;
}
.deck-container {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
font-size: 1.75em;
color: #aaa;
background: #000;
}
.deck-container > .slide {
padding: 0 48px;
}
.slide .deck-before, .slide .deck-previous {
opacity: 0.4;
}
.slide .deck-before:not(.deck-child-current) .deck-before, .slide .deck-before:not(.deck-child-current) .deck-previous, .slide .deck-previous:not(.deck-child-current) .deck-before, .slide .deck-previous:not(.deck-child-current) .deck-previous {
opacity: 1;
}
.slide .deck-child-current {
opacity: 1;
}
.deck-prev-link, .deck-next-link {
background: #f0a;
text-shadow: 0 0 3px #fff;
}
.deck-prev-link, .deck-prev-link:hover, .deck-prev-link:focus, .deck-prev-link:active, .deck-prev-link:visited, .deck-next-link, .deck-next-link:hover, .deck-next-link:focus, .deck-next-link:active, .deck-next-link:visited {
color: #fff;
}
.deck-prev-link:hover, .deck-prev-link:focus, .deck-next-link:hover, .deck-next-link:focus {
text-decoration: none;
box-shadow: 0 0 20px #f0a, 0 0 5px #fff;
}
.deck-status {
font-size: 0.6666em;
}
.goto-form {
background: #000;
border: 1px solid #f0a;
}
.goto-form label {
color: #fff;
}
.deck-menu .slide {
background: #333;
}
.deck-menu .deck-current {
background: #444;
}
.boxshadow .deck-menu .deck-current {
background: #000;
box-shadow: 0 0 20px #f0a, 0 0 5px #fff;
}
.no-touch .deck-menu .slide:hover {
background: #444;
}
.no-touch.boxshadow .deck-menu .slide:hover {
background: #000;
box-shadow: 0 0 20px #f0a, 0 0 5px #fff;
}

148
themes/style/neon.scss Normal file
View File

@ -0,0 +1,148 @@
@import "reset";
h1 {
color:#0af;
font-weight:normal;
font-weight:100;
text-shadow:0 0 50px #0af, 0 0 3px #fff;
}
h2 {
color:#af0;
border-bottom-color:#ccc;
font-weight:normal;
font-weight:100;
text-shadow:0 0 15px #af0, 0 0 2px #fff;
border-bottom:1px solid #333;
}
h3 {
color:#fff;
font-weight:normal;
font-weight:100;
text-shadow:0 0 10px #fff, 0 0 2px #fff;
}
pre {
border-color:#333;
code {
color:#fff;
}
}
code {
color:#f0a;
}
blockquote {
font-size:2em;
padding:1em 2em;
color:#fff;
border-left:5px solid #fff;
p {
margin:0;
}
cite {
font-size:.5em;
font-style:normal;
font-weight:normal;
font-weight:100;
color:#aaa;
text-shadow:0 0 15px #fff, 0 0 2px #fff;
}
}
::-moz-selection{ background:#a0f; }
::selection { background:#a0f; }
a {
&, &:hover, &:focus, &:active, &:visited {
color:#f0a;
text-decoration:none;
}
&:hover, &:focus {
text-decoration:underline;
}
}
.deck-container {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
font-size:1.75em;
color:#aaa;
background:#000;
> .slide {
padding:0 48px;
}
}
.slide {
.deck-before, .deck-previous {
opacity:0.4;
&:not(.deck-child-current) {
.deck-before, .deck-previous {
opacity:1;
}
}
}
.deck-child-current {
opacity:1;
}
}
.deck-prev-link, .deck-next-link {
background:#f0a;
text-shadow:0 0 3px #fff;
&, &:hover, &:focus, &:active, &:visited {
color:#fff;
}
&:hover, &:focus {
text-decoration:none;
box-shadow:0 0 20px #f0a, 0 0 5px #fff;
}
}
.deck-status {
font-size:0.6666em;
}
.goto-form {
background:#000;
border:1px solid #f0a;
label {
color:#fff;
}
}
.deck-menu {
.slide {
background:#333;
}
.deck-current {
background:#444;
.boxshadow & {
background:#000;
box-shadow:0 0 20px #f0a, 0 0 5px #fff;
}
}
.no-touch & .slide:hover {
background:#444;
}
.no-touch.boxshadow & .slide:hover {
background:#000;
box-shadow:0 0 20px #f0a, 0 0 5px #fff;
}
}

389
themes/style/swiss.css Normal file
View File

@ -0,0 +1,389 @@
/* Resets and base styles from HTML5 Boilerplate */
div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after, q:before, q:after {
content: "";
content: none;
}
ins {
background-color: #ff9;
color: #000;
text-decoration: none;
}
mark {
background-color: #ff9;
color: #000;
font-style: italic;
font-weight: bold;
}
del {
text-decoration: line-through;
}
abbr[title], dfn[title] {
border-bottom: 1px dotted;
cursor: help;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
input, select {
vertical-align: middle;
}
select, input, textarea, button {
font: 99% sans-serif;
}
pre, code, kbd, samp {
font-family: monospace, sans-serif;
}
a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
a:hover, a:active {
outline: none;
}
ul, ol {
margin-left: 2em;
vertical-align: top;
}
ol {
list-style-type: decimal;
}
nav ul, nav li {
margin: 0;
list-style: none;
list-style-image: none;
}
small {
font-size: 85%;
}
strong, th {
font-weight: bold;
}
td {
vertical-align: top;
}
sub, sup {
font-size: 75%;
line-height: 0;
position: relative;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
textarea {
overflow: auto;
}
input[type="radio"] {
vertical-align: text-bottom;
}
input[type="checkbox"] {
vertical-align: bottom;
}
label,
input[type="button"],
input[type="submit"],
input[type="image"],
button {
cursor: pointer;
}
button, input, select, textarea {
margin: 0;
}
input:invalid, textarea:invalid {
border-radius: 1px;
-moz-box-shadow: 0px 0px 5px red;
-webkit-box-shadow: 0px 0px 5px red;
box-shadow: 0px 0px 5px red;
}
input:invalid .no-boxshadow, textarea:invalid .no-boxshadow {
background-color: #f0dddd;
}
button {
width: auto;
overflow: visible;
}
select, input, textarea {
color: #444444;
}
a {
color: #607890;
}
a:hover, a:focus {
color: #036;
}
a:link {
-webkit-tap-highlight-color: #fff;
}
/* End HTML5 Boilerplate adaptations */
h1 {
font-size: 4.5em;
}
h1, .vcenter {
font-weight: bold;
text-align: center;
padding-top: 1em;
max-height: 100%;
}
.csstransforms h1, .csstransforms .vcenter {
padding: 0 48px;
position: absolute;
left: 0;
right: 0;
top: 50%;
-webkit-transform: translate(0, -50%);
-moz-transform: translate(0, -50%);
-ms-transform: translate(0, -50%);
-o-transform: translate(0, -50%);
transform: translate(0, -50%);
}
.vcenter h1 {
position: relative;
top: auto;
padding: 0;
-webkit-transform: none;
-moz-transform: none;
-ms-transform: none;
-o-transform: none;
transform: none;
}
h2 {
font-size: 2.25em;
font-weight: bold;
padding-top: .5em;
margin: 0 0 .66666em 0;
border-bottom: 3px solid #888;
}
h3 {
font-size: 1.4375em;
font-weight: bold;
margin-bottom: .30435em;
}
h4 {
font-size: 1.25em;
font-weight: bold;
margin-bottom: .25em;
}
h5 {
font-size: 1.125em;
font-weight: bold;
margin-bottom: .2222em;
}
h6 {
font-size: 1em;
font-weight: bold;
}
img, iframe, video {
display: block;
max-width: 100%;
}
video, iframe, img {
display: block;
margin: 0 auto;
}
p, blockquote, iframe, img, ul, ol, pre, video {
margin-bottom: 1em;
}
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
padding: 1em;
border: 1px solid #888;
}
em {
font-style: italic;
}
li {
padding: .25em 0;
vertical-align: middle;
}
li > ol, li > ul {
margin-bottom: inherit;
}
.deck-container {
font-size: 16px;
line-height: 1.25;
color: #444;
}
.slide {
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
}
h1 {
color: #000;
}
h2 {
color: #000;
border-bottom-color: #ccc;
}
h3 {
color: #888;
}
pre {
border-color: #ccc;
}
code {
color: #888;
}
blockquote {
font-size: 2em;
font-style: italic;
padding: 1em 2em;
color: #000;
border-left: 5px solid #ccc;
}
blockquote p {
margin: 0;
}
blockquote cite {
font-size: .5em;
font-style: normal;
font-weight: bold;
color: #888;
}
::-moz-selection {
background: #c00;
color: #fff;
}
::selection {
background: #c00;
color: #fff;
}
a, a:hover, a:focus, a:active, a:visited {
color: #c00;
text-decoration: none;
}
a:hover, a:focus {
text-decoration: underline;
}
.deck-container {
font-family: "Helvetica Neue", sans-serif;
font-size: 1.75em;
background: #fff;
}
.deck-container > .slide {
padding: 0 48px;
}
.slide .deck-before, .slide .deck-previous {
opacity: 0.4;
}
.slide .deck-before:not(.deck-child-current) .deck-before, .slide .deck-before:not(.deck-child-current) .deck-previous, .slide .deck-previous:not(.deck-child-current) .deck-before, .slide .deck-previous:not(.deck-child-current) .deck-previous {
opacity: 1;
}
.slide .deck-child-current {
opacity: 1;
}
.deck-prev-link, .deck-next-link {
background: #ccc;
font-family: serif;
}
.deck-prev-link, .deck-prev-link:hover, .deck-prev-link:focus, .deck-prev-link:active, .deck-prev-link:visited, .deck-next-link, .deck-next-link:hover, .deck-next-link:focus, .deck-next-link:active, .deck-next-link:visited {
color: #fff;
}
.deck-prev-link:hover, .deck-prev-link:focus, .deck-next-link:hover, .deck-next-link:focus {
background: #c00;
text-decoration: none;
}
.deck-status {
font-size: 0.6666em;
}
.deck-menu .slide {
background: #eee;
}
.deck-menu .deck-current, .no-touch .deck-menu .slide:hover {
background: #ddf;
}

109
themes/style/swiss.scss Normal file
View File

@ -0,0 +1,109 @@
@import "reset";
h1 {
color:#000;
}
h2 {
color:#c00;
border-bottom-color:#ccc;
}
h3 {
color:#888;
}
pre {
border-color:#ccc;
}
code {
color:#888;
}
blockquote {
font-size:2em;
font-style:italic;
padding:1em 2em;
color:#000;
border-left:5px solid #ccc;
p {
margin:0;
}
cite {
font-size:.5em;
font-style:normal;
font-weight:bold;
color:#888;
}
}
::-moz-selection{ background:#c00; color:#fff; }
::selection { background:#c00; color:#fff; }
a {
&, &:hover, &:focus, &:active, &:visited {
color:#c00;
text-decoration:none;
}
&:hover, &:focus {
text-decoration:underline;
}
}
.deck-container {
font-family: "Helvetica Neue", sans-serif;
font-size:1.75em;
background:#fff;
> .slide {
padding:0 48px;
}
}
.slide {
.deck-before, .deck-previous {
opacity:0.4;
&:not(.deck-child-current) {
.deck-before, .deck-previous {
opacity:1;
}
}
}
.deck-child-current {
opacity:1;
}
}
.deck-prev-link, .deck-next-link {
background:#ccc;
font-family:serif;
&, &:hover, &:focus, &:active, &:visited {
color:#fff;
}
&:hover, &:focus {
background:#c00;
text-decoration:none;
}
}
.deck-status {
font-size:0.6666em;
}
.deck-menu {
.slide {
background:#eee;
}
.deck-current, .no-touch & .slide:hover {
background:#ddf;
}
}

500
themes/style/web-2.0.css Normal file
View File

@ -0,0 +1,500 @@
@charset "UTF-8";
/* Resets and base styles from HTML5 Boilerplate */
div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure,
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after, q:before, q:after {
content: "";
content: none;
}
ins {
background-color: #ff9;
color: #000;
text-decoration: none;
}
mark {
background-color: #ff9;
color: #000;
font-style: italic;
font-weight: bold;
}
del {
text-decoration: line-through;
}
abbr[title], dfn[title] {
border-bottom: 1px dotted;
cursor: help;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
input, select {
vertical-align: middle;
}
select, input, textarea, button {
font: 99% sans-serif;
}
pre, code, kbd, samp {
font-family: monospace, sans-serif;
}
a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
a:hover, a:active {
outline: none;
}
ul, ol {
margin-left: 2em;
vertical-align: top;
}
ol {
list-style-type: decimal;
}
nav ul, nav li {
margin: 0;
list-style: none;
list-style-image: none;
}
small {
font-size: 85%;
}
strong, th {
font-weight: bold;
}
td {
vertical-align: top;
}
sub, sup {
font-size: 75%;
line-height: 0;
position: relative;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
textarea {
overflow: auto;
}
input[type="radio"] {
vertical-align: text-bottom;
}
input[type="checkbox"] {
vertical-align: bottom;
}
label,
input[type="button"],
input[type="submit"],
input[type="image"],
button {
cursor: pointer;
}
button, input, select, textarea {
margin: 0;
}
input:invalid, textarea:invalid {
border-radius: 1px;
-moz-box-shadow: 0px 0px 5px red;
-webkit-box-shadow: 0px 0px 5px red;
box-shadow: 0px 0px 5px red;
}
input:invalid .no-boxshadow, textarea:invalid .no-boxshadow {
background-color: #f0dddd;
}
button {
width: auto;
overflow: visible;
}
select, input, textarea {
color: #444444;
}
a {
color: #607890;
}
a:hover, a:focus {
color: #036;
}
a:link {
-webkit-tap-highlight-color: #fff;
}
/* End HTML5 Boilerplate adaptations */
h1 {
font-size: 4.5em;
}
h1, .vcenter {
font-weight: bold;
text-align: center;
padding-top: 1em;
max-height: 100%;
}
.csstransforms h1, .csstransforms .vcenter {
padding: 0 48px;
position: absolute;
left: 0;
right: 0;
top: 50%;
-webkit-transform: translate(0, -50%);
-moz-transform: translate(0, -50%);
-ms-transform: translate(0, -50%);
-o-transform: translate(0, -50%);
transform: translate(0, -50%);
}
.vcenter h1 {
position: relative;
top: auto;
padding: 0;
-webkit-transform: none;
-moz-transform: none;
-ms-transform: none;
-o-transform: none;
transform: none;
}
h2 {
font-size: 2.25em;
font-weight: bold;
padding-top: .5em;
margin: 0 0 .66666em 0;
border-bottom: 3px solid #888;
}
h3 {
font-size: 1.4375em;
font-weight: bold;
margin-bottom: .30435em;
}
h4 {
font-size: 1.25em;
font-weight: bold;
margin-bottom: .25em;
}
h5 {
font-size: 1.125em;
font-weight: bold;
margin-bottom: .2222em;
}
h6 {
font-size: 1em;
font-weight: bold;
}
img, iframe, video {
display: block;
max-width: 100%;
}
video, iframe, img {
display: block;
margin: 0 auto;
}
p, blockquote, iframe, img, ul, ol, pre, video {
margin-bottom: 1em;
}
pre {
white-space: pre;
white-space: pre-wrap;
word-wrap: break-word;
padding: 1em;
border: 1px solid #888;
}
em {
font-style: italic;
}
li {
padding: .25em 0;
vertical-align: middle;
}
li > ol, li > ul {
margin-bottom: inherit;
}
.deck-container {
font-size: 16px;
line-height: 1.25;
color: #444;
}
.slide {
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
}
h1, h2, h3, h4, h5, h6 {
font-family: "Hoefler Text", Constantia, Palatino, "Palatino Linotype", "Book Antiqua", Georgia, serif;
}
h1 {
color: #08455f;
}
h2 {
color: #0b7495;
border-bottom: 0;
}
.cssreflections h2 {
line-height: 1;
-webkit-box-reflect: below -0.5555em -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.3, transparent), color-stop(0.7, rgba(255, 255, 255, 0.1)), to(transparent));
-moz-box-reflect: below -0.5555em -moz-linear-gradient(top, transparent 0%, transparent 30%, rgba(255, 255, 255, 0.3) 100%);
}
h3 {
color: #000;
}
pre {
border-color: #cde;
background: #fff;
position: relative;
z-index: auto;
border-radius: 5px;
/* http://nicolasgallagher.com/css-drop-shadows-without-images/ */
}
.csstransforms.boxshadow pre > :first-child:before {
content: "";
position: absolute;
z-index: -1;
background: #fff;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.csstransforms.boxshadow pre:before, .csstransforms.boxshadow pre:after {
content: "";
position: absolute;
z-index: -2;
bottom: 15px;
width: 50%;
height: 20%;
max-width: 300px;
box-shadow: 0 15px 10px rgba(0, 0, 0, 0.7);
}
.csstransforms.boxshadow pre:before {
left: 10px;
-webkit-transform: rotate(-3deg);
-ms-transform: rotate(-3deg);
transform: rotate(-3deg);
}
.csstransforms.boxshadow pre:after {
right: 10px;
-webkit-transform: rotate(3deg);
-ms-transform: rotate(3deg);
transform: rotate(3deg);
}
code {
color: #789;
}
blockquote {
font-family: "Hoefler Text", Constantia, Palatino, "Palatino Linotype", "Book Antiqua", Georgia, serif;
font-size: 2em;
padding: 1em 2em .5em 2em;
color: #000;
background: #fff;
position: relative;
border: 1px solid #cde;
z-index: auto;
border-radius: 5px;
}
.boxshadow blockquote > :first-child:before {
content: "";
position: absolute;
z-index: -1;
background: #fff;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.boxshadow blockquote:after {
content: "";
position: absolute;
z-index: -2;
top: 10px;
bottom: 10px;
left: 0;
right: 50%;
-moz-border-radius: 10px / 100px;
border-radius: 10px / 100px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.6);
}
blockquote p {
margin: 0;
}
blockquote cite {
font-size: .5em;
font-style: normal;
font-weight: bold;
color: #888;
}
blockquote:before {
content: "“";
position: absolute;
top: 0;
left: 0;
font-size: 5em;
line-height: 1;
color: #ccf0f0;
z-index: 1;
}
::-moz-selection {
background: #08455f;
color: #fff;
}
::selection {
background: #08455f;
color: #fff;
}
a, a:hover, a:focus, a:active, a:visited {
color: #599;
text-decoration: none;
}
a:hover, a:focus {
text-decoration: underline;
}
.deck-container {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
font-size: 1.75em;
background: #f4fafe;
/* Old browsers */
background: -moz-linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f4fafe), color-stop(100%, #ccf0f0));
/* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* Opera11.10+ */
background: -ms-linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* IE10+ */
background: linear-gradient(top, #f4fafe 0%, #ccf0f0 100%);
/* W3C */
background-attachment: fixed;
text-shadow: 1px 1px 1px rgba(255, 255, 255, 0.5);
}
.deck-container > .slide {
padding: 0 48px;
}
.slide .deck-before, .slide .deck-previous {
opacity: 0.4;
}
.slide .deck-before:not(.deck-child-current) .deck-before, .slide .deck-before:not(.deck-child-current) .deck-previous, .slide .deck-previous:not(.deck-child-current) .deck-before, .slide .deck-previous:not(.deck-child-current) .deck-previous {
opacity: 1;
}
.slide .deck-child-current {
opacity: 1;
}
.deck-prev-link, .deck-next-link {
background: #fff;
opacity: 0.5;
}
.deck-prev-link, .deck-prev-link:hover, .deck-prev-link:focus, .deck-prev-link:active, .deck-prev-link:visited, .deck-next-link, .deck-next-link:hover, .deck-next-link:focus, .deck-next-link:active, .deck-next-link:visited {
color: #599;
}
.deck-prev-link:hover, .deck-prev-link:focus, .deck-next-link:hover, .deck-next-link:focus {
opacity: 1;
text-decoration: none;
}
.deck-status {
font-size: 0.6666em;
}
.deck-menu .slide {
background: transparent;
border-radius: 5px;
}
.rgba .deck-menu .slide {
background: rgba(0, 0, 0, 0.1);
}
.deck-menu .slide.deck-current, .rgba .deck-menu .slide.deck-current, .no-touch .deck-menu .slide:hover {
background: #fff;
}
.goto-form {
background: #fff;
border: 1px solid #cde;
border-radius: 5px;
}
.boxshadow .goto-form {
box-shadow: 0 15px 10px -10px rgba(0, 0, 0, 0.5), 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}

228
themes/style/web-2.0.scss Normal file
View File

@ -0,0 +1,228 @@
@mixin rotate($deg) {
-webkit-transform:rotate($deg);
-ms-transform:rotate($deg);
transform:rotate($deg);
}
@import "reset";
h1, h2, h3, h4, h5, h6 {
font-family: "Hoefler Text", Constantia, Palatino, "Palatino Linotype", "Book Antiqua", Georgia, serif;
}
h1 {
color:#08455f;
}
h2 {
color:#0b7495;
border-bottom:0;
.cssreflections & {
line-height:1;
-webkit-box-reflect:below -0.5555em -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.3, transparent), color-stop(0.7, rgba(255,255,255,.1)), to(transparent));
-moz-box-reflect:below -0.5555em -moz-linear-gradient(top, transparent 0%, transparent 30%, rgba(255,255,255,.3) 100%);
}
}
h3 {
color:#000;
}
pre {
border-color:#cde;
background:#fff;
position:relative;
z-index:auto;
border-radius:5px;
/* http://nicolasgallagher.com/css-drop-shadows-without-images/ */
.csstransforms.boxshadow & {
> :first-child:before {
content:"";
position:absolute;
z-index:-1;
background:#fff;
top:0;
bottom:0;
left:0;
right:0;
}
&:before, &:after {
content:"";
position:absolute;
z-index:-2;
bottom:15px;
width:50%;
height:20%;
max-width:300px;
box-shadow:0 15px 10px rgba(0, 0, 0, 0.7);
}
&:before {
left:10px;
@include rotate(-3deg);
}
&:after {
right:10px;
@include rotate(3deg);
}
}
}
code {
color:#789;
}
blockquote {
font-family: "Hoefler Text", Constantia, Palatino, "Palatino Linotype", "Book Antiqua", Georgia, serif;
font-size:2em;
padding:1em 2em .5em 2em;
color:#000;
background:#fff;
position:relative;
border:1px solid #cde;
z-index:auto;
border-radius:5px;
.boxshadow & {
> :first-child:before {
content:"";
position:absolute;
z-index:-1;
background:#fff;
top:0;
bottom:0;
left:0;
right:0;
}
&:after {
content:"";
position:absolute;
z-index:-2;
top: 10px;
bottom: 10px;
left: 0;
right: 50%;
-moz-border-radius: 10px / 100px;
border-radius: 10px / 100px;
box-shadow:0 0 15px rgba(0,0,0,0.6);
}
}
p {
margin:0;
}
cite {
font-size:.5em;
font-style:normal;
font-weight:bold;
color:#888;
}
&:before {
content:"";
position:absolute;
top:0;
left:0;
font-size:5em;
line-height:1;
color:#ccf0f0;
z-index:1;
}
}
::-moz-selection{ background:#08455f; color:#fff; }
::selection { background:#08455f; color:#fff; }
a {
&, &:hover, &:focus, &:active, &:visited {
color:#599;
text-decoration:none;
}
&:hover, &:focus {
text-decoration:underline;
}
}
.deck-container {
font-family: "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
font-size:1.75em;
background: rgb(244,250,254); /* Old browsers */
background: -moz-linear-gradient(top, rgba(244,250,254,1) 0%, rgba(204,240,240,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(244,250,254,1)), color-stop(100%,rgba(204,240,240,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, rgba(244,250,254,1) 0%,rgba(204,240,240,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, rgba(244,250,254,1) 0%,rgba(204,240,240,1) 100%); /* Opera11.10+ */
background: -ms-linear-gradient(top, rgba(244,250,254,1) 0%,rgba(204,240,240,1) 100%); /* IE10+ */
background: linear-gradient(top, rgba(244,250,254,1) 0%,rgba(204,240,240,1) 100%); /* W3C */
background-attachment: fixed;
text-shadow:1px 1px 1px rgba(255,255,255,.5);
> .slide {
padding:0 48px;
}
}
.slide {
.deck-before, .deck-previous {
opacity:0.4;
&:not(.deck-child-current) {
.deck-before, .deck-previous {
opacity:1;
}
}
}
.deck-child-current {
opacity:1;
}
}
.deck-prev-link, .deck-next-link {
background:#fff;
opacity:0.5;
&, &:hover, &:focus, &:active, &:visited {
color:#599;
}
&:hover, &:focus {
opacity:1;
text-decoration:none;
}
}
.deck-status {
font-size:0.6666em;
}
.deck-menu {
.slide {
background:transparent;
border-radius:5px;
.rgba & {
background:rgba(0,0,0,.1);
}
&.deck-current, .rgba &.deck-current, .no-touch &:hover {
background:#fff;
}
}
}
.goto-form {
background:#fff;
border:1px solid #cde;
border-radius:5px;
.boxshadow & {
box-shadow: 0 15px 10px -10px rgba(0, 0, 0, 0.5), 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 40px rgba(0, 0, 0, 0.1) inset;
}
}

View File

@ -0,0 +1,35 @@
.csstransitions.csstransforms .deck-container .slide {
-webkit-transition: opacity 500ms ease-in-out 0ms;
transition: opacity 500ms ease-in-out 0ms;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide {
position: absolute;
top: 0;
left: 0;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .slide {
position: relative;
left: 0;
top: 0;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .deck-next, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .deck-after {
opacity: 0;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .deck-current {
opacity: 1;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-previous, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-before, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-next, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-after {
opacity: 0;
pointer-events: none;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-before .slide, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-previous .slide {
visibility: visible;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-child-current {
opacity: 1;
visibility: visible;
pointer-events: auto;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-child-current .deck-next, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-child-current .deck-after {
visibility: hidden;
}

View File

@ -0,0 +1,59 @@
@mixin translate($x: 0, $y: 0, $z: 0) {
-webkit-transform:translate3d($x, $y, $z);
-ms-transform:translate($x, $y);
transform:translate3d($x, $y, $z);
}
@mixin transition($prop, $duration, $easing: ease-in-out, $delay: 0ms) {
-webkit-transition:$prop $duration $easing $delay;
transition:$prop $duration $easing $delay;
}
.csstransitions.csstransforms {
.deck-container .slide {
@include transition(opacity, 500ms);
}
.deck-container:not(.deck-menu) {
> .slide {
position:absolute;
top:0;
left:0;
.slide {
position:relative;
left:0;
top:0;
}
.deck-next, .deck-after {
opacity:0;
}
.deck-current {
opacity:1;
}
}
> .deck-previous, > .deck-before, > .deck-next, > .deck-after {
opacity:0;
pointer-events:none;
}
> .deck-before, > .deck-previous {
.slide {
visibility:visible;
}
}
> .deck-child-current {
opacity:1;
visibility:visible;
pointer-events:auto;
.deck-next, .deck-after {
visibility:hidden;
}
}
}
}

View File

@ -0,0 +1,53 @@
.csstransitions.csstransforms {
overflow-x: hidden;
}
.csstransitions.csstransforms .deck-container > .slide {
/* -webkit-transition: -webkit-transform 500ms ease-in-out;
transition: transform 500ms ease-in-out;*/
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide {
position: absolute;
top: 0;
left: 0;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .slide {
position: relative;
left: 0;
top: 0;
/* -webkit-transition: -webkit-transform 500ms ease-in-out, opacity 500ms ease-in-out;
transition: transform 500ms ease-in-out, opacity 500ms ease-in-out;*/
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .deck-next, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .deck-after {
visibility: visible;
-webkit-transform: translate3d(200%, 0, 0);
-ms-transform: translate(200%, 0);
transform: translate3d(200%, 0, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-previous {
-webkit-transform: translate3d(-200%, 0, 0);
-ms-transform: translate(-200%, 0);
transform: translate3d(-200%, 0, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-before {
-webkit-transform: translate3d(-400%, 0, 0);
-ms-transform: translate(-400%, 0);
transform: translate3d(-400%, 0, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-next {
-webkit-transform: translate3d(200%, 0, 0);
-ms-transform: translate(200%, 0);
transform: translate3d(200%, 0, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-after {
-webkit-transform: translate3d(400%, 0, 0);
-ms-transform: translate(400%, 0);
transform: translate3d(400%, 0, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-before .slide, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-previous .slide {
visibility: visible;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-child-current {
-webkit-transform: none;
-ms-transform: none;
transform: none;
}

View File

@ -0,0 +1,72 @@
@mixin translate($x: 0, $y: 0, $z: 0) {
-webkit-transform:translate3d($x, $y, $z);
-ms-transform:translate($x, $y);
transform:translate3d($x, $y, $z);
}
@mixin transition($prop, $duration, $easing: ease-in-out, $delay: 0ms) {
-webkit-transition:$prop $duration $easing $delay;
transition:$prop $duration $easing $delay;
}
@mixin transform($val) {
-webkit-transform:$val;
-ms-transform:$val;
transform:$val;
}
.csstransitions.csstransforms {
overflow-x:hidden;
.deck-container > .slide {
-webkit-transition:-webkit-transform 500ms ease-in-out;
transition:transform 500ms ease-in-out;
}
.deck-container:not(.deck-menu) {
> .slide {
position:absolute;
top:0;
left:0;
.slide {
position:relative;
left:0;
top:0;
-webkit-transition:-webkit-transform 500ms ease-in-out, opacity 500ms ease-in-out;
transition:transform 500ms ease-in-out, opacity 500ms ease-in-out;
}
.deck-next, .deck-after {
visibility:visible;
@include translate(200%);
}
}
> .deck-previous {
@include translate(-200%);
}
> .deck-before {
@include translate(-400%);
}
> .deck-next {
@include translate(200%);
}
> .deck-after {
@include translate(400%);
}
> .deck-before, > .deck-previous {
.slide {
visibility:visible;
}
}
> .deck-child-current {
@include transform(none);
}
}
}

View File

@ -0,0 +1,67 @@
.csstransitions.csstransforms .deck-container {
overflow-y: hidden;
}
.csstransitions.csstransforms .deck-container > .slide {
-webkit-transition: -webkit-transform 500ms ease-in-out;
transition: transform 500ms ease-in-out;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide {
position: absolute;
top: 0;
left: 0;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .slide {
position: relative;
left: 0;
top: 0;
-webkit-transition: -webkit-transform 500ms ease-in-out, opacity 500ms ease-in-out;
transition: transform 500ms ease-in-out, opacity 500ms ease-in-out;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .deck-next, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .slide .deck-after {
visibility: visible;
-webkit-transform: translate3d(0, 1600px, 0);
-ms-transform: translate(0, 1600px);
transform: translate3d(0, 1600px, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-previous {
-webkit-transform: translate3d(0, -200%, 0);
-ms-transform: translate(0, -200%);
transform: translate3d(0, -200%, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-before {
-webkit-transform: translate3d(0, -400%, 0);
-ms-transform: translate(0, -400%);
transform: translate3d(0, -400%, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-next {
-webkit-transform: translate3d(0, 200%, 0);
-ms-transform: translate(0, 200%);
transform: translate3d(0, 200%, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-after {
-webkit-transform: translate3d(0, 400%, 0);
-ms-transform: translate(0, 400%);
transform: translate3d(0, 400%, 0);
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-before .slide, .csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-previous .slide {
visibility: visible;
}
.csstransitions.csstransforms .deck-container:not(.deck-menu) > .deck-child-current {
-webkit-transform: none;
-ms-transform: none;
transform: none;
}
.csstransitions.csstransforms .deck-prev-link {
left: auto;
right: 8px;
top: 59px;
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}
.csstransitions.csstransforms .deck-next-link {
top: 99px;
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}

View File

@ -0,0 +1,92 @@
@mixin translate($x: 0, $y: 0, $z: 0) {
-webkit-transform:translate3d($x, $y, $z);
-ms-transform:translate($x, $y);
transform:translate3d($x, $y, $z);
}
@mixin rotate($deg) {
-webkit-transform:rotate($deg);
-ms-transform:rotate($deg);
transform:rotate($deg);
}
@mixin transition($prop, $duration, $easing: ease-in-out, $delay: 0ms) {
-webkit-transition:$prop $duration $easing $delay;
transition:$prop $duration $easing $delay;
}
@mixin transform($val) {
-webkit-transform:$val;
-ms-transform:$val;
transform:$val;
}
.csstransitions.csstransforms {
.deck-container {
overflow-y:hidden;
> .slide {
-webkit-transition:-webkit-transform 500ms ease-in-out;
transition:transform 500ms ease-in-out;
}
}
.deck-container:not(.deck-menu) {
> .slide {
position:absolute;
top:0;
left:0;
.slide {
position:relative;
left:0;
top:0;
-webkit-transition:-webkit-transform 500ms ease-in-out, opacity 500ms ease-in-out;
transition:transform 500ms ease-in-out, opacity 500ms ease-in-out;
}
.deck-next, .deck-after {
visibility:visible;
@include translate(0, 1600px);
}
}
> .deck-previous {
@include translate(0, -200%);
}
> .deck-before {
@include translate(0, -400%);
}
> .deck-next {
@include translate(0, 200%);
}
> .deck-after {
@include translate(0, 400%);
}
> .deck-before, > .deck-previous {
.slide {
visibility:visible;
}
}
> .deck-child-current {
@include transform(none);
}
}
.deck-prev-link {
left:auto;
right:8px;
top:59px;
@include rotate(90deg);
}
.deck-next-link {
top:99px;
@include rotate(90deg);
}
}