Creating a good API

Unlike writing end-user software, writing an API has two purposes. You must be able to have the developers understand how to use it fairly consistently, but you also must write it so that their end users get the performance that they need. In briefcase we have run into this problem in the form of a simple problem: to use multiple javascript files or not. The argument for using many files is that the code become easier to manage, you can create a file for each of the main focuses of your project. The downside and the argument against multiple files is that for each file you need another HTTP request to the server to get it. I believe that we have come up with a clever solution to this problem. The only files that we as the API creators are considering at the moment are the shared libraries, saving and loading, global menu, context menu, hotkey, infinite onload, etc. Our solution is to write them ourselves in multiple files, each section of the code gets its own little file to sit in and contemplate its existence. When we are done, or would like to release a new version the code is “compiled” into one file. Compiling will do two things. The first one is to simply squish all of the libraries into to one file. The second is to minify it, jquery uses a program called UglifyJS but more research definitely needs to be done.

– Asher

Advertisements

Meta Javascript

As my work on briefcase revs back up I wanted to figure out how to solve a problem that I ran into with multiple libraries.
The problem is with the ‘onload’ variable
JQuery does a nice job handling this by creating a new function, they even changed the way it works to their own custom implementation that only waits for the html to load not the pictures and ads. However this is not what I was after. I wanted a method that would be able to take two pieces of code that both had onload commands, for example a menu library and the actual application.  After a little bit of research i stumbled upon a function call defineProperty(). Using this function I was able to create the code below.

<pre>
onload = function () {alert("Not Loaded")};
onload = function () {alert("Loaded")};

// You probably dont want to have two onloads being set
window._onload = [];
window._onload.push(window.onload);
window.onload=function(){for(a in _onload) {_onload[a]()}}
Object.defineProperty(window,"onload",{get:function()){return this._onload},set:function(n){this._onload.push(n);}});

// Lets add a few more onloads to test the process
onload = function () {alert("Loaded2")};
onload = function () {alert("Loaded3")};

below This code has four onload functions being created. The first two onload calls are present before the code begins handling the onload commands, the second two appear after.

The very first onload statement will get overwritten by the second, however the third and fourth statements will all get run along with the first

Bad code and little documentation

In the past few weeks I have begun writing two new applications for Briefcase: Code editor, and Presentation Editor. The code editor is based off of the LDT syntax highlighter and the presentation editor is meant for use with the BIG presentation system. As I have been rapidly coding there is little to no documentation for these applications and the code base for them is quite horrendous. But that is ok. Why is it ok to have horrendous code? For research, just messing with code to figure out how it works. However, looking back on it I see that it is quite bad. I also tried to see how the LDT would work with a content editable DIV tag. It works, but there are many problems with it. So I am now going to begin working with ranges within text areas in order to implement adding and removing selected text within a text area. If I am able to do that then the entire code editor will be created using a slight derivation of the LDT. The documentation for Briefcase need to be improved quite a bit before I can consider the program even remotely ready for a release.

Rewriting the Spreadsheet Interface

I have begin rewriting the spreadsheet interface. It is very nice to look at some of the old code and say “what the hell is this, that’s stupid” and then make it better. I can only imagine that in the next time I do it I will be looking at the code I am writing now and say the same thing. But sometimes that is just what needs to happen, throw out all the old code and start again from scratch (or almost scratch). After learning about the two statements “loose coupling and high cohesion” I find that loose coupling, making each function not rely on global variables or non argument states and splitting up functions, is much more important when you go back to try to re-factor the code.

 

– Asher Glick

Keeping a Simple Development Environment

When going into this project I wanted to create an environment that was very easy for the users to use even if it meant more work on the development end, and I still believe that. Now that I have released the first version of the first application component I believe I fully realise that our users are not just the end users but they are also the developers. I myself have become both and end user and a developer user. When it is easy to contribute code or work to a project more people want to do it. If the development environment requires you to install Django on your laptop even though all you want to do is write some math library in javascirpt, that is a bad development environment. As a result I have tried to keep the environment simple. Django does not like static files, part of the reason why I am leaving all the Django work to Beth, so you cannot just write a web-app in your file-system and expect it to work on Django, you cant even write one using an apache server and expect it to run on just Django. I am not sure exactly what you need to change but there are some elements that do need to be changed. The way it is currently set up is that static files can be accessed but only through absolute paths. The absolute path on the server and the absolute path on your development platform are not going to be the same. So how to fix this problem. In Django the relative paths will not load and in Apache or a file system the absolute paths will not necessarily load. Django has a small fix for the absolute path problem by replacing the root of the absolute path with {{STATIC_URL}} we can create an absolute path with the root from the applications folder. If we include both the absolute path and the relative path depending on which environment you are using one of them will work and the other will not. relative will break on Django but the absolute will work, and  relative will work on everything else but the absolute will not. So by including both we know that the external file will load no matter what environment you are in.

Using JQuery

There are some people in the development community who avoid libraries like JQuery. So this is why we are using JQuery. It provides many features that make javascript simple, like AJAX request and animations. However JQery also has a unique onload method. You use it by passing a function into  $(document).ready(). The reason this is so important is that while docuent.onload can only have one functions set to it, you can add add multiple functions to .ready(). This way we can make plugins and components without having to worry about them overwriting each others onload functions.

Beginnings of the XML Menu and Menu API

A few weeks ago I set out to figure out the best way to create menus in our applications that were easy to use. At first the results were pretty bad. The menus would stack or they would not now up at all. Once I believe i even got one to pertinently stick to the middle of the screen. But now the menus are working quite well. The first alpha of the menu system is what I would call it. It is very simple to use as well. All of this information will be in the wiki as well. Individual menus for each application can be created via XML and different cross application styles can be created using CSS.

Alpha Build of XML Menu

Including the menu in your code

<script type="text/javascript" src="menu.js"></script>
<div id="TitleMenu"></div>

Include the javascript file and then put the menu div where ever you want the main title bar to go. Usually it is put first thing in the body. In later version you will be able to put the menus (or other menus) on the left and right sides of the screen
Creating the menu (in xml):

<XMLMenu>
  <menu name="File" iconsrc="icons/action_forward.gif" version="normal">
    <button name="save" function="save()" enabled="true" iconsrc="icons/action_save.gif" shortcutKey="Ctrl+S" version="normal"> </button>
    <button name="load" function="load()" enabled="true" iconsrc="icons/action_back.gif" shortcutKey="Ctrl+L" version="normal"> </button>
    <break></break>
    <menu name="Feature Select" iconsrc="icons/action_go.gif" version="normal">
      <button name="Feature One"   function="alert('one')"   iconsrc="icons/flag_blue.gif" shortcutKey="Shft+Ctrl+1" version="normal"> </button>
      <button name="Feature Two"   function="feature('two')"   iconsrc="icons/flag_green.gif" shortcutKey="Shft+Ctrl+2" version="normal"> </button>
      <button name="Feature Three" function="feature('three')" iconsrc="icons/flag_orange.gif" shortcutKey="Shft+Ctrl+3" version="normal"> </button>
      <button name="Feature Four"  function="feature('four')"  iconsrc="icons/flag_red.gif" shortcutKey="Shft+Ctrl+4" version="normal"> </button>
      <button name="Feature Five"  function="feature('five')"  iconsrc="icons/flag_white.gif" shortcutKey="Shft+Ctrl+5" version="normal"> </button>
    </menu>
  </menu>
  <menu name="Edit" iconsrc="" version="normal">
    <button name="copy" function="copy()" iconsrc="icons/copy.gif" shortcutKey="Ctrl+S" version="normal"> </button>
  </menu>
</XMLMenu>

the XMLMenu element is the wrapper for the XML menu
The three elements, menu, button, and break, all create different menu elements. If you nest elements inside of a menu element then they will show up as a sub menu. If you try to nest them in any other element (break or button) then they will be ignored. Every menu or button has a name and an image icon associated with them. Buttons have a function to run if they are clicked and all attributes have a version. The version does not do anything right now but in the future it will indicate advanced features of the menu system. XML above is the XML used to create the menu in the screen shot.