Skip to content

Instantly share code, notes, and snippets.

@christianp
Created June 14, 2016 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christianp/f987db1aca25eb94e4e6c3521e947d67 to your computer and use it in GitHub Desktop.
Save christianp/f987db1aca25eb94e4e6c3521e947d67 to your computer and use it in GitHub Desktop.
Numbas geogebra extension
Numbas.addExtension('geogebra',[],function(extension) {
window.geogebraIdAcc = window.geogebraIdAcc || 0;
var delay = 10;
var container;
$(document).ready(function() {
container = document.createElement('div');
container.setAttribute('id','numbasgeogebracontainer');
container.setAttribute('class','invisible');
document.body.appendChild(container);
});
var injectedDeployScript = false;
var loadGGB = new Promise(function(resolve,reject) {
if(window.GGBApplet) {
resolve(GGBApplet);
} else {
if(!injectedDeployScript) {
var s = document.createElement('script');
s.setAttribute('type','text/javascript');
s.setAttribute('src','https://www.geogebra.org/scripts/deployggb.js');
document.head.appendChild(s);
injectedDeployScript = true;
}
var int = setInterval(function() {
if(window.GGBApplet) {
clearInterval(int);
resolve(GGBApplet);
}
},delay);
}
});
var injectApplet = function(options) {
options.id = 'ggbApplet'+(window.geogebraIdAcc++);
console.log(options.id);
var applet = new GGBApplet(options, true);
var el = document.createElement('div');
container.appendChild(el);
applet.inject(el, 'preferHTML5');
return new Promise(function(resolve,reject) {
var int = setInterval(function() {
var app = applet.getAppletObject();
if(app) {
clearInterval(int);
resolve({app:app,el:el});
}
},delay);
});
}
var constructionFinished = function(app,names) {
return new Promise(function(resolve,reject) {
var int = setInterval(function() {
if(!app.exists) {
console.log(app);
reject("app.exists does not exist");
}
if(names.every(function(name) { return app.exists(name)})) {
clearInterval(int);
resolve(app);
}
},delay);
});
}
extension.createGeogebraApplet = function(options,names) {
names = names || [];
var element;
return loadGGB
.then(function() { return injectApplet(options)})
.then(function(d){ element=d.el; return constructionFinished(d.app,names)})
.then(function(app) { return new Promise(function(resolve,reject) { resolve({app:app,element:element}); }) })
;
}
var types = Numbas.jme.types;
var funcObj = Numbas.jme.funcObj;
var TString = types.TString;
var TList = types.TList;
var THTML = types.THTML;
function jmeCreateGeogebraApplet(material_id,replacements,results) {
// create a container element, which we'll return
// when the applet has been loaded, we'll attach it to the container element
var el = document.createElement('div');
el.innerHTML = 'GeoGebra applet loading...';
extension.createGeogebraApplet({material_id:material_id},replacements.map(function(r){return r[0]}))
.then(function(d) {
var app = d.app;
var int = setInterval(function() {
if(el.parentNode) {
el.innerHTML = '';
el.appendChild(d.element);
clearInterval(int);
replacements.forEach(function(r){
app.evalCommand(r[0]+'='+r[1]);
});
if(app.isExercise()) {
console.log('is exercise');
function check() {
var result = app.getExerciseResult();
console.log('result',result);
}
app.registerUpdateListener(check);
app.registerAddListener(check);
app.registerUpdateListener(check);
}
}
},delay);
})
.catch(function(e) {
throw(new Numbas.Error("Problem encountered when creating GeoGebra applet: "+e));
});
return el;
}
extension.scope.addFunction(new funcObj('geogebra_applet',[TString],THTML,function(material_id) {
return jmeCreateGeogebraApplet(material_id,[]);
},{unwrapValues:true}));
extension.scope.addFunction(new funcObj('geogebra_applet',[TString,TList],THTML,jmeCreateGeogebraApplet,{unwrapValues:true}));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment