More fine tuning of various visuals

Summarily:
- Bring back horizontal layout for fenix popup panel
  to be used in desktop environment
- Address feedback from
  https://github.com/gorhill/uBlock/commit/54b68ebd9426#commitcomment-38549940
- Allow future dark theme to be enabled programmatically
This commit is contained in:
Raymond Hill 2020-04-18 09:48:53 -04:00
parent d95b27915f
commit 21d7c7ee3d
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
9 changed files with 224 additions and 172 deletions

View File

@ -182,22 +182,25 @@ body.updating .listEntry.checked.obsolete .updating {
visibility: visible;
}
@media (pointer: coarse) {
.listEntries {
/* touch-screen devices */
:root.mobile .listEntry .fa-icon {
font-size: 120%;
margin: 0 0.5em 0 0;
}
:root.mobile .listEntries {
margin-inline-start: 0;
-webkit-margin-start: 0;
}
.li.listEntry {
:root.mobile .li.listEntry {
background-color: var(--bg-1);
overflow-x: auto;
}
.li.listEntry label > span {
:root.mobile .li.listEntry label > span {
flex-grow: 1;
padding-inline-start: 0.3em;
}
.li.listEntry .listname,
.li.listEntry .iconbar,
.li.listEntry.checked .counts {
:root.mobile .li.listEntry .listname,
:root.mobile .li.listEntry .iconbar,
:root.mobile .li.listEntry.checked .counts {
display: block;
}
}

View File

@ -1,17 +1,10 @@
body {
font: 14px/1.5 sans-serif;
}
@media (pointer: coarse) {
body {
font: 16px/1.5 sans-serif;
}
}
body {
background-color: var(--bg-0);
border: 0;
box-sizing: border-box;
color: var(--fg-0);
fill: var(--fg-0);
font: 14px/1.5 sans-serif;
margin: 0;
padding: 0;
}
@ -94,11 +87,6 @@ label {
align-items: center;
display: inline-flex;
}
@media (pointer: coarse) {
label {
flex-grow: 1
}
}
input[type="checkbox"] {
margin: 0;
margin-inline-start: 0.4em;
@ -156,3 +144,11 @@ input[type="checkbox"] {
height: 1em;
width: 1em;
}
/* touch-screen devices */
:root.mobile body {
font: 16px/1.5 sans-serif;
}
:root.mobile label {
flex-grow: 1
}

View File

@ -23,7 +23,7 @@ a {
.fa-icon.info {
color: var(--fg-icon-info-lvl-0-dimmed);
fill: var(--fg-icon-info-lvl-0-dimmed);
font-size: 120%;
font-size: 115%;
}
.fa.info:hover,
.fa-icon.info:hover {

View File

@ -76,12 +76,11 @@ body:not(.canUpdateShortcuts) .tabButton[data-pane="shortcuts.html"] {
display: none;
}
@media (pointer: coarse) {
#dashboard-nav {
/* touch-screen devices */
:root.mobile #dashboard-nav {
flex-wrap: nowrap;
overflow-x: auto;
}
#dashboard-nav .logo {
:root.mobile #dashboard-nav .logo {
display: none;
}
}

View File

@ -10,15 +10,8 @@
/* Internal CSS values */
body {
font: 14px/20px sans-serif;
min-width: 360px;
white-space: nowrap;
}
@media (pointer: coarse) {
body {
min-width: unset;
width: 100%;
}
}
a {
color: inherit;
text-decoration: none;
@ -27,7 +20,7 @@ a {
outline: 0;
}
#main {
#panes {
align-items: stretch;
display: flex;
flex-direction: column;
@ -109,20 +102,20 @@ body.needSave #revertRules {
.itemRibbon {
display: grid;
gap: 0.8em 1em;
grid-template: auto / auto auto;
padding: 1em 1em;
}
.itemRibbon > [data-i18n] + span {
justify-self: end;
text-align: end;
white-space: nowrap;
}
.itemRibbon > .h-gutter {
display: inline-block;
height: 1em;
}
#basicStats {
}
.toolRibbon {
align-items: start;
display: grid;
@ -173,7 +166,7 @@ body.needSave #revertRules {
visibility: visible;
}
#main:not(.dfEnabled) #moreButton .fa-icon {
body:not(.dfEnabled) #moreButton .fa-icon {
transform: rotate(180deg);
}
@ -210,7 +203,7 @@ body[dir="rtl"] #tooltip {
opacity: 1;
}
#firewallContainer {
#firewall {
border: 0;
flex-shrink: 0;
font-family: "Noto Sans", sans-serif;
@ -220,10 +213,10 @@ body[dir="rtl"] #tooltip {
overflow: hidden;
text-align: right;
}
#main:not(.dfEnabled) #firewallContainer {
body:not(.dfEnabled) #firewall {
display: none;
}
#firewallContainer > div {
#firewall > div {
border: 0;
direction: ltr;
display: flex;
@ -232,17 +225,17 @@ body[dir="rtl"] #tooltip {
margin-top: 1px;
padding: 0;
}
#firewallContainer > div:first-child {
#firewall > div:first-child {
margin-top: 0;
}
#firewallContainer > div:first-child ~ div[data-des="*"] {
#firewall > div:first-child ~ div[data-des="*"] {
display: none;
}
#firewallContainer:not(.expanded) > div.isSubDomain:not(.expandException):not(.isRootContext),
#firewallContainer.expanded > div.isSubDomain.expandException:not(.isRootContext) {
#firewall:not(.expanded) > div.isSubDomain:not(.expandException):not(.isRootContext),
#firewall.expanded > div.isSubDomain.expandException:not(.isRootContext) {
display: none;
}
#firewallContainer > div > span {
#firewall > div > span {
background-color: var(--bg-popup-cell-2);
border: none;
box-sizing: border-box;
@ -251,11 +244,11 @@ body[dir="rtl"] #tooltip {
padding: 0.4em 0;
position: relative;
}
#firewallContainer > div:first-of-type > span:first-of-type {
#firewall > div:first-of-type > span:first-of-type {
cursor: pointer;
flex-direction: unset;
}
#firewallContainer > div > span:first-of-type {
#firewall > div > span:first-of-type {
align-items: flex-end;
flex-direction: column;
flex-grow: 1;
@ -265,116 +258,116 @@ body[dir="rtl"] #tooltip {
width: calc(100% - 5em);
word-break: break-word;
}
#firewallContainer > div.isCname > span:first-of-type {
#firewall > div.isCname > span:first-of-type {
color: var(--fg-popup-cell-cname);
}
#firewallContainer > div > span:first-of-type > sub {
#firewall > div > span:first-of-type > sub {
display: inline-block;
font-size: 85%;
font-weight: normal;
padding: 0.25em 0 0 0;
}
#firewallContainer > div > span:first-of-type > sub:empty {
#firewall > div > span:first-of-type > sub:empty {
display: none;
}
#firewallContainer > div > span:first-of-type ~ span {
#firewall > div > span:first-of-type ~ span {
flex-shrink: 0;
margin-left: 1px;
width: 5em;
}
#firewallContainer > div > span:nth-of-type(2) {
#firewall > div > span:nth-of-type(2) {
display: none;
}
#firewallContainer > div > span:nth-of-type(3),
#firewallContainer > div > span:nth-of-type(4) {
#firewall > div > span:nth-of-type(3),
#firewall > div > span:nth-of-type(4) {
color: var(--fg-0-70);
display: none;
font-family: monospace;
text-align: center;
}
#firewallContainer > div.isDomain > span:first-of-type {
#firewall > div.isDomain > span:first-of-type {
font-weight: bold;
}
#firewallContainer > div:first-of-type > span:first-of-type::before {
#firewall > div:first-of-type > span:first-of-type::before {
color: var(--fg-0-50);
content: '+';
padding-right: 0.25em;
}
#firewallContainer.expanded > div:first-of-type > span:first-of-type::before {
#firewall.expanded > div:first-of-type > span:first-of-type::before {
content: '\2012';
}
#firewallContainer > div[data-des="*"] > span:nth-of-type(3),
#firewallContainer > div.isSubDomain > span:nth-of-type(3),
#firewallContainer > div.isSubDomain.isRootContext > span:nth-of-type(3),
#firewallContainer.expanded > div:not(.expandException) > span:nth-of-type(3),
#firewallContainer:not(.expanded) > div.expandException > span:nth-of-type(3),
#firewallContainer:not(.expanded) > div.isDomain:not(.expandException) > span:nth-of-type(4),
#firewallContainer.expanded > div.isDomain.expandException > span:nth-of-type(4) {
#firewall > div[data-des="*"] > span:nth-of-type(3),
#firewall > div.isSubDomain > span:nth-of-type(3),
#firewall > div.isSubDomain.isRootContext > span:nth-of-type(3),
#firewall.expanded > div:not(.expandException) > span:nth-of-type(3),
#firewall:not(.expanded) > div.expandException > span:nth-of-type(3),
#firewall:not(.expanded) > div.isDomain:not(.expandException) > span:nth-of-type(4),
#firewall.expanded > div.isDomain.expandException > span:nth-of-type(4) {
display: inline-flex;
justify-content: space-between;
}
#firewallContainer > div > span[data-acount]::before,
#firewallContainer > div > span[data-bcount]::after,
#firewallContainer > div > span[data-acount] > #actionSelector > #dynaCounts::before,
#firewallContainer > div > span[data-acount] > #actionSelector > #dynaCounts::after {
#firewall > div > span[data-acount]::before,
#firewall > div > span[data-bcount]::after,
#firewall > div > span[data-acount] > #actionSelector > #dynaCounts::before,
#firewall > div > span[data-acount] > #actionSelector > #dynaCounts::after {
content: ' ';
}
#firewallContainer > div > span[data-acount]::before,
#firewallContainer > div > span[data-acount] > #actionSelector > #dynaCounts::before {
#firewall > div > span[data-acount]::before,
#firewall > div > span[data-acount] > #actionSelector > #dynaCounts::before {
padding-left: 0.1em;
}
#firewallContainer > div > span[data-acount="1"]::before,
#firewallContainer > div > span[data-acount="1"] > #actionSelector > #dynaCounts::before {
#firewall > div > span[data-acount="1"]::before,
#firewall > div > span[data-acount="1"] > #actionSelector > #dynaCounts::before {
content: '+';
}
#firewallContainer > div > span[data-acount="2"]::before,
#firewallContainer > div > span[data-acount="2"] > #actionSelector > #dynaCounts::before {
#firewall > div > span[data-acount="2"]::before,
#firewall > div > span[data-acount="2"] > #actionSelector > #dynaCounts::before {
content: '++';
}
#firewallContainer > div > span[data-acount="3"]::before,
#firewallContainer > div > span[data-acount="3"] > #actionSelector > #dynaCounts::before {
#firewall > div > span[data-acount="3"]::before,
#firewall > div > span[data-acount="3"] > #actionSelector > #dynaCounts::before {
content: '+++';
}
#firewallContainer > div > span[data-bcount]::after,
#firewallContainer > div > span[data-bcount] > #actionSelector > #dynaCounts::after {
#firewall > div > span[data-bcount]::after,
#firewall > div > span[data-bcount] > #actionSelector > #dynaCounts::after {
padding-right: 0.1em;
}
#firewallContainer > div > span[data-bcount="1"]::after,
#firewallContainer > div > span[data-bcount="1"] > #actionSelector > #dynaCounts::after {
#firewall > div > span[data-bcount="1"]::after,
#firewall > div > span[data-bcount="1"] > #actionSelector > #dynaCounts::after {
content: '\2212';
}
#firewallContainer > div > span[data-bcount="2"]::after,
#firewallContainer > div > span[data-bcount="2"] > #actionSelector > #dynaCounts::after {
#firewall > div > span[data-bcount="2"]::after,
#firewall > div > span[data-bcount="2"] > #actionSelector > #dynaCounts::after {
content: '\2212\2212';
}
#firewallContainer > div > span[data-bcount="3"]::after,
#firewallContainer > div > span[data-bcount="3"] > #actionSelector > #dynaCounts::after {
#firewall > div > span[data-bcount="3"]::after,
#firewall > div > span[data-bcount="3"] > #actionSelector > #dynaCounts::after {
content: '\2212\2212\2212';
}
body.advancedUser #firewallContainer > div > span:first-of-type {
body.advancedUser #firewall > div > span:first-of-type {
width: calc(100% - 10em);
}
body.advancedUser #firewallContainer > div > span:nth-of-type(2) {
body.advancedUser #firewall > div > span:nth-of-type(2) {
display: inline-flex;
}
body.advancedUser #firewallContainer > div:first-child ~ div[data-des="*"] {
body.advancedUser #firewall > div:first-child ~ div[data-des="*"] {
display: flex;
}
body.advancedUser #firewallContainer > div > span:first-of-type ~ span {
body.advancedUser #firewall > div > span:first-of-type ~ span {
cursor: pointer;
}
/**
Small coloured label at the left of a row
*/
#firewallContainer > div.isRootContext > span:first-of-type::before,
#firewallContainer > div.allowed > span:first-of-type::before,
#firewallContainer > div.blocked > span:first-of-type::before,
#firewallContainer:not(.expanded) > div.isDomain.totalAllowed:not(.expandException) > span:first-of-type::before,
#firewallContainer:not(.expanded) > div.isDomain.totalBlocked:not(.expandException) > span:first-of-type::before,
#firewallContainer.expanded > div.isDomain.totalAllowed.expandException > span:first-of-type::before,
#firewallContainer.expanded > div.isDomain.totalBlocked.expandException > span:first-of-type::before {
#firewall > div.isRootContext > span:first-of-type::before,
#firewall > div.allowed > span:first-of-type::before,
#firewall > div.blocked > span:first-of-type::before,
#firewall:not(.expanded) > div.isDomain.totalAllowed:not(.expandException) > span:first-of-type::before,
#firewall:not(.expanded) > div.isDomain.totalBlocked:not(.expandException) > span:first-of-type::before,
#firewall.expanded > div.isDomain.totalAllowed.expandException > span:first-of-type::before,
#firewall.expanded > div.isDomain.totalBlocked.expandException > span:first-of-type::before {
box-sizing: border-box;
content: '';
display: inline-block;
@ -385,48 +378,48 @@ body.advancedUser #firewallContainer > div > span:first-of-type ~ span {
top: 0;
width: 7px;
}
#firewallContainer > div.isRootContext > span:first-of-type::before {
#firewall > div.isRootContext > span:first-of-type::before {
background-color: var(--fg-0-50);
width: 14px !important;
}
#firewallContainer > div.allowed > span:first-of-type::before,
#firewallContainer > div.isDomain.totalAllowed > span:first-of-type::before {
#firewall > div.allowed > span:first-of-type::before,
#firewall > div.isDomain.totalAllowed > span:first-of-type::before {
background-color: var(--bg-popup-cell-allow-own);
}
#firewallContainer > div.blocked > span:first-of-type::before,
#firewallContainer > div.isDomain.totalBlocked > span:first-of-type::before {
#firewall > div.blocked > span:first-of-type::before,
#firewall > div.isDomain.totalBlocked > span:first-of-type::before {
background-color: var(--bg-popup-cell-block-own);
}
#firewallContainer > div.allowed.blocked > span:first-of-type::before,
#firewallContainer > div.isDomain.totalAllowed.totalBlocked > span:first-of-type::before {
#firewall > div.allowed.blocked > span:first-of-type::before,
#firewall > div.isDomain.totalAllowed.totalBlocked > span:first-of-type::before {
background-color: var(--bg-popup-cell-label-mixed);
}
/* Rule cells */
body.advancedUser #firewallContainer > div > span.allowRule,
body.advancedUser #firewall > div > span.allowRule,
#actionSelector > #dynaAllow {
background-color: var(--bg-popup-cell-allow);
}
body.advancedUser #firewallContainer > div > span.blockRule,
body.advancedUser #firewall > div > span.blockRule,
#actionSelector > #dynaBlock {
background-color: var(--bg-popup-cell-block);
}
body.advancedUser #firewallContainer > div > span.noopRule,
body.advancedUser #firewall > div > span.noopRule,
#actionSelector > #dynaNoop {
background-color: var(--bg-popup-cell-noop);
}
body.advancedUser #firewallContainer > div > span.ownRule,
#firewallContainer > div > span.ownRule {
body.advancedUser #firewall > div > span.ownRule,
#firewall > div > span.ownRule {
color: var(--bg-0);
}
body.advancedUser #firewallContainer > div > span.allowRule.ownRule,
body.advancedUser #firewall > div > span.allowRule.ownRule,
#actionSelector > #dynaAllow:hover {
background-color: var(--bg-popup-cell-allow-own);
}
body.advancedUser #firewallContainer > div > span.blockRule.ownRule,
body.advancedUser #firewall > div > span.blockRule.ownRule,
#actionSelector > #dynaBlock:hover {
background-color: var(--bg-popup-cell-block-own);
}
body.advancedUser #firewallContainer > div > span.noopRule.ownRule,
body.advancedUser #firewall > div > span.noopRule.ownRule,
#actionSelector > #dynaNoop:hover {
background-color: var(--bg-popup-cell-noop-own);
}
@ -465,3 +458,37 @@ body.advancedUser #firewallContainer > div > span.noopRule.ownRule,
top: 0;
width: 100%;
}
/* mouse-driven devices */
:root.desktop body {
overflow: hidden;
}
:root.desktop #panes {
flex-direction: row-reverse;
width: unset;
}
:root.desktop #main {
max-width: 300px;
width: max-content;
}
:root.desktop #firewall {
direction: rtl;
flex-grow: 1;
line-height: 1.4;
max-height: 540px;
min-height: 100vh;
max-width: 400px;
min-width: 360px;
overflow-y: auto;
width: max-content;
}
:root.desktop .tool {
padding: 0.5em;
}
:root.desktop .tool:hover {
background-color: var(--bg-button);
}
:root.desktop .tool [data-i18n] {
/* display: none; */
width: min-content;
}

View File

@ -92,12 +92,8 @@
/* Default dark theme starts here */
@media (prefers-color-scheme: dark) {
:root {
}
:root.colorBlind {
}
:root.darkTheme {
}
:root.darkTheme.colorBlind {
}

View File

@ -44,12 +44,22 @@ let dfPaneVisibleStored;
vAPI.localStorage.getItemAsync('popupFirewallPane').then(value => {
dfPaneVisibleStored = value === true || value === 'true';
if ( dfPaneVisibleStored ) {
document.getElementById('main').classList.add('dfEnabled');
document.body.classList.add('dfEnabled');
}
});
/******************************************************************************/
if ( uDom.root.classList.contains('desktop') ) {
const sticky = document.getElementById('sticky');
const main = document.getElementById('main');
if ( sticky.parentElement !== main ) {
document.getElementById('main').prepend(sticky);
}
}
/******************************************************************************/
const messaging = vAPI.messaging;
const reIP = /^\d+(?:\.\d+){1,3}$/;
const scopeToSrcHostnameMap = {
@ -178,7 +188,7 @@ const rulekeyCompare = function(a, b) {
const updateFirewallCell = function(scope, des, type, rule) {
const row = document.querySelector(
`#firewallContainer div[data-des="${des}"][data-type="${type}"]`
`#firewall div[data-des="${des}"][data-type="${type}"]`
);
if ( row === null ) { return; }
@ -271,7 +281,7 @@ const buildAllFirewallRows = function() {
dfHotspots.remove();
// Update incrementally: reuse existing rows if possible.
const rowContainer = document.getElementById('firewallContainer');
const rowContainer = document.getElementById('firewall');
const toAppend = document.createDocumentFragment();
const rowTemplate = document.querySelector('#templates > div:nth-of-type(1)');
let row = rowContainer.querySelector('div:nth-of-type(7) + div');
@ -332,7 +342,7 @@ const buildAllFirewallRows = function() {
}
if ( dfPaneBuilt !== true && popupData.advancedUserEnabled ) {
uDom('#firewallContainer')
uDom('#firewall')
.on('click', 'span[data-src]', unsetFirewallRuleHandler)
.on('mouseenter', '[data-src]', mouseenterCellHandler)
.on('mouseleave', '[data-src]', mouseleaveCellHandler);
@ -473,7 +483,7 @@ const renderPopup = function() {
vAPI.localStorage.setItem('popupFirewallPane', dfPaneVisibleStored);
}
uDom.nodeFromId('main').classList.toggle(
document.body.classList.toggle(
'dfEnabled',
dfPaneVisible === true
);
@ -578,7 +588,7 @@ let renderOnce = function() {
// https://github.com/uBlockOrigin/uBlock-issues/issues/22
if ( popupData.advancedUserEnabled !== true ) {
uDom('#firewallContainer [data-i18n-tip][data-src]').removeAttr('data-tip');
uDom('#firewall [data-i18n-tip][data-src]').removeAttr('data-tip');
}
};
@ -718,7 +728,7 @@ const toggleFirewallPane = function() {
vAPI.localStorage.setItem('popupFirewallPane', dfPaneVisibleStored);
// Dynamic filtering pane may not have been built yet
uDom.nodeFromId('main').classList.toggle('dfEnabled', popupData.dfEnabled);
document.body.classList.toggle('dfEnabled', popupData.dfEnabled);
if ( popupData.dfEnabled && dfPaneBuilt === false ) {
buildAllFirewallRows();
}
@ -868,9 +878,9 @@ const saveExpandExceptions = function() {
const setGlobalExpand = function(state, internal = false) {
uDom('.expandException').removeClass('expandException');
if ( state ) {
uDom('#firewallContainer').addClass('expanded');
uDom('#firewall').addClass('expanded');
} else {
uDom('#firewallContainer').removeClass('expanded');
uDom('#firewall').removeClass('expanded');
}
if ( internal ) { return; }
popupData.firewallPaneMinimized = !state;
@ -917,11 +927,11 @@ uDom('[data-i18n="popupAnyRulePrompt"]').on('click', ev => {
}
setGlobalExpand(
uDom('#firewallContainer').hasClass('expanded') === false
uDom('#firewall').hasClass('expanded') === false
);
});
uDom('#firewallContainer').on(
uDom('#firewall').on(
'click', '.isDomain[data-type="*"] > span:first-of-type',
ev => {
const div = ev.target.closest('[data-des]');

View File

@ -32,7 +32,7 @@
// the code here does *only* what I need, and nothing more, and with a lot
// of assumption on passed parameters, etc. I grow it on a per-need-basis only.
const uDom = (function() {
const uDom = (( ) => {
/******************************************************************************/
@ -92,6 +92,27 @@ DOMListFactory.nodeFromSelector = function(selector) {
/******************************************************************************/
{
const root = DOMListFactory.root = document.querySelector(':root');
if (
window.matchMedia('(pointer: coarse)').matches ||
window.matchMedia('(hover: none)').matches
) {
root.classList.add('mobile');
}
if (
window.matchMedia('(pointer: fine)').matches &&
window.matchMedia('(hover: hover)').matches
) {
root.classList.add('desktop');
}
if ( window.matchMedia('(prefers-color-scheme: dark)').matches ) {
root.classList.add('darkTheme');
}
}
/******************************************************************************/
const addNodeToList = function(list, node) {
if ( node ) {
list.nodes.push(node);

View File

@ -12,7 +12,7 @@
</head>
<body>
<div id="main" class="tooltipContainer">
<div id="panes">
<div id="sticky">
<div>
<div class="rulesetTools">
@ -28,6 +28,7 @@
</div>
<hr>
</div>
<div id="main">
<div id="basicTools" class="toolRibbon">
<span id="gotoZap" class="fa-icon tool">bolt<span data-i18n="popupTipZapper"></span></span>
<span id="gotoPick" class="fa-icon tool">eye-dropper<span data-i18n="popupTipPicker"></span></span>
@ -37,9 +38,7 @@
<hr>
<div id="basicStats" class="itemRibbon">
<span data-i18n="popupBlockedOnThisPage_v2"></span><span></span>
<span class="h-gutter"></span><span></span>
<span data-i18n="popupBlockedSinceInstall_v2"></span><span></span>
<span class="h-gutter"></span><span></span>
<span data-i18n="popupDomainsConnected_v2"></span><span></span>
</div>
<hr>
@ -53,7 +52,8 @@
<div id="moreButton" class="itemRibbon">
<span data-i18n="popupMoreButton_v2"></span><span class="fa-icon">angle-up</span>
</div>
<div id="firewallContainer">
</div>
<div id="firewall">
<div data-des="*" data-type="*"><span data-i18n="popupAnyRulePrompt"></span><span data-src="/" data-i18n-tip="popupTipGlobalRules" data-tip-position="under"> </span><span data-src="." data-i18n-tip="popupTipLocalRules" data-tip-position="under"> </span></div>
<div data-des="*" data-type="image"><span data-i18n="popupImageRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>
<div data-des="*" data-type="3p"><span data-i18n="popup3pAnyRulePrompt"></span><span data-src="/"> </span><span data-src="."> </span></div>