1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-27 21:05:53 +00:00
* Added: Notice when FFZ fails to save settings because `localStorage` is full.
* Added: Setting to move "Chat Identity" from the chat input box to the chat settings menu. (Closes #1025)
* Fixed: Actually hide links when "Hide matching links for rich content." is enabled. (Closes #1019)
* Fixed: Open the control center when clicking a markdown settings link without the control center open.
* API Added: Toasts displayed by the `site.menu_button` module now support markdown.
This commit is contained in:
SirStendec 2021-04-19 15:08:12 -04:00
parent a80728a10d
commit 66702103ff
24 changed files with 303 additions and 190 deletions

View file

@ -773,6 +773,12 @@
"search": [
"threads"
]
},
{
"uid": "399ef63b1e23ab1b761dfbb5591fa4da",
"css": "right-open",
"code": 59462,
"src": "fontawesome"
}
]
}

View file

@ -1,7 +1,7 @@
{
"name": "frankerfacez",
"author": "Dan Salvato LLC",
"version": "4.20.90",
"version": "4.20.91",
"description": "FrankerFaceZ is a Twitch enhancement suite.",
"private": true,
"license": "Apache-2.0",

Binary file not shown.

View file

@ -1,7 +1,7 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Copyright (C) 2020 by original authors @ fontello.com</metadata>
<metadata>Copyright (C) 2021 by original authors @ fontello.com</metadata>
<defs>
<font id="ffz-fontello" horiz-adv-x="1000" >
<font-face font-family="ffz-fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
@ -146,6 +146,8 @@
<glyph glyph-name="volume-off" unicode="&#xe845;" d="M0 551l305 0 345 282 0-965-345 279-229 0z m713-283q0 4 2 6l76 76-76 76q-2 2-2 6t2 6l53 53q2 2 5 2t6-2l76-76 77 76q4 2 6 2t5-2l55-53q2-2 2-6t-2-6l-76-76 76-76q2-4 2-7t-2-5l-55-54q-2-2-5-2t-6 2l-77 78-76-78q-2-2-5-2t-6 2l-53 54q-2 2-2 6z" horiz-adv-x="1000" />
<glyph glyph-name="right-open" unicode="&#xe846;" d="M618 361l-414-415q-11-10-25-10t-25 10l-93 93q-11 11-11 25t11 25l296 297-296 296q-11 11-11 25t11 25l93 93q10 11 25 11t25-11l414-414q10-11 10-25t-10-25z" horiz-adv-x="714.3" />
<glyph glyph-name="move" unicode="&#xf047;" d="M1000 350q0-14-11-25l-142-143q-11-11-26-11t-25 11-10 25v72h-215v-215h72q14 0 25-10t11-25-11-25l-143-143q-10-11-25-11t-25 11l-143 143q-11 10-11 25t11 25 25 10h72v215h-215v-72q0-14-10-25t-25-11-25 11l-143 143q-11 11-11 25t11 25l143 143q10 11 25 11t25-11 10-25v-72h215v215h-72q-14 0-25 10t-11 25 11 26l143 142q11 11 25 11t25-11l143-142q11-11 11-26t-11-25-25-10h-72v-215h215v72q0 14 10 25t25 11 26-11l142-143q11-10 11-25z" horiz-adv-x="1000" />
<glyph glyph-name="link-ext" unicode="&#xf08e;" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" />

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Before After
Before After

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -558,7 +558,7 @@ export default class Badges extends Module {
}
render(msg, createElement, skip_hide = false) { // eslint-disable-line class-methods-use-this
render(msg, createElement, skip_hide = false, skip_click = false) { // eslint-disable-line class-methods-use-this
if ( ! msg.badges && ! msg.ffz_badges )
return null;
@ -769,7 +769,8 @@ export default class Badges extends Module {
props['data-tooltip-type'] = 'badge';
props['data-badge-data'] = JSON.stringify(data.badges);
props.onClick = this.handleClick;
if ( ! skip_click )
props.onClick = this.handleClick;
if ( data.replaced )
props['data-replaced'] = data.replaced;

View file

@ -206,7 +206,7 @@ export default class Chat extends Module {
});
this.settings.add('chat.rich.hide-tokens', {
default: true,
default: false,
ui: {
path: 'Chat > Appearance >> Rich Content',
title: 'Hide matching links for rich content.',
@ -262,6 +262,13 @@ export default class Chat extends Module {
}
});
this.settings.addUI('chat.filtering.pad-bottom', {
path: 'Chat > Filtering > Highlight',
sort: 1000,
component: 'setting-spacer',
top: '30rem'
});
this.settings.add('chat.filtering.click-to-reveal', {
default: false,
ui: {
@ -1694,7 +1701,7 @@ export default class Chat extends Module {
for(const token of tokens) {
for(const provider of providers)
if ( provider.test.call(this, token, msg) ) {
token.hidden = this.context.get('chat.rich.hide-tokens') && provider.hide_token;
token.hidden = provider.can_hide_token && (this.context.get('chat.rich.hide-tokens') || provider.hide_token);
return provider.process.call(this, token);
}
}

View file

@ -28,7 +28,7 @@ import {truncate} from 'utilities/object';
export const Links = {
type: 'link',
hide_token: false,
can_hide_token: true,
priority: -10,
test(token) {
@ -77,7 +77,7 @@ export const Links = {
export const Users = {
type: 'user',
hide_token: false,
can_hide_token: true,
test(token) {
if ( token.type !== 'link' || (! this.context.get('chat.rich.all-links') && ! token.force_rich) )
@ -190,7 +190,7 @@ export const Users = {
export const Clips = {
type: 'clip',
hide_token: false,
can_hide_token: true,
test(token) {
if ( token.type !== 'link' )
@ -278,7 +278,7 @@ export const Clips = {
export const Videos = {
type: 'video',
hide_token: false,
can_hide_token: true,
test(token) {
return token.type === 'link' && VIDEO_URL.test(token.url)

View file

@ -298,6 +298,9 @@ export default class MainMenu extends Module {
return;
this.requestPage(path);
if ( ! this.showing )
this.emit('site.menu_button:clicked');
}

View file

@ -99,6 +99,9 @@ export default class SettingsManager extends Module {
this.provider = provider;
this.log.info(`Using Provider: ${provider.constructor.name}`);
provider.on('changed', this._onProviderChange, this);
provider.on('quota-exceeded', err => {
this.emit(':quota-exceeded', err);
});
provider.on('change-provider', () => {
this.emit(':change-provider');
});

View file

@ -262,7 +262,18 @@ export class LocalStorageProvider extends SettingsProvider {
}
this._cached.set(key, value);
localStorage.setItem(this.prefix + key, JSON.stringify(value));
try {
localStorage.setItem(this.prefix + key, JSON.stringify(value));
} catch(err) {
if ( this.manager )
this.manager.log.error(`An error occurred while trying to save a value to localStorage for key "${this.prefix + key}"`);
if ( /quota/i.test(err.toString()) )
this.emit('quota-exceeded', err);
throw err;
}
this.broadcast({type: 'set', key});
this.emit('set', key, value, false);
}

View file

@ -18,6 +18,16 @@ export default class SettingsMenu extends Module {
this.inject('chat.badges');
this.inject('site.fine');
this.inject('site.web_munch');
this.inject('site.css_tweaks');
this.settings.add('chat.input.hide-identity', {
default: false,
ui: {
path: 'Chat > Input >> Appearance',
title: 'Display "Chat Identity" in the chat settings menu rather than the input box.',
component: 'setting-check-box'
}
});
this.SettingsMenu = this.fine.define(
'chat-settings',
@ -35,6 +45,12 @@ export default class SettingsMenu extends Module {
async onEnable() {
this.on('i18n:update', () => this.SettingsMenu.forceUpdate());
this.chat.context.on('changed:chat.scroller.freeze', () => this.SettingsMenu.forceUpdate());
this.chat.context.on('changed:chat.input.hide-identity', val => {
this.css_tweaks.toggle('hide-chat-identity', val);
this.SettingsMenu.forceUpdate();
});
this.css_tweaks.toggle('hide-chat-identity', this.chat.context.get('chat.input.hide-identity'));
const t = this,
React = await this.web_munch.findModule('react');
@ -101,71 +117,87 @@ export default class SettingsMenu extends Module {
return val;
}
cls.prototype.render = function() {
try {
if ( this.state.ffzPauseMenu ) {
if ( ! this.ffzSettingsClick )
this.ffzSettingsClick = e => t.click(this, e);
cls.prototype.ffzRenderIdentity = function() {
if ( ! this.state || ! this.props || this.state.moderatorMode || this.state.chatAppearance || this.state.chatPause || this.state.followerMode || this.state.recentRaids || this.state.repliesAppearance || this.state.slowMode || this.props.isShowingChatFilterSettings || this.props.isShowingDeletedMessageDisplaySettings || ! this.props.isLoggedIn || ! this.props.onClickEditAppearance )
return null;
if ( ! this.ffzPauseClick )
this.ffzPauseClick = () => this.setState({ffzPauseMenu: ! this.state.ffzPauseMenu});
if ( ! t.chat.context.get('chat.input.hide-identity') )
return null;
return (<div class="tw-absolute ffz-balloon ffz-balloon--auto ffz-balloon--right ffz-balloon--up tw-block" data-a-target="chat-settings-balloon" style={{marginRight: '-5.3rem'}}>
<div class="tw-border-radius-large tw-c-background-base tw-c-text-inherit tw-elevation-2">
<div class="chat-settings__popover">
<div class="chat-settings__header tw-align-items-center tw-c-background-base tw-flex tw-pd-x-1 tw-relative">
<div class="chat-settings__back-icon-container tw-left-0 tw-mg-r-05">
<button
class="tw-align-items-center tw-align-middle tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-border-top-left-radius-medium tw-border-top-right-radius-medium tw-button-icon ffz-core-button ffz-core-button--border tw-inline-flex tw-interactive tw-justify-content-center tw-overflow-hidden tw-relative"
data-test-selector="chat-settings-back-button"
aria-label={t.i18n.t('chat.settings.back', 'Back')}
onClick={this.ffzPauseClick}
>
<div class="tw-align-items-center tw-flex tw-flex-grow-0">
<span class="tw-button-icon__icon">
<figure class="ffz-i-left-open" />
</span>
</div>
</button>
</div>
<div class="tw-align-center tw-align-items-center tw-flex tw-flex-grow-1 tw-justify-content-center">
<p class="tw-c-text-alt tw-font-size-5 tw-semibold">
{ t.i18n.t('chat.settings.pause', 'Pause Chat') }
</p>
</div>
</div>
<div class="chat-settings scrollable-area scrollable-area--suppress-scroll-x" data-simplebar>
<div class="chat-settings__content tw-border-bottom-left-radius-medium tw-border-bottom-right-radius-medium tw-c-background-base tw-c-text-base tw-pd-1">
<div class="tw-pd-x-05">
<div class="tw-border-b tw-mg-b-1 tw-pd-b-1">
<p class="tw-c-text-alt-2">
{ t.i18n.t('chat.settings.pause-explain', 'FrankerFaceZ overrides the behavior of Pause Chat entirely. Please use FFZ\'s Scrolling settings within the FFZ Control Center under Chat > Behavior.') }
</p>
</div>
<button
class="tw-block tw-border-radius-medium tw-full-width ffz-interactable ffz-interactable--hover-enabled ffz-interactable--default tw-interactive"
data-page="chat.behavior"
onClick={this.ffzSettingsClick}
>
<div class="tw-align-items-center tw-flex tw-pd-05 tw-relative">
<div class="tw-flex-grow-1">
{t.i18n.t('chat.settings.open-settings', 'Open Control Center')}
</div>
</div>
</button>
</div>
</div>
</div>
const user = this.props.data?.currentUser,
raw_badges = this.props.data?.user?.self?.displayBadges;
if ( ! user || ! user.login || ! Array.isArray(raw_badges) )
return null;
const is_intl = user.login && user.displayName && user.displayName.trim().toLowerCase() !== user.login,
color = t.parent.colors.process(user.chatColor),
badges = {};
for(const badge of raw_badges) {
if ( badge?.setID && badge.version )
badges[badge.setID] = badge.version;
}
return (<div class="ffz-identity">
<div class="tw-mg-y-05 tw-pd-x-05">
<p class="tw-c-text-alt-2 tw-font-size-6 tw-strong tw-upcase">
{ t.i18n.t('chat.identity-menu', 'Chat Identity') }
</p>
</div>
<div class="tw-full-width tw-relative">
<button
class="tw-block tw-border-radius-medium tw-full-width ffz-interactable ffz-interactable--hover-enabled ffz-interactable--default tw-interactive"
onClick={this.props.onClickEditAppearance}
>
<div class="tw-align-items-center tw-flex tw-pd-05 tw-relative">
<div class="tw-flex-grow-1">
<span class="ffz--editor-name">
<span
class="ffz--editor-badges"
data-room-id={this.props.channelID}
data-room-login={this.props.channelLogin}
>
{t.badges.render({
user,
badges,
ffz_badges: t.badges.getBadges(user.id, user.login, this.props.channelID, this.props.channelLogin),
roomID: this.props.channelID,
roomLogin: this.props.channelLogin
}, createElement, true, true)}
</span>
<span class="tw-strong notranslate" style={{color}}>
<span class="name-display__name">{ user.displayName || user.login}</span>
{is_intl && <span class="intl-name"> ({user.login}) </span>}
</span>
</span>
</div>
<div class="tw-align-items-center tw-flex tw-flex-shrink-0 tw-mg-l-05">
<figure class="ffz-i-right-open" />
</div>
</div>
</div>)
</button>
</div>
</div>);
}
cls.prototype.render = function() {
const out = old_render.call(this);
try {
const children = out?.props?.children?.props?.children?.[1]?.props?.children?.props?.children;
if ( Array.isArray(children) ) {
const extra = this.ffzRenderIdentity();
if ( extra )
children.unshift(extra);
}
} catch(err) {
t.log.error('Error rendering chat settings menu.', err);
}
return old_render.call(this);
return out;
}
this.SettingsMenu.forceUpdate();
@ -228,9 +260,10 @@ export default class SettingsMenu extends Module {
}, this.badges.render({
user,
badges,
ffz_badges: this.badges.getBadges(user.id, user.login, inst.props.channelID, inst.props.channelLogin),
roomID: inst.props.channelID,
roomLogin: inst.props.channelLogin
}, createElement, true)),
}, createElement, true, true)),
<span class="tw-strong notranslate" style={{color}}>
<span class="name-display__name">{user.displayName || user.login}</span>
@ -292,17 +325,25 @@ export default class SettingsMenu extends Module {
} else if ( ! badge )
return;
cont.appendChild(<div class="ffz--badge-selector">
<p class="tw-pd-x-05">
{this.i18n.tList('chat.ffz-badge.about', '{title}: This badge appears globally for users with FrankerFaceZ.', {
title: <span class="tw-strong">{this.i18n.t('chat.ffz-badge.title', 'FrankerFaceZ Badge')}</span>
})}{' '}
{this.i18n.tList('chat.ffz-badge.site', 'Please visit the {website} to change this badge.', {
website: (<a href="https://www.frankerfacez.com/donate" class="ffz-link" rel="noopener noreferrer" target="_blank">
{this.i18n.t('chat.ffz-badge.site-link', 'FrankerFaceZ website')}
</a>)
})}
</p>
const out = (<div class="ffz--badge-selector tw-border-b tw-mg-b-1">
<div class="tw-mg-y-05 tw-pd-x-05">
<p class="tw-c-text-alt-2 tw-font-size-6 tw-strong tw-upcase">
{ this.i18n.t('chat.ffz-badge.title', 'FrankerFaceZ Badge') }
</p>
</div>
<div>
<p class="tw-mg-b-05 tw-pd-x-05">
{ this.i18n.tList(
'chat.ffz-badge.about',
'This badge appears globally for users with FrankerFaceZ. Please visit the {website} to change this badge.',
{
website: (<a href="https://www.frankerfacez.com/donate" class="ffz-link" rel="noopener noreferrer" target="_blank">
{this.i18n.t('chat.ffz-badge.site-link', 'FrankerFaceZ website')}
</a>)
}
) }
</p>
</div>
<div role="radiogroup" class="tw-align-items-center tw-flex tw-flex-wrap tw-mg-b-05 tw-mg-t-05 tw-pd-x-05">
<div class="tw-mg-r-1 tw-mg-y-05">
<div class="tw-inline-flex">
@ -321,6 +362,12 @@ export default class SettingsMenu extends Module {
</div>
</div>
</div>);
const after = cont.querySelector('[data-test-selector="global-badges-test-selector"]')?.nextElementSibling;
if ( after )
cont.insertBefore(out, after);
else
cont.appendChild(out);
}

View file

@ -0,0 +1,7 @@
.chat-input__badge-carousel {
display: none !important;
}
.chat-input__textarea .tw-textarea {
padding-left: 1rem !important;
}

View file

@ -9,6 +9,7 @@ import {SiteModule} from 'utilities/module';
import {createElement, ClickOutside, setChildren} from 'utilities/dom';
import Twilight from 'site';
import getMD from 'src/utilities/markdown';
export default class MenuButton extends SiteModule {
@ -257,6 +258,17 @@ export default class MenuButton extends SiteModule {
this.on('i18n:changed-strings', this.update);
this.on('i18n:update', this.update);
this.on('addons:data-loaded', this.update);
this.once('settings:quota-exceeded', () => {
this.addError(
'site.menu_button.quota-exceeded',
'Your local storage space for this website is full, and settings cannot be saved. Please backup your settings and switch to a higher capacity provider in [Data Management > Storage >> Provider](~data_management.storage.tabs.provider).',
'ffz-i-attention',
true
);
this.update();
});
this.on('settings:change-provider', () => {
this.addError('site.menu_button.changed',
'The FrankerFaceZ settings provider has changed. Please refresh this tab to avoid strange behavior.'
@ -266,11 +278,12 @@ export default class MenuButton extends SiteModule {
}
addError(i18n, text, icon = 'ffz-i-attention') {
addError(i18n, text, icon = 'ffz-i-attention', use_markdown = false) {
this.addToast({
icon,
text_i18n: i18n,
text
text,
markdown: use_markdown
});
}
@ -425,7 +438,8 @@ export default class MenuButton extends SiteModule {
{ data.title_i18n ? this.i18n.tList(data.title_i18n, data.title, data) : data.title}
</header>) : null }
{ data.text ? (<span class={`${data.lines ? 'ffz--line-clamp' : ''}`} style={{'--ffz-lines': data.lines}}>
{ data.text_i18n ? this.i18n.tList(data.text_i18n, data.text, data) : data.text}
{ data.markdown ? <span dangerouslySetInnerHTML={{__html: getMD().render(data.text_i18n ? this.i18n.t(data.text_i18n, data.text, data) : data.text) }} /> : null}
{ data.markdown ? null : (data.text_i18n ? this.i18n.tList(data.text_i18n, data.text, data) : data.text)}
</span>) : null }
</div>) : null}
{ ! data.unclosable && (<button

View file

@ -5,101 +5,7 @@
<script>
import MD from 'markdown-it';
import MILA from 'markdown-it-link-attributes';
import {parse as parse_path} from 'utilities/path-parser';
let _md;
function getMD() {
if ( ! _md ) {
const md = _md = new MD({
html: false,
linkify: true
});
md.use(SettingsLinks);
md.use(MILA, {
attrs: {
class: 'ffz-tooltip',
target: '_blank',
rel: 'noopener',
'data-tooltip-type': 'link'
}
});
}
return _md;
}
function SettingsLinks(md) {
const default_render = md.renderer.rules.link_open || this.defaultRender;
md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
const token = tokens[idx];
if ( token && token.type === 'link_open' && Array.isArray(token.attrs) ) {
let href;
for(const attr of token.attrs) {
if ( attr[0] === 'href' ) {
href = attr[1];
break;
}
}
if ( href.startsWith('~') ) {
let path;
if ( href === '~' ) {
// We don't have a path, make one from the bits.
let i = idx + 1;
let bits = [];
while(i < tokens.length) {
const tok = tokens[i],
type = tok?.type;
if ( type === 'text' )
bits.push(tok);
else if ( type === 'link_close' )
break;
i++;
}
bits = bits.map(x => x.content).join('');
const toks = parse_path(bits);
path = toks.map(x => x.key).join('.');
} else
path = href.slice(1);
if ( path && path.length ) {
for(const attr of token.attrs) {
if ( attr[0] === 'class' ) {
attr[1] = attr[1].replace(/ffz-tooltip/g, '');
break;
}
}
token.attrs.push([
'data-settings-link',
path
]);
token.attrs.push([
'onclick',
'FrankerFaceZ.get().resolve("main_menu").mdNavigate(this);return false'
]);
}
}
}
return default_render(tokens, idx, options, env, self);
}
}
SettingsLinks.defaultRender = function(tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options);
}
import getMD from 'utilities/markdown';
export default {
props: {

View file

@ -102,5 +102,6 @@ export default [
"link",
"volume-off",
"reply",
"threads"
"threads",
"right-open"
];

96
src/utilities/markdown.js Normal file
View file

@ -0,0 +1,96 @@
'use strict';
import MD from 'markdown-it';
import MILA from 'markdown-it-link-attributes';
import {parse as parse_path} from 'utilities/path-parser';
let _md;
function SettingsLinks(md) {
const default_render = md.renderer.rules.link_open || this.defaultRender;
md.renderer.rules.link_open = function(tokens, idx, options, env, self) {
const token = tokens[idx];
if ( token && token.type === 'link_open' && Array.isArray(token.attrs) ) {
let href;
for(const attr of token.attrs) {
if ( attr[0] === 'href' ) {
href = attr[1];
break;
}
}
if ( href.startsWith('~') ) {
let path;
if ( href === '~' ) {
// We don't have a path, make one from the bits.
let i = idx + 1;
let bits = [];
while(i < tokens.length) {
const tok = tokens[i],
type = tok?.type;
if ( type === 'text' )
bits.push(tok);
else if ( type === 'link_close' )
break;
i++;
}
bits = bits.map(x => x.content).join('');
const toks = parse_path(bits);
path = toks.map(x => x.key).join('.');
} else
path = href.slice(1);
if ( path && path.length ) {
for(const attr of token.attrs) {
if ( attr[0] === 'class' ) {
attr[1] = attr[1].replace(/ffz-tooltip/g, '');
break;
}
}
token.attrs.push([
'data-settings-link',
path
]);
token.attrs.push([
'onclick',
'FrankerFaceZ.get().resolve("main_menu").mdNavigate(this);return false'
]);
}
}
}
return default_render(tokens, idx, options, env, self);
}
}
SettingsLinks.defaultRender = function(tokens, idx, options, env, self) {
return self.renderToken(tokens, idx, options);
}
export default function getMD() {
if ( ! _md ) {
const md = _md = new MD({
html: false,
linkify: true
});
md.use(SettingsLinks);
md.use(MILA, {
attrs: {
class: 'ffz-tooltip',
target: '_blank',
rel: 'noopener',
'data-tooltip-type': 'link'
}
});
}
return _md;
}

View file

@ -69,6 +69,7 @@
.ffz-i-link:before { content: '\e843'; } /* '' */
.ffz-i-threads:before { content: '\e844'; } /* '' */
.ffz-i-volume-off:before { content: '\e845'; } /* '' */
.ffz-i-right-open:before { content: '\e846'; } /* '' */
.ffz-i-move:before { content: '\f047'; } /* '' */
.ffz-i-link-ext:before { content: '\f08e'; } /* '' */
.ffz-i-twitter:before { content: '\f099'; } /* '' */

File diff suppressed because one or more lines are too long

View file

@ -69,6 +69,7 @@
.ffz-i-link { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe843;&nbsp;'); }
.ffz-i-threads { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe844;&nbsp;'); }
.ffz-i-volume-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe845;&nbsp;'); }
.ffz-i-right-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe846;&nbsp;'); }
.ffz-i-move { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf047;&nbsp;'); }
.ffz-i-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08e;&nbsp;'); }
.ffz-i-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf099;&nbsp;'); }

View file

@ -80,6 +80,7 @@
.ffz-i-link { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe843;&nbsp;'); }
.ffz-i-threads { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe844;&nbsp;'); }
.ffz-i-volume-off { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe845;&nbsp;'); }
.ffz-i-right-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe846;&nbsp;'); }
.ffz-i-move { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf047;&nbsp;'); }
.ffz-i-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf08e;&nbsp;'); }
.ffz-i-twitter { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xf099;&nbsp;'); }

View file

@ -1,11 +1,11 @@
@font-face {
font-family: 'ffz-fontello';
src: url('../font/ffz-fontello.eot?89863637');
src: url('../font/ffz-fontello.eot?89863637#iefix') format('embedded-opentype'),
url('../font/ffz-fontello.woff2?89863637') format('woff2'),
url('../font/ffz-fontello.woff?89863637') format('woff'),
url('../font/ffz-fontello.ttf?89863637') format('truetype'),
url('../font/ffz-fontello.svg?89863637#ffz-fontello') format('svg');
src: url('../font/ffz-fontello.eot?52570921');
src: url('../font/ffz-fontello.eot?52570921#iefix') format('embedded-opentype'),
url('../font/ffz-fontello.woff2?52570921') format('woff2'),
url('../font/ffz-fontello.woff?52570921') format('woff'),
url('../font/ffz-fontello.ttf?52570921') format('truetype'),
url('../font/ffz-fontello.svg?52570921#ffz-fontello') format('svg');
font-weight: normal;
font-style: normal;
}
@ -15,7 +15,7 @@
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'ffz-fontello';
src: url('../font/ffz-fontello.svg?89863637#ffz-fontello') format('svg');
src: url('../font/ffz-fontello.svg?52570921#ffz-fontello') format('svg');
}
}
*/
@ -125,6 +125,7 @@
.ffz-i-link:before { content: '\e843'; } /* '' */
.ffz-i-threads:before { content: '\e844'; } /* '' */
.ffz-i-volume-off:before { content: '\e845'; } /* '' */
.ffz-i-right-open:before { content: '\e846'; } /* '' */
.ffz-i-move:before { content: '\f047'; } /* '' */
.ffz-i-link-ext:before { content: '\f08e'; } /* '' */
.ffz-i-twitter:before { content: '\f099'; } /* '' */