PASTEBIN
| #1 paste tool since 2002
create new paste
tools
api
archive
faq
PASTEBIN
create new paste
trending pastes
sign up
login
my alerts
my settings
my profile
Don't like ads?
PRO users
don't see any ads ;-)
Public Pastes
Untitled
0 sec ago
wow ferocity pets
12 sec ago
Untitled
6 sec ago
Untitled
7 sec ago
Untitled
48 sec ago
Untitled
33 sec ago
Untitled
36 sec ago
Untitled
39 sec ago
New Paste
<!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script> <script type="text/javascript" src="http://code.jquery.com/ui/1.8.18/jquery-ui.js"></script> <script type="text/javascript" src="http://documentcloud.github.com/underscore/underscore.js"></script> <script> (function (window, $j, undefined) { var statics = { eventNamespace: 'priorityHandler', priorityData: 'POI.priority', handlerNS: 'handlerQueue', capturedEventNames: {}, originalDispatchMethod: undefined, max_priority: 10, min_priority: -10, peek: 'justPeeking' }; $j.widget("POI.onPriority", { // These options will be used as defaults options: { events: undefined, selector: undefined, data: undefined, fn: undefined, priority: 0, max_priority: statics.max_priority, min_priority: statics.min_priority }, //runs only once/DOM element _create: function() { //capture for other events which don't need ordering if (!statics.originalDispatchMethod) { statics.originalDispatchMethod = $j.event.dispatch; this._replaceDispatchMethod(); } }, //runs each time the plugin is called which might be mutliple times/DOM element //Event-map isn't supported yet _init: function () { var options = this.options, eventNames, i; eventNames = this._parseEventNames(options.events, options.selector); for(i = 0; i<eventNames.length;i++){ var name = eventNames[i]; //only bind if not already bound to make sure the event bubbles all the way if (!statics.capturedEventNames[name]) { statics.capturedEventNames[name] = {}; $j(window).on(name + "." + statics.eventNamespace, function(){ //no action necessary, only to ensure that event bubbling is over }); } }; if(options.priority > statics.max_priority || options.priority < statics.min_priority) { throw "The priority can only be set between "+statics.max_priority+" and "+statics.min_priority+"."; } options.data = (options.data || {}); options.data[statics.priorityData] = options.priority; this.element.on(options.events, options.selector, options.data, options.fn); }, /********************************************************************************* * * jQuery private methods * *********************************************************************************/ _hoverHack: function( events ) { var rhoverHack = /(?:^|\s)hover(\.\S+)?\b/; return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); }, /********************************************************************************* * * jQuery private methods * *********************************************************************************/ //partially taken from jQuery _parseEventNames: function(types, selector){ var rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, t, tns, type, result = []; // Handle multiple events separated by a space // jQuery(...).bind("mouseover mouseout", fn); types = jQuery.trim(this._hoverHack(types)).split(" "); for (t = 0; t < types.length; t++) { tns = rtypenamespace.exec(types[t]) || []; type = tns[1]; // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[type] || {}; // If selector defined, determine special event api type, otherwise given type type = (selector ? special.delegateType : special.bindType) || type; result[t] = type; } return result; }, /** * Method has to be overwritten as we want to encapsulate the event * handling chain, first the priority of events is taken into account, * secondly the regular bubbling hierarchy is used. Most of the code is * copied directly from jQuery, the only adaptions are regarding resorting * the handler's based on a priority and the wrapping of the event bubbling * to ensure all handler's are included. **/ _replaceDispatchMethod: function() { var _quickIs = function( elem, m ) { var attrs = elem.attributes || {}; return ((!m[1] || elem.nodeName.toLowerCase() === m[1]) && (!m[2] || (attrs.id || {}).value === m[2]) && (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) ); }; //CAREFUL: this isn't ourself here, rather it's the element $j.event.dispatch = function(event){ //event isn't interested in ordering by priority if (statics.capturedEventNames[event.type] === undefined) { return statics.originalDispatchMethod ? statics.originalDispatchMethod.apply(this, arguments) : null; } // Make a writable $j.Event from the native event object event = $j.event.fix(event || window.event); var handlers = (($j._data(this, "events") || {})[event.type] || []), delegateCount = handlers.delegateCount, args = [].slice.call(arguments, 0), run_all = !event.exclusive && !event.namespace, special = $j.event.special[event.type] || {}, handlerQueue = [], i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related; // Use the fix-ed $j.Event rather than the (read-only) native event args[0] = event; event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if (special.preDispatch && special.preDispatch.call(this, event) === false) { return; } // Determine handlers that should run if there are delegated events // Avoid non-left-click bubbling in Firefox (#3861) if (delegateCount && !(event.button && event.type === "click")) { // Pregenerate a single $j object for reuse with .is() jqcur = $j(this); jqcur.context = this.ownerDocument || this; for (cur = event.target; cur != this; cur = cur.parentNode || this) { // Don't process events on disabled elements (#6911, #8165) if (cur.disabled !== true) { selMatch = {}; matches = []; jqcur[0] = cur; for (i = 0; i < delegateCount; i++) { handleObj = handlers[i]; sel = handleObj.selector; if (selMatch[sel] === undefined) { selMatch[sel] = (handleObj.quick ? _quickIs(cur, handleObj.quick) : jqcur.is(sel)); } if (selMatch[sel]) { matches.push(handleObj); } } if (matches.length) { handlerQueue.push({ elem: cur, matches: matches }); } } } } // Add the remaining (directly-bound) handlers if (handlers.length > delegateCount) { handlerQueue.push({ elem: this, matches: handlers.slice(delegateCount) }); } //has to exist as we have an exit clause on top of the function statics.capturedEventNames[event.type][statics.handlerNS] = statics.capturedEventNames[event.type][statics.handlerNS] || []; if(!!handlerQueue.length) { statics.capturedEventNames[event.type][statics.handlerNS].push(handlerQueue); } if(this === window) { var accumulatedHandlers = _.flatten(statics.capturedEventNames[event.type][statics.handlerNS]), sortedHandlers = [], sortedElement, sortedMatch, sortedMatches, requireResort = false; //from now on we work with the sorted copy or if it wasn't necessary just with a local copy delete statics.capturedEventNames[event.type][statics.handlerNS]; //check if our handler is the only one registered, if so, ignore if (accumulatedHandlers.length === 1 //only one level is interested in the event && accumulatedHandlers[0].matches.length === 1 //only one handler (that's us) && accumulatedHandlers[0].matches[0].namespace === statics.eventNamespace) //make sure it's our handler { //no sorting or handling necessary return; } //iterate over all levels for (i = 0; i < accumulatedHandlers.length; i++) { sortedElement = accumulatedHandlers[i].elem; sortedMatches = accumulatedHandlers[i].matches; for (j = 0; j < sortedMatches.length; j++) { sortedMatch = sortedMatches[j]; if(sortedMatch.data && sortedMatch.data[statics.priorityData]){ requireResort = true; } sortedHandlers.push({ elem: sortedElement, matches: sortedMatch }); } } if(!!sortedHandlers.length && requireResort){ function sortByPriority(a,b){ var aPrio = (a.matches.data || {})[statics.priorityData] || 0, bPrio = (b.matches.data || {})[statics.priorityData] || 0; //revert order if prio is not 0, keep prio for 0 if (aPrio || bPrio) { return aPrio > bPrio ? -1 : 1; } return aPrio >= bPrio ? -1 : 1; }; sortedHandlers.sort(sortByPriority); } //used when peeking to get the highest priority if(sortedHandlers[0].matches.namespace.indexOf(statics.peek)!==-1) { var matched = sortedHandlers[0]; args.push(sortedHandlers.slice(1)); return matched.matches.handler.apply(matched.elem, args); } // Run delegates first; they may want to stop propagation beneath us for (i = 0; i < sortedHandlers.length; i++) { matched = sortedHandlers[i]; //uncommented as bubbling doesn't really match our concept of priorities //stop bubbling only if the context switches // if(event.isPropagationStopped() && lastContext && lastContext != matched.elem){ // //we don't allow preventing bubbling when specifying a priority // currentPriority = (event.data || {})[statics.priorityData]||0; // // if (!currentPriority) { // return; // } // } // lastContext = matched.elem; event.currentTarget = matched.elem; if(matched.matches){ if (event.isImmediatePropagationStopped()) { return; } handleObj = matched.matches; // Triggered event must either 1) be non-exclusive and have no namespace, or // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). if (run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test(handleObj.namespace)) { event.data = handleObj.data; event.handleObj = handleObj; ret = (($j.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args); if (ret !== undefined) { event.result = ret; if (ret === false) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if (special.postDispatch) { special.postDispatch.call(this, event); } return event.result; } // Call the postDispatch hook for the mapped type if (special.postDispatch) { special.postDispatch.call(this, event); } } }, _setOption: function (key, value) { switch (key) { case "max_priority": if(value<this.options.min_priority){ throw "The max. priority can't be lower than the min. priority"; } statics.max_priority = value; break; case "min_priority": if(value>this.options.max_priority){ throw "The min. priority can't be higher than the max. priority"; } statics.min_priority = value; break; } // In jQuery UI 1.8, you have to manually invoke the _setOption method from the base widget $j.Widget.prototype._setOption.apply(this, arguments); // In jQuery UI 1.9 and above, you use the _super method instead // this._super("_setOption", key, value); }, // Use the destroy method to clean up any modifications your widget has made to the DOM destroy: function () { // In jQuery UI 1.8, you must invoke the destroy method from the base widget $.Widget.prototype.destroy.call(this); // In jQuery UI 1.9 and above, you would define _destroy instead of destroy and not call the base method } }); $j.POI = $j.POI || {}; $j.extend($j.POI, { peek: function(eventName, selector, lowest){ if (typeof eventName !== 'string') { return; } var element, returnQueue = []; if (typeof selector === 'string' || !(selector instanceof $j)) { element = $j(selector); } element = element || selector; if (!element || (element && element.length === 0)) { throw "No elements were found with the provided selector"; } $j(window).onPrio(eventName + "." + statics.peek, function(event, data){ $j(window).off("." + statics.peek); returnQueue = data || returnQueue; }, statics.max_priority); element.trigger(eventName + "." + statics.peek); if (lowest) { return ((((returnQueue || [])[returnQueue.length - 1] || {}).matches || {}).data || {})['POI.priority'] || 0; } return ((((returnQueue || [])[0] || {}).matches || {}).data || {})['POI.priority'] || 0; } }); function registerHandler(types, selector, data, fn, firstOrLast){ //taken from jQuery.fn.on var origFn, type; // Types can be a map of types/handlers if (typeof types === "object") { // ( types-Object, selector, data ) if (typeof selector !== "string") { // && selector != null // ( types-Object, data ) data = data || selector; selector = undefined; } for (type in types) { registerHandler.call(this, type, selector, data, types[type], firstOrLast); } return this; } if (data == null && fn == null) { // ( types, fn ) fn = selector; data = selector = undefined; } else if (fn == null) { if (typeof selector === "string") { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if (fn === false) { fn = returnFalse; } else if (!fn) { return this; } return this.each(function(){ if(typeof firstOrLast === 'boolean'){ var sel = selector || this; priority = firstOrLast ? $j.POI.peek(types, sel, firstOrLast)-1 : $j.POI.peek(types, sel, firstOrLast)+1; if (priority > statics.max_priority) { statics.max_priority = priority+5; } else if (priority < statics.min_priority) { statics.min_priority = priority-5; } } $j(this).onPriority({'events':types, 'selector':selector, 'data':data, 'fn':fn, 'priority':priority}); }); } $j.fn.addFirst = function(types, selector, data, fn){ return registerHandler.call(this, types, selector, data, fn, false); } $j.fn.addLast = function(types, selector, data, fn){ return registerHandler.call(this, types, selector, data, fn, true); } /** * Just for convenience to allow calling in natural fashion instead of object literal * @param {Object} event see jQuery on method * @param {Object} selector see jQuery on method * @param {Object} data see jQuery on method * @param {Object} handler see jQuery on method * @param {Object} priority a priority between 10 and -10 */ $j.fn.onPrio = function(types, selector, data, fn, priority){ /** * influenced by jQuery.on */ var type; // Types can be a map of types/handlers if (typeof types === "object") { // (types-Object, priority) if(typeof selector === "number"){ priority = selector; selector = data = undefined; } // ( types-Object, selector, priority ) else if (typeof selector === "string" && typeof data === "number") { priority = data; data = undefined; } // ( types-Object, data, priority ) else if (typeof selector !== "string" && typeof data === "number") { priority = data; data = selector; selector = undefined; } // ( types-Object, selector, data, priority ) else if (typeof fn === "number") { priority = fn; } for (type in types) { this.onPrio(type, selector, data, types[type], priority); } return this; } //function(types, selector, data, fn, priority) if (!fn && fn != 0 && !priority) { // (types, fn, priority) fn = selector; priority = data; data = selector = undefined; } else if (!priority) { if (typeof selector === "string") { // ( types, selector, fn ) priority = fn; fn = data; data = undefined; } else { // ( types, data, fn ) priority = fn; fn = data; data = selector; selector = undefined; } } if (fn === false) { fn = returnFalse; } else if (!fn) { return this; } return this.each(function(){ $j(this).onPriority({'events':types, 'selector':selector, 'data':data, 'fn':fn, 'priority':priority}); }); }; $j(document).ready(function(){ $j(document).on('click.poi','p', function(){console.log('9 Default jQuery still works as expected, registered very first on document with selector to p');}); $j(document).onPrio('click.poi', 'p', {someData: 'data'}, function(){console.log('13 Using a selector and data as args');}, -4); $j(document).onPrio('click.poi', 'p', function(){console.log('5 Using only a selector and prio 2');}, 2); $j(document).onPrio('click.poi','p', function(){console.log('10 Registered with 0 as prio on document with selector p');}, 0); $j(document).onPrio('click.poi','p', {'someData':'something'}, function(){console.log('2 Registered before 10 with prio 8');},8); $j(document).onPrio('click.poi','p', function(){console.log('1 Registered after others with prio 10');},10); $j(document).on('click.poi', function(){console.log('11 Registered with on on document');}); $j(document).onPrio('click.poi', function(){console.log('12 Registered with -3 as prio on document');}, -3); $j('p').on('click.poi', function(){console.log('8 Registered with on on p');}); $j('p').onPrio('click.poi', function(){console.log('7 No selector or data, prio 1');}, 1); $j('p').onPrio('click.poi', {someData:'data'}, function(){console.log('4 No selector but data, prio 3');}, 3); //covering all possibilities using a map $j('p').onPrio({'click.poi':function(){console.log('6 Registered using a map, prio 1 after other prio 1 gets resorted');}, 'dblclick.poi':function(){console.log('1 Registered double click with prio 1');}}, 1); $j(document).onPrio({'click.poi':function(){console.log('Registered using a map, prio -5');}, 'dblclick.poi':function(){console.log('Registered double click with prio -5');}}, 'p', -5); $j(document).onPrio( {'click.poi':function(event){ console.log('Registered using a map, prio 1 after other prio 1 gets resorted'); console.log(" Show data from event.data:"); for (var x in event.data) { console.log(" "+x+" hat den Wert "+event.data[x]); } }, 'dblclick.poi':function(event){ console.log('Registered double click with prio 1'); console.log(" Show data from event.data:"); for (var x in event.data) { console.log(" "+x+" hat den Wert "+event.data[x]); } }}, 'p', {someData:'data'}, 1); $j(document).onPrio( {'click.poi':function(event){ console.log('Registered using a map, prio 7'); console.log(" Show data from event.data:"); for (var x in event.data) { console.log(" "+x+" hat den Wert "+event.data[x]); } }, 'dblclick.poi':function(event){ console.log('Registered double click with prio 7'); console.log(" Show data from event.data:"); for (var x in event.data) { console.log(" "+x+" hat den Wert "+event.data[x]); } }} , {someData:'data'}, 7); $j('p').onPrio('click.poi', {some:'data'}, function(event){ console.log('3 Registered with data and 6 as prio'); console.log(" Show data from event.data:"); for (var x in event.data) { console.log(" "+x+" hat den Wert "+event.data[x]); } }, 6); $j(document).onPriority('option', 'max_priority', 100); $j(document).onPrio('click.poi', function(){console.log("I'm the first even when registered last. Prio is 100");}, 100); $j(document).addLast('click.poi', 'p', function(){console.log("I don't know my priority but i'm running last");}); $j(document).addFirst('click.poi', 'p', function(){console.log("I don't know my priority but i'm the first one running");}); }); })(window, jQuery); </script> </head> <body> <div> <h3> This page shows how the events can be bound with JS and how the priority influences the order of execution. All events are bound using a namespace which is the intended way of using events. </h3> </div> <br/> <p> $j(document).on('click.poi','p', function(){console.log('9 Default jQuery still works as expected, registered very first on document with selector to p');}); </p> <p> $j(document).onPrio('click.poi', 'p', {someData: 'data'}, function(){console.log('13 Using a selector and data as args');}, -4); </p> <p> $j(document).onPrio('click.poi', 'p', function(){console.log('5 Using only a selector and prio 2');}, 2); </p> <p> $j(document).onPrio('click.poi','p', function(){console.log('10 Registered with 0 as prio on document with selector p');}, 0); </p> <p> $j(document).onPrio('click.poi','p', {'someData':'something'}, function(){console.log('2 Registered before 10 with prio 8');},8); </p> <p> $j(document).onPrio('click.poi','p', function(){console.log('1 Registered after others with prio 10');},10); </p> <br/> <p> $j(document).on('click.poi', function(){console.log('11 Registered with on on document');}); </p> <p> $j(document).onPrio('click.poi', function(){console.log('12 Registered with -3 as prio on document');}, -3); </p> <br/> <p> $j('p').on('click.poi', function(){console.log('8 Registered with on on p');}); </p> <p> $j('p').onPrio('click.poi', function(){console.log('7 No selector or data, prio 1');}, 1); </p> <p> $j('p').onPrio('click.poi', {someData:'data'}, function(){console.log('4 No selector but data, prio 3');}, 3); </p> <p> $j('p').onPrio({'click.poi':function(){console.log('6 Registered using a map, prio 1 after other prio 1 gets resorted');}, 'dblclick.poi':function(){console.log('1 Registered double click with prio 1');}}, 1); </p> <p> $j(document).onPrio({'click.poi':function(){console.log('Registered using a map, prio 1 after other prio -5 gets resorted');}, 'dblclick.poi':function(){console.log('Registered double click with prio -5');}}, 'p', -5); </p> <p> $j(document).onPrio({ 'click.poi':function(){ console.log('Registered using a map, prio 1 after other prio 1 gets resorted'); console.log(" Show data from event.data:"); for (var x in event.data) { console.log(" "+x+" hat den Wert "+event.data[x]); }}, 'dblclick.poi':function(){ console.log('Registered double click with prio 1'); console.log(" Show data from event.data:"); for (var x in event.data) { console.log(" "+x+" hat den Wert "+event.data[x]); } }}, 'p', {someData:'data'}, 1); </p> <p> $j(document).onPrio({'click.poi':function(){console.log('Registered using a map, prio 7');}, 'dblclick.poi':function(){console.log('Registered double click with prio 7');console.log(" Show data from event.data:"); for (var x in event.data) { console.log(" "+x+" hat den Wert "+event.data[x]); }}}, {someData:'data'}, 7); <p> $j('p').onPrio('click.poi', {some:'data'}, function(event){ console.log('3 Registered with data and 6 as prio'); console.log(" Show data from event.data:"); for (var x in event.data) { console.log(" "+x+" hat den Wert "+event.data[x]); } }, 6); </p> <br/> <h3> Changing the priority is accomplished through the following method. It doesn't matter on which element the min/max priority is set as it's a global parameter shared by all instances. </h3> <p> $j(document).onPriority('option', 'max_priority', 100); </p> <p> $j(document).onPrio('click.poi', function(){console.log("I'm the first even when registered last. Prio is 100");}, 100); </p> </body> </html>
Optional Paste Settings
Syntax Highlighting:
None
Bash
C
C#
C++
CSS
HTML
HTML 5
Java
JavaScript
Lua
None
Objective C
Perl
PHP
Python
Rails
-------------
4CS
6502 ACME Cross Assembler
6502 Kick Assembler
6502 TASM/64TASS
ABAP
ActionScript
ActionScript 3
Ada
ALGOL 68
Apache Log
AppleScript
APT Sources
ARM
ASM (NASM)
ASP
Asymptote
autoconf
Autohotkey
AutoIt
Avisynth
Awk
BASCOM AVR
Bash
Basic4GL
BibTeX
Blitz Basic
BNF
BOO
BrainFuck
C
C for Macs
C Intermediate Language
C#
C++
C++ (with QT extensions)
C: Loadrunner
CAD DCL
CAD Lisp
CFDG
ChaiScript
Clojure
Clone C
Clone C++
CMake
COBOL
CoffeeScript
ColdFusion
CSS
Cuesheet
D
DCL
DCPU-16
DCS
Delphi
Delphi Prism (Oxygene)
Diff
DIV
DOS
DOT
E
ECMAScript
Eiffel
Email
EPC
Erlang
F#
Falcon
FO Language
Formula One
Fortran
FreeBasic
FreeSWITCH
GAMBAS
Game Maker
GDB
Genero
Genie
GetText
Go
Groovy
GwBasic
Haskell
Haxe
HicEst
HQ9 Plus
HTML
HTML 5
Icon
IDL
INI file
Inno Script
INTERCAL
IO
J
Java
Java 5
JavaScript
jQuery
KiXtart
Latex
LDIF
Liberty BASIC
Linden Scripting
Lisp
LLVM
Loco Basic
Logtalk
LOL Code
Lotus Formulas
Lotus Script
LScript
Lua
M68000 Assembler
MagikSF
Make
MapBasic
MatLab
mIRC
MIX Assembler
Modula 2
Modula 3
Motorola 68000 HiSoft Dev
MPASM
MXML
MySQL
Nagios
newLISP
None
NullSoft Installer
Oberon 2
Objeck Programming Langua
Objective C
OCalm Brief
OCaml
Octave
OpenBSD PACKET FILTER
OpenGL Shading
Openoffice BASIC
Oracle 11
Oracle 8
Oz
ParaSail
PARI/GP
Pascal
PAWN
PCRE
Per
Perl
Perl 6
PHP
PHP Brief
Pic 16
Pike
Pixel Bender
PL/SQL
PostgreSQL
POV-Ray
Power Shell
PowerBuilder
ProFTPd
Progress
Prolog
Properties
ProvideX
PureBasic
PyCon
Python
Python for S60
q/kdb+
QBasic
R
Rails
REBOL
REG
Rexx
Robots
RPM Spec
Ruby
Ruby Gnuplot
SAS
Scala
Scheme
Scilab
SdlBasic
Smalltalk
Smarty
SPARK
SPARQL
SQL
StoneScript
SystemVerilog
T-SQL
TCL
Tera Term
thinBasic
TypoScript
Unicon
UnrealScript
UPC
Urbi
Vala
VB.NET
Vedit
VeriLog
VHDL
VIM
Visual Pro Log
VisualBasic
VisualFoxPro
WhiteSpace
WHOIS
Winbatch
XBasic
XML
Xorg Config
XPP
YAML
Z80 Assembler
ZXBasic
Paste Expiration:
Never
10 Minutes
1 Hour
1 Day
1 Week
2 Weeks
1 Month
Paste Exposure:
Public
Unlisted
Private (members only)
Paste Name / Title:
Hello
Guest
Sign Up
or
Login
You are currently not logged in, this means you can not edit or delete anything you paste.
Sign Up
or
Login