From: Michael Stapelberg Date: Thu, 21 Jul 2011 18:58:50 +0000 (+0200) Subject: Initial commit X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;ds=sidebyside;h=9ab77c40da0d4175c967343485e443a04166cde9;p=i3%2Fi3.github.io Initial commit --- 9ab77c40da0d4175c967343485e443a04166cde9 diff --git a/_config.py b/_config.py new file mode 100644 index 0000000..e69de29 diff --git a/contact/index.html.mako b/contact/index.html.mako new file mode 100644 index 0000000..1f4230c --- /dev/null +++ b/contact/index.html.mako @@ -0,0 +1,38 @@ +<%! + section = "contact" +%> +<%inherit file="_templates/i3.mako" /> +
+

Contact

+ +

+If you have any questions which are not answered by the Documentation, please do not hesitate to contact us. The best +way to reach us is via IRC: +

+ +

+i3’s IRC channel is +irc://irc.twice-irc.de/i3 (or, #i3 on irc.twice-irc.de, for those without proper URL +handling setup). Feel free to ask questions, please don’t ask to ask and please +think before you ask :-). +

+ +

Mailing lists

+ +

+If you dislike IRC, you can also post questions etc. to our mailing list. +

+ +

Package maintainers

+ +

+If you are a package maintainer and have any questions, +ideas, hints, problems or whatever, please do not hesitate to contact me. I +will help you out. Just drop me an E-Mail (scroll down to +bottom), contact me using the same address in jabber or ask on our IRC +channel (see above). +

+ +
diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..9ad8474 --- /dev/null +++ b/css/style.css @@ -0,0 +1,318 @@ +body { + background-color: #2e2e2e; + color: #CCC; + font-family: 'Droid Sans', "Lucida Grande", "Lucida Sans", "Liberation Sans", sans-serif; + font-size: 0.8em; +} + +h2, h3 { + font-family: "Helvetica Neue", Helvetica, 'Ovo', Arial, sans-serif; + font-weight: bold; + letter-spacing: -1px; + color: #FFF; + line-height: 1.2em; + border-bottom: 2px solid #333; +} + +h2 { + font-size: 1.8em; +} + +a { + color: #2b7dbc; + text-decoration: underline; +} + + +a:hover { + text-decoration: none; +} + +#main { + width: 912px; + margin: 0 auto; + padding: 0; +} + +#nav { + float: right; + color: #FFF; + margin: 10px 18px 0 0; + padding: 0; +} + +#nav li { + font-size: 1.3em; + list-style: none; + float: left; + margin-top: 1.8em; + margin-left: 5px; + border-right: 2px solid #3A8ECD; +} + +#nav li:last-child { + border-right: 0; +} + +#nav li a { + font-size: 1.2em; + margin: 0.4em 0.8em; + display: block; + color: #FFF; + text-decoration: none; +} + +#nav li a:hover { + border-bottom: 2px solid #fff; +} + +h1#title { + height: 146px; + width: 458px; + float: left; + margin: 0; + background-image: url(../img/logo.png); + background-repeat: no-repeat; + text-indent: -9999px; +} + +#screens { + padding-top: 1em; + float: right; +} + +#info img, .screenshots img, .video img { + -webkit-box-shadow: 0px 0px 0.20em #000; + -moz-box-shadow: 0px 0px 0.20em #000; + -o-box-shadow: 0px 0px 0.20em #000; +} + +#info { + clear: both; + padding: 5px 30px 15px 18px; + border-radius: 4px; + margin-right: 0.9em; + margin-top: 1em; + + width: 840px; + color: #666; + font-size: 1.6em; + letter-spacing: -1px; + background-color: #dddddd; + background-repeat: no-repeat; + + -webkit-box-shadow: 0px 0px 0.60em #000; + -moz-box-shadow: 0px 0px 0.60em #000; + -o-box-shadow: 0px 0px 0.60em #000; + +} + +#download { + background-color: #000; + background-image: -webkit-gradient( + linear, + left bottom, + left top, + color-stop(0.44, rgb(0,0,0)), + color-stop(0.61, rgb(53,53,53)) + ); + background-image: -moz-linear-gradient( + center bottom, + rgb(0,0,0) 44%, + rgb(53,53,53) 61% + ); + color: #ffffff; + padding-top: 0.5em; + padding-bottom: 0.5em; + margin-top: 1.0em; + -webkit-box-shadow: 0px 0px 0.30em #000; + -moz-box-shadow: 0px 0px 0.30em #000; + -o-box-shadow: 0px 0px 0.30em #000; + float: left; +} + +#download a { + color: white; + text-decoration: none; + padding-left: 1em; + padding-top: 0.5em; + padding-bottom: 0.5em; + padding-right: 1em; +} + +#info h2 { + margin: 17px 0 15px 0; + border: 0; + font-family: 'Georgia', 'Ovo', serif; + color: #2b7dbc; + font-size: 1.75em; + font-weight: normal; +} + +#info p { + line-height: 150%; +} + +#content { + text-align: justify; + width: 874px; + padding-left: 1em; + padding-right: 1em; + line-height: 150%; + color: #fff; + font-size: 1.2em; +} + +#content p { + padding-right: 2em; +} +#content li { + margin-bottom: 1em; + padding-right: 2em; +} + +#distributions { + margin-left: 2em; + line-height: 100px; +} + +#distributions img { + vertical-align: middle; + margin-left: 1.5em; + margin-right: 1.5em; + margin-bottom: 1.5em; + margin-top: .5em; +} + +#footer { + border-top: 2px solid #333; + margin-top: 4em; + padding-top: 1em; + font-size: 90%; + text-align: center; +} + +.docs { + float: left; + width: 48%; +} + +@font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: normal; + src: local('Droid Sans'), local('DroidSans'), url('/fonts/DroidSans.woff') format('woff'), url('/fonts/DroidSans.ttf') format('truetype'); +} + +@font-face { + font-family: 'Ovo'; + font-style: normal; + font-weight: normal; + src: local('Ovo'), url('/fonts/Ovo.ttf') format('truetype'); +} + +.video img { + margin-left: 1em; + margin-right: 1em; +} + +.imgdesc { + margin-bottom: 1em; +} + +.screenshots .shot { + float: left; + margin-left: 1em; + margin-right: 1em; + margin-top: 1em; + margin-bottom: 1em; + text-align: center; + color: #c0c0c0; +} + +.screenshots br { + clear: left; +} + +#mask { + position: absolute; + left: 0; + top: 0; + background-color: #000; + opacity: 0.7; + display: none; +} + +#loading { + position: fixed; + left: 50%; + top: 50%; + width: 64px; + height: 64px; + background-color: red; + opacity: 0.9; + z-index: 20; + display: none; + border-radius: 4px; +} + +#bigimg { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: none; +} + +#maskouter { + height: 100%; + display: table; + margin: 0 auto; +} + +#maskinner { + vertical-align: middle; + display: table-cell; +} + +#imgleft, #imgright { + position: fixed; + top: 50%; + width: 64px; + height: 64px; + border-radius: 4px; + background-color: green; + z-index: 19; +} + +#imgleft { + left: 0; +} + +#imgright { + right: 0; + background-color: blue; +} + +/* clearfix */ +.clearfix:after { + content: "."; + display: block; + clear: both; + visibility: hidden; + line-height: 0; + height: 0; +} + +.clearfix { + display: inline-block; +} + +html[xmlns] .clearfix { + display: block; +} + +* html .clearfix { + height: 1%; +} diff --git a/docs/index.html.mako b/docs/index.html.mako new file mode 100644 index 0000000..c52a4f6 --- /dev/null +++ b/docs/index.html.mako @@ -0,0 +1,66 @@ +<%! + section = "docs" +%> +<%inherit file="_templates/i3.mako" /> +
+

Documentation

+ +

+One of i3’s goals is good documentation. The documents which you will find +below will hopefully answer all your questions. If you have any corrections or +suggestions please let us know! +

+ +
+

For users

+ +

+User’s Guide
+Introduction and reference. Read this one. +

+ +

+Multi-monitor
+Interesting for users of the nVidia binary driver. +

+ +

+Debugging i3
+Explains you how to enable the i3 logfile. +

+ +

+External workspace bars
+About bar programs such as i3bar or dzen2. +

+ +

+i3 reference card (PDF)
+Might be useful to memorize i3’s shortcuts. +

+
+ +
+

For developers

+ +

+Hacking Howto
+Helps you if you want to get into i3’s source code. +

+ +

+Debugging i3
+Explains you how to enable core dumps. +

+ +

+IPC documentation
+Explains how i3’s Inter Process Communication interface works. Read this if you +want to talk to i3 within your own scripts or programs. +

+ +
+ +
+ +
diff --git a/downloads/index.html.mako b/downloads/index.html.mako new file mode 100644 index 0000000..4558889 --- /dev/null +++ b/downloads/index.html.mako @@ -0,0 +1,199 @@ +<%! + section = "downloads" +%> +<%inherit file="_templates/i3.mako" /> +
+ +

Distributions

+ +

+Please use the i3 packages provided by the distribution you are using. i3 is +currently distributed in the following operating systems/distributions: +

+ +
+<% + distros = [ + [ + "Debian GNU/Linux", + "http://packages.debian.org/sid/i3", + "/img/debian.png", + 93 + ], + [ + "Arch Linux", + "http://www.archlinux.org/packages/community/x86_64/i3-wm/", + "/img/archlinux.png", + 75 + ], + [ + "Gentoo Linux", + "http://packages.gentoo.org/package/x11-wm/i3", + "/img/gentoo-logo.png", + 79 + ], + [ + "Ubuntu Linux", + "http://packages.ubuntu.com/karmic/i3", + "/img/ubuntu.png", + 75 + ], + [ + "FreeBSD", + "http://www.freebsd.org/cgi/cvsweb.cgi/ports/x11-wm/i3/", + "/img/freebsd.png", + 59 + ], + [ + "NetBSD", + "http://pkgsrc.se/wip/i3", + "/img/netbsd_logo.png", + 56 + ], + [ + "OpenBSD", + "http://www.openbsd.org/cgi-bin/cvsweb/ports/x11/i3/", + "/img/Openbsd2.png", + 49 + ] + ] + + c = 0 +%> +% for title, link, img, height in distros: +
${title}
+<% c += 1 %> +% if c == (len(distros) / 4) * 4: +
+% endif +% endfor +
+ + +

+Because Ubuntu syncs its packages only every 6 months with Debian, we provide a more recent repository. +

+ +

Downloads

+ +

+ The current stable version is 3.ε-bf3 (transcribed 3.e-bf3 because many systems still can’t + handle UTF-8 in version numbers). +

+ +

+ IMPORTANT: If you use the nVidia binary driver (which does + not support XRandR at the moment), read this document for an explanation and how + to enable the work-around! +

+ + + + +

Development version

+ +

+ Use git to follow the latest changes: +

+ +
+  $ git clone git://code.stapelberg.de/i3
+
+ +

+ If you prefer to download a tarball, or if you cannot use git for whatever reason, + you may download the current master branch from + + http://code.stapelberg.de/git/i3/snapshot/i3-master.tar.bz2 + +

+ +

Announce mailing list

+ +

+ If you want to be notified when a new version of i3 is released, please subscribe + to the announce mailing list by sending a mail to i3-announce-subscribe@i3.zekjur.net +

+ + +
diff --git a/fonts/DroidSans.ttf b/fonts/DroidSans.ttf new file mode 100644 index 0000000..69a61da Binary files /dev/null and b/fonts/DroidSans.ttf differ diff --git a/fonts/DroidSans.woff b/fonts/DroidSans.woff new file mode 100644 index 0000000..891ce42 Binary files /dev/null and b/fonts/DroidSans.woff differ diff --git a/fonts/Ovo.ttf b/fonts/Ovo.ttf new file mode 100644 index 0000000..c0aecf7 Binary files /dev/null and b/fonts/Ovo.ttf differ diff --git a/img/Openbsd2.png b/img/Openbsd2.png new file mode 100644 index 0000000..65ac3bb Binary files /dev/null and b/img/Openbsd2.png differ diff --git a/img/archlinux.png b/img/archlinux.png new file mode 100644 index 0000000..7ff6f40 Binary files /dev/null and b/img/archlinux.png differ diff --git a/img/debian.png b/img/debian.png new file mode 100644 index 0000000..8924464 Binary files /dev/null and b/img/debian.png differ diff --git a/img/freebsd.png b/img/freebsd.png new file mode 100644 index 0000000..4d934e4 Binary files /dev/null and b/img/freebsd.png differ diff --git a/img/gentoo-logo.png b/img/gentoo-logo.png new file mode 100644 index 0000000..be6384f Binary files /dev/null and b/img/gentoo-logo.png differ diff --git a/img/logo.png b/img/logo.png new file mode 100644 index 0000000..18ef330 Binary files /dev/null and b/img/logo.png differ diff --git a/img/netbsd_logo.png b/img/netbsd_logo.png new file mode 100644 index 0000000..edb8f2e Binary files /dev/null and b/img/netbsd_logo.png differ diff --git a/img/ubuntu.png b/img/ubuntu.png new file mode 100644 index 0000000..df7f5b8 Binary files /dev/null and b/img/ubuntu.png differ diff --git a/index.html.mako b/index.html.mako new file mode 100644 index 0000000..3c124d2 --- /dev/null +++ b/index.html.mako @@ -0,0 +1,86 @@ +<%! + section = "index" +%> +<%inherit file="_templates/i3.mako" /> +
+ +
+ +
+ +

Do What I Mean. Good Docs. Clean Code. Sounds good?

+

Bleh bleh.

+ +
+ +
+

+i3 is a tiling window manager, completely written from scratch. It is primarily +targeted at advanced users and developers. Based upon the experiences we made +when wanting to hack/fix wmii, we agreed upon the following goals for i3: +

+ +
    +
  1. + Write well readable, well documented code. Create additional + documentation on how to extend i3 by explaining its internal workings. +
    + This includes being modifiable by people who do know how to program but who are + not necessarily familiar with all of X11’s internals. That is, document why + things happen and when they happen so that the user gets a picture of the whole + process a Window Manager is responsible of by just reading the source code. +
  2. +
  3. + Use xcb as far as possible (it does not provide functions for some features + yet, like XKB) instead of Xlib. xcb has a much cleaner API and should be faster + in quite a lot of situations. +
  4. +
  5. + Implement multi-monitor correctly, that is by assigning each workspace to a + virtual screen. Especially make sure that attaching and detaching new monitors + like video projectors works during operation and does the right thing. Also + provide support for rotated monitors. +
  6. +
  7. + Use a tree as data structure. This allows for more flexible layouts than + the column-based approach used by other window managers. +
  8. +
  9. + Implement different modes, like in vim. You can use different keybindings + when in the 'resize' mode than when you are in the default mode, for + example. +
  10. +
  11. + Do not use programs such as autoconf/automake for configuration and + creating unreadable/broken makefiles. Instead, use a clean makefile which automatically + enables/disables features for specific platforms. Also, document the dependencies + properly, so that package maintainers have an easy job packaging i3. +
  12. +
  13. + Implement an IPC interface for other programs. Provide subscription to + certain events and accept commands. +
    + This approach should be more lightweight than wmii’s usage of the 9P filesystem. + Furthermore, core functionality does not depend on a separate program, so that i3 + runs faster, especially when your system is under load. +
  14. +
  15. + Be UTF-8 clean. +
  16. +
  17. + The usual elitism amongst minimal window managers: Don’t be bloated, don’t be fancy + (simple borders are the most decoration we want to have), don’t add support for Xft + and blurred fonts. +
    + However, we do not enforce unnecessary limits such as a maximum amount of source lines + of code. If it needs to be a bit bigger, it will be. +
  18. +
+ +
diff --git a/js/jquery.ba-hashchange.js b/js/jquery.ba-hashchange.js new file mode 100644 index 0000000..47105f4 --- /dev/null +++ b/js/jquery.ba-hashchange.js @@ -0,0 +1,390 @@ +/*! + * jQuery hashchange event - v1.3 - 7/21/2010 + * http://benalman.com/projects/jquery-hashchange-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ + +// Script: jQuery hashchange event +// +// *Version: 1.3, Last updated: 7/21/2010* +// +// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/ +// GitHub - http://github.com/cowboy/jquery-hashchange/ +// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js +// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped) +// +// About: License +// +// Copyright (c) 2010 "Cowboy" Ben Alman, +// Dual licensed under the MIT and GPL licenses. +// http://benalman.com/about/license/ +// +// About: Examples +// +// These working examples, complete with fully commented code, illustrate a few +// ways in which this plugin can be used. +// +// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/ +// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/ +// +// About: Support and Testing +// +// Information about what version or versions of jQuery this plugin has been +// tested with, what browsers it has been tested in, and where the unit tests +// reside (so you can test it yourself). +// +// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2 +// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5, +// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5. +// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/ +// +// About: Known issues +// +// While this jQuery hashchange event implementation is quite stable and +// robust, there are a few unfortunate browser bugs surrounding expected +// hashchange event-based behaviors, independent of any JavaScript +// window.onhashchange abstraction. See the following examples for more +// information: +// +// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/ +// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/ +// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/ +// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/ +// +// Also note that should a browser natively support the window.onhashchange +// event, but not report that it does, the fallback polling loop will be used. +// +// About: Release History +// +// 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more +// "removable" for mobile-only development. Added IE6/7 document.title +// support. Attempted to make Iframe as hidden as possible by using +// techniques from http://www.paciellogroup.com/blog/?p=604. Added +// support for the "shortcut" format $(window).hashchange( fn ) and +// $(window).hashchange() like jQuery provides for built-in events. +// Renamed jQuery.hashchangeDelay to and +// lowered its default value to 50. Added +// and properties plus document-domain.html +// file to address access denied issues when setting document.domain in +// IE6/7. +// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin +// from a page on another domain would cause an error in Safari 4. Also, +// IE6/7 Iframe is now inserted after the body (this actually works), +// which prevents the page from scrolling when the event is first bound. +// Event can also now be bound before DOM ready, but it won't be usable +// before then in IE6/7. +// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug +// where browser version is incorrectly reported as 8.0, despite +// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag. +// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special +// window.onhashchange functionality into a separate plugin for users +// who want just the basic event & back button support, without all the +// extra awesomeness that BBQ provides. This plugin will be included as +// part of jQuery BBQ, but also be available separately. + +(function($,window,undefined){ + '$:nomunge'; // Used by YUI compressor. + + // Reused string. + var str_hashchange = 'hashchange', + + // Method / object references. + doc = document, + fake_onhashchange, + special = $.event.special, + + // Does the browser support window.onhashchange? Note that IE8 running in + // IE7 compatibility mode reports true for 'onhashchange' in window, even + // though the event isn't supported, so also test document.documentMode. + doc_mode = doc.documentMode, + supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 ); + + // Get location.hash (or what you'd expect location.hash to be) sans any + // leading #. Thanks for making this necessary, Firefox! + function get_fragment( url ) { + url = url || location.href; + return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' ); + }; + + // Method: jQuery.fn.hashchange + // + // Bind a handler to the window.onhashchange event or trigger all bound + // window.onhashchange event handlers. This behavior is consistent with + // jQuery's built-in event handlers. + // + // Usage: + // + // > jQuery(window).hashchange( [ handler ] ); + // + // Arguments: + // + // handler - (Function) Optional handler to be bound to the hashchange + // event. This is a "shortcut" for the more verbose form: + // jQuery(window).bind( 'hashchange', handler ). If handler is omitted, + // all bound window.onhashchange event handlers will be triggered. This + // is a shortcut for the more verbose + // jQuery(window).trigger( 'hashchange' ). These forms are described in + // the section. + // + // Returns: + // + // (jQuery) The initial jQuery collection of elements. + + // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and + // $(elem).hashchange() for triggering, like jQuery does for built-in events. + $.fn[ str_hashchange ] = function( fn ) { + return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange ); + }; + + // Property: jQuery.fn.hashchange.delay + // + // The numeric interval (in milliseconds) at which the + // polling loop executes. Defaults to 50. + + // Property: jQuery.fn.hashchange.domain + // + // If you're setting document.domain in your JavaScript, and you want hash + // history to work in IE6/7, not only must this property be set, but you must + // also set document.domain BEFORE jQuery is loaded into the page. This + // property is only applicable if you are supporting IE6/7 (or IE8 operating + // in "IE7 compatibility" mode). + // + // In addition, the property must be set to the + // path of the included "document-domain.html" file, which can be renamed or + // modified if necessary (note that the document.domain specified must be the + // same in both your main JavaScript as well as in this file). + // + // Usage: + // + // jQuery.fn.hashchange.domain = document.domain; + + // Property: jQuery.fn.hashchange.src + // + // If, for some reason, you need to specify an Iframe src file (for example, + // when setting document.domain as in ), you can + // do so using this property. Note that when using this property, history + // won't be recorded in IE6/7 until the Iframe src file loads. This property + // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7 + // compatibility" mode). + // + // Usage: + // + // jQuery.fn.hashchange.src = 'path/to/file.html'; + + $.fn[ str_hashchange ].delay = 50; + /* + $.fn[ str_hashchange ].domain = null; + $.fn[ str_hashchange ].src = null; + */ + + // Event: hashchange event + // + // Fired when location.hash changes. In browsers that support it, the native + // HTML5 window.onhashchange event is used, otherwise a polling loop is + // initialized, running every milliseconds to + // see if the hash has changed. In IE6/7 (and IE8 operating in "IE7 + // compatibility" mode), a hidden Iframe is created to allow the back button + // and hash-based history to work. + // + // Usage as described in : + // + // > // Bind an event handler. + // > jQuery(window).hashchange( function(e) { + // > var hash = location.hash; + // > ... + // > }); + // > + // > // Manually trigger the event handler. + // > jQuery(window).hashchange(); + // + // A more verbose usage that allows for event namespacing: + // + // > // Bind an event handler. + // > jQuery(window).bind( 'hashchange', function(e) { + // > var hash = location.hash; + // > ... + // > }); + // > + // > // Manually trigger the event handler. + // > jQuery(window).trigger( 'hashchange' ); + // + // Additional Notes: + // + // * The polling loop and Iframe are not created until at least one handler + // is actually bound to the 'hashchange' event. + // * If you need the bound handler(s) to execute immediately, in cases where + // a location.hash exists on page load, via bookmark or page refresh for + // example, use jQuery(window).hashchange() or the more verbose + // jQuery(window).trigger( 'hashchange' ). + // * The event can be bound before DOM ready, but since it won't be usable + // before then in IE6/7 (due to the necessary Iframe), recommended usage is + // to bind it inside a DOM ready handler. + + // Override existing $.event.special.hashchange methods (allowing this plugin + // to be defined after jQuery BBQ in BBQ's source code). + special[ str_hashchange ] = $.extend( special[ str_hashchange ], { + + // Called only when the first 'hashchange' event is bound to window. + setup: function() { + // If window.onhashchange is supported natively, there's nothing to do.. + if ( supports_onhashchange ) { return false; } + + // Otherwise, we need to create our own. And we don't want to call this + // until the user binds to the event, just in case they never do, since it + // will create a polling loop and possibly even a hidden Iframe. + $( fake_onhashchange.start ); + }, + + // Called only when the last 'hashchange' event is unbound from window. + teardown: function() { + // If window.onhashchange is supported natively, there's nothing to do.. + if ( supports_onhashchange ) { return false; } + + // Otherwise, we need to stop ours (if possible). + $( fake_onhashchange.stop ); + } + + }); + + // fake_onhashchange does all the work of triggering the window.onhashchange + // event for browsers that don't natively support it, including creating a + // polling loop to watch for hash changes and in IE 6/7 creating a hidden + // Iframe to enable back and forward. + fake_onhashchange = (function(){ + var self = {}, + timeout_id, + + // Remember the initial hash so it doesn't get triggered immediately. + last_hash = get_fragment(), + + fn_retval = function(val){ return val; }, + history_set = fn_retval, + history_get = fn_retval; + + // Start the polling loop. + self.start = function() { + timeout_id || poll(); + }; + + // Stop the polling loop. + self.stop = function() { + timeout_id && clearTimeout( timeout_id ); + timeout_id = undefined; + }; + + // This polling loop checks every $.fn.hashchange.delay milliseconds to see + // if location.hash has changed, and triggers the 'hashchange' event on + // window when necessary. + function poll() { + var hash = get_fragment(), + history_hash = history_get( last_hash ); + + if ( hash !== last_hash ) { + history_set( last_hash = hash, history_hash ); + + $(window).trigger( str_hashchange ); + + } else if ( history_hash !== last_hash ) { + location.href = location.href.replace( /#.*/, '' ) + history_hash; + } + + timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay ); + }; + + // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + // vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv + // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + $.browser.msie && !supports_onhashchange && (function(){ + // Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8 + // when running in "IE7 compatibility" mode. + + var iframe, + iframe_src; + + // When the event is bound and polling starts in IE 6/7, create a hidden + // Iframe for history handling. + self.start = function(){ + if ( !iframe ) { + iframe_src = $.fn[ str_hashchange ].src; + iframe_src = iframe_src && iframe_src + get_fragment(); + + // Create hidden Iframe. Attempt to make Iframe as hidden as possible + // by using techniques from http://www.paciellogroup.com/blog/?p=604. + iframe = $('