1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00

3.5.529. Tooltip stuff.

This commit is contained in:
SirStendec 2017-09-28 23:18:26 -04:00
parent 373f521de8
commit e0bad1dc10
25 changed files with 549 additions and 97 deletions

View file

@ -1,3 +1,15 @@
<div class="list-header">3.5.529 <time datetime="2017-09-28">(2017-09-28)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Changed: Rewrite tooltip rendering to try making them better positioned.</li>
<li>Added: Clickable links in the Following tooltip, as a result of the rewrite.</li>
</ul>
<div class="list-header">3.5.528 <time datetime="2017-09-26">(2017-09-26)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: Bug loading emote data from the server.</li>
<li>Fixed: Initialize the full Ember modifications when loading the settings pages and products page that has been brought into the Ember app.</li>
</ul>
<div class="list-header">3.5.527 <time datetime="2017-09-25">(2017-09-25)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Changed: More tweaks to tooltip rendering to support backend improvements.</li>
@ -49,10 +61,5 @@
<li>Changed: Support multiple sub tiers with the Channel emoticons menu.</li>
</ul>
<div class="list-header">3.5.518 <time datetime="2017-09-02">(2017-09-02)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: Bug with rich content attached to chat messages not getting removed when a message is timed out.</li>
</ul>
<div class="list-header" id="ffz-old-news-button"><a href="#">View Older</a></div>
<div id="ffz-old-news"></div>

View file

@ -1,3 +1,8 @@
<div class="list-header">3.5.518 <time datetime="2017-09-02">(2017-09-02)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Fixed: Bug with rich content attached to chat messages not getting removed when a message is timed out.</li>
</ul>
<div class="list-header">3.5.517 <time datetime="2017-09-02">(2017-09-02)</time></div>
<ul class="chat-menu-content menu-side-padding">
<li>Changed: Dark theme CSS tweak for the directory.</li>

View file

@ -47,7 +47,7 @@ module.exports = FrankerFaceZ.constants = {
CHAT_COLORS: ["#FF0000", "#0000FF", "#008000", "#B22222", "#FF7F50", "#9ACD32", "#FF4500", "#2E8B57", "#DAA520", "#D2691E", "#5F9EA0", "#1E90FF", "#FF69B4", "#8A2BE2", "#00FF7F"],
TOOLTIP_DISTANCE: 100,
TOOLTIP_DISTANCE: 25,
SEPARATORS: SEPARATORS,
SPLITTER: SPLITTER,

View file

@ -951,7 +951,7 @@ FFZ.prototype.modify_chat_room_manager = function(component) {
tbl.innerHTML = '<thead><tr><th colspan="2">Channels</th><th class="ffz-row-switch" title="Pinning a channel makes it so you always join that channel\'s chat, no matter where you are on Twitch.">Pin</th></tr></thead><tbody></tbody>';
room_list.insertBefore(tbl, room_list.firstChild);
jQuery('.ffz-row-switch', tbl).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'se')});
jQuery('.ffz-row-switch', tbl).zipsy({gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'se')});
chan_table = this._ffz_chan_table = tbl.querySelector('tbody');
@ -1171,7 +1171,7 @@ FFZ.prototype.modify_chat_room_manager = function(component) {
link.title = "Chat Room Management";
link.innerHTML = '<figure class="icon">' + constants.ROOMS + '</figure><span class="notifications"></span>';
jQuery(link).tipsy({gravity: "n", offset: 10});
jQuery(link).zipsy({gravity: "n", offset: 10});
link.addEventListener('click', function() {
view.set('isShowingList', !view.get('isShowingList'));

View file

@ -190,7 +190,7 @@ FFZ.prototype.modify_conversation_window = function(component) {
header_name.setAttribute('data-color', raw_color);
}
jQuery('.badge', el).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
jQuery('.badge', el).zipsy({gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')});
}
});
}

View file

@ -476,7 +476,7 @@ FFZ.prototype.modify_game_follow_button = function(component) {
spoiler.addEventListener('click', click_button('spoiler_games', update_spoiler));
el.appendChild(spoiler);
jQuery('.tooltip', el).tipsy();
jQuery('.tooltip', el).zipsy();
}
})
}
@ -581,7 +581,7 @@ FFZ.prototype.modify_directory_live = function(component, mode) {
t_el.appendChild(t_span);
t_el.setAttribute('original-title', 'Stream Uptime <nobr>(since ' + up_since.toLocaleString() + ')</nobr>');
jQuery(t_el).tipsy({html: true, gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 's')});
jQuery(t_el).zipsy({html: true, gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 's')});
cont.appendChild(t_el);
}
@ -780,7 +780,7 @@ FFZ.prototype.modify_directory_host = function(component) {
if ( hosts && hosts.length > 1 ) {
title.textContent = utils.number_commas(hosts.length) + ' hosting ' + utils.sanitize(target.display_name);
title.title = _.sortBy(hosts, "name").mapBy("display_name").join(", ");
jQuery(title).tipsy({gravity: 's'});
jQuery(title).zipsy({gravity: 's'});
}
}

View file

@ -86,9 +86,6 @@ FFZ.prototype.modify_feed_card = function(component) {
output = f.render_tokens(tokens, true, false);
pbody.innerHTML = '<p>' + output + '</p>';
//jQuery('.ffz-tooltip', pbody).tipsy({html: true, title: f.render_tooltip(), gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
//jQuery('.html-tooltip', pbody).tipsy({html: true, gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
}
});
}

View file

@ -121,7 +121,7 @@ FFZ.prototype.modify_twitch_profile_card = function(component) {
var el = this.get('element');
el.classList.add('ffz-processed');
jQuery('.aspect', el).tipsy();
jQuery('.aspect', el).zipsy();
if ( ! f.settings.enhance_profile_following )
return;
@ -239,7 +239,7 @@ FFZ.prototype.modify_twitch_profile_card = function(component) {
el.classList.add('ffz-processed');
jQuery('.aspect', el).tipsy();
jQuery('.aspect', el).zipsy();
if ( ! data )
return false;

View file

@ -868,7 +868,8 @@ FFZ.prototype.setup_line = function() {
// Tipsy Handler
jQuery(document.body).on("mouseleave", ".tipsy", function() {
this.parentElement.removeChild(this);
if ( ! this.classList.contains('zipsy') )
this.parentElement.removeChild(this);
});
// Aliases

View file

@ -1015,7 +1015,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
name.innerHTML = results[0];
name.title = results[1] || '';
if ( results[1] )
jQuery(name).tipsy({html: true, gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
jQuery(name).zipsy({html: true, gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')});
}
});
});
@ -1105,9 +1105,9 @@ FFZ.prototype.modify_moderation_card = function(component) {
add_btn_make = function(label, cmd) {
var btn = utils.createElement('button', 'button ffz-no-bg', utils.sanitize(label));
jQuery(btn).tipsy({
jQuery(btn).zipsy({
html: true,
gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n'),
gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n'),
title: function() {
var user = t.get('cardInfo.user'),
chat_controller = utils.ember_lookup('controller:chat'),
@ -1169,7 +1169,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
else if ( f.settings.mod_card_hotkeys && timeout === 1 )
btn.title = "(P)urge - " + btn.title;
jQuery(btn).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
jQuery(btn).zipsy({gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')});
btn.addEventListener('click', btn_click.bind(this, timeout));
return btn;
@ -1220,7 +1220,7 @@ FFZ.prototype.modify_moderation_card = function(component) {
unban_btn.innerHTML = '<figure class="icon">' + CHECK + '</figure>';
unban_btn.title = (f.settings.mod_card_hotkeys ? "(U)" : "U") + "nban User";
jQuery(unban_btn).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
jQuery(unban_btn).zipsy({gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')});
unban_btn.addEventListener("click", btn_click.bind(this, -1));
jQuery(ban_btn).after(unban_btn);
@ -1229,7 +1229,8 @@ FFZ.prototype.modify_moderation_card = function(component) {
// Tooltips for ban and ignore.
jQuery("button.ignore, button.ban").tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
jQuery("button.ignore, button.ban").zipsy({
gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')});
// More Fixing Other Buttons
@ -1245,7 +1246,8 @@ FFZ.prototype.modify_moderation_card = function(component) {
// Follow Button
var follow_button = el.querySelector(".follow-button");
if ( follow_button )
jQuery(follow_button).tipsy({title: function() { return follow_button.classList.contains('is-following') ? "Unfollow" : "Follow"}});
jQuery(follow_button).zipsy({
title: function() { return follow_button.classList.contains('is-following') ? "Unfollow" : "Follow"}});
// Whisper and Message Buttons
@ -1257,7 +1259,8 @@ FFZ.prototype.modify_moderation_card = function(component) {
msg_btn.classList.add('message');
msg_btn.title = "Whisper User";
jQuery(msg_btn).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
jQuery(msg_btn).zipsy({
gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')});
var real_msg = utils.createElement('button', 'message-button button float-left button--icon-only message html-tooltip');
@ -1365,7 +1368,9 @@ FFZ.prototype.modify_moderation_card = function(component) {
name.innerHTML = results[0];
name.title = results[1] || '';
if ( results[1] )
jQuery(name).tipsy({html: true, gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
jQuery(name).zipsy({
html: true,
gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')});
}
}

View file

@ -956,7 +956,7 @@ FFZ.prototype.modify_room_component = function(component) {
if ( ! badge ) {
badge = utils.createElement('span', 'ffz room-state stat float-right', (label || info[0]).charAt(0).toUpperCase() + '<span>' + (label || info[0]).substr(1).toUpperCase() + '</span>');
badge.id = id;
jQuery(badge).tipsy({html: true, gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'se')});
jQuery(badge).zipsy({html: true, gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'se')});
container.appendChild(badge);
}

View file

@ -495,13 +495,14 @@ FFZ.prototype.modify_navigation = function(component, is_top_nav) {
_initTooltips: function() {
this._tipsySelector = this.$("#js-warp a, #small_search button, #small_more button");
this._tipsySelector.off("mouseenter").off("mouseleave").teardownTipsy();
this._tipsySelector.tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'w')});
this._tipsySelector.zipsy({
gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'w')});
this.$('a[data-href="following"]').tipsy({
this.$('a[data-href="following"]').zipsy({
html: true,
className: function() { return f.settings.following_count ? 'ffz-wide-tip' : '' },
title: function() { return f._build_following_tooltip(this) },
gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE * 2, 'w')
gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE * 2, 'w')
});
},

View file

@ -61,7 +61,7 @@ FFZ.channel_metadata = {};
// Version
var VER = FFZ.version_info = {
major: 3, minor: 5, revision: 527,
major: 3, minor: 5, revision: 529,
toString: function() {
return [VER.major, VER.minor, VER.revision].join(".") + (VER.extra || "");
}
@ -322,7 +322,7 @@ FFZ.prototype.initialize = function(increment, delay) {
// Twitch ember application is ready.
// Pages we don't want to interact with at all.
if ( ['passport.twitch.tv', 'im.twitch.tv', 'api.twitch.tv', 'chatdepot.twitch.tv', 'spade.twitch.tv'].indexOf(location.hostname) !== -1 || /^\/products\//.test(location.pathname) || /^\/pr\//.test(location.pathname) || /^\/user\/two_factor/.test(location.pathname) ) {
if ( ['passport.twitch.tv', 'im.twitch.tv', 'api.twitch.tv', 'chatdepot.twitch.tv', 'spade.twitch.tv'].indexOf(location.hostname) !== -1 || /^\/pr\//.test(location.pathname) || /^\/user\/two_factor/.test(location.pathname) ) {
this.log("Found banned sub-domain. Not initializing.");
window.FrankerFaceZ = null;
return;
@ -337,12 +337,12 @@ FFZ.prototype.initialize = function(increment, delay) {
return this.init_clips(delay);
// Check for special non-ember pages.
if ( /^\/(?:team\/|user\/|p\/|settings|m\/|messages?\/)/.test(location.pathname) )
if ( /^\/(?:team\/|user\/|p\/|m\/|settings\/(?:prime|turbo|channel|security|connections)|messages?\/)/.test(location.pathname) )
return this.init_normal(delay);
// Check for the dashboard.
if ( window.PP && /\/[^\/]+\/dashboard/.test(location.pathname) && !/bookmarks$/.test(location.pathname) )
return this.init_dashboard(delay);
/*if ( window.PP && /\/[^\/]+\/dashboard/.test(location.pathname) && !/bookmarks$/.test(location.pathname) )
return this.init_dashboard(delay);*/
var loaded = FFZ.utils.ember_resolve('model:room');
if ( !loaded ) {

View file

@ -544,8 +544,6 @@ var is_android = navigator.userAgent.indexOf('Android') !== -1,
el.appendChild(label);
el.appendChild(help);
menu.appendChild(el);
//jQuery('.html-tooltip', el).tipsy({html: true, gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
//jQuery('.ffz-tooltip', el).tipsy({live: true, html: true, title: this.render_tooltip(), gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
}
container.appendChild(menu);

View file

@ -10,7 +10,7 @@ var FFZ = window.FrankerFaceZ,
HOP = Object.prototype.hasOwnProperty,
TOOLTIP_VERSION = 2,
TOOLTIP_VERSION = 3,
FAV_MARKER = '<span class="ffz-favorite"></span>',
EXPLANATION_WARN = '<hr>This link has been sent to you via a whisper rather than standard chat, and has not been checked or approved of by any moderators or staff members. Please treat this link with caution and do not visit it if you do not trust the sender.',
@ -21,7 +21,7 @@ var FFZ = window.FrankerFaceZ,
LINK = /(?:https?:\/\/)?(?:[-a-zA-Z0-9@:%_\+~#=]+\.)+[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=()]*)/g,
TIME_REPLACER = /<time\s+datetime=(["'])([^>]+?)\1[^>]*>(.*?)<\/time>/i,
TIME_REPLACER = /<time\s+(?:class=(["'])([^>]+?)\1\s+)?datetime=(["'])([^>]+?)\3[^>]*>(.*?)<\/time>/i,
CLIP_URL = /^(?:https?:\/\/)?clips\.twitch\.tv\/(\w+?\/?\w*?)(?:\/edit)?(?:[\?#]|$)/,
VIDEO_URL = /^(?:https?:\/\/)?(?:www\.)?twitch\.tv\/(?:\w+\/v|videos)\/(\w+)$/,
FFZ_EMOTE_URL = /^(?:https?:\/\/)?(?:www\.)?frankerfacez\.com\/emoticon\/(\d+)(?:-\w*)?$/,
@ -349,7 +349,7 @@ FFZ.prototype.get_twitch_set_for = function(emote_id, callback) {
this._twitch_emote_to_set[emote_id] = null;
var f = this,
use_ss = this._ws_open,
//use_ss = true, //this._ws_open,
timer = null,
cb = function(success, data) {
if ( timer ) {
@ -373,18 +373,18 @@ FFZ.prototype.get_twitch_set_for = function(emote_id, callback) {
callback(set_id);
};
if ( use_ss ) {
this.ws_send("get_emote", emote_id, cb);
timer = setTimeout(cb.bind(this, false, null), 1000);
} else
fetch(constants.API_SERVER = "ed/emote/" + emote_id)
/*if ( use_ss ) {*/
this.ws_send("get_emote", emote_id, cb, true);
timer = setTimeout(cb.bind(this, false, null), 5000);
/*} else
fetch(constants.API_SERVER + "ed/emote/" + emote_id)
.then(function(resp) {
if ( ! resp.ok )
return cb(false, null);
resp.json().then(function(data) {
cb(true, data);
})
});
});*/
return null;
}
@ -403,7 +403,7 @@ FFZ.prototype.get_twitch_set = function(set_id, callback) {
this._twitch_set_to_channel[set_id] = null;
var f = this,
use_ss = this._ws_open,
//use_ss = this._ws_open,
timer = null,
cb = function(success, data) {
if ( timer ) {
@ -421,10 +421,10 @@ FFZ.prototype.get_twitch_set = function(set_id, callback) {
callback(data || null);
};
if ( use_ss ) {
this.ws_send("get_emote_set", set_id, cb);
timer = setTimeout(cb.bind(this, false, null), 1000);
} else
/*if ( use_ss ) {*/
this.ws_send("get_emote_set", set_id, cb, true);
timer = setTimeout(cb.bind(this, false, null), 5000);
/*} else
fetch(constants.API_SERVER + "ed/set/" + set_id)
.then(function(resp) {
if ( ! resp.ok )
@ -432,7 +432,7 @@ FFZ.prototype.get_twitch_set = function(set_id, callback) {
resp.json().then(function(data) {
cb(true, data);
})
});
});*/
return null;
}
@ -466,6 +466,8 @@ FFZ.prototype.get_link_info = function(url, no_promises) {
li = this.settings.link_info;
console.log('get_link_info', url, info);
if ( ! li || (expires && Date.now() > expires) )
info = this._link_data[url] = null;
@ -522,17 +524,19 @@ FFZ.prototype.render_link_tooltip = function(data, el) {
var content = data.content || data.html || '';
if ( content )
content = content.replace(TIME_REPLACER, function(match, junk, timestamp, old) {
content = content.replace(TIME_REPLACER, function(match, junk_one, cls, junk_two, timestamp, old) {
var now = Date.now(),
posted_at = utils.parse_date(timestamp),
time_ago = posted_at && (now - posted_at) / 1000;
if ( time_ago < 86400 )
old = utils.full_human_time(time_ago);
else if ( posted_at )
old = posted_at.toLocaleString();
if ( cls !== 'keep' ) {
if ( cls === 'human' || (cls !== 'ts' && time_ago < 86400) )
old = utils.full_human_time(time_ago);
else if ( posted_at )
old = posted_at.toLocaleString();
}
return '<time timestamp="' + utils.sanitize(timestamp) + '">' + utils.sanitize(old) + '</time>';
return '<time class="' + utils.quote_attr(cls||'') + '" timestamp="' + utils.quote_attr(timestamp) + '">' + utils.sanitize(old) + '</time>';
});

View file

@ -302,13 +302,13 @@ FFZ.prototype.render_metadata = function(key, basic_info, metabar, timers, refre
if ( dynamic_tooltip ) {
je = jQuery(btn);
je.hover(
function() { je.data("hover", true).tipsy("show") },
function() { je.data("hover", false).tipsy("hide") })
function() { je.data("hover", true).zipsy("show") },
function() { je.data("hover", false).zipsy("hide") })
.data("hover", false)
.tipsy({
.zipsy({
trigger: "manual",
html: true,
gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n'),
gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n'),
title: function() {
// We can't wait for a promise to resolve now, so hope this hasn't changed.
var dat = info.setup ? info.setup.apply(f, basic_info) : basic_info;
@ -397,7 +397,7 @@ FFZ.prototype.render_metadata = function(key, basic_info, metabar, timers, refre
stat.innerHTML = label;
if ( dynamic_tooltip && je.data('hover') )
je.tipsy('hide').tipsy('show');
je.zipsy('hide').zipsy('show');
if ( info.hasOwnProperty('disabled') )
el.classList.toggle('disabled', typeof info.disabled === 'function' ? info.disabled.apply(f, data) : info.disabled);

View file

@ -102,12 +102,12 @@ FFZ.prototype.build_dash_feed = function() {
align_btn.insertBefore(chk_share, align_btn.firstChild);
}
});
jQuery(tnc).tipsy();
jQuery(tnc).zipsy();
align_btn.appendChild(tnc);
}
char_count.title = 'Roughly the first 115 characters of a post will appear in a Tweet.';
jQuery(char_count).tipsy();
jQuery(char_count).zipsy();
align_btn.appendChild(btn_submit);
align_btn.appendChild(char_count);

View file

@ -63,7 +63,7 @@ FFZ.msg_commands.chatter_count = function(data) {
stat.appendChild(el);
cont.appendChild(stat);
jQuery(stat).tipsy({gravity: 's'});
jQuery(stat).zipsy({gravity: 's'});
}
el.textContent = utils.number_commas(data.chatters);

View file

@ -218,12 +218,13 @@ FFZ.prototype._build_following_tooltip = function(el) {
var up_since = this.settings.stream_uptime && stream.created_at && utils.parse_date(stream.created_at),
now = Date.now() - (this._ws_server_offset || 0),
uptime = up_since && (Math.floor((now - up_since.getTime()) / 60000) * 60) || 0,
channel_name = stream.channel.name,
tags = stream.channel.game === 'Creative' && this.tokenize_ctags(stream.channel.status, true);
tooltip += (c === 1 ? '<hr>' : '') +
(uptime > 0 ? '<span class="stat">' + constants.CLOCK + ' ' + utils.duration_string(uptime) + '</span>' : '') +
'<span class="stat">' + constants.LIVE + ' ' + utils.number_commas(stream.viewers) + '</span>' +
'<b>' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '</b><br>' +
'<a href="https://www.twitch.tv/' + utils.quote_san(channel_name) + '" onclick="return FrankerFaceZ.utils.transition_user(&quot;' + utils.quote_san(channel_name) + '&quot;)"><b>' + utils.sanitize(stream.channel.display_name || stream.channel.name) + '</b></a><br>' +
'<span class="playing">' +
(stream.stream_type === 'watch_party' ? '<span class="pill is-watch-party">Vodcast</span> ' : '') +
(stream.channel.game === 'Creative' ? 'Being Creative' : (stream.channel.game ? 'Playing ' + utils.sanitize(stream.channel.game) : 'Not Playing')) + (tags ? ' | ' + _.pluck(tags, "text").join(" ") : '') + '</span>';
@ -269,7 +270,7 @@ FFZ.prototype._build_following_tooltip = function(el) {
}*/
// Reposition the tooltip.
setTimeout(function() {
/*setTimeout(function() {
var tip = document.querySelector('.tipsy');
if ( ! tip )
return;
@ -283,7 +284,7 @@ FFZ.prototype._build_following_tooltip = function(el) {
tip.style.left = (left - bb.left) + 5 + 'px';
else if ( right > document.body.clientWidth - 5 )
tip.style.left = (left - (5 + right - document.body.clientWidth)) + 'px';
});
});*/
return tooltip;
}
@ -293,9 +294,15 @@ FFZ.prototype._install_following_tooltips = function() {
var f = this,
data = {
html: true,
delayOut: 100,
className: function() { return WIDE_TIP(f, this); },
title: function() { return f._build_following_tooltip(this); },
gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE * 2, 'w')
gravity: function(box) {
return (box ?
utils.newtip_placement :
utils.tooltip_placement)(constants.TOOLTIP_DISTANCE, 'w').call(this, box);
//utils.tooltip_placement(constants.TOOLTIP_DISTANCE * 2, 'w')
}
};
for(var i=0; i < FOLLOWING_CONTAINERS.length; i++) {
@ -305,7 +312,7 @@ FFZ.prototype._install_following_tooltips = function() {
if ( td && td.options ) {
td.options = _.extend(td.options, data);
} else
following.tipsy(data);
following.zipsy(data);
}
}
}

View file

@ -175,10 +175,6 @@ FFZ.prototype.build_ui_popup = function(view) {
inner.className = 'emoticon-selector-box dropmenu';
container.appendChild(inner);
// Stuff
//jQuery(inner).find('.html-tooltip').tipsy({live: true, html: true, gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 's')});
//jQuery(inner).find('.ffz-tooltip').tipsy({live: true, html: true, title: this.render_tooltip(), gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
// Menu Container
var sub_container = document.createElement('div');
sub_container.className = 'ffz-ui-menu-page';
@ -263,7 +259,7 @@ FFZ.prototype.build_ui_popup = function(view) {
link.title = page.name;
link.innerHTML = page.icon;
jQuery(link).tipsy({gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
jQuery(link).zipsy({gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')});
link.addEventListener("click", this._ui_change_page.bind(this, view, inner, menu, sub_container, key));

View file

@ -76,7 +76,7 @@ FFZ.prototype._update_subscribers = function() {
});
cont.appendChild(stat);
jQuery(stat).tipsy({gravity: 's'});
jQuery(stat).zipsy({gravity: 's'});
}
el.textContent = utils.number_commas(sub_count);

View file

@ -9,14 +9,21 @@ var FFZ = window.FrankerFaceZ,
FFZ.prototype.fix_tooltips = function() {
// Add handlers to FFZ's tooltip classes.
jQuery(".html-tooltip").tipsy({live: true, html: true, gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
jQuery(".ffz-tooltip").tipsy({
jQuery(".html-tooltip").zipsy({
live: true,
html: true,
gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')
//gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')
});
jQuery(".ffz-tooltip").zipsy({
live: true,
html: true,
className: this.render_tooltip_class(),
title: this.render_tooltip(),
gravity: utils.tooltip_placement(2*constants.TOOLTIP_DISTANCE, 'n')});
gravity: utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')
//gravity: utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')
});
// First, override the tooltip mixin.
var TipsyTooltip = utils.ember_resolve('component:tipsy-tooltip');
@ -26,9 +33,9 @@ FFZ.prototype.fix_tooltips = function() {
didInsertElement: function() {
var gravity = this.get("gravity");
if ( ! gravity || typeof gravity === "string" )
gravity = utils.tooltip_placement(constants.TOOLTIP_DISTANCE, gravity || 's');
gravity = utils.newtip_placement(constants.TOOLTIP_DISTANCE, gravity || 's');
this.$().tipsy({
this.$().zipsy({
gravity: gravity
});
}
@ -44,6 +51,7 @@ FFZ.prototype.fix_tooltips = function() {
})
};
// Iterate all existing tipsy stuff~!
this.log('Fixing already existing tooltips.');
if ( ! window.jQuery || ! jQuery.cache )
@ -55,4 +63,351 @@ FFZ.prototype.fix_tooltips = function() {
obj.data.tipsy.options.gravity = utils.tooltip_placement(constants.TOOLTIP_DISTANCE, obj.data.tipsy.options.gravity || 's');
}
}
}
}
// ---------------------
// Zipsy!
// ---------------------
var zipsyIdcounter = 0;
function maybeCall(thing, ctx) {
return typeof thing === 'function' ? thing.apply(ctx, Array.prototype.slice.call(arguments, 2)) : thing;
}
function Zipsy(element, options) {
this.$element = jQuery(element);
this.options = options;
this.enabled = true;
this.fixTitle();
}
Zipsy.prototype = {
show: function() {
var j_el = this.$element,
el = j_el[0];
if ( ! this.enabled || ! document.contains(el) || ! j_el.is(':visible') )
return;
var title = this.getTitle(),
$tip = this.tip();
if ( ! title )
return;
$tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
$tip[0].className = 'zipsy tipsy';
if ( this.options.className )
$tip.addClass(maybeCall(this.options.className, el));
$tip.detach().css({
top: 0, left: 0,
width: '', height: '',
visibility: 'hidden',
display: 'block'
}).prependTo(this.options.prependTo).data('tipsy-pointee', el);
var pos;
if ( j_el.parents('svg').length > 0 )
pos = jQuery.extend({}, j_el.offset(), el.getBBox());
else if ( this.options.prependTo !== document.body )
pos = jQuery.extend(j_el.position(), {
width: j_el.width(),
height: j_el.height()
});
else
pos = jQuery.extend({}, j_el.offset(), {
width: el.offsetWidth || 0,
height: el.offsetHeight || 0
});
var bbox = $tip[0].getBoundingClientRect(),
actual_width = Math.ceil(bbox.width),
actual_height = Math.ceil(bbox.height),
gravity = maybeCall(this.options.gravity, el, bbox),
g1 = gravity.charAt(0),
g2 = gravity.length > 1 ? gravity.charAt(1) : 'c',
offset = maybeCall(this.options.offset, el),
tp = {};
if ( g1 === 'n' )
tp.top = pos.top + pos.height + offset;
else if ( g1 === 's' )
tp.top = pos.top - actual_height - offset;
else if ( g1 === 'e' )
tp.left = pos.left - actual_width - offset;
else if ( g1 === 'w' )
tp.left = pos.left + pos.width + offset;
if ( g1 === 'n' || g1 === 's' ) {
if ( g2 === 'c' )
tp.left = pos.left + pos.width / 2 - actual_width / 2;
else if ( g2 === 'e' )
tp.left = pos.left + pos.width - actual_width + 5;
else if ( g2 === 'w' )
tp.left = pos.left - 5;
} else if ( g1 === 'e' || g1 === 'w' ) {
if ( g2 === 'c' )
tp.top = pos.top + pos.height / 2 - actual_height / 2;
else if ( g2 === 'n' )
tp.top = pos.top - 5;
else if ( g2 === 's' )
tp.top = pos.top + pos.height - actual_height + 5;
}
$tip.css(tp).addClass('tipsy-' + gravity);
$tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
$tip.css({width: actual_width + 'px'});
var opacity = maybeCall(this.options.opacity, el);
if ( this.options.fade )
$tip.stop().css({
opacity: 0,
display: 'block',
visibility: 'hidden'
}).animate({
opacity: opacity
}, this.options.fadeInTime);
else
$tip.css({
visibility: 'visible',
opacity: opacity
});
if ( this.options.aria ) {
var tip_id = zipsyIdcounter++;
$tip.attr('id', tip_id);
j_el.attr('aria-describedby', tip_id);
}
},
hide: function() {
if ( this.options.fade )
this.tip().stop().fadeOut(this.options.fadeOutTime, function() { jQuery(this).detach() });
else
this.tip().detach();
if ( this.options.aria )
this.$element.removeAttr('aria-describedby');
},
fixTitle: function() {
var e = this.$element;
if ( e.attr('title') || typeof e.attr('original-title') !== 'string' )
e.attr('original-title', e.attr('title') || '').removeAttr('title');
},
getTitle: function() {
var e = this.$element,
title = this.options.title;
if ( title === 'title' ) {
this.fixTitle();
title = e.attr('original-title');
} else if ( typeof title === 'string' )
title = e.attr(title);
else if ( typeof title === 'function' )
title = title.call(e[0]);
else
title = '';
return (''+title).trim() || this.options.fallback;
},
tip: function() {
var t = this;
if ( ! this._tip )
this._tip = jQuery('<div class="zipsy tipsy" role="tooltip"><div class="tipsy-arrow"></div><div class="tipsy-inner"></div></div>');
this._tip
.off('mouseenter mouseleave')
.on('mouseenter', function() {
t.hoverState = 'in';
}).on('mouseleave', function() {
t.hoverState = 'out';
if ( t.options.delayOut === 0 )
t.hide();
else
setTimeout(function() {
if ( t.hoverState === 'out' || ! t.$element || ! t.$element.is(':visible') )
t.hide();
}, t.options.delayOut);
})
return this._tip;
},
validate: function() {
if ( ! this.$element[0].parentNode ) {
this.hide();
this.$element = null;
this.options = null;
this.enabled = false;
}
},
enable: function() {
this.enabled = true;
},
disable: function() {
this.enabled = false;
},
toggleEnabled: function() {
this.enabled = !this.enabled;
}
}
jQuery.fn.zipsy = function(options) {
jQuery.fn.zipsy.enable();
if ( options === true )
return this.data('tipsy');
else if ( typeof options === 'string' ) {
var tipsy = this.data('tipsy');
if ( tipsy )
tipsy[options]();
return this;
}
options = jQuery.extend({}, jQuery.fn.zipsy.defaults, options);
function get(el) {
var zipsy = jQuery.data(el, 'tipsy');
if ( ! zipsy ) {
zipsy = new Zipsy(el, jQuery.fn.zipsy.elementOptions(el, options));
jQuery.data(el, 'tipsy', zipsy);
}
return zipsy;
}
function enter() {
if ( ! jQuery.fn.zipsy.enabled )
return;
var zipsy = get(this);
zipsy.hoverState = 'in';
if ( options.delayIn === 0 )
zipsy.show();
else
setTimeout(function() {
if ( zipsy.hoverState === 'in' )
zipsy.show();
}, options.delayIn);
}
function leave() {
var zipsy = get(this);
zipsy.hoverState = 'out';
if ( options.delayOut === 0 )
zipsy.hide();
else
setTimeout(function() {
if ( zipsy.hoverState === 'out' || ! zipsy.$element || ! zipsy.$element.is(':visible') )
zipsy.hide();
}, options.delayOut);
}
if ( ! options.live )
this.each(function() { get(this) });
if ( options.trigger !== 'manual' ) {
var event_in = options.trigger === 'hover' ? 'mouseenter mouseover' : 'focus',
event_out = options.trigger === 'hover' ? 'mouseleave mouseout' : 'blur';
if ( options.live && options.live !== true ) {
jQuery(this).on(event_in, options.live, enter);
jQuery(this).on(event_out, options.live, leave);
} else if ( options.live ) {
jQuery(document.body).on(event_in, this.selector, enter);
jQuery(document.body).on(event_out, this.selector, leave);
} else {
var binder = options.live ? 'live' : 'bind';
this[binder](event_in, enter)[binder](event_out, leave);
}
}
return this;
}
jQuery.fn.zipsy.defaults = {
aria: false,
className: null,
delayIn: 0,
delayOut: 0,
fade: false,
fadeInTime: 400,
fadeOutTime: 400,
fallback: '',
gravity: 'n',
html: false,
live: false,
offset: 0,
opacity: 0.8,
title: 'title',
trigger: 'hover',
theme: '',
prependTo: document.body
};
jQuery.fn.zipsy.revalidate = function() {
jQuery('.tipsy').each(function() {
var t = jQuery.data(this, "tipsy-pointee");
(!t || !t[0] || !document.contains(t[0])) && jQuery(this).remove();
});
}
jQuery.fn.zipsy.clear = function() {
jQuery('.tipsy').remove();
}
jQuery.fn.zipsy.enable = function() {
jQuery.fn.zipsy.enabled = true;
}
jQuery.fn.zipsy.disable = function() {
jQuery.fn.zipsy.enabled = false;
}
jQuery.fn.zipsy.elementOptions = function(el, options) {
return options;
}
jQuery.fn.zipsy.autoNS = function() {
return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
}
jQuery.fn.zipsy.autoWE = function() {
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
}
jQuery.fn.zipsy.autoNWNE = function() {
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'ne' : 'nw';
}
jQuery.fn.zipsy.autoSWSE = function() {
return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'se' : 'sw';
}
jQuery.fn.zipsy.autoBounds = utils.newtip_placement;

View file

@ -66,6 +66,7 @@ FFZ.ws_commands.viewers = function(data) {
view_count.innerHTML = content;
parent.appendChild(view_count);
jQuery(view_count).tipsy({gravity: this.is_dashboard ? "s" : utils.tooltip_placement(constants.TOOLTIP_DISTANCE, 'n')});
jQuery(view_count).zipsy({
gravity: this.is_dashboard ? "s" : utils.newtip_placement(constants.TOOLTIP_DISTANCE, 'n')});
}
}

View file

@ -585,6 +585,7 @@ module.exports = FFZ.utils = {
transition_user: function(username) {
var Channel = ember_resolve('model:deprecated-channel');
ember_transition('channel.index', Channel.find({id: username}).load());
return false;
},
transition_link: function(callback) {
@ -881,7 +882,7 @@ module.exports = FFZ.utils = {
tooltip_placement: function(margin, prefer) {
return function() {
return function(box) {
var pref = prefer;
if ( typeof pref === "function" )
pref = pref.call(this);
@ -913,6 +914,42 @@ module.exports = FFZ.utils = {
}
},
newtip_placement: function(margin, prefer) {
return function(box) {
var pref = prefer;
if ( typeof pref === 'function' )
pref = pref.call(this);
var dir = {},
win = jQuery(window),
t = jQuery(this),
offset = t.offset(),
width = box.width,
height = box.height,
d_st = document.body.scrollTop,
d_sl = document.body.scrollLeft;
if ( pref.length > 1 ) {
dir.ns = pref[0];
dir.ew = pref[1];
} else if ( pref[0] === 'e' || pref[0] === 'w' )
dir.ew = pref[0];
else
dir.ns = pref[0];
if ( offset.top < d_st + margin ) dir.ns = 'n';
if ( offset.left < d_sl + margin ) dir.ew = 'w';
if ( win.width() + d_sl - (offset.left + width) < margin ) dir.ew = 'e';
if ( win.height() + d_st - (offset.top + height) < margin ) dir.ns = 's';
return (dir.ns ? dir.ns : '') + (dir.ew ? dir.ew : '');
}
},
uncompressBadges: uncompressBadges,
uncompressEmotes: uncompressEmotes,

View file

@ -1731,6 +1731,8 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator {
margin-left: 5px;
}
.ffz-wide-tip a b { color: #fff }
.ffz-wide-tip b { margin-right: 20px; }
.ffz-wide-tip span.stat svg {
@ -1786,14 +1788,20 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator {
.ffz-rich-tip .avatar {
float: left;
margin-right: 8px;
height: 48px;
width: 48px;
max-height: 48px;
max-width: 100px;
}
.ffz-rich-tip .tweet-heading .avatar {
border-radius: 50%;
}
.ffz-rich-tip .heading .title {
font-weight: bold;
display: block;
text-align: justify;
}
.ffz-rich-tip .display-name {
padding-top: 3px;
font-size: 14px;
@ -1811,7 +1819,7 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator {
font-size: 12px;
}
.ffz-rich-tip .twitch-heading .badge.verified {
.ffz-rich-tip .twitch-heading .tip-badge.verified {
height: 12px;
width: 12px;
margin: 2px 0 -1px 5px;
@ -1820,13 +1828,13 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator {
display: inline-block;
}
.ffz-rich-tip .twitch-heading .big-name .badge.verified {
.ffz-rich-tip .twitch-heading .big-name .tip-badge.verified {
height: 18px;
width: 18px;
margin: 1px 0 0 10px;
}
.ffz-rich-tip .tweet-heading .badge {
.ffz-rich-tip .tweet-heading .tip-badge {
height: 12px;
width: 12px;
margin: 2px 0 -1px 5px;
@ -1834,15 +1842,15 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator {
display: inline-block;
}
.ffz-rich-tip .badge.verified {
.ffz-rich-tip .tip-badge.verified {
background-position: 0 -15px;
}
.ffz-rich-tip .badge.translator {
.ffz-rich-tip .tip-badge.translator {
background-position: -12px -15px;
}
.ffz-rich-tip .badge.protected {
.ffz-rich-tip .tip-badge.protected {
background-position: -24px -15px;
width: 14px;
}
@ -1867,11 +1875,13 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator {
font-size: 10px;
}
.ffz-rich-tip .subtitle,
.ffz-rich-tip .quoted .body,
.ffz-rich-tip .stats,
.ffz-rich-tip .username { opacity: 0.6 }
.ffz-rich-tip .stats { display: flex }
.ffz-rich-tip .stats .wide-stat,
.ffz-rich-tip time { flex-grow: 1 }
.ffz-rich-tip .tweet-stats .stat:before {
@ -1894,13 +1904,41 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator {
.ffz-rich-tip .media { position: relative; text-align: center }
.ffz-rich-tip .media:not([data-count="1"]) {
.ffz-rich-tip .media[data-count]:not([data-count="1"]) {
display: flex;
margin: 8px -5px -5px 0;
flex-flow: column wrap;
height: 329px;
}
.ffz-rich-tip .media .duration {
position: absolute;
bottom: 0; right: 0;
margin: 4px;
background: #000;
opacity: .8;
padding: 2px 4px;
border-radius: 2px;
z-index: 10;
font-weight: 500;
}
.ffz-rich-tip .sixteen-nine {
width: 100%;
overflow: hidden;
margin: 0;
padding-top: 56.25%;
position: relative;
}
.ffz-rich-tip .sixteen-nine img {
position: absolute;
top: 50%;
left: 50%;
width: 100%;
transform: translate(-50%, -50%);
}
.ffz-rich-tip .media video {
width: 100%;
max-height: 324px;
@ -1911,7 +1949,7 @@ body:not(.ffz-bttv) .chat-container:not(.chatReplay) .more-messages-indicator {
.ffz-rich-tip .media[data-count="2"] { height: 164.5px }
.ffz-rich-tip .media img { max-height: 324px }
.ffz-rich-tip .quoted .media:not([data-count="1"]) { height: 150px }
.ffz-rich-tip .quoted .media[data-count]:not([data-count="1"]) { height: 150px }
.ffz-rich-tip .quoted .media[data-count="2"] { height: 150px }
.ffz-rich-tip .quoted .media video,
.ffz-rich-tip .quoted .media img { max-height: 150px }