2016-07-28 03:41:13 +00:00
|
|
|
javascript:
|
|
|
|
/*
|
|
|
|
This javascript bookmarklet takes anchors, images, and media elements from
|
|
|
|
the page, and displays them in a nice gallery. Designed for use on open
|
|
|
|
directory listings, but works in many places.
|
|
|
|
*/
|
|
|
|
var seen_urls = new Set();
|
|
|
|
var image_height = 200;
|
|
|
|
var video_height = 300;
|
|
|
|
var audio_width = 1000;
|
|
|
|
var IMAGE_TYPES = ["\\.jpg", "\\.jpeg", "\\.jpg", "\\.bmp", "\\.tiff", "\\.tif", "\\.bmp", "\\.gif", "\\.png"].join("|");
|
|
|
|
var AUDIO_TYPES = ["\\.aac", "\\.mp3", "\\.m4a", "\\.ogg", "\\.wav"].join("|");
|
|
|
|
var VIDEO_TYPES = ["\\.mp4", "\\.m4v", "\\.webm", "\\.ogv"].join("|");
|
|
|
|
IMAGE_TYPES = new RegExp(IMAGE_TYPES, "i");
|
|
|
|
AUDIO_TYPES = new RegExp(AUDIO_TYPES, "i");
|
|
|
|
VIDEO_TYPES = new RegExp(VIDEO_TYPES, "i");
|
|
|
|
|
|
|
|
var has_started = false;
|
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
var CSS = ""
|
|
|
|
+ "body { background-color: #fff; }"
|
|
|
|
+ "audio, video { display: block; }"
|
|
|
|
+ "audio { width: $audio_width$px; }"
|
|
|
|
+ "video { height: $video_height$px; }"
|
|
|
|
+ "img { display: block; height: $image_height$px; max-width: 100% }"
|
|
|
|
+ ".control_panel { position: relative; background-color: #aaa; min-height: 10px; width: 100%; }"
|
|
|
|
+ ".workspace { background-color: #ddd; min-height: 10px; float: left; }"
|
|
|
|
+ ".arealabel { position:absolute; right: 0; bottom: 0; opacity: 0.8; background-color: #000; color: #fff; }"
|
|
|
|
+ ".delete_button { color: #d00; font-family: Arial; font-size: 11px; left: 0; position: absolute; top: 0; width: 25px; }"
|
|
|
|
+ ".ingest { position:absolute; right: 5px; top: 5px; height: 100%; width: 30% }"
|
|
|
|
+ ".ingestbox { position:relative; height: 75%; width:100%; box-sizing: border-box; }"
|
|
|
|
+ ".urldumpbox { overflow-y: scroll; height: 300px; width: 90% }"
|
|
|
|
+ ".load_button { position: absolute; top: 10%; width: 100%; height: 80%; word-wrap: break-word; }"
|
|
|
|
+ ".odi_anchor { display: block; }"
|
|
|
|
+ ".odi_image_div, .odi_media_div { display: inline-block; margin: 5px; float: left; position: relative; background-color: #aaa; }"
|
|
|
|
+ ".odi_image_div { min-width: $image_height$px; }"
|
|
|
|
;
|
2016-07-28 03:41:13 +00:00
|
|
|
|
|
|
|
function apply_css()
|
|
|
|
{
|
|
|
|
console.log("applying CSS");
|
|
|
|
var css = document.createElement("style");
|
|
|
|
css.innerHTML = format_css();
|
|
|
|
document.head.appendChild(css);
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_extend(a, b)
|
|
|
|
{
|
|
|
|
/* Append all elements of b onto a */
|
|
|
|
for (var i = 0; i < b.length; i += 1)
|
|
|
|
{
|
|
|
|
a.push(b[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_remove(a, item)
|
|
|
|
{
|
|
|
|
/* Thanks peter olson http://stackoverflow.com/a/5767335 */
|
|
|
|
for(var i = a.length - 1; i >= 0; i -= 1)
|
|
|
|
{
|
|
|
|
if(a[i].id === item.id)
|
|
|
|
{
|
|
|
|
a.splice(i, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function clear_page()
|
|
|
|
{
|
2016-08-01 23:42:03 +00:00
|
|
|
/* Remove EVERYTHING */
|
2016-07-28 03:41:13 +00:00
|
|
|
console.log("clearing page");
|
|
|
|
document.removeChild(document.documentElement);
|
|
|
|
|
|
|
|
var html = document.createElement("html");
|
|
|
|
document.appendChild(html);
|
|
|
|
|
|
|
|
var head = document.createElement("head");
|
|
|
|
html.appendChild(head);
|
|
|
|
|
|
|
|
var body = document.createElement("body");
|
|
|
|
html.appendChild(body);
|
|
|
|
|
|
|
|
document.documentElement = html;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function clear_workspace()
|
|
|
|
{
|
|
|
|
console.log("clearing workspace");
|
|
|
|
workspace = document.getElementById("WORKSPACE");
|
|
|
|
while (workspace.children.length > 0)
|
|
|
|
{
|
|
|
|
workspace.removeChild(workspace.children[0]);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function create_command_box(boxname, operation)
|
|
|
|
{
|
|
|
|
var box = document.createElement("input");
|
|
|
|
box.type = "text";
|
|
|
|
box.id = boxname;
|
|
|
|
box.onkeydown=function()
|
|
|
|
{
|
|
|
|
if (event.keyCode == 13)
|
|
|
|
{
|
|
|
|
operation(this.value);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return box;
|
|
|
|
}
|
|
|
|
|
|
|
|
function create_command_button(label, operation)
|
|
|
|
{
|
|
|
|
var button = document.createElement("button");
|
|
|
|
button.innerHTML = label;
|
|
|
|
button.onclick = operation;
|
|
|
|
return button;
|
|
|
|
}
|
|
|
|
|
|
|
|
function create_command_box_button(boxname, label, operation)
|
|
|
|
{
|
|
|
|
var box = create_command_box(boxname, operation);
|
|
|
|
var button = create_command_button(label, function(){operation(box.value)});
|
|
|
|
var div = document.createElement("div");
|
|
|
|
div.appendChild(box);
|
|
|
|
div.appendChild(button);
|
2016-08-01 23:42:03 +00:00
|
|
|
div.box = box;
|
|
|
|
div.button = button;
|
2016-07-28 03:41:13 +00:00
|
|
|
return div;
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
function create_odi_div(url)
|
2016-07-28 03:41:13 +00:00
|
|
|
{
|
2016-08-01 23:42:03 +00:00
|
|
|
var div = null;
|
|
|
|
var paramless_url = url.split("?")[0];
|
|
|
|
var basename = get_basename(url);
|
|
|
|
|
|
|
|
if (paramless_url.match(IMAGE_TYPES))
|
2016-07-28 03:41:13 +00:00
|
|
|
{
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log("Creating image div for " + paramless_url);
|
2016-08-01 23:42:03 +00:00
|
|
|
var div = document.createElement("div");
|
|
|
|
div.id = generate_id(32);
|
|
|
|
div.className = "odi_image_div";
|
|
|
|
div.odi_type = "image";
|
|
|
|
|
|
|
|
var a = document.createElement("a");
|
|
|
|
a.className = "odi_anchor";
|
|
|
|
a.odi_div = div;
|
|
|
|
a.href = url;
|
|
|
|
a.target = "_blank";
|
|
|
|
|
|
|
|
var img = document.createElement("img");
|
|
|
|
img.odi_div = div;
|
|
|
|
img.anchor = a;
|
|
|
|
img.border = 0;
|
|
|
|
|
|
|
|
img.lazy_src = url;
|
|
|
|
img.src = "";
|
|
|
|
|
|
|
|
var arealabel = document.createElement("span");
|
|
|
|
arealabel.className = "arealabel";
|
|
|
|
arealabel.odi_div = div;
|
|
|
|
arealabel.innerHTML = "0x0";
|
|
|
|
img.arealabel = arealabel;
|
|
|
|
|
|
|
|
var load_button = document.createElement("button");
|
|
|
|
load_button.className = "load_button";
|
|
|
|
load_button.odi_div = div;
|
|
|
|
load_button.innerHTML = basename;
|
|
|
|
load_button.onclick = function()
|
2016-07-28 03:41:13 +00:00
|
|
|
{
|
2016-08-01 23:42:03 +00:00
|
|
|
this.parentElement.removeChild(this);
|
|
|
|
lazy_load_one(this.odi_div);
|
|
|
|
};
|
2016-07-28 03:41:13 +00:00
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
div.image = img;
|
|
|
|
div.anchor = a;
|
|
|
|
a.appendChild(img);
|
|
|
|
a.appendChild(arealabel);
|
|
|
|
div.appendChild(a);
|
|
|
|
div.appendChild(load_button);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (paramless_url.match(AUDIO_TYPES))
|
2016-07-28 03:41:13 +00:00
|
|
|
{
|
2016-08-01 23:42:03 +00:00
|
|
|
var mediatype = "audio";
|
|
|
|
}
|
|
|
|
else if (paramless_url.match(VIDEO_TYPES))
|
|
|
|
{
|
|
|
|
var mediatype = "video";
|
2016-07-28 03:41:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-08-01 23:42:03 +00:00
|
|
|
return null;
|
|
|
|
}
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log("Creating " + mediatype + " div for " + paramless_url);
|
2016-07-28 03:41:13 +00:00
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
var div = document.createElement("div");
|
|
|
|
div.id = generate_id(32);
|
|
|
|
div.className = "odi_media_div";
|
|
|
|
div.odi_type = "media";
|
|
|
|
div.mediatype = mediatype;
|
|
|
|
|
|
|
|
var center = document.createElement("center");
|
|
|
|
center.odi_div = div;
|
|
|
|
|
|
|
|
var a = document.createElement("a");
|
|
|
|
a.odi_div = div;
|
|
|
|
a.innerHTML = get_basename(url);
|
|
|
|
a.target = "_blank";
|
|
|
|
a.style.display = "block";
|
|
|
|
a.href = url;
|
|
|
|
|
|
|
|
var media = document.createElement(mediatype);
|
|
|
|
media.odi_div = div;
|
|
|
|
media.controls = true;
|
|
|
|
media.preload = "none";
|
|
|
|
|
|
|
|
sources = get_alternate_sources(url);
|
|
|
|
for (var sourceindex = 0; sourceindex < sources.length; sourceindex += 1)
|
|
|
|
{
|
|
|
|
source = document.createElement("source");
|
|
|
|
source.src = sources[sourceindex];
|
|
|
|
source.odi_div = div;
|
|
|
|
media.appendChild(source);
|
|
|
|
}
|
2016-07-28 03:41:13 +00:00
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
div.media = media;
|
|
|
|
div.anchor = a;
|
|
|
|
center.appendChild(a);
|
|
|
|
div.appendChild(center);
|
|
|
|
div.appendChild(media);
|
|
|
|
}
|
2016-07-28 03:41:13 +00:00
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
if (div == null)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
2016-07-28 03:41:13 +00:00
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
div.url = url;
|
|
|
|
div.basename = basename;
|
2016-07-28 03:41:13 +00:00
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
button = document.createElement("button");
|
|
|
|
button.className = "delete_button";
|
|
|
|
button.odi_div = div;
|
|
|
|
button.innerHTML = "X";
|
|
|
|
button.onclick = function()
|
|
|
|
{
|
|
|
|
delete_odi_div(this);
|
|
|
|
};
|
|
|
|
div.appendChild(button);
|
|
|
|
return div;
|
|
|
|
}
|
|
|
|
function create_odi_divs(urls)
|
|
|
|
{
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log("Creating odi divs");
|
2016-08-01 23:42:03 +00:00
|
|
|
image_divs = [];
|
|
|
|
media_divs = [];
|
|
|
|
odi_divs = [];
|
|
|
|
for (var index = 0; index < urls.length; index += 1)
|
|
|
|
{
|
|
|
|
url = urls[index];
|
|
|
|
var paramless_url = url.split("?")[0];
|
|
|
|
if (!url)
|
|
|
|
{
|
|
|
|
continue;
|
2016-07-28 03:41:13 +00:00
|
|
|
}
|
2016-08-01 23:42:03 +00:00
|
|
|
var odi_div = create_odi_div(url);
|
|
|
|
if (odi_div == null)
|
2016-07-28 03:41:13 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2016-08-01 23:42:03 +00:00
|
|
|
if (odi_div.odi_type == "image")
|
2016-07-28 03:41:13 +00:00
|
|
|
{
|
2016-08-01 23:42:03 +00:00
|
|
|
image_divs.push(odi_div);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
media_divs.push(odi_div);
|
|
|
|
}
|
2016-07-28 03:41:13 +00:00
|
|
|
}
|
|
|
|
array_extend(odi_divs, image_divs);
|
|
|
|
array_extend(odi_divs, media_divs);
|
|
|
|
return odi_divs;
|
|
|
|
}
|
|
|
|
|
|
|
|
function create_workspace()
|
|
|
|
{
|
|
|
|
clear_page();
|
|
|
|
apply_css();
|
|
|
|
console.log("creating workspace");
|
|
|
|
|
|
|
|
var control_panel = document.createElement("div");
|
|
|
|
var workspace = document.createElement("div");
|
|
|
|
|
|
|
|
var resizer = create_command_box_button("resizer", "resize", resize_images);
|
|
|
|
var refilter = create_command_box_button("refilter", "remove regex", function(x){filter_re(x, true)});
|
|
|
|
var rekeeper = create_command_box_button("rekeeper", "keep regex", function(x){filter_re(x, false)});
|
|
|
|
var heightfilter = create_command_box_button("heightfilter", "min height", filter_height);
|
|
|
|
var widthfilter = create_command_box_button("widthfilter", "min width", filter_width);
|
|
|
|
var sorter = create_command_button("sort size", sort_size);
|
|
|
|
var dumper = create_command_button("dump urls", dump_urls);
|
2016-08-01 23:42:03 +00:00
|
|
|
var ingest_box = document.createElement("textarea");
|
|
|
|
var ingest_button = create_command_button("ingest", ingest);
|
2016-07-28 03:41:13 +00:00
|
|
|
var start_button = create_command_button("load all", function(){start(); this.parentElement.removeChild(this);});
|
|
|
|
|
|
|
|
start_button.style.display = "block";
|
|
|
|
|
|
|
|
control_panel.id = "CONTROL_PANEL";
|
|
|
|
control_panel.className = "control_panel";
|
|
|
|
|
|
|
|
workspace.id = "WORKSPACE";
|
|
|
|
workspace.className = "workspace";
|
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
var ingest_div = document.createElement("div");
|
|
|
|
ingest_div.id = "INGEST";
|
|
|
|
ingest_div.className = "ingest";
|
|
|
|
ingest_box.id = "ingestbox";
|
|
|
|
ingest_box.className = "ingestbox";
|
|
|
|
ingest_div.appendChild(ingest_box);
|
|
|
|
ingest_div.appendChild(ingest_button);
|
|
|
|
ingest_div.appendChild(ingest_box);
|
|
|
|
ingest_div.appendChild(ingest_button);
|
|
|
|
|
2016-07-28 03:41:13 +00:00
|
|
|
document.body.appendChild(control_panel);
|
|
|
|
control_panel.appendChild(resizer);
|
|
|
|
control_panel.appendChild(refilter);
|
|
|
|
control_panel.appendChild(rekeeper);
|
|
|
|
control_panel.appendChild(heightfilter);
|
|
|
|
control_panel.appendChild(widthfilter);
|
|
|
|
control_panel.appendChild(sorter);
|
|
|
|
control_panel.appendChild(dumper);
|
2016-08-01 23:42:03 +00:00
|
|
|
control_panel.appendChild(ingest_div);
|
2016-07-28 03:41:13 +00:00
|
|
|
control_panel.appendChild(start_button);
|
|
|
|
document.body.appendChild(workspace);
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log("finished workspace");
|
2016-07-28 03:41:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function delete_odi_div(element)
|
|
|
|
{
|
|
|
|
if (element.odi_div != undefined)
|
|
|
|
{
|
|
|
|
element = element.odi_div;
|
|
|
|
}
|
|
|
|
if (element.media != undefined)
|
|
|
|
{
|
|
|
|
/* http://stackoverflow.com/questions/3258587/how-to-properly-unload-destroy-a-video-element */
|
|
|
|
element.media.pause();
|
|
|
|
element.media.src = "";
|
|
|
|
element.media.load();
|
|
|
|
}
|
|
|
|
var parent = element.parentElement;
|
|
|
|
parent.removeChild(element);
|
|
|
|
}
|
|
|
|
|
|
|
|
function dump_urls()
|
|
|
|
{
|
|
|
|
var divs = get_odi_divs();
|
|
|
|
var textbox = document.getElementById("url_dump_box");
|
|
|
|
if (textbox == null)
|
|
|
|
{
|
|
|
|
textbox = document.createElement("textarea");
|
2016-08-01 23:42:03 +00:00
|
|
|
textbox.className = "urldumpbox";
|
2016-09-05 23:37:07 +00:00
|
|
|
textbox.id = "url_dump_box";
|
2016-07-28 03:41:13 +00:00
|
|
|
workspace = document.getElementById("WORKSPACE");
|
|
|
|
workspace.appendChild(textbox);
|
|
|
|
}
|
|
|
|
textbox.innerHTML = "";
|
|
|
|
for (var index = 0; index < divs.length; index += 1)
|
|
|
|
{
|
|
|
|
textbox.innerHTML += divs[index].url + "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function fill_workspace(divs)
|
|
|
|
{
|
|
|
|
console.log("filling workspace");
|
|
|
|
|
|
|
|
workspace = document.getElementById("WORKSPACE");
|
|
|
|
for (var index = 0; index < divs.length; index += 1)
|
|
|
|
{
|
|
|
|
workspace.appendChild(divs[index]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function filter_dimension(dimension, minimum)
|
|
|
|
{
|
|
|
|
minimum = parseInt(minimum);
|
|
|
|
images = Array.from(document.images);
|
|
|
|
for (var i = 0; i < images.length; i += 1)
|
|
|
|
{
|
|
|
|
image = images[i];
|
|
|
|
if (image[dimension] == 0)
|
|
|
|
{continue;}
|
|
|
|
if (image[dimension] < minimum)
|
|
|
|
{
|
|
|
|
delete_odi_div(image);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function filter_height(minimum)
|
|
|
|
{
|
|
|
|
filter_dimension('naturalHeight', minimum);
|
|
|
|
}
|
|
|
|
|
|
|
|
function filter_width(minimum)
|
|
|
|
{
|
|
|
|
filter_dimension('naturalWidth', minimum);
|
|
|
|
}
|
|
|
|
|
|
|
|
function filter_re(pattern, do_delete)
|
|
|
|
{
|
|
|
|
if (!pattern)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
pattern = new RegExp(pattern, "i");
|
|
|
|
do_keep = !do_delete;
|
|
|
|
console.log(pattern + " " + do_delete);
|
|
|
|
odi_divs = get_odi_divs();
|
|
|
|
for (var index = 0; index < odi_divs.length; index += 1)
|
|
|
|
{
|
|
|
|
div = odi_divs[index];
|
2016-08-01 23:42:03 +00:00
|
|
|
match = div.url.match(pattern);
|
2016-07-28 03:41:13 +00:00
|
|
|
if ((match && do_delete) || (!match && do_keep))
|
|
|
|
{
|
|
|
|
delete_odi_div(div);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function format_css()
|
|
|
|
{
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log("Formatting CSS variables");
|
2016-07-28 03:41:13 +00:00
|
|
|
var css = CSS;
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
matches = css.match("\\$.+?\\$");
|
|
|
|
if (!matches)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log(matches);
|
|
|
|
matches = new Set(matches);
|
|
|
|
/* Originally used Array.from(set) and did regular iteration, but I found
|
|
|
|
that sites can override and break that conversion. */
|
|
|
|
matches.forEach(
|
|
|
|
function(injector)
|
|
|
|
{
|
|
|
|
var injected = injector.replace(new RegExp("\\$", 'g'), "");
|
|
|
|
css = css.replace(injector, this[injected]);
|
|
|
|
}
|
|
|
|
);
|
2016-07-28 03:41:13 +00:00
|
|
|
}
|
|
|
|
return css;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_all_urls()
|
|
|
|
{
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log("Collecting urls");
|
2016-07-28 03:41:13 +00:00
|
|
|
var urls = [];
|
|
|
|
function include(source, attr)
|
|
|
|
{
|
|
|
|
for (var index = 0; index < source.length; index += 1)
|
|
|
|
{
|
|
|
|
url = source[index][attr];
|
|
|
|
if (url === undefined)
|
|
|
|
{continue;}
|
|
|
|
|
|
|
|
if (seen_urls.has(url))
|
|
|
|
{continue;}
|
|
|
|
console.log(url);
|
|
|
|
if (url.indexOf("thumbs.redditmedia") != -1)
|
|
|
|
{console.log("Rejecting reddit thumb"); continue;}
|
|
|
|
if (url.indexOf("pixel.reddit") != -1 || url.indexOf("reddit.com/static/pixel") != -1)
|
|
|
|
{console.log("Rejecting reddit pixel"); continue}
|
2016-08-01 23:42:03 +00:00
|
|
|
/*if (url.indexOf("/thumb/") != -1)
|
|
|
|
{console.log("Rejecting /thumb/"); continue;}*/
|
2016-07-28 03:41:13 +00:00
|
|
|
if (url.indexOf("/loaders/") != -1)
|
|
|
|
{console.log("Rejecting loader"); continue;}
|
|
|
|
if (url.indexOf("memegen") != -1)
|
|
|
|
{console.log("Rejecting retardation"); continue;}
|
|
|
|
if (url.indexOf("4cdn") != -1 && url.indexOf("s.jpg") != -1)
|
|
|
|
{console.log("Rejecting 4chan thumb"); continue;}
|
|
|
|
|
|
|
|
sub_urls = normalize_url(url);
|
|
|
|
if (sub_urls == null)
|
|
|
|
{continue;}
|
|
|
|
|
|
|
|
for (var url_index = 0; url_index < sub_urls.length; url_index += 1)
|
|
|
|
{
|
|
|
|
sub_url = sub_urls[url_index];
|
|
|
|
if (seen_urls.has(sub_url))
|
|
|
|
{continue;}
|
|
|
|
|
|
|
|
urls.push(sub_url);
|
|
|
|
seen_urls.add(sub_url);
|
|
|
|
}
|
|
|
|
seen_urls.add(url);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var docs = [];
|
|
|
|
docs.push(document);
|
|
|
|
while (docs.length > 0)
|
|
|
|
{
|
|
|
|
var d = docs.pop();
|
|
|
|
include(d.links, "href");
|
|
|
|
include(d.images, "src");
|
|
|
|
include(d.getElementsByTagName("audio"), "src");
|
|
|
|
include(d.getElementsByTagName("video"), "src");
|
|
|
|
include(d.getElementsByTagName("source"), "src");
|
|
|
|
}
|
|
|
|
console.log("collected " + urls.length + " urls.");
|
|
|
|
return urls;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_alternate_sources(url)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
For sites that must try multiple resource urls, that logic
|
|
|
|
may go here
|
|
|
|
*/
|
|
|
|
return [url];
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_basename(url)
|
|
|
|
{
|
|
|
|
var basename = url.split("/");
|
|
|
|
basename = basename[basename.length - 1];
|
|
|
|
return basename;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_gfycat_video(id)
|
|
|
|
{
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log("Resolving gfycat " + id);
|
2016-07-28 03:41:13 +00:00
|
|
|
var url = "https://gfycat.com/cajax/get/" + id;
|
|
|
|
var request = new XMLHttpRequest();
|
|
|
|
request.answer = null;
|
|
|
|
request.onreadystatechange = function()
|
|
|
|
{
|
|
|
|
if (request.readyState == 4 && request.status == 200)
|
|
|
|
{
|
|
|
|
var text = request.responseText;
|
|
|
|
var details = JSON.parse(text);
|
|
|
|
request.answer = details["gfyItem"]["mp4Url"];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var asynchronous = false;
|
|
|
|
request.open("GET", url, asynchronous);
|
|
|
|
request.send(null);
|
|
|
|
return request.answer;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_lazy_divs()
|
|
|
|
{
|
|
|
|
var divs = document.getElementsByTagName("div");
|
|
|
|
var lazy_elements = [];
|
|
|
|
for (index = 0; index < divs.length; index += 1)
|
|
|
|
{
|
|
|
|
var div = divs[index];
|
|
|
|
if (div.image && div.image.lazy_src)
|
|
|
|
{
|
|
|
|
lazy_elements.push(div);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return lazy_elements;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_odi_divs()
|
|
|
|
{
|
|
|
|
var divs = document.getElementsByTagName("div");
|
|
|
|
var odi_divs = [];
|
|
|
|
for (index = 0; index < divs.length; index += 1)
|
|
|
|
{
|
|
|
|
var div = divs[index];
|
|
|
|
if (div.id.indexOf("odi_") == -1)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
odi_divs.push(div);
|
|
|
|
}
|
|
|
|
return odi_divs;
|
|
|
|
}
|
|
|
|
|
|
|
|
function generate_id(length)
|
|
|
|
{
|
|
|
|
/* Thanks csharptest http://stackoverflow.com/a/1349426 */
|
|
|
|
var text = [];
|
|
|
|
var possible = "abcdefghijklmnopqrstuvwxyz";
|
|
|
|
|
|
|
|
for(var i = 0; i < length; i += 1)
|
|
|
|
{
|
|
|
|
c = possible.charAt(Math.floor(Math.random() * possible.length));
|
|
|
|
text.push(c);
|
|
|
|
}
|
|
|
|
return "odi_" + text.join("");
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:42:03 +00:00
|
|
|
function ingest()
|
|
|
|
{
|
|
|
|
/* Take the text from the INGEST box, and make odi divs from it */
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log("Ingesting");
|
2016-08-01 23:42:03 +00:00
|
|
|
var odi_divs = get_odi_divs();
|
|
|
|
var ingestbox = document.getElementById("ingestbox");
|
|
|
|
var text = ingestbox.value;
|
|
|
|
var urls = text.split("\n");
|
|
|
|
for (var index = 0; index < urls.length; index += 1)
|
|
|
|
{
|
|
|
|
url = urls[index].trim();
|
|
|
|
sub_urls = normalize_url(url);
|
|
|
|
if (sub_urls == null)
|
|
|
|
{continue;}
|
|
|
|
|
|
|
|
for (var url_index = 0; url_index < sub_urls.length; url_index += 1)
|
|
|
|
{
|
|
|
|
sub_url = sub_urls[url_index];
|
|
|
|
var odi_div = create_odi_div(sub_url);
|
|
|
|
if (odi_div == null)
|
|
|
|
{continue;}
|
|
|
|
odi_divs.push(odi_div);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ingestbox.value = "";
|
|
|
|
clear_workspace();
|
|
|
|
fill_workspace(odi_divs);
|
|
|
|
}
|
|
|
|
|
2016-07-28 03:41:13 +00:00
|
|
|
function lazy_load_all()
|
|
|
|
{
|
2016-08-18 01:24:38 +00:00
|
|
|
console.log("Starting lazyload");
|
2016-07-28 03:41:13 +00:00
|
|
|
lazies = get_lazy_divs();
|
|
|
|
lazies.reverse();
|
|
|
|
lazy_buttons = document.getElementsByClassName("load_button");
|
|
|
|
for (var index = 0; index < lazy_buttons.length; index += 1)
|
|
|
|
{
|
|
|
|
lazy_buttons[index].parentElement.removeChild(lazy_buttons[index]);
|
|
|
|
}
|
|
|
|
while (lazies.length > 0)
|
|
|
|
{
|
|
|
|
var element = lazies.pop();
|
|
|
|
if (element.image != undefined)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (element == undefined)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
lazy_load_one(element, true);
|
|
|
|
return
|
|
|
|
;}
|
|
|
|
|
|
|
|
function lazy_load_one(element, comeback)
|
|
|
|
{
|
|
|
|
var image = element.image;
|
|
|
|
if (!image.lazy_src)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
image.onload = function()
|
|
|
|
{
|
|
|
|
width = this.naturalWidth;
|
|
|
|
height = this.naturalHeight;
|
|
|
|
if (width == 161 && height == 81)
|
|
|
|
{delete_odi_div(this);}
|
|
|
|
this.arealabel.innerHTML = width + " x " + height;
|
|
|
|
this.odi_div.style.minWidth = "0px";
|
|
|
|
if (comeback){lazy_load_all()};
|
|
|
|
};
|
|
|
|
image.onerror = function()
|
|
|
|
{
|
|
|
|
delete_odi_div(this);
|
|
|
|
if (comeback){lazy_load_all()};
|
|
|
|
};
|
|
|
|
/*console.log("Lazy loading " + element.lazy_src)*/
|
|
|
|
image.src = image.lazy_src;
|
|
|
|
image.lazy_src = null;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
function normalize_url(url)
|
|
|
|
{
|
|
|
|
var protocol = window.location.protocol;
|
|
|
|
if (protocol == "file:")
|
|
|
|
{
|
|
|
|
protocol = "http:";
|
|
|
|
}
|
|
|
|
url = url.replace("http:", protocol);
|
|
|
|
url = url.replace("https:", protocol);
|
|
|
|
url = decodeURIComponent(unescape(url));
|
|
|
|
url = url.replace("imgur.com/gallery/", "imgur.com/a/");
|
|
|
|
|
|
|
|
if (url.indexOf("vidble") >= 0)
|
|
|
|
{
|
|
|
|
url = url.replace("_med", "");
|
|
|
|
url = url.replace("_sqr", "");
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (url.indexOf("imgur.com/a/") != -1)
|
|
|
|
{
|
|
|
|
var urls = [];
|
|
|
|
var id = url.split("imgur.com/a/")[1];
|
|
|
|
id = id.split("#")[0].split("?")[0];
|
|
|
|
console.log("imgur album: " + id);
|
|
|
|
var url = "https://api.imgur.com/3/album/" + id;
|
|
|
|
var request = new XMLHttpRequest();
|
|
|
|
request.onreadystatechange = function()
|
|
|
|
{
|
|
|
|
if (request.readyState == 4 && request.status == 200)
|
|
|
|
{
|
|
|
|
var text = request.responseText;
|
|
|
|
var images = JSON.parse(request.responseText);
|
|
|
|
images = images['data']['images'];
|
|
|
|
for (var index = 0; index < images.length; index += 1)
|
|
|
|
{
|
|
|
|
var image = images[index];
|
|
|
|
var image_url = image["mp4"] || image["link"];
|
|
|
|
if (!image_url){continue;}
|
|
|
|
image_url = normalize_url(image_url)[0];
|
|
|
|
console.log("+" + image_url);
|
|
|
|
urls.push(image_url);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var asynchronous = false;
|
|
|
|
request.open("GET", url, asynchronous);
|
|
|
|
request.setRequestHeader("Authorization", "Client-ID 1d8d9b36339e0e2");
|
|
|
|
request.send(null);
|
|
|
|
return urls;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (url.indexOf("imgur.com") >= 0)
|
|
|
|
{
|
|
|
|
var url_parts = url.split("/");
|
|
|
|
var image_id = url_parts[url_parts.length - 1];
|
|
|
|
var extension = ".jpg";
|
|
|
|
if (image_id.indexOf(".") != -1)
|
|
|
|
{
|
|
|
|
image_id = image_id.split(".");
|
|
|
|
extension = "." + image_id[1];
|
|
|
|
image_id = image_id[0];
|
|
|
|
}
|
|
|
|
extension = extension.replace(".gifv", ".mp4");
|
|
|
|
extension = extension.replace(".gif", ".mp4");
|
|
|
|
|
|
|
|
if (image_id.length % 2 == 0)
|
|
|
|
{
|
|
|
|
image_id = image_id.split("");
|
|
|
|
image_id[image_id.length - 1] = "";
|
|
|
|
image_id = image_id.join("");
|
|
|
|
}
|
|
|
|
url = protocol + "//i.imgur.com/" + image_id + extension;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (url.indexOf("gfycat.com") >= 0)
|
|
|
|
{
|
|
|
|
var gfy_id = url.split("/");
|
|
|
|
gfy_id = gfy_id[gfy_id.length - 1];
|
|
|
|
gfy_id = gfy_id.split(".")[0];
|
|
|
|
if (gfy_id.length > 0)
|
|
|
|
{
|
|
|
|
url = get_gfycat_video(gfy_id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return [url];
|
|
|
|
}
|
|
|
|
|
|
|
|
function resize_images(height)
|
|
|
|
{
|
|
|
|
odi_divs = get_odi_divs();
|
2016-08-01 23:42:03 +00:00
|
|
|
height = height.toString() + "px";
|
2016-07-28 03:41:13 +00:00
|
|
|
for (var index = 0; index < odi_divs.length; index += 1)
|
|
|
|
{
|
|
|
|
var div = odi_divs[index];
|
2016-08-01 23:42:03 +00:00
|
|
|
if (div.image)
|
2016-07-28 03:41:13 +00:00
|
|
|
{
|
2016-08-01 23:42:03 +00:00
|
|
|
div.image.style.height = height;
|
|
|
|
}
|
|
|
|
else if (div.media && div.mediatype == "video")
|
|
|
|
{
|
|
|
|
div.media.style.height = height;
|
2016-07-28 03:41:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function sort_size()
|
|
|
|
{
|
|
|
|
console.log("sorting size");
|
|
|
|
|
|
|
|
odi_divs = get_odi_divs();
|
|
|
|
odi_divs.sort(sort_size_comparator);
|
|
|
|
odi_divs.reverse();
|
|
|
|
clear_workspace();
|
|
|
|
fill_workspace(odi_divs);
|
|
|
|
}
|
|
|
|
|
|
|
|
function sort_size_comparator(div1, div2)
|
|
|
|
{
|
|
|
|
if (div1.odi_type != "image" || div1.lazy_src)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (div2.odi_type != "image" || div2.lazy_src)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
pixels1 = div1.image.naturalHeight * div1.image.naturalWidth;
|
|
|
|
pixels2 = div2.image.naturalHeight * div2.image.naturalWidth;
|
|
|
|
if (pixels1 < pixels2)
|
|
|
|
{return -1;}
|
|
|
|
if (pixels1 > pixels2)
|
|
|
|
{return 1;}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
function start()
|
|
|
|
{
|
|
|
|
lazy_load_all();
|
|
|
|
has_started = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function main()
|
|
|
|
{
|
2016-08-01 23:42:03 +00:00
|
|
|
var all_urls = get_all_urls();
|
2016-07-28 03:41:13 +00:00
|
|
|
var divs = create_odi_divs(all_urls);
|
|
|
|
create_workspace();
|
|
|
|
fill_workspace(divs);
|
|
|
|
}
|
|
|
|
|
|
|
|
main();
|