CSI - Client Side Includes


CSI - Client Side Includes is a library which provides an easy to use system for including other JS files. With CSI, it's easy to spread your program across several files and reuse them in other project as you see fit.


070821 domina.js has been extended by ns.tw.domina.getInnerDimension, ns.tw.domina.make and ns.tw.domina.class_screenDiv. Various documentation fixes.


How it works

CSI uses a very simple and effective system... instead of retrieving, parsing and appending files itself, it simply appends script elements pointing to the original files. All included files themselves register with the main CSI instance and provide the code to be executed after all files have loaded (Think of it as a simple event system). After all files have loaded it runs all registered code bottom to top.

How to use it

Follow these steps to get CSI running:
  1. Drop the lib directory somewhere near your project files and add CSI to your HTML file's head section:
    <script type="text/javascript" src="../lib/csi.js"></script>
    Make sure this is your first script element.
  2. Set the basepath. This string gets prefixed to all paths that are loaded via an include. Set this so that it points to the top directory to which all other includes are relative The default libraries require that this be set to one level above the lib directory.
    So if your HTML file resides in /devel/project0/html/ and the libs are in /devel/libs/ this should either be set to /devel/ (abolute path) or ../../ (relative path, relative to the HTML) Don't forget the trailing slashes.
  3. Use ns.tw.csi.include to load a file. It's very important that you always use the same notation for paths, because this string is also used to determin if a file has already been added. So don't use "bar.js" one time "Bar.js" another time and finally "./bar.js", because this would cause bar.js to be loaded three times!
  4. Register your main instance... think of this as an onload listener that gets called after all libraries have been loaded. Put this at the end of your JS block (Of course with your own code instead of the alert):
    	alert("All Libraries are loaded now!");
    You can also put code between the includes and this block, but remember that this code will be run immediately, even before all libraries are loaded!
  5. Add a registerInclude call to the END (this is important!) of your library files. provide a callback that should be run after all libraries that this file includes have been loaded. This is required, even if you don't include any files (it will still be run) or you don't need any initialization code (just provide an empty function).
    	alert("Initializing myLib");
  6. (Optional) Add this line to the beginning of each library to make sure that you're not accidently using it in a non-CSI project:
    if(!ns || !ns.tw || !ns.tw.csi) alert("CSI - Client Side Include has not been loaded.");

Included libraries

This is just a tiny collection to get you started... It'll grow over time.

csi.js - Client Side Includes & Name Space Allocator

 ns.tw.csi : NameSpace TapperWare ClientSideIncludes
 ns.tw.nsa : NameSpace TapperWare NameSpaceAllocator

 (void) ns.tw.csi.include((string) filePath)
  Adds the specified file (prefixed with ns.tw.csi.glb.basepath)
  to the loading queue
 (void) ns.tw.csi.registerInclude((function) onLoadCallback)
  Notifies the system that a file has been loaded. Registers a
  callback to be run after all following includes have finished
 (void) ns.tw.nsa.create((string) namespaceName)
  Creates a namespace while keeping already existing parts.
  Parameter should be in the form "level1.level2.level3".
 (string) ns.tw.csi.glb.basepath
  Prefix for all paths added via ns.tw.csi.include

ja.js - Javascript Assistant

 ns.tw.ja : NameSpace TapperWare JavascriptAssistant

 (void) ns.tw.ja.extend((function)child, (function)parent)
  Copies the prototype from the parent class to the child
  class. Use directly below the constructor function and
  before modifying the prototype.
 (function) ns.tw.ja.scope((function) embeddingFunction
                           [,(object) newScope] [, ...])
  Returns a wrapper function that will always run
  embeddingFunction in the scope of newScope.
  embeddingFunction receives the following parameters:
   (object) nativeScope: The scope in which the wrapper
		         function was called
   (array) args: An array consisting of all parameters passed
                 to ns.tw.ja.scope, except embeddingFunction
		 and newScope
 (void) ns.tw.ja.asap((function) callback [,(object) newScope])
  Schedules a function to be run after the next update (timeout=0)
  An optional scope can be defined for the callback.
  callback receives the following parameters:
   (object) nativeScope: The scope in which the wrapper
                         function was called
   (array) args: An array consisting of a single array containing
                 all parameters passed to ns.tw.ja.asap, except
		 callback and newScope
 (function) ns.tw.ja.encapsulate((function) callback
                                 [,(object) data] [, ...])
  Returns a function that will always run callback with the
  defined parameters, no matter what parameters the wrapper receives.
  callback receives the following parameters:
   (object) data: The data parameter passed to ns.tw.ja.encapsulate
   (array) args: An array consisting of all parameters passed to
 (void) ns.tw.ja.tween((function) callback, (number) numberOfSteps,
                       (number) delayAfterStep, (array) startEndPairs)
  Runs a callback (in a non-blocking way) a numberOfSteps times,
  waiting delayAfterStep milliseconds after each step.
  startEndPairs defines an array of value pairs (contained in an array
  as well: [[0,10],[2,5]]).
  callback is called with an array of interpolated values, one for
  each value pair
   (array) vals: An array of internpolated numbers, according to the
                 progress made (For example 5 for 0,10 after 50%)
 (void) ns.tw.ja.timetween((function) callback, (number) totalTime,
                           (array) startEndPairs)
  Runs a callback (in a non-blocking way) as often as possible within a
  specified totalTime (in milliseconds), (at least 1x for the
  initial value and 1x for the end value).
  startEndPairs defines an array of value pairs (contained in an array
  as well: [[0,10],[2,5]]).
  callback is called with an array of interpolated values, one for each
value pair
   (array) vals: An array of internpolated numbers, according to the
                 progress made (For example 5 for 0,10 after 50%)

astral.js - A String Assistance Library

 ns.tw.astral : NameSpace TapperWare ASTRingAssistanceLibrary

 (bool) ns.tw.astral.has((string)haystack, (string)needle)
  returns true if haystack contains needle, otherwise returns false.
 (number) ns.tw.astral.which((string)haystack, (array)needles)
  returns the position of the last string in needles that's found in
  Returns -1 if no occurence is found.

evening.js - Event Handling

 ns.tw.evening : NameSpace TapperWare EVENthandlING

 (void) ns.tw.evening.addEventListener((element) targetNode,
				(string)eventType, (function)callback)
  Adds an event listener for the specified event type (for example
  "click") to a node in the document. The callback is launched natively
  by the browser, so IE will not provide the event as the first parameter.

domina.js - DOM Integration Assistant

 ns.tw.domina : NameSpace TapperWare DOMINtegrationAssistant

 (node) ns.tw.domina.byId((string)id)
  Macro for document.getElementById. Returns the first node with the
  specified ID.
 (array) ns.tw.domina.byName((string)name [, (element)baseNode])
  Macro for HTMLElement.getElementByName. Returns an array of all
  nodes with the specified NAME.
  If baseNode is specified it will only take into account nodes
  that are childNodes of baseNode.
 (array) ns.tw.domina.byClass((string)className [, (element)baseNode]
                              [, (string)findOnlyThisTag])
  Finds all nodes with the specified class attribute. The search can
  be limited by providing a base node see (ns.tw.domina.byName) and
  limiting the search to only one kind of tags.
 (void) ns.tw.domina.setOpacity((element) targetNode,
                                (number) opacityPercent)
  Sets the opacity of an element to a given percentage. Note that this
  requires "hasLayout" in IE, in other words your element has to either
  be block-inline, float, or have its dimensions specified.
 (object) ns.tw.domina.getInnerDimension()
  Returns an object with fours properties: w (Width), h (Height),
  u (LeftScrollOffset) and v (TopScrollOffset).
  Note that these are the dimensions of the viewpane, without
  scrollbars, except for Safari in strict mode.
  Scrolling is essentially untested.
 (node) ns.tw.domina.make((string)tagName)
  Macro for document.createElement.
  Creates a fixed position div, with dimensions specified relative to
  topLeft and bottomRight of the display window. The div automatically
  resizes and if position:fixed is not supported also scrolls
 Constructor: ( (number)leftPositon, (number)topPosition,
                (number)rightPosition, (number)bottomPosition,
  ___Position defines the distance to the window border on that side.
  ___PositionIsPercentage defines if the corresponding coordinate is to be
  interpreted as Pixels or Percent.
  Note that not setting width or height is possible by passing false as
  rightPosition or bottomPosition
 Public Properties:
  (Read/Write) (number)topLeft||bottomRight.x||y.coord Sets the offset to
  the corresponding window border
  Note that not setting width or height is possible by setting
  bottomRight.x||y.coord to false.
  (Read/Write) (string)topLeft||bottomRight.x||y.unit Sets the unit
   of the corresponding coord "%" or "px"
  (Read) (node)node
 Public Methods:
  (void) update() Reapplies the coordinates specified in
   topLeft||bottomRight.x||y.coord||unit to the node.


All code is Copyright 2007 Hans Schmucker and provided under the CC Attribute-ShareAlike license.


Now that you've read through all this, here's the download (Sorted from latest to oldest):