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

Commit ecc8500

Browse files
committed
Merge pull request #34 from riknos314/revealPR
Ported reveal to be RSE-0001 complient
2 parents d4aff39 + 63b14e3 commit ecc8500

File tree

4 files changed

+317
-22
lines changed

4 files changed

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

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)