rhet-butler 0.13.0 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/default-configuration/assets/fonts.googleapis.com/css/family=Arimo:700|Droid Sans Mono|Cinzel Decorative:700,900|Slackey,subset=latin,latin-ext +30 -0
- data/default-configuration/assets/fonts.gstatic.com/s/arimo/v12/P5sBzZCDf9_T_1Wi4TRNrZc.ttf +0 -0
- data/default-configuration/assets/fonts.gstatic.com/s/cinzeldecorative/v7/daaHSScvJGqLYhG8nNt8KPPswUAPniZQa9lESTQ.ttf +0 -0
- data/default-configuration/assets/fonts.gstatic.com/s/cinzeldecorative/v7/daaHSScvJGqLYhG8nNt8KPPswUAPniZoadlESTQ.ttf +0 -0
- data/default-configuration/assets/fonts.gstatic.com/s/droidsansmono/v10/6NUO8FuJNQ2MbkrZ5-J8lKFrp7pRef2u.ttf +0 -0
- data/default-configuration/assets/fonts.gstatic.com/s/slackey/v9/N0bV2SdQO-5yM0-dGlNQIQ.ttf +0 -0
- data/default-configuration/assets/javascript/presenter.js +317 -0
- data/default-configuration/assets/javascript/rhet-butler/child-step.js +13 -0
- data/default-configuration/assets/javascript/rhet-butler/step.js +197 -0
- data/default-configuration/assets/javascript/rhet-butler/steps/group.js +50 -0
- data/default-configuration/assets/javascript/rhet-butler/steps/item.js +60 -0
- data/default-configuration/assets/javascript/rhet-butler/steps/root.js +41 -0
- data/default-configuration/assets/javascript/rhet-butler/steps/slide.js +96 -0
- data/default-configuration/assets/javascript/rhet-butler/transition-states.js +173 -0
- data/default-configuration/assets/javascript/rhet-butler/transition-station.js +133 -0
- data/default-configuration/assets/javascript/rhet-butler/transition-stations.js +107 -0
- data/default-configuration/assets/javascript/rhet-butler/tree-builder.js +103 -0
- data/default-configuration/assets/javascript/utils.js +78 -0
- data/default-configuration/assets/stylesheets/font.sass +5 -9
- data/default-configuration/common/templates/presentation.html.erb +5 -5
- data/lib/rhet-butler/file-loading.rb +1 -1
- data/lib/rhet-butler/stasis/transform-queue.rb +2 -0
- data/spec/command-line.rb +1 -0
- data/spec/configuration.rb +27 -0
- data/spec/javascripts/fixtures/long-animation-group-1.html +19 -0
- data/spec/javascripts/fixtures/long-transition-group-1.html +10 -0
- data/spec/javascripts/fixtures/looped-animation-group-1.html +20 -0
- data/spec/javascripts/fixtures/quiet_console.js +2 -0
- data/spec/javascripts/fixtures/test-presentation.html +49 -0
- data/spec/javascripts/helpers/.gitkeep +0 -0
- data/spec/javascripts/helpers/jasmine-jquery.js +841 -0
- data/spec/javascripts/helpers/jj-fixture-path.js +3 -0
- data/spec/javascripts/helpers/jquery-3.4.0.min.js +2 -0
- data/spec/javascripts/present_spec.js +728 -0
- data/spec/javascripts/support/jasmine.yml +148 -0
- data/spec/javascripts/support/jasmine_helper.rb +23 -0
- data/spec/javascripts/support/run.html.erb +22 -0
- data/spec/javascripts/utils_spec.js +7 -0
- data/spec/main-app.rb +18 -0
- data/spec/messaging.rb +32 -0
- data/spec/presentation-view.rb +4 -4
- data/spec/resource-localizer.rb +37 -0
- data/spec/sass-functions.rb +25 -0
- data/spec/slide-loader.rb +1 -1
- data/spec/slide-rendering.rb +58 -0
- data/spec/static-generator.rb +54 -0
- metadata +211 -178
- data/default-configuration/assets/javascript/rhet-present.js +0 -855
- data/default-configuration/assets/javascript/rhet-present.min.js +0 -55
- data/default-configuration/assets/stylesheets/animate/attention/._pulse.scss.swp +0 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/arimo/v5/K-bXE71xZHgbUS_UdQjugvesZW2xOQ-xsNqO47m55DA.ttf +0 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/cinzeldecorative/v1/pXhIVnhFtL_B9Vb1wq2F9wIh9oxuYcmvOvyh_107lQs.ttf +0 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/cinzeldecorative/v1/pXhIVnhFtL_B9Vb1wq2F9zCUrkmwPfdnoTjOU_kXqBI.ttf +0 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/droidsansmono/v4/ns-m2xQYezAtqh7ai59hJYW_AySPyikQrZReizgrnuw.ttf +0 -0
- data/default-configuration/assets/themes.googleusercontent.com/static/fonts/slackey/v3/bJZDrYrGx8atJRHR9DVdqg.ttf +0 -0
- data/default-configuration/skels/slides.yaml +0 -7
@@ -0,0 +1,107 @@
|
|
1
|
+
//StationList -> *[Station]
|
2
|
+
// Runs through the JS mechanics of transitioning between steps -
|
3
|
+
//
|
4
|
+
// * marks all slides in the stream as prior and post
|
5
|
+
// * marks the current step,
|
6
|
+
// * handles event listeners
|
7
|
+
// * issues most custom events.
|
8
|
+
//
|
9
|
+
// FSM: preparing -> started-uphill -> downhill -> completed
|
10
|
+
//
|
11
|
+
|
12
|
+
import states from './transition-states.js';
|
13
|
+
import TransitionStation from './transition-station.js';
|
14
|
+
//import * from '../utils.js';
|
15
|
+
|
16
|
+
export default class {
|
17
|
+
constructor(presenter, firstStep, currentStep, lastStep){
|
18
|
+
this.presenter = presenter;
|
19
|
+
this.uphill = [];
|
20
|
+
this.uphillIndex = 0;
|
21
|
+
this.downhill = [];
|
22
|
+
this.downhillIndex = 0;
|
23
|
+
this.firstStep = firstStep;
|
24
|
+
this.currentStep = currentStep;
|
25
|
+
this.lastStep = lastStep;
|
26
|
+
this.buildList();
|
27
|
+
this.currentState = null;
|
28
|
+
this.changeState("preparing")
|
29
|
+
}
|
30
|
+
|
31
|
+
changeState(name){
|
32
|
+
if(typeof quiet_console == "undefined"){
|
33
|
+
console.log("Changing state: " + name +
|
34
|
+
" S/C/E: " + this.firstStep.toString() +
|
35
|
+
" / " + this.currentStep.toString() +
|
36
|
+
" / " + this.lastStep.toString()
|
37
|
+
);
|
38
|
+
}
|
39
|
+
var newState = states[name];
|
40
|
+
for(let func in newState){
|
41
|
+
this[func] = newState[func];
|
42
|
+
}
|
43
|
+
for(let stateName in states){
|
44
|
+
this.presenter.rootStep.removeClass(stateName);
|
45
|
+
}
|
46
|
+
this.presenter.rootStep.addClass(name);
|
47
|
+
this.currentState = name;
|
48
|
+
this.enterState();
|
49
|
+
}
|
50
|
+
|
51
|
+
buildList(){
|
52
|
+
var step = this.firstStep;
|
53
|
+
var checkedIn = true;
|
54
|
+
var station;
|
55
|
+
|
56
|
+
this.direction = this.firstStep.relativePosition(this.lastStep);
|
57
|
+
|
58
|
+
while(step != null){
|
59
|
+
checkedIn = checkedIn && (step != this.currentStep);
|
60
|
+
station = new TransitionStation(step);
|
61
|
+
this.uphill.push(station);
|
62
|
+
if(checkedIn){
|
63
|
+
station.visited();
|
64
|
+
}
|
65
|
+
step = step.parent;
|
66
|
+
}
|
67
|
+
step = this.lastStep;
|
68
|
+
while(step != null){
|
69
|
+
this.downhill.unshift(new TransitionStation(step));
|
70
|
+
step = step.parent;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
startElemId(){
|
75
|
+
return "prev_" + this.firstStep.element.id;
|
76
|
+
}
|
77
|
+
|
78
|
+
endElemId(){
|
79
|
+
return "next_" + this.lastStep.element.id;
|
80
|
+
}
|
81
|
+
|
82
|
+
eachStation(func){
|
83
|
+
this.uphill.forEach(func, this);
|
84
|
+
this.downhill.forEach(func, this);
|
85
|
+
}
|
86
|
+
|
87
|
+
//XXX The bind does not appear to be working:
|
88
|
+
// station is an animation event, and
|
89
|
+
// event is undefined
|
90
|
+
arriveListener(station, event){
|
91
|
+
console.log("rhet-butler/transition-stations.js:256", "event", event);
|
92
|
+
event.stopPropagation();
|
93
|
+
|
94
|
+
station.visited();
|
95
|
+
this.elementArrived();
|
96
|
+
|
97
|
+
return true;
|
98
|
+
}
|
99
|
+
|
100
|
+
elementArrived(station){
|
101
|
+
while(this.nextStation()){
|
102
|
+
};
|
103
|
+
if(typeof quiet_console == "undefined"){
|
104
|
+
console.log("Waiting for event")
|
105
|
+
};
|
106
|
+
}
|
107
|
+
}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
import { arrayify } from "../utils.js";
|
2
|
+
import Step from "./step.js";
|
3
|
+
import StepsRoot from "./steps/root.js";
|
4
|
+
import StepsGroup from "./steps/group.js";
|
5
|
+
import StepsSlide from "./steps/slide.js";
|
6
|
+
import StepsItem from "./steps/item.js";
|
7
|
+
|
8
|
+
export default class {
|
9
|
+
constructor(element, stepClass){
|
10
|
+
this.root = element;
|
11
|
+
this.stepClass = stepClass;
|
12
|
+
this.rootStep = null;
|
13
|
+
this.parentStack = [];
|
14
|
+
this.indexes = {
|
15
|
+
step: 0,
|
16
|
+
group: 0,
|
17
|
+
slide: 0,
|
18
|
+
item: 0
|
19
|
+
};
|
20
|
+
}
|
21
|
+
|
22
|
+
getParent(element){
|
23
|
+
var checkElement, parent, parentElement;
|
24
|
+
while(this.parentStack.length > 0) {
|
25
|
+
parent = this.parentStack[0];
|
26
|
+
parentElement = parent.element;
|
27
|
+
checkElement = element;
|
28
|
+
while(checkElement != parentElement && checkElement != this.root){
|
29
|
+
checkElement = checkElement.parentElement;
|
30
|
+
}
|
31
|
+
|
32
|
+
if(checkElement == parentElement){
|
33
|
+
return parent;
|
34
|
+
}
|
35
|
+
|
36
|
+
this.parentStack.shift().treeFinished();
|
37
|
+
}
|
38
|
+
|
39
|
+
return null;
|
40
|
+
}
|
41
|
+
|
42
|
+
assembleNextElement(element){
|
43
|
+
var step;
|
44
|
+
|
45
|
+
var parent = this.getParent(element);
|
46
|
+
|
47
|
+
if(element.classList.contains("root")){
|
48
|
+
if(element.id.length == 0){
|
49
|
+
element.id = "rhet-root"
|
50
|
+
}
|
51
|
+
step = new StepsRoot(element, this.indexes);
|
52
|
+
this.rootStep = step;
|
53
|
+
this.indexes.step++;
|
54
|
+
this.parentStack.unshift(step);
|
55
|
+
} else if(element.classList.contains("group")){
|
56
|
+
this.indexes.group++;
|
57
|
+
if(element.id.length == 0){
|
58
|
+
element.id = "group-" + this.indexes.group
|
59
|
+
}
|
60
|
+
|
61
|
+
step = new StepsGroup(parent, element, this.indexes);
|
62
|
+
this.indexes.step++;
|
63
|
+
this.parentStack.unshift(step);
|
64
|
+
} else if(element.classList.contains("slide")){
|
65
|
+
this.indexes.slide++;
|
66
|
+
if(element.id.length == 0){
|
67
|
+
element.id = "slide-" + this.indexes.slide
|
68
|
+
}
|
69
|
+
|
70
|
+
step = new StepsSlide(parent, element, this.indexes);
|
71
|
+
this.indexes.step++;
|
72
|
+
this.parentStack.unshift(step);
|
73
|
+
} else if(element.classList.contains("item")){
|
74
|
+
var cues = (Array.prototype.filter.call(element.classList, function(klass){ return /^cue-.*/.test(klass); }));
|
75
|
+
var cueLength = cues.length;
|
76
|
+
for(var i = 0; i < cueLength; i++){
|
77
|
+
this.indexes.item++;
|
78
|
+
if(element.id.length == 0){
|
79
|
+
element.id = "item-" + this.indexes.item
|
80
|
+
}
|
81
|
+
step = new StepsItem(parent, element, this.indexes, cues[i]);
|
82
|
+
if(step.parent.items.some(function(item){ return item == step})){
|
83
|
+
this.indexes.step++;
|
84
|
+
} else {
|
85
|
+
this.indexes.item--;
|
86
|
+
}
|
87
|
+
}
|
88
|
+
} else {
|
89
|
+
return //malformed
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
buildTree(){
|
94
|
+
var elements = arrayify(this.root.getElementsByClassName(this.stepClass));
|
95
|
+
|
96
|
+
elements.forEach(this.assembleNextElement, this);
|
97
|
+
while(this.parentStack.length > 0){
|
98
|
+
this.parentStack.shift().treeFinished();
|
99
|
+
};
|
100
|
+
|
101
|
+
return this.rootStep;
|
102
|
+
}
|
103
|
+
}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
/*
|
2
|
+
* RhetButler presentation Javascript (version <%= version %>
|
3
|
+
* Build date: <%= build_date %>
|
4
|
+
*
|
5
|
+
* Copyright <%= copyright_year %> Judson Lester (@judsonlester)
|
6
|
+
*
|
7
|
+
* Inspired by impress.js by
|
8
|
+
* Bartek Szopka (@bartaz)
|
9
|
+
*
|
10
|
+
* Released under the MIT and GPL Licenses.
|
11
|
+
*/
|
12
|
+
|
13
|
+
// `arraify` takes an array-like object and turns it into real Array
|
14
|
+
// to make all the Array.prototype goodness available.
|
15
|
+
export function arrayify( a ) {
|
16
|
+
return [].slice.call( a );
|
17
|
+
};
|
18
|
+
|
19
|
+
// `$$` return an array of elements for given CSS `selector` in the `context` of
|
20
|
+
// the given element or whole document.
|
21
|
+
export function $$( selector, context ) {
|
22
|
+
context = context || document;
|
23
|
+
return this.arrayify( context.querySelectorAll(selector) );
|
24
|
+
};
|
25
|
+
|
26
|
+
// `byId` returns element with given `id` - you probably have guessed that ;)
|
27
|
+
export function byId( id ) {
|
28
|
+
return document.getElementById(id);
|
29
|
+
};
|
30
|
+
|
31
|
+
// `triggerEvent` builds a custom DOM event with given `eventName` and `detail` data
|
32
|
+
// and triggers it on element given as `el`.
|
33
|
+
export function triggerEvent(el, eventName, detail) {
|
34
|
+
var event = document.createEvent("CustomEvent");
|
35
|
+
event.initCustomEvent(eventName, true, true, detail);
|
36
|
+
el.dispatchEvent(event);
|
37
|
+
};
|
38
|
+
|
39
|
+
var prefixes = ['Webkit', 'webkit', 'moz', 'Moz', 'o', 'O', 'ms', 'khtml', 'Khtml'];
|
40
|
+
|
41
|
+
var style = window.getComputedStyle(document.createElement('dummy')),
|
42
|
+
memory = {};
|
43
|
+
|
44
|
+
// `pfx` is a function that takes a standard CSS property name as a parameter
|
45
|
+
// and returns it's prefixed version valid for current browser it runs in.
|
46
|
+
// The code is heavily inspired by Modernizr http://www.modernizr.com/
|
47
|
+
export function pfx( prop ) {
|
48
|
+
if ( typeof memory[ prop ] === "undefined" ) {
|
49
|
+
|
50
|
+
var ucProp, props;
|
51
|
+
ucProp = prop.replace(/-[a-z]/g, function(match){ return match.slice(-1)[0].toUpperCase(); }),
|
52
|
+
props = [prop, ucProp];
|
53
|
+
ucProp = ucProp.replace(/^[a-z]/, function(letter){ return letter.toUpperCase() });
|
54
|
+
|
55
|
+
var allPfx = prefixes.forEach(function(prefix){
|
56
|
+
props.push(prefix + prop);
|
57
|
+
props.push(prefix + ucProp);
|
58
|
+
props.push(prefix + "-" + prop);
|
59
|
+
props.push(prefix + "-" + ucProp);
|
60
|
+
props.push("-" + prefix + "-" + prop);
|
61
|
+
props.push("-" + prefix + "-" + ucProp);
|
62
|
+
});
|
63
|
+
|
64
|
+
props = props.concat(allPfx);
|
65
|
+
|
66
|
+
memory[ prop ] = null;
|
67
|
+
for ( var i in props ) {
|
68
|
+
var testValue = style.getPropertyValue(props[i]);
|
69
|
+
if (!(testValue === null || testValue === undefined) ) {
|
70
|
+
memory[ prop ] = props[i];
|
71
|
+
break;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
}
|
76
|
+
|
77
|
+
return memory[ prop ];
|
78
|
+
};
|
@@ -2,32 +2,28 @@
|
|
2
2
|
font-family: 'Arimo'
|
3
3
|
font-style: normal
|
4
4
|
font-weight: 700
|
5
|
-
src: local(
|
6
|
-
|
5
|
+
src: local('Arimo Bold'), local('Arimo-Bold'), url(../fonts.gstatic.com/s/arimo/v12/P5sBzZCDf9_T_1Wi4TRNrZc.ttf) format('truetype')
|
7
6
|
|
8
7
|
@font-face
|
9
8
|
font-family: 'Cinzel Decorative'
|
10
9
|
font-style: normal
|
11
10
|
font-weight: 700
|
12
|
-
src: local(
|
13
|
-
|
11
|
+
src: local('Cinzel Decorative Bold'), local('CinzelDecorative-Bold'), url(../fonts.gstatic.com/s/cinzeldecorative/v7/daaHSScvJGqLYhG8nNt8KPPswUAPniZoadlESTQ.ttf) format('truetype')
|
14
12
|
|
15
13
|
@font-face
|
16
14
|
font-family: 'Cinzel Decorative'
|
17
15
|
font-style: normal
|
18
16
|
font-weight: 900
|
19
|
-
src: local(
|
20
|
-
|
17
|
+
src: local('Cinzel Decorative Black'), local('CinzelDecorative-Black'), url(../fonts.gstatic.com/s/cinzeldecorative/v7/daaHSScvJGqLYhG8nNt8KPPswUAPniZQa9lESTQ.ttf) format('truetype')
|
21
18
|
|
22
19
|
@font-face
|
23
20
|
font-family: 'Droid Sans Mono'
|
24
21
|
font-style: normal
|
25
22
|
font-weight: 400
|
26
|
-
src: local(
|
27
|
-
|
23
|
+
src: local('Droid Sans Mono Regular'), local('DroidSansMono-Regular'), url(../fonts.gstatic.com/s/droidsansmono/v10/6NUO8FuJNQ2MbkrZ5-J8lKFrp7pRef2u.ttf) format('truetype')
|
28
24
|
|
29
25
|
@font-face
|
30
26
|
font-family: 'Slackey'
|
31
27
|
font-style: normal
|
32
28
|
font-weight: 400
|
33
|
-
src: local(
|
29
|
+
src: local('Slackey Regular'), local('Slackey-Regular'), url(../fonts.gstatic.com/s/slackey/v9/N0bV2SdQO-5yM0-dGlNQIQ.ttf) format('truetype')
|
@@ -9,7 +9,6 @@
|
|
9
9
|
<meta name="description" content="<%= presentation.description %>" />
|
10
10
|
<meta name="author" content="<%= presentation.author_name %>" />
|
11
11
|
|
12
|
-
<script src="/javascript/rhet-present.js"></script>
|
13
12
|
<script src="/javascript/keyboard-nav.js"></script>
|
14
13
|
<%= render 'stylesheets.html' %>
|
15
14
|
<%= render 'header-javascript.html' %>
|
@@ -28,10 +27,11 @@
|
|
28
27
|
</div>
|
29
28
|
|
30
29
|
<%= render 'live-javascript.html' %>
|
31
|
-
<script>
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
<script type='module'>
|
31
|
+
import Presenter from '/javascript/presenter.js';
|
32
|
+
|
33
|
+
var presenter = new rhetButler.Presenter(document, window, "presentation");
|
34
|
+
setupUserInterface(presenter);
|
35
35
|
</script>
|
36
36
|
|
37
37
|
</body>
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'rhet-butler/command-line'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rhet-butler/configuration'
|
2
|
+
require 'valise'
|
3
|
+
|
4
|
+
describe RhetButler::Configuration, "defaults" do
|
5
|
+
let :test_fileset do
|
6
|
+
Valise::Set.new
|
7
|
+
end
|
8
|
+
|
9
|
+
subject :config do
|
10
|
+
described_class.new(test_fileset)
|
11
|
+
end
|
12
|
+
|
13
|
+
its(:root_slide_template){ should == "presentation.html" }
|
14
|
+
its(:username){ should == 'judson' }
|
15
|
+
its(:password){ should == 'judsonr00tzme' }
|
16
|
+
its(:author){ should == "Judson Lester" }
|
17
|
+
its(:title){ should == 'Presentation' }
|
18
|
+
its(:description){ should == "A nifty presentation made with Rhet Butler" }
|
19
|
+
its(:search_paths){ should == [] }
|
20
|
+
its(:static_target){ should == "static" }
|
21
|
+
its(:impress_config){ should == {} }
|
22
|
+
its(:root_arrangement){ should == "horizontal" }
|
23
|
+
its(:arrangement_blueprint){ should == [] }
|
24
|
+
its(:serve_port){ should == 8081 }
|
25
|
+
its(:root_slide){ should == "slides.yaml" }
|
26
|
+
its('default_content_filters'){ should == "textile" }
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<style type="text/css">
|
2
|
+
#group-1 {
|
3
|
+
color: black;
|
4
|
+
}
|
5
|
+
|
6
|
+
#group-1.am-at {
|
7
|
+
-webkit-animation-iteration-count: infinite;
|
8
|
+
-webkit-animation-name: pulse;
|
9
|
+
}
|
10
|
+
|
11
|
+
@keyframes pulse {
|
12
|
+
from {
|
13
|
+
color: black;
|
14
|
+
}
|
15
|
+
|
16
|
+
to {
|
17
|
+
color: white;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
</style>
|