3 These notes are collected by Heikki, mostly from skype chats with Wolfram
4 and Mike. I collected them for my own use, but I hope they will turn out
5 to be helpful to anyone who needs to get started with mkws.
11 * We are using jquery as a browser indepent layer to access the dom, so we
12 don't have to worry about IE bugs. Wolfram looked why we are using
13 jquery.json-2.4.js ... it turns out we needed it because the standard functions
16 * jasmine is a test framework (mkws dev). you will not use jasmine in a
17 production site. the nice thing with the jasmine test framework is that it
18 will work with any browser. I can start a virtual machine with IE8, open the
19 test page, wait 3 seconds for success and shutdown windows.
21 * handlebar is a template engine
28 The whitepaper says to include mkws-complete.js. This file is made by concatenating
29 a number of files (see Makefile). For us developers, it is easier to include the
32 <script type="text/javascript" src="tools/htdocs/jquery-1.10.0.min.js"></script>
33 <script type="text/javascript" src="tools/htdocs/pz2.js"></script>
34 <script type="text/javascript" src="tools/htdocs/handlebars-v1.1.2.js"></script>
35 <script type="text/javascript" src="tools/htdocs/jquery.json-2.4.js"></script>
36 <script type="text/javascript" src="tools/htdocs/mkws.js"></script>
38 You can also include the css directly in your test page:
39 <style type="text/css">
40 #mkwsTermlists div.facet {
51 Most (all?) code work happens in mkws.js.
57 if you want understand the test than you can look at mkws/test/spec/mkws-config.js
58 and mkws/test/spec/mkws-pazpar2.js . See also mkws/test/README.txt
63 (This will soon be out of date, but should provide some kind of starting
66 First page is just helper functions for the Handlebars template library, which we
67 use to generate some of the HTML output. (Down the line, we will use this more
68 heavilty -- right now it's only used for records).
70 Then we define the mkws object, which contains all global state -- which hopefully
71 there is not much of. It is one of only two objects we place in the global namespace:
72 the other is mkws_config, which is a hash supplied by the application if it wants
73 to override default configs.
75 Next is a very short function defined to allow us to publish and subscribe events.
76 That is not yet used: shifting much of the code to do so is a big part of what I
77 am working on right now.
79 Next, a very short stanza of code that just makes sure mkws_config is defined:
80 simple applications won't bother to define it at all since they override node
83 Next, a factory method for making widget objects. At present this is trivial
84 because we are only now starting to need a representation of individual widgets
85 as JS objects. More of the functionality will get moved into these objects over
88 Next, a factory method for making widget-team objects. This is where all the
89 awesomeness is at the moment. A team is a bunch of widgets that work together
90 to achieve a common goal, e.g. the search-box, search-button and results-pane
93 HTML elements are defined as belonging to the same team if they have an
94 mkwsTeam_NAME class for the same NAME. You can have multiple teams (as in
95 two-teams.html that I linked to earlier) which are completely independent of
98 I guess you're familiar with the JS idiom where the factory function for a kind
99 of object also acts as a namespace where all the object's member-variables live,
100 invisible to the outside world? That's what we do here. All the member variables
101 have names of the form m_NAME.
103 Now I sugges you skip over all the team-object code for now -- we'll return to it
104 later. For now, page down to "// wrapper to call team() after page load" which is
105 the next thing after the end of that function (or class, if you like).
107 You're familiar with this JS idiom?
108 (function() { code ... })();
109 Runs the code immediately, but within its own namespace. That's what we do for
110 all the remaining code in mkws.js. In this case, we pass the jQuery object into
111 that namespace under the name `j' for reasons that are frankly opaque to me.
113 There's still a few places in the code where oddities live on, either from jsdemo
114 or from work Wolfram's done, where I don't really understand why it's that way
115 but I'm scared to change it. In this case, IIRC, it's something to do with
116 protecting our copy of the jQuery object, or something.
118 Aaanyway, within that namespaced area, where's what we do.
120 First, we set up the mkws.debug() function, which just logs to the console in a
121 form that doesn't explode IE. I have plans for this function, make it understand
122 debugging levels a bit like log4j or maybe more like yaz-log where there are
123 named logging types that are not in a sequence.
125 (You will notice that the teams have a debug() function which delegates to this
126 but adds some other useful team-specific stuff.)
128 Next up: the utility function mkws.handle_node_with_team(). We use a LOT of nodes
129 that have their team-name in a class (as in "mkwsTeam_NAME" outlined above).
130 All the utility does is parse out that team-name, and the widget-type, from the
131 classes, and pass them through to the callback.
133 mkws.resize_page() does what it says. Gets called when window-size changes, and
134 allows us to move the facers to the side or the bottom as the screen is wide or
135 narrow (e.g. when you turn your iPad 90 degrees)
137 (Aside: I thought we'd have to iterate over all teams to move their facet lists
138 but it turns out we don't: jQuery just Does The Right Thing if you call
139 $(".mkwsTermlistContainer1").hide();
140 or similar and there are multiple hits.)
142 Next come a bunch of JS functions that are invoked from the MKWS UIs --
143 swithching between target and record views, stepping through pages of results,
144 etc. All of these are team-specific, but the global code in the HTML can't
145 invoke a team's member function directly. So these stub functions just invoke
146 the relevant member of the appropriate team.
148 default_mkws_config() fills in the mkws_config structure from hardwired defaults.
149 This is the wrong way round: instead, whenever we want to find a config value, we
150 should default our way up a tree, starting with the individual widget's config,
151 falling back to the team's config if the widget doesn't define that value, then
152 the global config, and finally the default. I'll make that change once widget
153 objects are fully real.
155 authenticate_session() authenticates onto the SP when we're using it (rather
156 than raw pp2). It's a bit sellotape-and-string, to be honest, just does a wget.
157 It would be better if this was supported by pz2.js
159 run_auto_searches() is what makes pages like
160 http://example.indexdata.com/auto3.html
161 work. THere are two places it's invoked from. Either directly when all the HTML
162 has been set up if we're using raw pp2; or when SP authentication has been
163 completed if we're using that. As with the UI functions, it just delegates down
166 Finally, code that runs when the page has finished loading -- this is really
169 The first thing it does is patch up the HTML so that old-style MKWS apps work
170 using new-style elements. This is the code you just fixed.
172 Straight after that, more fixup: elements that have an mkws* class but no
173 team are given an extra class kwsTeam_AUTO. This is the ONLY thing that's special
174 about the team "AUTO" -- it has no other privileges.
176 Very near the end now: we walk through all nodes with an mkws* class, and create
177 the team and widget objects using the factories we described earlier. Jason is
178 worried this will be slow, hence the instrumentation. It's not :-)
180 Last of all: start things off! SP-auth if used, otherwise straight to the