forked from Khan/khan-exercises
-
Notifications
You must be signed in to change notification settings - Fork 0
/
volume_pressure_relationship.html
133 lines (116 loc) · 5.94 KB
/
volume_pressure_relationship.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<!DOCTYPE html>
<html data-require="math graphie">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>The Volume-Pressure Relationship</title>
<script type="text/javascript">
/*global LabExercise:true, $ */
/*jshint eqnull: true */
LabExercise = {};
LabExercise.injectIframe = function() {
$('#iframe-container').html('<iframe id="model" width="495px" height="340px" frameborder="no" scrolling="no" src="http://lab.dev.concord.org/examples/interactives/embeddable.html#interactives/sam/gas-laws/3-volume-pressure-relationship.json"></iframe>');
// http://stackoverflow.com/questions/1z993900/should-i-use-dom-ready-functions-if-my-scripts-are-at-the-end-of-the-body
// seems to suggest that the DOM will always be ready here. (Seeking more explicit docs!)
// Note that using a script tag to load jQuery in this document seems to cause the exercise
// framework to break (symptom: <var>s are not substituted.)
var iframe = document.getElementById('model'),
iframeOrigin = iframe.src.match(/(.*?\/\/.*?)\//)[1],
post = LabExercise.post = function(message) {
var iframe = document.getElementById('model');
try {
iframe.contentWindow.postMessage(message, iframeOrigin);
} catch (e) {
// Assume that failure means we can only post strings, not objects (IE9)
// See http://dev.opera.com/articles/view/window-postmessage-messagechannel/#crossdoc
iframe.contentWindow.postMessage(JSON.stringify(message), iframeOrigin);
}
};
LabExercise.properties = {};
function receiveMessage(message) {
var messageData,
iframe = document.getElementById('model'),
volumeToDisplay;
if (message.source === iframe.contentWindow && message.origin === iframeOrigin) {
messageData = message.data;
if (typeof messageData === 'string') {
messageData = JSON.parse(messageData);
}
if (messageData.type === 'hello') {
// Handshake with the model
post({
type: 'hello',
origin: window.location.href.match(/(.*?\/\/.*?)\//)[1]
});
post({
type: 'observe',
propertyName: 'volume'
});
post({
type: 'observe',
propertyName: 'pressureProbeFiltered'
});
// Data about the initial settings may be in the DOM! (showGuess works by
// constructing div.problems for each guess up front, then simply appending
// the appropriate div.problem to the DOM when the user navigates the
// timeline to that guess)
volumeToDisplay = $('#iframe-container').attr('data-volume');
if (volumeToDisplay != null) {
post({
type: 'set',
propertyName: 'volume',
propertyValue: parseFloat(volumeToDisplay)
});
}
post({
type: 'play'
});
} else if (messageData.type === 'propertyValue') {
LabExercise.properties[messageData.name] = messageData.value;
}
}
}
window.addEventListener('message', receiveMessage, false);
};
</script>
<script src="../khan-exercise.js"></script>
</head>
<body>
<div class="exercise">
<div class="vars">
<var id="PRESSURE">randRange(6, 14) / 10</var>
</div>
<div class="problems">
<div>
<div class="problem">
<p>Make the pressure greater than <var>PRESSURE</var> bar.</p>
<div id="iframe-container">
<div class="volume"></div>
</div>
<div class="graphie">
// So, just including the iframe doesn't work because it gets detached and
// then reattached to the DOM by the Khan exercise framework. This confuses
// the postMessage protocol (we end up handshaking with a model that isn't
// the one the student sees) plus, it's wasteful.
// A khan-exercises trick is that the text in a graphie gets evaled, after
// the problem has been re-appended to the DOM.
LabExercise.injectIframe();
</div>
</div>
<div class="solution" data-type="custom">
<div class="instruction">
Use the Volume buttons to modify the pressure.
</div>
<div class="guess"> { volume: LabExercise.properties.volume, pressure: LabExercise.properties.pressureProbeFiltered } </div>
<div class="validator-function">
return guess.pressure >= PRESSURE;
</div>
<div class="show-guess">
// Just set data-volume, and MW will configure itself when appended.
$('#iframe-container').attr('data-volume', guess.volume);
</div>
</div>
</div>
</div>
</div>
</body>
</html>