1
|
|
|
// Nonblock |
2
|
|
|
// Uses AMD or browser globals for jQuery. |
3
|
|
|
(function (factory) { |
4
|
|
|
if (typeof define === 'function' && define.amd) { |
5
|
|
|
// AMD. Register as a module. |
6
|
|
|
define('pnotify.nonblock', ['jquery', 'pnotify'], factory); |
7
|
|
|
} else { |
8
|
|
|
// Browser globals |
9
|
|
|
factory(jQuery, PNotify); |
10
|
|
|
} |
11
|
|
|
}(function($, PNotify){ |
12
|
|
|
// Some useful regexes. |
13
|
|
|
var re_on = /^on/, |
14
|
|
|
re_mouse_events = /^(dbl)?click$|^mouse(move|down|up|over|out|enter|leave)$|^contextmenu$/, |
15
|
|
|
re_ui_events = /^(focus|blur|select|change|reset)$|^key(press|down|up)$/, |
16
|
|
|
re_html_events = /^(scroll|resize|(un)?load|abort|error)$/; |
17
|
|
|
// Fire a DOM event. |
18
|
|
|
var dom_event = function(e, orig_e){ |
19
|
|
|
var event_object; |
20
|
|
|
e = e.toLowerCase(); |
21
|
|
|
if (document.createEvent && this.dispatchEvent) { |
22
|
|
|
// FireFox, Opera, Safari, Chrome |
23
|
|
|
e = e.replace(re_on, ''); |
24
|
|
|
if (e.match(re_mouse_events)) { |
25
|
|
|
// This allows the click event to fire on the notice. There is |
26
|
|
|
// probably a much better way to do it. |
27
|
|
|
$(this).offset(); |
28
|
|
|
event_object = document.createEvent("MouseEvents"); |
29
|
|
|
event_object.initMouseEvent( |
30
|
|
|
e, orig_e.bubbles, orig_e.cancelable, orig_e.view, orig_e.detail, |
31
|
|
|
orig_e.screenX, orig_e.screenY, orig_e.clientX, orig_e.clientY, |
32
|
|
|
orig_e.ctrlKey, orig_e.altKey, orig_e.shiftKey, orig_e.metaKey, orig_e.button, orig_e.relatedTarget |
33
|
|
|
); |
34
|
|
|
} else if (e.match(re_ui_events)) { |
35
|
|
|
event_object = document.createEvent("UIEvents"); |
36
|
|
|
event_object.initUIEvent(e, orig_e.bubbles, orig_e.cancelable, orig_e.view, orig_e.detail); |
37
|
|
|
} else if (e.match(re_html_events)) { |
38
|
|
|
event_object = document.createEvent("HTMLEvents"); |
39
|
|
|
event_object.initEvent(e, orig_e.bubbles, orig_e.cancelable); |
40
|
|
|
} |
41
|
|
|
if (!event_object) return; |
|
|
|
|
42
|
|
|
this.dispatchEvent(event_object); |
43
|
|
|
} else { |
44
|
|
|
// Internet Explorer |
45
|
|
|
if (!e.match(re_on)) e = "on"+e; |
|
|
|
|
46
|
|
|
event_object = document.createEventObject(orig_e); |
47
|
|
|
this.fireEvent(e, event_object); |
48
|
|
|
} |
49
|
|
|
}; |
50
|
|
|
|
51
|
|
|
|
52
|
|
|
// This keeps track of the last element the mouse was over, so |
53
|
|
|
// mouseleave, mouseenter, etc can be called. |
54
|
|
|
var nonblock_last_elem; |
55
|
|
|
// This is used to pass events through the notice if it is non-blocking. |
56
|
|
|
var nonblock_pass = function(notice, e, e_name){ |
57
|
|
|
notice.elem.css("display", "none"); |
58
|
|
|
var element_below = document.elementFromPoint(e.clientX, e.clientY); |
59
|
|
|
notice.elem.css("display", "block"); |
60
|
|
|
var jelement_below = $(element_below); |
61
|
|
|
var cursor_style = jelement_below.css("cursor"); |
62
|
|
|
notice.elem.css("cursor", cursor_style !== "auto" ? cursor_style : "default"); |
63
|
|
|
// If the element changed, call mouseenter, mouseleave, etc. |
64
|
|
|
if (!nonblock_last_elem || nonblock_last_elem.get(0) != element_below) { |
65
|
|
|
if (nonblock_last_elem) { |
66
|
|
|
dom_event.call(nonblock_last_elem.get(0), "mouseleave", e.originalEvent); |
67
|
|
|
dom_event.call(nonblock_last_elem.get(0), "mouseout", e.originalEvent); |
68
|
|
|
} |
69
|
|
|
dom_event.call(element_below, "mouseenter", e.originalEvent); |
70
|
|
|
dom_event.call(element_below, "mouseover", e.originalEvent); |
71
|
|
|
} |
72
|
|
|
dom_event.call(element_below, e_name, e.originalEvent); |
73
|
|
|
// Remember the latest element the mouse was over. |
74
|
|
|
nonblock_last_elem = jelement_below; |
75
|
|
|
}; |
76
|
|
|
|
77
|
|
|
|
78
|
|
|
PNotify.prototype.options.nonblock = { |
79
|
|
|
// Create a non-blocking notice. It lets the user click elements underneath it. |
80
|
|
|
nonblock: false, |
81
|
|
|
// The opacity of the notice (if it's non-blocking) when the mouse is over it. |
82
|
|
|
nonblock_opacity: .2 |
83
|
|
|
}; |
84
|
|
|
PNotify.prototype.modules.nonblock = { |
85
|
|
|
// This lets us update the options available in the closures. |
86
|
|
|
myOptions: null, |
87
|
|
|
|
88
|
|
|
init: function(notice, options){ |
89
|
|
|
var that = this; |
90
|
|
|
this.myOptions = options; |
91
|
|
|
notice.elem.on({ |
92
|
|
|
"mouseenter": function(e){ |
93
|
|
|
if (that.myOptions.nonblock) e.stopPropagation(); |
|
|
|
|
94
|
|
|
if (that.myOptions.nonblock) { |
95
|
|
|
// If it's non-blocking, animate to the other opacity. |
96
|
|
|
notice.elem.stop().animate({"opacity": that.myOptions.nonblock_opacity}, "fast"); |
97
|
|
|
} |
98
|
|
|
}, |
99
|
|
|
"mouseleave": function(e){ |
100
|
|
|
if (that.myOptions.nonblock) e.stopPropagation(); |
|
|
|
|
101
|
|
|
nonblock_last_elem = null; |
102
|
|
|
notice.elem.css("cursor", "auto"); |
103
|
|
|
// Animate back to the normal opacity. |
104
|
|
|
if (that.myOptions.nonblock && notice.animating !== "out") |
105
|
|
|
notice.elem.stop().animate({"opacity": notice.options.opacity}, "fast"); |
|
|
|
|
106
|
|
|
}, |
107
|
|
|
"mouseover": function(e){ |
108
|
|
|
if (that.myOptions.nonblock) e.stopPropagation(); |
|
|
|
|
109
|
|
|
}, |
110
|
|
|
"mouseout": function(e){ |
111
|
|
|
if (that.myOptions.nonblock) e.stopPropagation(); |
|
|
|
|
112
|
|
|
}, |
113
|
|
|
"mousemove": function(e){ |
114
|
|
|
if (that.myOptions.nonblock) { |
115
|
|
|
e.stopPropagation(); |
116
|
|
|
nonblock_pass(notice, e, "onmousemove"); |
117
|
|
|
} |
118
|
|
|
}, |
119
|
|
|
"mousedown": function(e){ |
120
|
|
|
if (that.myOptions.nonblock) { |
121
|
|
|
e.stopPropagation(); |
122
|
|
|
e.preventDefault(); |
123
|
|
|
nonblock_pass(notice, e, "onmousedown"); |
124
|
|
|
} |
125
|
|
|
}, |
126
|
|
|
"mouseup": function(e){ |
127
|
|
|
if (that.myOptions.nonblock) { |
128
|
|
|
e.stopPropagation(); |
129
|
|
|
e.preventDefault(); |
130
|
|
|
nonblock_pass(notice, e, "onmouseup"); |
131
|
|
|
} |
132
|
|
|
}, |
133
|
|
|
"click": function(e){ |
134
|
|
|
if (that.myOptions.nonblock) { |
135
|
|
|
e.stopPropagation(); |
136
|
|
|
nonblock_pass(notice, e, "onclick"); |
137
|
|
|
} |
138
|
|
|
}, |
139
|
|
|
"dblclick": function(e){ |
140
|
|
|
if (that.myOptions.nonblock) { |
141
|
|
|
e.stopPropagation(); |
142
|
|
|
nonblock_pass(notice, e, "ondblclick"); |
143
|
|
|
} |
144
|
|
|
} |
145
|
|
|
}); |
146
|
|
|
}, |
147
|
|
|
update: function(notice, options){ |
148
|
|
|
this.myOptions = options; |
149
|
|
|
} |
150
|
|
|
}; |
151
|
|
|
})); |
152
|
|
|
|
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.
Consider:
If you or someone else later decides to put another statement in, only the first statement will be executed.
In this case the statement
b = 42
will always be executed, while the logging statement will be executed conditionally.ensures that the proper code will be executed conditionally no matter how many statements are added or removed.