Browse files

add files @ version 0.9.0

  • Loading branch information...
1 parent 59e93de commit 05902bd0af0bcb46025888643774c8642076c2e3 @ryanve committed Sep 13, 2012
Showing with 393 additions and 2 deletions.
  1. +52 −0 .gitignore
  2. +44 −2 README.md
  3. +2 −0 ender.js
  4. +213 −0 oi.js
  5. +4 −0 oi.min.js
  6. +14 −0 package.json
  7. +64 −0 test.html
View
52 .gitignore
@@ -0,0 +1,52 @@
+# github.com/h5bp/html5-boilerplate/
+
+# Numerous always-ignore extensions
+*.diff
+*.err
+*.orig
+*.log
+*.rej
+*.swo
+*.swp
+*.vi
+*~
+*.sass-cache
+
+# OS or Editor folders
+.DS_Store
+._*
+Thumbs.db
+.cache
+.project
+.settings
+.tmproj
+nbproject
+*.sublime-project
+*.sublime-workspace
+
+# Dreamweaver added files
+_notes
+dwsync.xml
+
+# Komodo
+*.komodoproject
+.komodotools
+
+# Espresso
+*.esproj
+*.espressostorage
+
+# Rubinius
+*.rbc
+
+# Folders to ignore
+.hg
+.svn
+.CVS
+intermediate
+publish
+.idea
+
+# build script local files
+build/buildinfo.properties
+build/config/buildinfo.properties
View
46 README.md
@@ -1,4 +1,46 @@
-oi
+[oi](https://github.com/ryanve/oi)
==
-cross-browser standalone DOM ready method
+cross-browser standalone DOM ready method:
+
+```js
+oi.domReady(function (oi) {
+ // This function fires when the DOM is ready.
+ // `this === document` in here
+});
+```
+
+Note that `oi.domReady` and `oi.fn.ready` are identical. (The latter is provided for purely for integration purposes.)
+
+**oi** also provides two simple cross-browser event methods:
+
+```js
+oi.addEvent(elem, type, handler);
+oi.removeEvent(elem, type, handler);
+```
+
+### integration
+
+Use the `oi.bridge(receiver)` to integrate `oi` into a receiver (or host). Integrated methods include the top-level `.domReady`/`.addEvent`/`.removeEvent` methods. and if the `receiver` has an `.fn` object, it will also receive `.fn.ready`:
+
+```js
+oi.bridge(receiver) // integrate `oi`'s public methods into `receiver` (won't overwrite existing props)
+oi.bridge(receiver, true) // integrate `oi`'s public methods into `receiver` (overwrites existing props)
+```
+
+The default behavior of the `oi.bridge()` makes it so that the `receiver` becomes the first arg passed to fns, like so:
+
+```js
+receiver.domReady(function (receiver) {
+ // This function fires when the DOM is ready.
+ // `this === document` in here
+});
+```
+
+The `.domReady` (and `.fn.ready`) methods both contain both a `.remix()` method that can be used for freeform integration. Use this if you want to create a new version of the ready function which sends multiple custom args. The `.remix()` method returns a new version of itself:
+
+```js
+var customReadyMethod = oi.domReady.remix(customArg0, customArg1 /*, ...*/);
+```
+
+See advanced #integration notes in [the source](https://github.com/ryanve/oi/blob/master/oi.js).
View
2 ender.js
@@ -0,0 +1,2 @@
+// bridge file for ender.no.de
+require('oi')['bridge'](ender);
View
213 oi.js
@@ -0,0 +1,213 @@
+/*!
+ * oi Standalone DOM ready method with jQueryish functionality and
+ * bloody ballistic integration capabilities. See #integration notes
+ * at the bottom of this file. Based on github.com/ded/domready
+ * @author Ryan Van Etten (c) 2012
+ * @link http://github.com/ryanve/oi
+ * @license MIT
+ * @version 0.9.0
+ */
+
+/*jslint browser: true, devel: true, node: true, passfail: false, bitwise: true, continue: true
+, debug: true, eqeq: true, es5: true, forin: true, newcap: true, nomen: true, plusplus: true
+, regexp: true, undef: true, sloppy: true, stupid: true, sub: true, vars: true, white: true
+, indent: 4, maxerr: 180 */
+
+(function (root, name, factory) {
+ if ( typeof module != 'undefined' && module.exports ){ module.exports = factory(); } // node
+ else { root[name] = factory(); } // browser
+}(this, 'oi', function () {
+
+ // Array notation is used on property names that we don't want the
+ // Google Closure Compiler to rename in advanced optimization mode.
+ // developers.google.com/closure/compiler/docs/api-tutorial3
+ // developers.google.com/closure/compiler/docs/js-for-compiler
+
+ var win = window
+ , doc = document
+ , readyStack = [] // array of fns to fire when the DOM is ready
+ , slice = readyStack.slice
+ , docElem = doc.documentElement
+ , needsHack = !!docElem.doScroll
+ , isReady = /^loade|c/.test(doc.readyState) // initial state
+ , readyType = needsHack ? 'onreadystatechange' : 'DOMContentLoaded'
+ , domReady // internal version
+ , W3C = !!doc.addEventListener
+ , add = W3C ? function (node, type, fn) { node.addEventListener(type, fn, false); }
+ : function (node, type, fn) { node.attachEvent('on' + type, fn); }
+ , rem = W3C ? function (node, type, fn) { node.removeEventListener(type, fn, false); }
+ : function (node, type, fn) { node.detachEvent('on' + type, fn); }
+ ;
+
+ /*
+ * Push the readyStack or, if the DOM is already ready, fire the `fn`
+ * @param {Function} fn the function to fire when the DOM is ready
+ * @param {Array=} argsArray is an array of args to supply to `fn`
+ * @param {(boolean|number)=} argsArray is an array of args to supply to `fn`
+ */
+ function pushOrFire (fn, argsArray, forceFire) {
+ if ( isReady || forceFire ) {
+ // Inside the fn `this` refers to the `document`
+ // Supply args defined @ remixReady
+ fn.apply( doc, argsArray || [] );
+ } else {
+ // Push an object onto the readyStack that includes the
+ // func to fire and the arguments array so that the
+ // arguments are accessible inside flush().
+ readyStack.push({ f: fn, a: argsArray });
+ }
+ }
+
+ /**
+ * Fire all funcs in the readyStack (clearing stack as it's fired)
+ */
+ function flush () {
+
+ var ob;
+ // When the hack is needed, we prevent the flush from
+ // running until the readyState regex passes:
+ if ( needsHack && !(/^c/).test(doc.readyState) ) { return; }
+
+ // Remove the listener:
+ rem(doc, readyType, flush);
+
+ // The flush itself only runs once:
+ isReady = 1; // Record that the DOM is ready ( see usage in pushOrFire )
+ while ( ob = readyStack.shift() ) {// each object added via pushOrFire
+ pushOrFire( ob.f, ob.a );
+ }
+ readyStack = null;
+
+ }
+
+ // Add the ready listener:
+ add(doc, readyType, flush);
+
+ /*
+ * Private `domReady` method:
+ * The `argsArray` parameter is for internal use ( but extendable via oi.bridge(yourLib) )
+ * @param {Function} fn the function to fire when the DOM is ready
+ * @param {Array=} argsArray is an array of args to supply to `fn`
+ */
+ domReady = needsHack ? function (fn, argsArray) {
+ if ( self != top) {
+ pushOrFire(fn, argsArray);
+ } else {
+ try {
+ docElem.doScroll('left');
+ } catch (e) {
+ return setTimeout(function () {
+ domReady(fn, argsArray);
+ }, 50);
+ }
+ pushOrFire(fn, argsArray, true);
+ }
+ } : pushOrFire;
+
+ /*
+ * Utility for making the public domReady method(s)
+ * @param {...} args are 0 or more args that fns passed to domReady will receive
+ * @return {Function}
+ */
+ function remixReady (args) {// (arg 0 expected to be host $ function if applicable)
+
+ // The `args` get passed to `fn` when fired ( see pushOrFire )
+ args = slice.call(arguments);
+
+ function ready (fn) {// this becomes the actual domReady/.ready method(s)
+ domReady(fn, args); // call the outer local domReady method, which takes args
+ if (this !== win) { return this; } // chain instance or parent but not the global scope
+ }
+
+ // Include refs to the relay/remix methods. Every "remixed" version gets
+ // refs back to these, so that they can remixed again or detected as such.
+ // More about bridge/relay can be found in the source @link github.com/ryanve/dj
+ ready['remix'] = remixReady; // .remix is for freeform extending.
+ ready['relay'] = relayReady; // .relay is for extending via bridge/relay.
+
+ return ready;
+
+ }// ===> oi.domReady.remix()
+
+ //
+ function relayReady ($) {
+ return remixReady($ || void 0);
+ }// ===> oi.domReady.relay()
+
+ /**
+ * bridge() Integrate applicable methods into a host.
+ * This `bridge()` is specific to this module,
+ * however it uses the same signature as the
+ * library-agnostic `dj.bridge()`, available
+ * @link github.com/ryanve/dj
+ *
+ * @this {Object|Function} supplier
+ * @param {Object|Function} r receiver
+ * @param {boolean=} force whether to overwrite existing methods (default: false)
+ * @param {(Function|boolean)=} $ the top-level of the host api. (default: `r`)
+ */
+ function bridge ( r, force, $ ) {
+
+ var ready, effin;
+ if ( !r ) { return; }
+ force = true === force; // require explicit true to force
+ $ = typeof $ == 'function' || $ === false ? $ : r; // allow null
+
+ if ( force || r['domReady'] == null ) {
+ r['domReady'] = ready = relayReady($);
+ }
+
+ if ( effin = r['fn'] ) {
+ if ( force || effin['ready'] == null ) {
+ effin['ready'] = ready || relayReady($);
+ }
+ }
+
+ if ( force || r['addEvent'] == null ) {
+ r['addEvent'] = add;
+ }
+
+ if ( force || r['removeEvent'] == null ) {
+ r['removeEvent'] = rem;
+ }
+
+ return r; // the receiver ( makes it so you can do `oi.bridge({fn: {}})` )
+
+ }// ===> oi.bridge()
+ bridge['relay'] = false; // signify that this bridge only applies to this module
+
+
+ /* == #integration notes =================================================
+
+ Use `oi.bridge(receiver)` to integrate domReady/ready into the receiver. By
+ default, the receiver will become the first arg passed to fns fired via the
+ ready methods. This is probably what you do. But if you want have a different
+ arg passed you use the 3rd param of bridge() OR you can use the default bridge
+ and then use the .remix method. (See remixReady.)
+
+ In fns passed to domReady/.ready methods created via bridge/relay
+ the scope `this === document` (same as in jQuery) and the first arg
+ can be specified to host the host lib. ( see bridge() && remixReady() )
+
+ In jQuery, handlers added via .on('ready', handler) receive an eventData
+ object as the arg and are fired after ones added by $(document).ready
+ The other difference is that handlers added via $(document).ready are
+ retro-fired and ones added by .on() are not. In other words, in jQuery, if
+ you add a ready handler via .on() after the DOM ready flush has happened
+ it will NOT be fired. But if you use $(document).ready or $(handler)
+
+ To properly accomplish full integration of domReady into an event library
+ that wants to have jQuery-compatible .on() and .trigger() methods, do this:
+
+ oi.bridge(ender); // integrate domReady/.ready into ender
+ ender.fn.ready(function ($) { // fat/bean, ryanve/elo, and other event libs can do this
+ var $doc = $(this);
+ $doc.trigger && $doc.trigger('ready');
+ });
+
+ ========================================================================= */
+
+ // create the export:
+ return bridge({ 'fn': {}, 'bridge': bridge });
+
+})); // factory and closure
View
4 oi.min.js
@@ -0,0 +1,4 @@
+/*! oi 0.9.0 | domReady module by @ryanve | @link github.com/ryanve/oi | @license MIT */
+(function(d,g,f){"undefined"!=typeof module&&module.exports?module.exports=f():d[g]=f()})(this,"oi",function(){function d(a,b,c){m||c?a.apply(e,b||[]):h.push({f:a,a:b})}function g(){var a;if(!i||/^c/.test(e.readyState)){n(e,o,g);for(m=1;a=h.shift();)d(a.f,a.a);h=null}}function f(a){function b(b){j(b,a);if(this!==s)return this}a=t.call(arguments);b.remix=f;b.relay=k;return b}function k(a){return f(a||void 0)}function l(a,b,c){var e,d;if(a){b=!0===b;c="function"==typeof c||!1===c?c:a;if(b||null==a.domReady)a.domReady=
+e=k(c);if(d=a.fn)if(b||null==d.ready)d.ready=e||k(c);if(b||null==a.addEvent)a.addEvent=p;if(b||null==a.removeEvent)a.removeEvent=n;return a}}var s=window,e=document,h=[],t=h.slice,q=e.documentElement,i=!!q.doScroll,m=/^loade|c/.test(e.readyState),o=i?"onreadystatechange":"DOMContentLoaded",j,r=!!e.addEventListener,p=r?function(a,b,c){a.addEventListener(b,c,!1)}:function(a,b,c){a.attachEvent("on"+b,c)},n=r?function(a,b,c){a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent("on"+b,c)};p(e,
+o,g);j=i?function(a,b){if(self!=top)d(a,b);else{try{q.doScroll("left")}catch(c){return setTimeout(function(){j(a,b)},50)}d(a,b,!0)}}:d;l.relay=!1;return l({fn:{},bridge:l})});
View
14 package.json
@@ -0,0 +1,14 @@
+{
+ "name": "oi",
+ "description": "Cross-browser domReady module with jQuery-like usage and modular integration capabilities.",
+ "version": "0.9.0",
+ "homepage": "https://github.com/ryanve/oi",
+ "author": "Ryan Van Etten <@ryanve>",
+ "keywords": ["domready", "dom", "ready", "events", "ender", "jam", "javascript", "js"],
+ "main": "./oi.js",
+ "ender": "./ender.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ryanve/oi.git"
+ }
+}
View
64 test.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset=utf-8>
+ <title>oi :: test suite</title>
+ <meta name=viewport content="width=device-width,initial-scale=1.0">
+ <meta name=author content="Ryan Van Etten">
+ <style>
+ body{
+ font:normal 100% sans-serif;
+ width:94%; max-width:1280px;
+ margin: 0 auto; padding:20px 3%;
+ background:#eed; color:#133;
+ }
+ #test{background:#8d2;max-width:100%;padding:3em;margin:1em 0}
+ [accesskey]:hover{cursor:pointer}
+ </style>
+ <script src="oi.js"></script><!-- github.com/ryanve/oi -->
+ <script>
+ (function (document, console, oi) {
+
+ var log = console && console.log ? function (s) {
+ console.log(s);
+ } : function (s, force) {
+ force && alert(s);
+ };
+
+ log ( oi );
+ log ( oi.bridge({ fn: {} }) );
+ log ( oi.domReady === oi.fn.ready );
+
+ (oi.domReady.remix(log, 47))(function (o, n) {
+ log( o === log && document === this && n === 47 && 2 == arguments.length );
+ });
+
+ (oi.domReady.relay(null, 88))(function (o, u) {
+ log( void 0 === o && o === u && 1 == arguments.length );
+ });
+
+ oi.domReady(function (u) {
+ var e = this.getElementById('test')
+ , i = 3, handler;
+
+ e.innerHTML = (e && e.nodeType
+ ? "Oi! =) The DOM is ready. Now click this div. "
+ : "Bugger =( oi.domReady did not work properly." );
+
+ oi.addEvent(e, 'click', (handler = function () {
+ e.innerHTML += ' //// ' + e.tagName.toLowerCase() + " was clicked."
+ if ( !i-- ) {
+ oi.removeEvent(e, 'click', handler);
+ e.innerHTML = 'Event removed. Next click should do nothing. All tests passed!';
+ e.removeAttribute('accesskey');
+ }
+ }));
+ });
+
+ }(document, this.console, this.oi));
+ </script>
+</head>
+<body>
+ <div id="test" accesskey="3"></div>
+</body>
+</html>

0 comments on commit 05902bd

Please sign in to comment.