A bit of cleanup in $. Add $.hasClass.

This commit is contained in:
Nicolas Stepien 2012-08-25 02:59:55 +02:00
parent 7b49ae4c76
commit e9f3c0e49b
2 changed files with 116 additions and 114 deletions

View File

@ -214,7 +214,7 @@
el.className = 'reply dialog';
el.innerHTML = html;
el.id = id;
el.style.cssText = localStorage.getItem("" + Main.namespace + id + ".position") || position;
el.style.cssText = localStorage.getItem("" + $.NAMESPACE + id + ".position") || position;
el.querySelector('.move').addEventListener('mousedown', UI.dragstart, false);
return el;
},
@ -243,7 +243,7 @@
return style.bottom = top ? null : '0px';
},
dragend: function() {
localStorage.setItem("" + Main.namespace + UI.el.id + ".position", UI.el.style.cssText);
localStorage.setItem("" + $.NAMESPACE + UI.el.id + ".position", UI.el.style.cssText);
d.removeEventListener('mousemove', UI.drag, false);
d.removeEventListener('mouseup', UI.dragend, false);
return delete UI.el;
@ -293,16 +293,24 @@
};
$.extend($, {
NAMESPACE: '4chan_X.',
SECOND: 1000,
MINUTE: 1000 * 60,
HOUR: 1000 * 60 * 60,
DAY: 1000 * 60 * 60 * 24,
log: console.log.bind(console),
engine: /WebKit|Presto|Gecko/.exec(navigator.userAgent)[0].toLowerCase(),
id: function(id) {
return d.getElementById(id);
},
ready: function(fc) {
var cb;
if (/interactive|complete/.test(d.readyState)) {
return setTimeout(fc);
try {
fc();
} finally {
return;
}
}
cb = function() {
$.off(d, 'DOMContentLoaded', cb);
@ -312,25 +320,21 @@
},
sync: function(key, cb) {
return $.on(window, 'storage', function(e) {
if (e.key === ("" + Main.namespace + key)) {
if (e.key === ("" + $.NAMESPACE + key)) {
return cb(JSON.parse(e.newValue));
}
});
},
id: function(id) {
return d.getElementById(id);
},
formData: function(arg) {
formData: function(form) {
var fd, key, val;
if (arg instanceof HTMLFormElement) {
fd = new FormData(arg);
} else {
fd = new FormData();
for (key in arg) {
val = arg[key];
if (val) {
fd.append(key, val);
}
if (form instanceof HTMLFormElement) {
return new FormData(form);
}
fd = new FormData();
for (key in form) {
val = form[key];
if (val) {
fd.append(key, val);
}
}
return fd;
@ -354,35 +358,34 @@
return r;
},
cache: function(url, cb) {
var req;
if (req = $.cache.requests[url]) {
var req, reqs, _base;
reqs = (_base = $.cache).requests || (_base.requests = {});
if (req = reqs[url]) {
if (req.readyState === 4) {
return cb.call(req);
cb.call(req);
} else {
return req.callbacks.push(cb);
req.callbacks.push(cb);
}
} else {
req = $.ajax(url, {
onload: function() {
var _i, _len, _ref, _results;
_ref = this.callbacks;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
cb = _ref[_i];
_results.push(cb.call(this));
}
return _results;
},
onabort: function() {
return delete $.cache.requests[url];
},
onerror: function() {
return delete $.cache.requests[url];
}
});
req.callbacks = [cb];
return $.cache.requests[url] = req;
return;
}
req = $.ajax(url, {
onload: function() {
var _i, _len, _ref;
_ref = this.callbacks;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
cb = _ref[_i];
cb.call(this);
}
},
onabort: function() {
return delete reqs[url];
},
onerror: function() {
return delete reqs[url];
}
});
req.callbacks = [cb];
return reqs[url] = req;
},
cb: {
checked: function() {
@ -414,6 +417,9 @@
rmClass: function(el, className) {
return el.classList.remove(className);
},
hasClass: function(el, className) {
return el.classList.contains(className);
},
rm: function(el) {
return el.parentNode.removeChild(el);
},
@ -432,11 +438,11 @@
}
return frag;
},
add: function(parent, children) {
return parent.appendChild($.nodes(children));
add: function(parent, el) {
return parent.appendChild($.nodes(el));
},
prepend: function(parent, children) {
return parent.insertBefore($.nodes(children), parent.firstChild);
prepend: function(parent, el) {
return parent.insertBefore($.nodes(el), parent.firstChild);
},
after: function(root, el) {
return root.parentNode.insertBefore($.nodes(el), root.nextSibling);
@ -472,10 +478,7 @@
}
},
open: function(url) {
return (GM_openInTab || window.open)(location.protocol + url, '_blank');
},
event: function(el, e) {
return el.dispatchEvent(e);
return (GM_openInTab || window.open)(url, '_blank');
},
globalEval: function(code) {
var script;
@ -487,9 +490,9 @@
},
shortenFilename: function(filename, isOP) {
var threshold;
threshold = 30 + 10 * isOP;
if (filename.replace(/\.\w+$/, '').length > threshold) {
return "" + filename.slice(0, threshold - 5) + "(...)" + (filename.match(/\.\w+$/));
threshold = isOP ? 40 : 30;
if (filename.length - 4 > threshold) {
return "" + filename.slice(0, threshold - 5) + "(...)." + (filename.match(/\w+$/));
} else {
return filename;
}
@ -506,41 +509,38 @@
}
});
$.cache.requests = {};
$.extend($, typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null ? {
"delete": function(name) {
name = Main.namespace + name;
return GM_deleteValue(name);
return GM_deleteValue($.NAMESPACE + name);
},
get: function(name, defaultValue) {
var value;
name = Main.namespace + name;
if (value = GM_getValue(name)) {
if (value = GM_getValue($.NAMESPACE + name)) {
return JSON.parse(value);
} else {
return defaultValue;
}
},
set: function(name, value) {
name = Main.namespace + name;
localStorage.setItem(name, JSON.stringify(value));
return GM_setValue(name, JSON.stringify(value));
name = $.NAMESPACE + name;
value = JSON.stringify(value);
localStorage.setItem(name, value);
return GM_setValue(name, value);
}
} : {
"delete": function(name) {
return localStorage.removeItem(Main.namespace + name);
return localStorage.removeItem($.NAMESPACE + name);
},
get: function(name, defaultValue) {
var value;
if (value = localStorage.getItem(Main.namespace + name)) {
if (value = localStorage.getItem($.NAMESPACE + name)) {
return JSON.parse(value);
} else {
return defaultValue;
}
},
set: function(name, value) {
return localStorage.setItem(Main.namespace + name, JSON.stringify(value));
return localStorage.setItem($.NAMESPACE + name, JSON.stringify(value));
}
});

View File

@ -175,7 +175,7 @@ UI =
el.className = 'reply dialog'
el.innerHTML = html
el.id = id
el.style.cssText = localStorage.getItem("#{Main.namespace}#{id}.position") or position
el.style.cssText = localStorage.getItem("#{$.NAMESPACE}#{id}.position") or position
el.querySelector('.move').addEventListener 'mousedown', UI.dragstart, false
el
dragstart: (e) ->
@ -207,7 +207,7 @@ UI =
style.right = if left then null else '0px'
style.bottom = if top then null else '0px'
dragend: ->
localStorage.setItem "#{Main.namespace}#{UI.el.id}.position", UI.el.style.cssText
localStorage.setItem "#{$.NAMESPACE}#{UI.el.id}.position", UI.el.style.cssText
d.removeEventListener 'mousemove', UI.drag, false
d.removeEventListener 'mouseup', UI.dragend, false
delete UI.el
@ -250,33 +250,35 @@ $.extend = (object, properties) ->
return
$.extend $,
NAMESPACE: '4chan_X.'
SECOND: 1000
MINUTE: 1000 *60
HOUR : 1000 *60 * 60
DAY : 1000 *60 * 60 * 24
log: console.log.bind console
engine: /WebKit|Presto|Gecko/.exec(navigator.userAgent)[0].toLowerCase()
id: (id) ->
d.getElementById id
ready: (fc) ->
if /interactive|complete/.test d.readyState
# Execute the functions in parallel.
# If one fails, do not stop the others.
return setTimeout fc
try
fc()
finally
return
cb = ->
$.off d, 'DOMContentLoaded', cb
fc()
$.on d, 'DOMContentLoaded', cb
sync: (key, cb) ->
$.on window, 'storage', (e) ->
cb JSON.parse e.newValue if e.key is "#{Main.namespace}#{key}"
id: (id) ->
d.getElementById id
formData: (arg) ->
if arg instanceof HTMLFormElement
fd = new FormData arg
else
fd = new FormData()
for key, val of arg
fd.append key, val if val
if e.key is "#{$.NAMESPACE}#{key}"
cb JSON.parse e.newValue
formData: (form) ->
if form instanceof HTMLFormElement
return new FormData form
fd = new FormData()
for key, val of form
fd.append key, val if val
fd
ajax: (url, callbacks, opts={}) ->
{type, headers, upCallbacks, form} = opts
@ -290,18 +292,21 @@ $.extend $,
r.send form
r
cache: (url, cb) ->
if req = $.cache.requests[url]
reqs = $.cache.requests or= {}
if req = reqs[url]
if req.readyState is 4
cb.call req
else
req.callbacks.push cb
else
req = $.ajax url,
onload: -> cb.call @ for cb in @callbacks
onabort: -> delete $.cache.requests[url]
onerror: -> delete $.cache.requests[url]
req.callbacks = [cb]
$.cache.requests[url] = req
return
req = $.ajax url,
onload: ->
cb.call @ for cb in @callbacks
return
onabort: -> delete reqs[url]
onerror: -> delete reqs[url]
req.callbacks = [cb]
reqs[url] = req
cb:
checked: ->
$.set @name, @checked
@ -316,12 +321,13 @@ $.extend $,
style
x: (path, root=d.body) ->
# XPathResult.ANY_UNORDERED_NODE_TYPE is 8
d.evaluate(path, root, null, 8, null).
singleNodeValue
d.evaluate(path, root, null, 8, null).singleNodeValue
addClass: (el, className) ->
el.classList.add className
rmClass: (el, className) ->
el.classList.remove className
hasClass: (el, className) ->
el.classList.contains className
rm: (el) ->
el.parentNode.removeChild el
tn: (s) ->
@ -329,17 +335,17 @@ $.extend $,
nodes: (nodes) ->
# In (at least) Chrome, elements created inside different
# scripts/window contexts inherit from unequal prototypes.
# window_ext1.Node !== window_ext2.Node
# window_context1.Node !== window_context2.Node
unless nodes instanceof Array
return nodes
frag = d.createDocumentFragment()
for node in nodes
frag.appendChild node
frag
add: (parent, children) ->
parent.appendChild $.nodes children
prepend: (parent, children) ->
parent.insertBefore $.nodes(children), parent.firstChild
add: (parent, el) ->
parent.appendChild $.nodes el
prepend: (parent, el) ->
parent.insertBefore $.nodes(el), parent.firstChild
after: (root, el) ->
root.parentNode.insertBefore $.nodes(el), root.nextSibling
before: (root, el) ->
@ -359,20 +365,19 @@ $.extend $,
el.removeEventListener event, handler, false
return
open: (url) ->
(GM_openInTab or window.open) location.protocol + url, '_blank'
event: (el, e) ->
el.dispatchEvent e
(GM_openInTab or window.open) url, '_blank'
globalEval: (code) ->
script = $.el 'script', textContent: code
script = $.el 'script',
textContent: code
$.add d.head, script
$.rm script
shortenFilename: (filename, isOP) ->
# FILENAME SHORTENING SCIENCE:
# OPs have a +10 characters threshold.
# The file extension is not taken into account.
threshold = 30 + 10 * isOP
if filename.replace(/\.\w+$/, '').length > threshold
"#{filename[...threshold - 5]}(...)#{filename.match(/\.\w+$/)}"
threshold = if isOP then 40 else 30
if filename.length - 4 > threshold
"#{filename[...threshold - 5]}(...).#{filename.match(/\w+$/)}"
else
filename
bytesToString: (size) ->
@ -391,34 +396,31 @@ $.extend $,
Math.round size
"#{size} #{['B', 'KB', 'MB', 'GB'][unit]}"
$.cache.requests = {}
$.extend $,
if GM_deleteValue?
delete: (name) ->
name = Main.namespace + name
GM_deleteValue name
GM_deleteValue $.NAMESPACE + name
get: (name, defaultValue) ->
name = Main.namespace + name
if value = GM_getValue name
if value = GM_getValue $.NAMESPACE + name
JSON.parse value
else
defaultValue
set: (name, value) ->
name = Main.namespace + name
name = $.NAMESPACE + name
value = JSON.stringify value
# for `storage` events
localStorage.setItem name, JSON.stringify value
GM_setValue name, JSON.stringify value
localStorage.setItem name, value
GM_setValue name, value
else
delete: (name) ->
localStorage.removeItem Main.namespace + name
localStorage.removeItem $.NAMESPACE + name
get: (name, defaultValue) ->
if value = localStorage.getItem Main.namespace + name
if value = localStorage.getItem $.NAMESPACE + name
JSON.parse value
else
defaultValue
set: (name, value) ->
localStorage.setItem Main.namespace + name, JSON.stringify value
localStorage.setItem $.NAMESPACE + name, JSON.stringify value
$$ = (selector, root=d.body) ->
Array::slice.call root.querySelectorAll selector