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

Commit e773011

Browse files
Merge branch 'master' into accessibility_fixes
2 parents a50d551 + 891d1d7 commit e773011

39 files changed

Lines changed: 7667 additions & 2764 deletions

.gitattributes

Lines changed: 0 additions & 2 deletions
This file was deleted.

package-lock.json

Lines changed: 2375 additions & 2730 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"main": "dist/runestone.js",
66
"scripts": {
77
"test": "echo \"Error: no test specified\" && exit 1",
8+
"check-env": "node -e 'console.log(process.env)' | grep npm",
89
"build": "webpack --mode=development",
910
"buildj": "webpack --mode=development --profile --json > stats.json",
1011
"watch": "webpack --mode=development --watch",
@@ -37,6 +38,7 @@
3738
"jexcel": "^3.9.1",
3839
"jquery-ui": "1.10.4",
3940
"sql.js": "1.5.0",
40-
"vega-embed": "3.14.0"
41+
"vega-embed": "3.14.0",
42+
"wavedrom": "^2.0.0"
4143
}
42-
}
44+
}

runestone/__init__.py

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
from .animation import Animation
88
from .mchoice import MChoice, QuestionNumber
99
from .blockly import Blockly
10+
from .quizly import Quizly
11+
from .khanex import Khanex
1012
from .codelens import Codelens
1113
from .clickableArea import ClickableArea
1214
from .datafile import DataFile
@@ -51,11 +53,7 @@ def runestone_static_dirs():
5153
module_static_css.append(os.path.join(basedir, "webgldemo", "css"))
5254
module_static_css.append(os.path.join(basedir, "matrixeq", "css"))
5355
module_static_css.append(os.path.join(basedir, "lp", "css"))
54-
return (
55-
module_static_js
56-
+ module_static_css
57-
+ CodeChat.CodeToRest.html_static_path()
58-
)
56+
return module_static_js + module_static_css + CodeChat.CodeToRest.html_static_path()
5957

6058

6159
# runestone_extensions()
@@ -76,6 +74,7 @@ def runestone_extensions():
7674
modules.insert(0, modules.pop(modules.index("runestone.common")))
7775
return modules
7876

77+
7978
# setup_js_defer(app, pagename, templatexname, context, doctree)
8079
# -----------------------
8180
# Used to inspect js right before it is rendered to page so that
@@ -85,16 +84,20 @@ def js_defer(script_files):
8584
for js in sorted(script_files):
8685
if app.config.html_defer_js:
8786
# Files added from Runestone should already have defer set - so just add it to sphinx based ones
88-
to_defer = ["_static/jquery.js", "_static/underscore.js","_static/doctools.js"]
87+
to_defer = [
88+
"_static/jquery.js",
89+
"_static/underscore.js",
90+
"_static/doctools.js",
91+
]
8992
if isinstance(js, JavaScript) and js in to_defer:
9093
js.attributes["defer"] = ""
9194
else:
92-
#config flag not set, prevent all deferrals
95+
# config flag not set, prevent all deferrals
9396
if isinstance(js, JavaScript):
9497
js.attributes.pop("defer", None)
95-
return ''
98+
return ""
9699

97-
context['js_defer'] = js_defer
100+
context["js_defer"] = js_defer
98101

99102

100103
# setup(app)
@@ -108,7 +111,13 @@ def setup(app):
108111
we wanted to do for all projects.
109112
"""
110113
# Include JS and CSS produced by webpack. See `webpack static imports <webpack_static_imports>`_.
111-
with open(pkg_resources.resource_filename("runestone", "dist/webpack_static_imports.json"), "r", encoding="utf-8") as f:
114+
with open(
115+
pkg_resources.resource_filename(
116+
"runestone", "dist/webpack_static_imports.json"
117+
),
118+
"r",
119+
encoding="utf-8",
120+
) as f:
112121
wb_imports = json.load(f)
113122
script_files = wb_imports["js"]
114123
_css_files = css_files + wb_imports["css"]
@@ -124,9 +133,26 @@ def setup(app):
124133
except ExtensionError:
125134
app.add_css_file(cssfile)
126135

136+
# projects can define their own custom css or js files to include
137+
# But since this is imported into their conf.py authors must
138+
# define them as attributes of the setup function
139+
# ``setup.custom_xxx_files``
140+
try:
141+
for c in setup.custom_css_files:
142+
app.add_css_file(c)
143+
print("Adding custom CSS files")
144+
except AttributeError:
145+
print("No custom CSS files")
146+
try:
147+
for c in setup.custom_js_files:
148+
app.add_js_file(c)
149+
print("Adding custom Javascript")
150+
except AttributeError:
151+
print("No custom js files")
152+
127153
app.config.html_static_path.append("dist/")
128-
app.add_config_value("html_defer_js", False, 'env')
129-
app.connect('html-page-context', setup_js_defer)
154+
app.add_config_value("html_defer_js", False, "env")
155+
app.connect("html-page-context", setup_js_defer)
130156

131157

132158
def get_master_url():
@@ -217,6 +243,7 @@ def build(options):
217243
"dragndrop": DragNDrop,
218244
"parsonsprob": ParsonsProblem,
219245
"poll": Poll,
246+
"quizly": Quizly,
220247
"reveal": RevealDirective,
221248
"selectquestion": SelectQuestion,
222249
"shortanswer": JournalDirective,

runestone/common/js/renderComponent.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ export async function renderRunestoneComponent(componentSrc, whereDiv, moreOpts)
66
* The tedious part is calling the right functions to turn the
77
* source into the actual component.
88
*/
9+
if (!componentSrc) {
10+
jQuery(`#${whereDiv}`).html(`<p>Sorry, no source is available for preview.</p>`);
11+
return;
12+
}
913
let patt = /..\/_images/g;
1014
componentSrc = componentSrc.replace(
1115
patt,
@@ -38,7 +42,7 @@ export async function renderRunestoneComponent(componentSrc, whereDiv, moreOpts)
3842

3943
if (typeof component_factory === "undefined") {
4044
alert(
41-
"Error: Missing the component factory! Clear you browser cache."
45+
"Error: Missing the component factory!"
4246
);
4347
} else {
4448
if (

runestone/common/project_template/_templates/plugin_layouts/sphinx_bootstrap/layout.html

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<div class="navbar-header">
3434
<!-- .btn-navbar is used as the toggle for collapsed navbar content -->
3535
<button type='button' class='navbar-toggle' data-toggle="collapse" data-target=".navbar-ex1-collapse">
36-
<span class="icon-bar visuallyhidden" aria-label="navbar toggle">toggle navbar</span>
36+
<span class="icon-bar" aria-label="navbar toggle">toggle navbar</span>
3737
<span class="icon-bar"></span>
3838
<span class="icon-bar"></span>
3939
</button>
@@ -68,7 +68,7 @@
6868
{% if minimal_outside_links != 'True' %}
6969
<li class="dropdown">
7070
<a class="dropdown-toggle" href="#" data-toggle="dropdown">
71-
<i class="glyphicon glyphicon-globe visuallyhidden" style="opacity: 0.9"><span aria-label="Social">Social</span></i>
71+
<i class="glyphicon glyphicon-globe" style="opacity: 0.9"><span class="visuallyhidden" aria-label="Social">Social</span></i>
7272
</a>
7373
<ul class="dropdown-menu social-menu">
7474
<li>
@@ -105,7 +105,7 @@
105105
<!-- search dropdown -->
106106
<li class="dropdown">
107107
<a class="dropdown-toggle" href="#" data-toggle="dropdown">
108-
<i class="glyphicon glyphicon-search visuallyhidden" style='opacity:0.9;'><span aria-label="Search">Search</span></i>
108+
<i class="glyphicon glyphicon-search" style='opacity:0.9;'><span class="visuallyhidden" aria-label="Search">Search</span></i>
109109
</a>
110110
<ul class='dropdown-menu'>
111111
{% if 'overview' in course_id %}
@@ -139,7 +139,7 @@
139139
<!-- user account dropdown -->
140140
<li class="dropdown">
141141
<a class="dropdown-toggle" href="#" data-toggle="dropdown">
142-
<i class="glyphicon glyphicon-user visuallyhidden" style="opacity:0.9;"><span aria-label="User">User</span></i>
142+
<i class="glyphicon glyphicon-user" style="opacity:0.9;"><span class="visuallyhidden" aria-label="User">User</span></i>
143143
</a>
144144
<ul class="dropdown-menu user-menu">
145145
<li><span class='loggedinuser'></span></li>
@@ -173,8 +173,8 @@
173173
<!-- <li id="scratch_ac_link"><a href="javascript:ACFactory.toggleScratchActivecode()">Scratch ActiveCode</a></li> -->
174174

175175
<!-- <li class="dropdown"> -->
176-
<li id="scratch_ac_link" class="dropdown"><a href="javascript:ACFactory.toggleScratchActivecode()">
177-
<i class="glyphicon glyphicon-pencil visuallyhidden" style="opacity:0.9;"><span aria-label="Scratch Activecode">Scratch Activecode</span></i></a></li>
176+
<li id="scratch_ac_link" class="dropdown"><a href="javascript:runestoneComponents.popupScratchAC()">
177+
<i class="glyphicon glyphicon-pencil" style="opacity:0.9;"><span class="visuallyhidden" aria-label="Scratch Activecode" >Scratch Activecode</span></i></a></li>
178178
<!-- </li> -->
179179

180180
<li class="divider-vertical"></li>
@@ -183,7 +183,7 @@
183183
<!-- help menu dropdown -->
184184
<li class="dropdown">
185185
<a class="dropdown-toggle" href="#" data-toggle="dropdown">
186-
<i class="glyphicon glyphicon-question-sign visuallyhidden" style="opacity:0.9;"><span aria-label="Help">Help</span></i>
186+
<i class="glyphicon glyphicon-question-sign" style="opacity:0.9;"><span class="visuallyhidden" aria-label="Help">Help</span></i>
187187
</a>
188188
<ul class="dropdown-menu user-menu">
189189
<li><a href='http://runestoneinteractive.org/pages/faq.html'>FAQ</a></li>
@@ -262,7 +262,6 @@
262262
eBookConfig.proxyuri_files = '{{proxy_uri_files}}';
263263
eBookConfig.enable_chatcodes = {{enable_chatcodes}} ? {{ enable_chatcodes }} : false;
264264

265-
266265
</script>
267266

268267
<!-- Ad Serving Headers Only serve ads to Anonymous Users -->

runestone/khanex/README.txt

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
README.txt
2+
3+
The content files for the khanex component must be stored in the
4+
course's _static folder. Download the following file and unzip it in _static:
5+
https://github.com/ram8647/khanex/blob/16398fd496fad5b93fdf4d72c274064db8d1d1ac/khanex-runestone.zip
6+
7+
The khanex directive, in this first pass looks like this:
8+
-----------------------------------------------
9+
10+
.. khanex::
11+
:exercise: unique-exercise-name /qs folder
12+
13+
The quizly component uses and requires the following resources:
14+
----------------------------------------------
15+
16+
runestone/khanex/khanex.py -- creates KhanexNode from directive
17+
runestone/khanex/__init__.py -- imports the khanex code
18+
19+
runestone/khanex/js -- javascript resources
20+
21+
22+
runestone/khanex/test -- some test code
23+
-- _sources -- test files
24+
-- conf.py -- sphinx config file for runestone
25+
-- pavement.py -- needed for runestone build
26+
27+
The files that need to be coded by the developer
28+
-----------------------------------------------
29+
30+
./runestone/khanex/khanex.py
31+
----------------------------
32+
Th script that runs during runestone build. Runestone build parses the
33+
source document and translates the directive and its options into a QuizlyNode.
34+
35+
- QuizlyNode -- defines the node. The only option needed for this is the quizname,
36+
which is parsed from the directive.
37+
38+
- visit_quizly_mode(self, node) -- appends the quizly template, instantiated, to the
39+
body of the html document that will represent the quizly exercise
40+
41+
- Quizly(RunestoneDirective) -- its run() method instantiates and returns QuizlyNode,
42+
probably called by runestone build.
43+
44+
./runestone/khanex/__init__.py -- called by runestone build, imports khanex.py
45+
------------------------------
46+
47+
./runestone/khanex/js/khanex.js
48+
-------------------------------
49+
50+
This script runs when the html page containing the khanex iframe is loaded. It contains
51+
methods to render the khanex component and to handle the interface with runestone.
52+
53+
This script will be invoked automatically when the page is loaded, provided a khanex entry
54+
is made in the module.exports list in webpack.config.js.
55+
56+
"./runestone/khanex/js/khanex.js",
57+
58+
khanex.js contains the following methods and functions:
59+
60+
-- class Khanex extends RunestoneBase -- constructs a Khanex object that holds the
61+
data from the exercise. Calls renderQuiz() method.
62+
63+
-- getIFrame() -- extracts the iframe from the fully instantiated html code produced
64+
by khanex.py and contained in KhanexNode.
65+
66+
-- renderKhanex() -- renders the khanex iframe inside a container <div>.
67+
68+
-- submitKhanex() -- the method invoked from the callback function when the user
69+
clicks "Check Me" button in the khanex exercise.
70+
71+
$(document).bind( ,,, function() {}) -- function that sets up the callback function
72+
and binds it to the html document.
73+
74+
setupCallback(khanex) -- defines the callback function that is invoked when the "Check Me"
75+
button is clicked. It calls khanex.submitKhanex(result), where result is the
76+
khanex-graded response to the user's attempt.
77+

runestone/khanex/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .khanex import *

runestone/khanex/js/.htaccess

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Header set Access-Control-Allow-Origin "*"

0 commit comments

Comments
 (0)