From 43e82e8d17afd135d181f0b025c8e42baf9f0df4 Mon Sep 17 00:00:00 2001 From: James Campos Date: Sat, 12 Mar 2011 13:13:47 -0800 Subject: [PATCH] image hover --- 4chan_x.js | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++- script.coffee | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/4chan_x.js b/4chan_x.js index d5cf8692a..1d6fda398 100644 --- a/4chan_x.js +++ b/4chan_x.js @@ -56,7 +56,7 @@ */ (function() { - var $, $$, DAY, Dialog, a, arr, as, autoWatch, autohide, b, board, callback, changeCheckbox, changeValue, clearHidden, closeQR, config, cooldown, cutoff, d, delform, down, editSauce, el, expand, expandComment, expandThread, formSubmit, g, getConfig, getThread, getTime, hide, hideReply, hideThread, href, html, i, id, iframe, iframeLoad, imageClick, imageExpand, imageExpandClick, imageResize, imageThumb, imageToggle, imageType, imageTypeChange, img, inAfter, inBefore, input, inputs, keyModeInsert, keyModeNormal, keydown, keypress, l1, lastChecked, log, m, mv, n, navbotr, navtopr, nodeInserted, now, omitted, onloadComment, onloadThread, option, options, parseResponse, pathname, qrListener, qrText, quickReply, recaptcha, recaptchaListener, recaptchaReload, redirect, replace, replyNav, report, request, rm, scroll, scrollThread, show, showReply, showThread, slice, span, src, start, stopPropagation, temp, text, textContent, thread, threadF, threads, tn, tzOffset, up, updateAuto, updateCallback, updateFavicon, updateInterval, updateNow, updateTime, updateTitle, updateVerbose, updaterMake, watch, watchX, watcher, watcherUpdate, x, zeroPad, _, _base, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _ref, _ref2, _ref3, _ref4, _ref5, _ref6; + var $, $$, DAY, Dialog, a, arr, as, autoWatch, autohide, b, board, callback, changeCheckbox, changeValue, clearHidden, closeQR, config, cooldown, cutoff, d, delform, down, editSauce, el, expand, expandComment, expandThread, formSubmit, g, getConfig, getThread, getTime, hide, hideReply, hideThread, href, html, i, id, iframe, iframeLoad, imageClick, imageExpand, imageExpandClick, imageHover, imageResize, imageThumb, imageToggle, imageType, imageTypeChange, img, inAfter, inBefore, input, inputs, keyModeInsert, keyModeNormal, keydown, keypress, l1, lastChecked, log, m, mv, n, navbotr, navtopr, nodeInserted, now, omitted, onloadComment, onloadThread, option, options, parseResponse, pathname, qrListener, qrText, quickReply, recaptcha, recaptchaListener, recaptchaReload, redirect, replace, replyNav, report, request, rm, scroll, scrollThread, show, showReply, showThread, slice, span, src, start, stopPropagation, temp, text, textContent, thread, threadF, threads, tn, tzOffset, up, updateAuto, updateCallback, updateFavicon, updateInterval, updateNow, updateTime, updateTitle, updateVerbose, updaterMake, watch, watchX, watcher, watcherUpdate, x, zeroPad, _, _base, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _ref, _ref2, _ref3, _ref4, _ref5, _ref6; var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __slice = Array.prototype.slice; if (typeof console != "undefined" && console !== null) { log = console.log; @@ -68,6 +68,7 @@ 'Comment Expansion': [true, 'Expand too long comments'], 'Image Auto-Gif': [false, 'Animate gif thumbnails'], 'Image Expansion': [true, 'Expand images'], + 'Image Hover': [false, 'Show full image on mouseover'], 'Image Preloading': [false, 'Preload Images'], 'Keybinds': [false, 'Binds actions to keys'], 'Localize Time': [true, 'Show times based on your timezone'], @@ -551,6 +552,64 @@ } return recaptchaReload(); }; + imageHover = { + init: function() { + var img; + img = n('img', { + id: 'iHover' + }); + hide(img); + d.body.appendChild(img); + return g.callbacks.push(imageHover.cb.node); + }, + offset: { + x: 45, + y: -120 + }, + cb: { + node: function(root) { + var thumb, thumbs, _i, _len, _results; + thumbs = $$('img[md5]', root); + _results = []; + for (_i = 0, _len = thumbs.length; _i < _len; _i++) { + thumb = thumbs[_i]; + _results.push(thumb.addEventListener('mouseover', imageHover.cb.mouseover, true)); + } + return _results; + }, + mouseover: function(e) { + var clientX, clientY, img, target; + target = e.target, clientX = e.clientX, clientY = e.clientY; + img = $('#iHover'); + img.src = target.parentNode.href; + show(img); + imageHover.winHeight = d.body.clientHeight; + imageHover.winWidth = d.body.clientWidth; + target.addEventListener('mousemove', imageHover.cb.mousemove, true); + return target.addEventListener('mouseout', imageHover.cb.mouseout, true); + }, + mousemove: function(e) { + var bot, clientX, clientY, img, imgHeight, top; + clientX = e.clientX, clientY = e.clientY; + img = $('#iHover'); + imgHeight = img.offsetHeight; + top = clientY + imageHover.offset.y; + bot = top + imgHeight; + log(bot, imageHover.winHeight); + img.style.top = imageHover.winHeight < imgHeight || top < 0 ? '0px' : bot > imageHover.winHeight ? imageHover.winHeight - imgHeight + 'px' : top + 'px'; + return img.style.left = clientX + imageHover.offset.x; + }, + mouseout: function(e) { + var img, target; + target = e.target; + img = $('#iHover'); + hide(img); + img.src = null; + target.removeEventListener('mousemove', imageHover.cb.mousemove, true); + return target.removeEventListener('mouseout', imageHover.cb.mouseout, true); + } + } + }; imageClick = function(e) { if (e.shiftKey || e.altKey || e.ctrlKey) { return; @@ -1426,6 +1485,9 @@ GM_setValue('lastChecked', now); } GM_addStyle('\ + #iHover {\ + position: fixed;\ + }\ #options textarea {\ height: 100px;\ width: 500px;\ @@ -1589,6 +1651,9 @@ return _results; }); } + if (getConfig('Image Hover')) { + imageHover.init(); + } if (getConfig('Image Auto-Gif')) { g.callbacks.push(function(root) { var src, thumb, thumbs, _i, _len, _results; diff --git a/script.coffee b/script.coffee index bd625892c..acfde2d5c 100644 --- a/script.coffee +++ b/script.coffee @@ -14,6 +14,7 @@ config = 'Comment Expansion': [true, 'Expand too long comments'] 'Image Auto-Gif': [false, 'Animate gif thumbnails'] 'Image Expansion': [true, 'Expand images'] + 'Image Hover': [false, 'Show full image on mouseover'] 'Image Preloading': [false, 'Preload Images'] 'Keybinds': [false, 'Binds actions to keys'] 'Localize Time': [true, 'Show times based on your timezone'] @@ -373,6 +374,53 @@ iframeLoad = -> rm qr recaptchaReload() +imageHover = + init: -> + img = n 'img', id: 'iHover' + hide img + d.body.appendChild img + g.callbacks.push imageHover.cb.node + offset: + x: 45 + y: -120 + cb: + node: (root) -> + thumbs = $$ 'img[md5]', root + for thumb in thumbs + thumb.addEventListener 'mouseover', imageHover.cb.mouseover, true + mouseover: (e) -> + {target, clientX, clientY} = e + img = $ '#iHover' + img.src = target.parentNode.href + show img + imageHover.winHeight = d.body.clientHeight + imageHover.winWidth = d.body.clientWidth + target.addEventListener 'mousemove', imageHover.cb.mousemove, true + target.addEventListener 'mouseout', imageHover.cb.mouseout, true + mousemove: (e) -> + {clientX, clientY} = e + img = $ '#iHover' + imgHeight = img.offsetHeight + + top = clientY + imageHover.offset.y + bot = top + imgHeight + log bot, imageHover.winHeight + img.style.top = + if imageHover.winHeight < imgHeight or top < 0 + '0px' + else if bot > imageHover.winHeight + imageHover.winHeight - imgHeight + 'px' + else + top + 'px' + img.style.left = clientX + imageHover.offset.x + mouseout: (e) -> + {target} = e + img = $ '#iHover' + hide img + img.src = null + target.removeEventListener 'mousemove', imageHover.cb.mousemove, true + target.removeEventListener 'mouseout', imageHover.cb.mouseout, true + imageClick = (e) -> return if e.shiftKey or e.altKey or e.ctrlKey e.preventDefault() @@ -1071,6 +1119,9 @@ if lastChecked < now - 1*DAY GM_setValue('lastChecked', now) GM_addStyle ' + #iHover { + position: fixed; + } #options textarea { height: 100px; width: 500px; @@ -1212,6 +1263,9 @@ if getConfig 'Image Expansion' thumb.parentNode.addEventListener 'click', imageClick, true if g.expand then imageToggle thumb.parentNode +if getConfig 'Image Hover' + imageHover.init() + if getConfig 'Image Auto-Gif' g.callbacks.push (root) -> thumbs = $$ 'img[md5]', root