Skip to content
This repository was archived by the owner on Jun 7, 2023. It is now read-only.

Commit 0c9eb4a

Browse files
committed
preparing reveal for PR
1 parent 2345e3a commit 0c9eb4a

File tree

4 files changed

+316
-22
lines changed

4 files changed

+316
-22
lines changed

runestone/reveal/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Reveal
2+
3+
The reveal component allows for hiding a bit of html and then showing when the user clicks a button. The revealed component can either be displayed inline in the page, or using a bootstrap modal.
4+
5+
6+
```html
7+
<div data-component="reveal" id="reveal_1" data-title="Super cool title" data-showtitle="Reveal Me!" data-hidetitle="Hide Me!">
8+
9+
<ul data-component="multiplechoice" data-multipleanswers="true" id="question_1">
10+
The Question can go right here.
11+
<li data-component="answer" id="123" >Answer One</li>
12+
<li data-component="feedback" for="123">Feedback for One</li>
13+
14+
<li data-component="answer" data-correct id="456">Answer Two</li>
15+
<li data-component="feedback" for="456">Feedback for Two</li>
16+
17+
<li data-component="answer" id="789" data-correct>Answer Three</li>
18+
<li data-component="feedback" for="789">Feedback for Three</li>
19+
</ul>
20+
</div>
21+
```
22+
23+
24+
<ul>
25+
<li><code>id</code> Must be unique on the page</li>
26+
<li><code>data-showtitle</code> Sets the text for the show button</li>
27+
<li><code>data-hidetitle</code> Sets the text for the hide button</li>
28+
<li><code>data-modal</code> Causes the revealed content to be shown in a modal rather than inline</li>
29+
<li><code>data-title</code> Optional, sets the title for the modal popup if modal is being used</li>
30+
</ul>

runestone/reveal/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from .reveal import *
1+
from .reveal import *

runestone/reveal/js/reveal.js

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/*==========================================
2+
======= Master reveal.js ========
3+
============================================
4+
=== This file contains the JS for ===
5+
=== the Runestone reval component. ===
6+
============================================
7+
=== Created by ===
8+
=== Isaiah Mayerchak ===
9+
=== 06/12/15 ===
10+
==========================================*/
11+
function RunestoneBase () { // Parent function
12+
13+
}
14+
15+
RunestoneBase.prototype.logBookEvent = function (info) {
16+
console.log("logging event " + this.divid);
17+
};
18+
19+
RunestoneBase.prototype.logRunEvent = function (info) {
20+
console.log("running " + this.divid);
21+
};
22+
var RevealList = {}; // Dictionary that contains all instances of Reveal objects
23+
24+
Reveal.prototype = new RunestoneBase();
25+
26+
// Define Reveal object
27+
function Reveal (opts) {
28+
if (opts) {
29+
this.init(opts);
30+
}
31+
}
32+
33+
/*======================================
34+
== Initialize basic Reveal attributes ==
35+
========================================*/
36+
Reveal.prototype.init = function (opts) {
37+
RunestoneBase.apply(this, arguments);
38+
var orig = opts.orig; // entire <div> element that will be replaced by new HTML
39+
this.origElem = orig;
40+
this.divid = orig.id;
41+
this.dataModal = false; // is a model dialog vs. inline
42+
if ($(this.origElem).is("[data-modal]")) {
43+
this.dataModal = true;
44+
}
45+
this.modalTitle = null;
46+
this.showtitle = null; // Title of button that shows the concealed data
47+
this.hidetitle = null;
48+
this.origContent = $(this.origElem).html();
49+
this.children = this.origElem.childNodes;
50+
51+
if (this.dataModal) {
52+
this.checkForTitle();
53+
}
54+
55+
this.getButtonTitles();
56+
this.createShowButton();
57+
58+
if (!this.dataModal) {
59+
this.createHideButton(); // Hide button is already implemented in modal dialog
60+
}
61+
};
62+
63+
/*====================================
64+
== Get text for buttons/modal title ==
65+
====================================*/
66+
Reveal.prototype.getButtonTitles = function () { // to support old functionality
67+
this.showtitle = $(this.origElem).data("showtitle");
68+
if (this.showtitle === undefined) {
69+
this.showtitle = "Show"; // default
70+
}
71+
this.hidetitle = $(this.origElem).data("hidetitle");
72+
if (this.hidetitle === undefined) {
73+
this.hidetitle = "Hide"; // default
74+
}
75+
};
76+
77+
Reveal.prototype.checkForTitle = function () {
78+
this.modalTitle = $(this.origElem).data("title");
79+
if (this.modalTitle === undefined) {
80+
this.modalTitle = "Message from the author"; // default
81+
}
82+
};
83+
84+
/*============================
85+
== Create show/hide buttons ==
86+
============================*/
87+
Reveal.prototype.createShowButton = function () {
88+
var _this = this;
89+
this.wrapDiv = document.createElement("div"); // wrapper div
90+
this.revealDiv = document.createElement("div"); // Div that is hidden that contains content
91+
this.revealDiv.id = this.divid;
92+
this.wrapDiv.appendChild(this.revealDiv);
93+
94+
// Get original content, put it inside revealDiv and replace original div with revealDiv
95+
//$(this.revealDiv).html(this.origContent);
96+
for (var i = 0; i < this.children.length; i++) {
97+
this.revealDiv.appendChild(this.children[i]);
98+
}
99+
$(this.revealDiv).hide();
100+
$(this.origElem).replaceWith(this.wrapDiv);
101+
102+
this.sbutt = document.createElement("button");
103+
this.sbutt.style = "margin-bottom:10px";
104+
this.sbutt.class = "btn btn-default reveal_button";
105+
this.sbutt.textContent = this.showtitle;
106+
this.sbutt.id = this.divid + "_show";
107+
if (!this.dataModal) {
108+
this.sbutt.onclick = function () {
109+
_this.showInline();
110+
$(this).hide();
111+
};
112+
} else {
113+
this.createModal();
114+
$(this.sbutt).attr({"data-toggle":"modal",
115+
"data-target":"#" + this.divid + "_modal"});
116+
}
117+
this.wrapDiv.appendChild(this.sbutt);
118+
};
119+
120+
Reveal.prototype.createHideButton = function () {
121+
var _this = this;
122+
this.hbutt = document.createElement("button");
123+
$(this.hbutt).hide();
124+
this.hbutt.textContent = this.hidetitle;
125+
this.hbutt.class = "btn btn-default reveal_button";
126+
this.hbutt.id = this.divid + "_hide";
127+
this.hbutt.onclick = function () {
128+
_this.hideInline();
129+
$(this).hide();
130+
};
131+
this.wrapDiv.appendChild(this.hbutt);
132+
133+
};
134+
135+
/*=================
136+
=== Modal logic ===
137+
=================*/
138+
Reveal.prototype.createModal = function () { // Displays popup dialog modal window
139+
this.modalContainerDiv = document.createElement("div");
140+
$(this.modalContainerDiv).addClass("modal fade");
141+
this.modalContainerDiv.id = this.divid + "_modal";
142+
$(this.modalContainerDiv).attr("role", "dialog");
143+
document.body.appendChild(this.modalContainerDiv);
144+
145+
this.modalDialogDiv = document.createElement("div");
146+
$(this.modalDialogDiv).addClass("modal-dialog compare-modal");
147+
this.modalContainerDiv.appendChild(this.modalDialogDiv);
148+
149+
this.modalContentDiv = document.createElement("div");
150+
$(this.modalContentDiv).addClass("modal-content");
151+
this.modalDialogDiv.appendChild(this.modalContentDiv);
152+
153+
this.modalHeaderDiv = document.createElement("div");
154+
$(this.modalHeaderDiv).addClass("modal-header");
155+
this.modalContentDiv.appendChild(this.modalHeaderDiv);
156+
157+
this.modalButton = document.createElement("button");
158+
this.modalButton.type = "button";
159+
$(this.modalButton).addClass("close");
160+
$(this.modalButton).attr({"aria-hidden":"true",
161+
"data-dismiss":"modal"});
162+
this.modalButton.innerHTML = "&times";
163+
this.modalHeaderDiv.appendChild(this.modalButton);
164+
165+
this.modalTitleE = document.createElement("h4");
166+
$(this.modalTitleE).addClass("modal-title");
167+
this.modalTitleE.innerHTML = this.modalTitle;
168+
this.modalHeaderDiv.appendChild(this.modalTitleE);
169+
170+
this.modalBody = document.createElement("div");
171+
$(this.modalBody).addClass("modal-body");
172+
for (var i = 0; i < this.children.length; i++) {
173+
this.modalBody.appendChild(this.children[i]);
174+
}
175+
this.modalContentDiv.appendChild(this.modalBody);
176+
177+
178+
179+
180+
/*var html = "<div class='modal fade'>" +
181+
" <div class='modal-dialog compare-modal'>" +
182+
" <div class='modal-content'>" +
183+
" <div class='modal-header'>" +
184+
" <button type='button' class='close' data-dismiss='modal' aria-hidden='true'>&times;</button>" +
185+
" <h4 class='modal-title'>" + this.modalTitle + "</h4>" +
186+
" </div>" +
187+
" <div class='modal-body'>" +
188+
this.origContent +
189+
" </div>" +
190+
" </div>" +
191+
" </div>" +
192+
"</div>";*/
193+
//var el = $(this.modalContainerDiv);
194+
//el.modal();
195+
};
196+
197+
/*==================
198+
=== Inline logic ===
199+
==================*/
200+
Reveal.prototype.showInline = function () { // Displays inline version of reveal
201+
$(this.revealDiv).show();
202+
$(this.hbutt).show();
203+
$(this.revealDiv).find(".CodeMirror").each(function (i, el) {el.CodeMirror.refresh(); });
204+
205+
};
206+
207+
Reveal.prototype.hideInline = function () {
208+
$(this.revealDiv).hide();
209+
$(this.sbutt).show();
210+
};
211+
212+
/*=================================
213+
== Find the custom HTML tags and ==
214+
== execute our code on them ==
215+
=================================*/
216+
$(document).ready(function () {
217+
$("[data-component=reveal]").each(function (index) {
218+
RevealList[this.id] = new Reveal({"orig": this});
219+
});
220+
});

runestone/reveal/reveal.py

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,102 @@
1-
__author__ = 'isaacdontjelindell'
1+
# Copyright (C) 2011 Bradley N. Miller
2+
#
3+
# This program is free software: you can redistribute it and/or modify
4+
# it under the terms of the GNU General Public License as published by
5+
# the Free Software Foundation, either version 3 of the License, or
6+
# (at your option) any later version.
7+
#
8+
# This program is distributed in the hope that it will be useful,
9+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
# GNU General Public License for more details.
12+
#
13+
# You should have received a copy of the GNU General Public License
14+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
#
16+
__author__ = 'isaiahmayerchak'
217

318
from docutils import nodes
419
from docutils.parsers.rst import directives
520
from docutils.parsers.rst import Directive
621

22+
#add directives/javascript/css
723
def setup(app):
824
app.add_directive('reveal', RevealDirective)
925

10-
app.add_node(RevealNode, html=(visit_reveal_node, depart_reveal_node))
11-
26+
app.add_javascript('reveal.js')
1227

13-
BEGIN = """
14-
<button type='button' id='%(divid)s_show' class='btn btn-default reveal_button' style='margin-bottom:10px;' onclick="$(this).hide();$('#%(divid)s').show();$('#%(divid)s_hide').show();$('#%(divid)s').find('.CodeMirror').each(function(i, el){el.CodeMirror.refresh();});">
15-
%(showtitle)s
16-
</button>
17-
<button type='button' id='%(divid)s_hide' class='btn btn-default reveal_button' onclick="$(this).hide();$('#%(divid)s').hide();$('#%(divid)s_show').show();" style='display:none'>%(hidetitle)s</button>
18-
<div id='%(divid)s' style='display:none'>
19-
"""
20-
21-
END = """
22-
</div>
23-
"""
28+
app.add_node(RevealNode, html=(visit_reveal_node, depart_reveal_node))
2429

2530
class RevealNode(nodes.General, nodes.Element):
2631
def __init__(self,content):
2732
super(RevealNode,self).__init__()
28-
self.reveal_components = content
33+
self.reveal_options = content
2934

3035

3136
def visit_reveal_node(self, node):
32-
res = BEGIN % node.reveal_components
37+
#Set options and format templates accordingly
38+
39+
if 'modal' in node.reveal_options:
40+
node.reveal_options['modal'] = 'data-modal'
41+
else:
42+
node.reveal_options['modal'] = ''
3343

44+
if 'modaltitle' in node.reveal_options:
45+
temp = node.reveal_options['modaltitle']
46+
node.reveal_options['modaltitle'] = '''data-title=''' + '"' + temp + '"'
47+
else:
48+
node.reveal_options['modaltitle'] = ''
49+
50+
res = TEMPLATE_START % node.reveal_options
3451
self.body.append(res)
3552

3653
def depart_reveal_node(self,node):
37-
res = END % node.reveal_components
54+
#Set options and format templates accordingly
55+
res = TEMPLATE_END % node.reveal_options
3856

3957
self.body.append(res)
4058

59+
#Templates to be formatted by node options
60+
TEMPLATE_START = '''
61+
<div data-component="reveal" id="%(divid)s" %(modal)s %(modaltitle)s %(showtitle)s %(hidetitle)s>
62+
'''
63+
TEMPLATE_END = '''
64+
</div>
65+
'''
4166
class RevealDirective(Directive):
4267
required_arguments = 1
4368
optional_arguments = 0
4469
final_argument_whitespace = True
4570
has_content = True
4671
option_spec = {"showtitle":directives.unchanged,
47-
"hidetitle":directives.unchanged}
72+
"hidetitle":directives.unchanged,
73+
"modal":directives.flag,
74+
"modaltitle":directives.unchanged}
4875

4976
def run(self):
50-
self.assert_has_content() # an empty reveal block isn't very useful...
77+
"""
78+
process the reveal directive and generate html for output.
79+
:param self:
80+
:return:
81+
.. reveal:: identifier
82+
:showtitle: Text on the 'show' button--default is "Show"
83+
:hidetitle: Text on the 'hide' button--default is "Hide"
84+
:modal: Boolean--if included, revealed display will be a modal
85+
:modaltitle: Title of modal dialog window--default is "Message from the author"
86+
87+
Content
88+
...
89+
"""
90+
self.assert_has_content() # make sure reveal has something in it
5191

5292
if not 'showtitle' in self.options:
53-
self.options['showtitle'] = "Show"
93+
self.options['showtitle'] = 'data-showtitle="Show"'
94+
else:
95+
self.options['showtitle'] = '''data-showtitle=''' + '"' + self.options['showtitle'] + '"'
5496
if not 'hidetitle' in self.options:
55-
self.options['hidetitle'] = "Hide"
97+
self.options['hidetitle'] = 'data-hidetitle="Hide"'
98+
else:
99+
self.options['hidetitle'] = '''data-hidetitle=''' + '"' + self.options['hidetitle'] + '"'
56100

57101
self.options['divid'] = self.arguments[0]
58102

0 commit comments

Comments
 (0)