Skip to content

Commit

Permalink
v1.7
Browse files Browse the repository at this point in the history
added alt text display
added alternate file size divisions
added tool tips to explain each setting
fixed examples alignment
  • Loading branch information
cubeleco authored Jun 22, 2019
1 parent d302dc4 commit 46cb24b
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 245 deletions.
24 changes: 11 additions & 13 deletions background.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
function toggleExtension() {
//get current enabled state
browser.storage.local.get('enabled', toggleState);
chrome.storage.local.get('enabled', toggleState);
}
function toggleState(result) {
var state = (typeof result.enabled == 'undefined')? false : !result.enabled;
function toggleState(storage) {
//disable state on first toggle since default is enabled
const state = (typeof storage.enabled === 'undefined')? false : !storage.enabled;

browser.storage.local.set({
chrome.storage.local.set({
enabled: state
});
updateIcon(state);
//send message to content script to update its state
browser.tabs.query({currentWindow: true, active: true}, function(tabs) {
browser.tabs.sendMessage(tabs[0].id, {imgDataState: "update"});
});
}

function updateIcon(state) {
browser.browserAction.setIcon({ path: state? 'icons/thumb-48.png' : 'icons/disable-48.png' });
chrome.browserAction.setIcon({ path: state? 'icons/thumb-48.png' : 'icons/disable-48.png' });
chrome.browserAction.setTitle({ title: state? 'Image Data (Enabled)' : 'Image Data (Disabled)' });
}
function initIcon(result) {
updateIcon((typeof result.enabled == 'undefined')? true : result.enabled);
function initIcon(storage) {
updateIcon((typeof storage.enabled === 'undefined')? true : storage.enabled);
}
//toggle extension when toolbar button is clicked
browser.browserAction.onClicked.addListener(toggleExtension);
chrome.browserAction.onClicked.addListener(toggleExtension);
//on browser startup get prior state
browser.storage.local.get('enabled', initIcon);
chrome.storage.local.get('enabled', initIcon);
245 changes: 123 additions & 122 deletions imgdata.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
//Image Data by Cubeleco
//web extension that displays an info tooltip when hovering over an image

//converts a number in bytes to a human readable string
function getHumanReadable(fileSizeInBytes) {
var i = -1;
var byteUnits = [' kB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'];
do {
fileSizeInBytes /= 1024;
i++;
} while (fileSizeInBytes > 1024);

return Math.max(fileSizeInBytes, 0.1).toFixed(1) + byteUnits[i];
const byteUnits = [' B', ' kB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB'];
var i = 0;
for(; fileSizeInBytes > prefDiv; i++)
fileSizeInBytes /= prefDiv;
//round to first decimal place and add size unit
return (Math.round(fileSizeInBytes * 10) / 10) + byteUnits[i];
}

function imgHover(event) {
Expand All @@ -23,93 +22,81 @@ function imgHover(event) {
lastMY = data.style.top;

//check if mouse left our div
if(img.id != 'imgData' && img.id != 'imgDataSize') {
if(img.id !== 'imgData' && img.id !== 'imgDataSize') {
//remove div from html
data.parentNode.removeChild(data);
}
}
if(img.nodeName.toLowerCase() == 'img') {
//get image data according to prefs and add to page
//update data when the image finishes loading
if(!img.complete) img.addEventListener('load', imgHover);

//reposition if tooltip
if(prefPos == 2 || prefPos == 5)
img.addEventListener('mousemove', curMove);
else //remove leftover event listener if editing preferences
img.removeEventListener('mousemove', curMove);

//get position and style based off of preferences
var pos;
switch(prefPos) {
default://on top
pos = 'absolute';
break;
case 1: //static
pos = 'fixed;top:3px;left:3px';
break;
case 2: //cursor
case 5: //tooltip
//add our previous mouse position for when image reloads
pos = 'fixed;top:' +lastMY+ ';left:' +lastMX;
break;
case 3: //above
case 4: //below
pos = 'static';
break;
}

//create div container
data = document.createElement('div');
data.id = 'imgData';
data.style.cssText = 'z-index: 9999999999 !important; visibility: visible; overflow: auto; clear: both; line-height: normal; float: none; width: auto; position: ' + pos + ';' + prefStyle;

//add placeholder for filesize
var size = document.createElement('div');
size.id = 'imgDataSize';

//create info string to fill div. image dimensions and file extension
var ext = (/(jpe?g|a?png|gif|webp|tiff?|bmp|svg|bpg|ico)/i).exec( img.src.substr(img.src.lastIndexOf('.')+1) );
var text = img.naturalWidth + '\u00D7' + img.naturalHeight + (ext? '\xa0' + ext[0] : '');

//add first line to div
data.appendChild(document.createTextNode(text));
if(img.nodeName.toLowerCase() !== 'img')
return;
//update data when the image finishes loading
if(!img.complete) img.addEventListener('load', imgHover);


//create div container
data = document.createElement('div');
data.id = 'imgData';
//get position and style based off of preferences
data.style.cssText = prefStyle;

//reposition if tooltip/follow cursor
if(prefPos === 2 || prefPos === 5) {
data.style.left = lastMX;
data.style.top = lastMY;
img.addEventListener('mousemove', curMove);
}
else //remove leftover event listener if editing preferences
img.removeEventListener('mousemove', curMove);
//create info string to fill div. image dimensions and file extension
var ext = /jpe?g|a?png|gif|webp|tiff?|bmp|svg|bpg|ico/i.exec( img.src.substr(img.src.lastIndexOf('.')+1) );
var fullDim = img.naturalWidth + '\u00D7' + img.naturalHeight + (ext? '\xa0' + ext[0] : '');

//add first line to div
data.appendChild(document.createTextNode(fullDim));
data.appendChild(document.createElement('br'));

//add alt text if pref enabled and if present
if(prefAlt && img.alt) {
data.appendChild(document.createTextNode(img.alt));
data.appendChild(document.createElement('br'));
}

//display scaled dimensions if they differ from original
if(prefScale && (img.width != img.naturalWidth && img.height != img.naturalHeight)) {
data.appendChild(document.createTextNode(img.width + '\u2922' + img.height));
data.appendChild(document.createElement('br'));
}
data.appendChild(size);

//add div to page
switch(prefPos) {
default: //on top and above
img.parentNode.insertBefore(data, img);
break;
case 1: //static
case 2: //cursor
case 5: //tooltip
document.body.appendChild(data);
break;
case 4: //below
img.parentNode.appendChild(data);
break;
}

//try to get filesize of image
var xhr = new XMLHttpRequest();
xhr.open('HEAD', img.src, true);
xhr.send();
xhr.onreadystatechange = function() {
if(this.readyState == 4 && this.status == 200) {
var sizeDiv = document.getElementById('imgDataSize');
if(sizeDiv)
sizeDiv.innerText = getHumanReadable(this.getResponseHeader('Content-Length'));
}
};
//display scaled dimensions if they differ from original
if(prefScale && (img.width !== img.naturalWidth && img.height !== img.naturalHeight)) {
data.appendChild(document.createTextNode(img.width + '\u2922' + img.height));
data.appendChild(document.createElement('br'));
}
//add placeholder for filesize
var size = document.createElement('div');
size.id = 'imgDataSize';
data.appendChild(size);

//add div to page
switch(prefPos) {
case 1: //static
case 2: //cursor
case 5: //tooltip
document.body.appendChild(data);
break;
case 4: //below
img.parentNode.appendChild(data);
break;
default: //on top and above
img.parentNode.insertBefore(data, img);
}

//try to get filesize of image
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(this.readyState === 2 && this.status === 200) {
var sizeDiv = document.getElementById('imgDataSize');
var bytes = this.getResponseHeader('Content-Length');
if(sizeDiv && bytes > 0)
sizeDiv.textContent = getHumanReadable(bytes);
}
};
xhr.open('HEAD', img.src, true);
xhr.send();
}
function curMove(event) {
var data = document.getElementById('imgData');
Expand All @@ -119,48 +106,62 @@ function curMove(event) {
data.style.top = (event.clientY + prefCurOffY) + 'px';
if(prefCurLeft)
data.style.left = (event.clientX + prefCurOffX) + 'px';
if(prefPos == 5) //stop moving for tooltip
event.target.removeEventListener('mousemove', curMove);
}
if(prefPos == 5) //stop moving for tooltip
event.target.removeEventListener('mousemove', curMove);
}

//preference global vars
var prefPos, prefStyle, prefScale;
var prefPos, prefDiv, prefStyle, prefAlt, prefScale;
var prefCurTop, prefCurLeft, prefCurOffX, prefCurOffY;

function loadPreferences() {
function setPrefs(storage) {
//check enable status
if(typeof storage.enabled == 'undefined' || storage.enabled) {
document.addEventListener('mouseover', imgHover);

prefPos = storage.position || 0;
prefStyle = storage.style || 'color: rgba(255,255,255,1.0); background: rgba(0,0,20,0.8); font: 1.2em Arial, Helvetica, sans-serif; padding: 4px; border-radius: 2px;';
prefScale = storage.scale || false;

//check for user positioning to overwrite follow cursor top/left
prefCurTop = prefStyle.indexOf(' top:') == -1;
prefCurLeft = prefStyle.indexOf(' left:') == -1;
prefCurOffX = storage.offX || 20;
prefCurOffY = storage.offY || 20;
} else { //disable
document.removeEventListener('mouseover', imgHover);
//remove leftover div from page
var data = document.getElementById('imgData');
if(data) data.parentNode.removeChild(data);

function setPrefs(storage) {
//check extension enable status
if(typeof storage.enabled === 'undefined' || storage.enabled) {
prefPos = storage.position || 0;
prefDiv = storage.fsdivision || 1024;
var sty = storage.style || 'color: white; background: rgba(0,0,20,0.8); font: 1.2em Arial, Helvetica, sans-serif; padding: 4px; border-radius: 2px;';
prefAlt = storage.alt || false;
prefScale = storage.scale || false;

//check for user positioning to overwrite follow cursor top/left
prefCurTop = sty.indexOf(' top:') === -1;
prefCurLeft = sty.indexOf(' left:') === -1;
prefCurOffX = storage.offX || 20;
prefCurOffY = storage.offY || 20;

var pos;
switch(prefPos) {
case 1: //static
pos = 'fixed;top:3px;left:3px;';
break;
case 2: //cursor
case 5: //tooltip
pos = 'fixed;';
break;
case 3: //above
case 4: //below
pos = 'static;';
break;
default://on top
pos = 'absolute;';
}
//add default style attributes to hopefully avoid being affected by the page's styles
prefStyle = 'z-index: 2147483647 !important; visibility: visible; overflow: auto; clear: both; line-height: normal; float: none; width: auto; position: ' + pos + sty;
document.addEventListener('mouseover', imgHover);
} else { //disable
document.removeEventListener('mouseover', imgHover);
//remove leftover div from page
var data = document.getElementById('imgData');
if(data) data.parentNode.removeChild(data);
}

browser.storage.local.get(['position', 'style', 'scale', 'enabled', 'offX', 'offY'], setPrefs);
}
function loadPreferences() {
chrome.storage.local.get(['enabled', 'position', 'fsdivision', 'style', 'alt', 'scale', 'offX', 'offY'], setPrefs);
}

//reload preferences from browser local storage at startup and page focus
//reload preferences from browser local storage at startup and when changed
loadPreferences();
window.addEventListener('focus', loadPreferences);

function checkMessage(request) {
if(request.imgDataState == 'update')
loadPreferences();
}
//reload extension when message is recieved from background script
browser.runtime.onMessage.addListener(checkMessage);
// document.addEventListener('DOMContentLoaded', loadPreferences);
chrome.storage.onChanged.addListener(loadPreferences);
16 changes: 7 additions & 9 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
{
"manifest_version": 2,
"name": "Image Data",
"version": "1.6",
"version": "1.7",

"applications": {
"gecko": {
"id": "{b8ecb56e-f778-4df4-962a-52974b36abdd}",
"strict_min_version": "48.0"
"strict_min_version": "57.0"
}
},

"description": "Shows more information about an image when you hover over it, such as its dimensions, file extension, and file size. \nCustomize with multiple dynamic and static positions, and change Image Data's look with CSS styles.",
"description": "Shows more information about an image when you hover over it, such as its resolution, file extension, and file size.",

"browser_action": {
"default_icon": {
"48": "icons/thumb-48.png"
},
"default_title": "Toggle Image Data"
}
},
"icons": {
"48": "icons/thumb-48.png"
Expand All @@ -32,9 +31,8 @@
}],

"options_ui": {
"page": "options.html",
"browser_style": true
},
"page": "options.html"
},

"permissions": ["tabs","storage"]
"permissions": ["storage"]
}
28 changes: 28 additions & 0 deletions options.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
input[type="number"] {
width: 5em;
}

.preset {
display: inline-block;
vertical-align: top;
cursor: pointer;
/*margin: 0 0.05em;*/
}
#boxContainer {
padding-bottom: .3em;
}
#boxLeft {
float: left;
}
#boxRight {
float: right;
}
#settCurOffset {
display: none;
}
#settStyle {
width: 100%;
}
#settScale {
margin-bottom: 1.2em;
}
Loading

0 comments on commit 46cb24b

Please sign in to comment.