wiki:GeoGebraMobile/CodingHints
Last modified 13 months ago Last modified on 05/06/11 07:37:12

GeoGebraMobile Coding Hints

The GeoGebraMobile is a GWT application. About GWT you can read here : http://code.google.com/intl/hu-HU/webtoolkit/overview.html Basically, it compiles the slightly modified Java code of GeoGebra to JavaScript. This produces optimized .js files for every browser engine, and uses html5 <canvas> element to show the construction. There are other html5 techniques are used as well. Everything, that is considered to be the logic of GeoGebra (mainly the kernel) should be stay as close as possible to the original code. Any other part, that is related to the browser, must follow the rules of web development.

Export (in progress)

The html5 export from the original GeoGebra should produce a markup like that:

<!DOCTYPE html> <!--Html5 doctype-->
<html>
<head>
    <title>GeoGebra to JavaScript port</title>
</head>
<body>
	<script type="text/javascript" src="http://www.geogebra.org/mobile/4.0/geogebramobile/geogebramobile.nocache.js"></script> <!--Script include-->
	<article class="ggm" style="width: 905px; height: 491px;" <!--article element to parse with html5 custom data attributes-->
    		data-param-ggbbase64="UEsDB...xgAAAAA"></article>
</body>
</html>

See the html5 specification of article element http://dev.w3.org/html5/spec/Overview.html#the-article-element, and about the data attributes http://dev.w3.org/html5/spec/Overview.html#attr-data.

This markup is the minimal, it could (and should) formated by CSS and and can be used with full page markup (header, text etc...). The original markup works too, but this should be the production version when we are ready.

GeoGebraMobile package layout

If you open the GeoGebraMobile in eclipse, you can see the following layout:

geogebramobile/
  >src <==the Java source classes
  >test <==not used
  >lib  <==.jar libraries used for math, for example 
  >war <==compiled JavaScript files (geogebramobile/ subfolder) and html files stay here: this is basically a test web server, used by eclipse connected with Firefox or Chrome (depends on the GWT plugin you installed).

If you open the src directory, there are mainly three part of them:

geogebra.geogebramobile <=Root package, It contains the GeoGebraMobile.gwt.xml, where the compiling directives can be placed and changed

geogebra.geogebramobile.client <=everything, that is taken here will be compiled to JavaScript. So, if you like to be your new classes compiled to JavaScript, they stay under that package hierarcy (in subpackages as you wish). The layout under client package match to the layout of GeoGebra, as close as possible.

geogebra.geogebramobile.jre.java.io <== super-sourced classes, see http://code.google.com/intl/hu-HU/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModules They drop errors in Eclipse, but good on compile.

JSNI methods

Everything, that is not possible to Java, but possible to JavaScript (Dom and browser specific issues, features that not implemented in GWT yet) should be written in plain javascript. This is the way how to do that: http://code.google.com/intl/hu-HU/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html. Now a lot of JSNI method stays in ..client.main.Application.java but they should and will go to ..client.GeoGebraMobileTag.java, where all the JSNI methods stay. It is easier to maintain if they are all in one file.

Pure JavaScript and Globals

As we don't know, in which browsers environment the GeoGebraMobile will be used, it is important to hide our variables under a namespace (there are other methods as well, but this will do). This namespace is created in client.GeoGebraMobile.java which is the application entry point, by the GeoGebraMobileTag.getGeoGebraMobileTags() method:

	//init the namespace
		$wnd.ggm = {};
		$wnd.ggm.geogebramobiletags = {};

If you plan any specific, that must stay in JavaScript, but specific to the given '<article' element (as it possible to have more GeoGebraMobile in one page with only one script include) to not interfere with others, use the id of the given article like in the GeoGebraMobileTag.initAppletFunctions():

$wnd.ggm.geogebramobiletags[id] = {};
		//set the reference

		$wnd.ggm.geogebramobiletags[id].getXML = function(objName) {
			if (objName) {
				return appletImpl.@geogebra.geogebramobile.client.main.AppletImplementation::getXml(Ljava/lang/String;)(objName);
			} else {
				return appletImpl.@geogebra.geogebramobile.client.main.AppletImplementation::getXML()();
			}
		};

if you plan to use a function, that needed by all the possible GeoGebraMobile instances in the page (to stay static function) in plain JavaScript you can go like this:

private static native void registerFileDropHandlers(MyXMLHandler x,
			Application app, String ggmtag_id) /*-{
		//====JSXGRAPH UTIL CLASS THANKS FOR THE UNZIPPING FUNCTIONALITY======//
		$wnd.ggm.JXG = {};

		$wnd.ggm.JXG.Util = {};

This way the GeoGebraMobile hopefully wont interfere with other libraries on a page. It could be refined more off course, for example the upper code if placed in Appliation.java will run every time the <article> element (GeoGebraMobile instance) found.

As GWT evolving, is very important to check always the new features, and change from handwritten JavaScript to Java, as Java code is compiled properly, and we get smaller codebase with it than plain JavaScript.

Loading other libraries

If you need an other library, it can be done by dynamic script loading like this:

if (!$wnd.ggm.latex.updateLatex) {
			$wnd.ggm.latex.updateLatex = function(domElement,drawable) {
				if (!$wnd.MathJax) {
						var mathjax_script_tag = $doc.createElement("script");
						mathjax_script_tag.src = @geogebra.geogebramobile.client.main.Application::MATHJAX_URL;
						mathjax_script_tag.type = "text/javascript";
						mathjax_script_tag.charset = "utf-8";
						mathjax_script_tag.async = true;
						
						mathjax_script_tag.onload = function() {
							$wnd.ggm.latex.updateLatex=function(domElement,drawable) {
								//console.log(domElement.getAttribute("id"));
								$wnd.MathJax.Hub.Typeset(domElement,$wnd.ggm.latex.drawMultilineLaTeXCallback(domElement.clientWidth,domElement.clientHeight,drawable));	
							};
							$wnd.MathJax.Hub.Startup.onload();
							$wnd.ggm.latex.updateLatex(domElement,drawable);
						};
						var head = $doc.getElementsByTagName("head")[0];
						head.appendChild(mathjax_script_tag);			
				}
			};

Styling with CSS

The style is now in the GeoGebraMobile.css. If you need to style an user intarface element, you must do it from css, and not from JavaScript. In JavaScript, only the swapping - adding of class names should be. See http://code.google.com/intl/hu-HU/webtoolkit/doc/latest/DevGuideUiCss.html and http://googlewebtoolkit.blogspot.com/2008/12/gwt-no-need-to-shortchange-your-style.html The css import is in the GeoGebraMobile.initResources() function, when you can change your stylesheet declaration to the local version of your css file.

public native void initResources() /*-{
		var geogebramobile_css = $doc.createElement('link');
		geogebramobile_css.type = 'text/css';
		geogebramobile_css.rel='stylesheet';
		geogebramobile_css.href = @geogebra.geogebramobile.client.GeoGebraMobile::GEOGEBRAMOBILE_CSS;
		$doc.getElementsByTagName('head')[0].appendChild(geogebramobile_css);
	}-*/;