Gelbooru Paged Gallery

A simplified gallery for viewing gelbooru images in succession.

  1. // ==UserScript==
  2. // @name Gelbooru Paged Gallery
  3. // @namespace zixaphir
  4. // @description A simplified gallery for viewing gelbooru images in succession.
  5. // @match *://*.gelbooru.com/index.php?*
  6. // @version 1
  7. // @grant none
  8. // ==/UserScript==
  9.  
  10. /*
  11. #
  12. * $ object largely based on 4chan X's $, which is largely based on jQuery.
  13. * non-chainable.
  14. #
  15. * Copyright (c) 2009-2011 James Campos <james.r.campos@gmail.com>
  16. * Copyright (c) 2012-2014 Nicolas Stepien <stepien.nicolas@gmail.com>
  17. #
  18. * Permission is hereby granted, free of charge, to any person
  19. * obtaining a copy of this software and associated documentation
  20. * files (the "Software"), to deal in the Software without
  21. * restriction, including without limitation the rights to use,
  22. * copy, modify, merge, publish, distribute, sublicense, and/or sell
  23. * copies of the Software, and to permit persons to whom the
  24. * Software is furnished to do so, subject to the following
  25. * conditions:
  26. #
  27. * The above copyright notice and this permission notice shall be
  28. * included in all copies or substantial portions of the Software.
  29. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  30. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  31. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  32. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  33. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  34. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  35. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  36. * OTHER DEALINGS IN THE SOFTWARE.
  37. #
  38. */
  39.  
  40. (function() {
  41. "use strict";
  42. var $, FNLIMIT, LIMIT, PRELOAD, SimpleDict, THRESHOLD, cb, clickThumb, d, err, fer, g, loadGallery, mkImage, mkURL, preload, query, queryImages, setImage, setup, setupImages, updateImages,
  43. slice = [].slice;
  44.  
  45. d = document;
  46.  
  47. FNLIMIT = 255;
  48.  
  49. PRELOAD = 1;
  50.  
  51. THRESHOLD = 3;
  52.  
  53. LIMIT = 100;
  54.  
  55. g = {
  56. galleryCSS: "#a-gallery {\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n z-index: 30;\n display: flex;\n flex-direction: row;\n background: rgba(0,0,0,0.7);\n}\n.gal-thumbnails {\n flex-basis: 170px;\n overflow-y: auto;\n overflow-x: hidden;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n text-align: center;\n background: rgba(0,0,0,.5);\n border-left: 1px solid #222;\n order: 3;\n}\n.gal-hide-thumbnails .gal-thumbnails {\n display: none;\n}\n.gal-thumb img {\n max-width: 150px;\n max-height: 150px;\n height: auto;\n width: auto;\n}\n.gal-thumb {\n flex-basis: auto;\n padding: 3px;\n line-height: 0;\n transition: background .2s linear;\n}\n.gal-highlight {\n background: rgba(0, 190, 255, .8);\n}\n.gal-prev {\n order: 0;\n border-right: 1px solid #222;\n}\n.gal-next {\n order: 2;\n border-left: 1px solid #222;\n}\n.gal-prev,\n.gal-next {\n flex-basis: 20px;\n position: relative;\n cursor: pointer;\n opacity: 0.7;\n background-color: rgba(0, 0, 0, 0.3);\n}\n.gal-prev:hover,\n.gal-next:hover {\n opacity: 1;\n}\n.gal-prev::after,\n.gal-next::after {\n position: absolute;\n top: 50%;\n transform: translateY(-50%)\n line-height: 22px;\n display: inline-block;\n border-top: 11px solid transparent;\n border-bottom: 11px solid transparent;\n content: \"\";\n}\n.gal-prev::after {\n border-right: 12px solid #fff;\n right: 5px;\n}\n.gal-next::after {\n border-left: 12px solid #fff;\n right: 3px;\n}\n.gal-image {\n position: relative;\n order: 1;\n display: flex;\n align-items: flex-start;\n justify-content: space-around;\n overflow: hidden;\n flex-grow: 1;\n}\n:root:not(.gal-fit-height):not(.gal-pdf) .gal-image {\n overflow-y: auto !important;\n}\n:root:not(.gal-fit-width):not(.gal-pdf) .gal-image {\n overflow-x: auto !important;\n}\n.gal-image a {\n line-height: 0;\n}\n.gal-image > div {\n margin: auto;\n max-width: 100%;\n}\n:root.gal-pdf .gal-image a {\n width: 100%;\n height: 100%;\n}\n.gal-image video,\n.gal-image img {\n max-width: 100%;\n}\n.gal-fit-height .gal-image video,\n.gal-fit-height .gal-image img {\n max-height: 95vh;\n}\n.gal-image iframe {\n width: 100%;\n height: 100%;\n}\n.gal-buttons .menu-button {\n bottom: 2px;\n color: #ffffff;\n text-shadow: 0px 0px 1px #000000;\n}\n.gal-close {\n font-size: 2em;\n color: #ffffff;\n text-shadow: 0px 0px 1px #000000;\n top: 5px;\n cursor: pointer;\n}\n.gal-close,\n.gal-info {\n position: absolute;\n right: 5px;\n}\n.gal-info {\n bottom: 5px;\n background: rgba(0,0,0,0.6) !important;\n}\n.gal-info,\n.gal-ex-info {\n border-radius: 3px;\n padding: 1px 5px 2px 5px;\n color: #ffffff !important;\n}\n.gal-ex-info {\n display: none;\n position: absolute;\n bottom: 0;\n right: 0;\n font-size: 12px;\n font-family: calibri;\n min-width: 200px;\n padding-left: 15px;\n text-indent: -15px;\n background: rgba(0,0,0,0.8) !important;\n}\n.gal-ex-info p {\n margin: 3px;\n}\n.gal-info:hover .gal-ex-info {\n display: block;\n}\n:root:not(.gal-fit-width):not(.gal-pdf) .gal-name {\n bottom: 23px !important;\n}\n:root:not(.gal-fit-width):not(.gal-pdf) .gal-count {\n bottom: 44px !important;\n}\n:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-buttons,\n:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-name,\n:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-count {\n right: 178px !important;\n}\n:root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-buttons,\n:root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-name,\n:root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-count {\n right: 28px !important;\n}\n.spinner {\n width: 30px;\n height: 30px;\n background-color: #aaa;\n -webkit-animation: rotateplane 1.2s infinite ease-in-out;\n animation: rotateplane 1.2s infinite ease-in-out;\n}\n@-webkit-keyframes rotateplane {\n 0% { -webkit-transform: perspective(120px) }\n 50% { -webkit-transform: perspective(120px) rotateY(180deg) }\n 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }\n}\n@keyframes rotateplane {\n 0% {\n transform: perspective(120px) rotateX(0deg) rotateY(0deg);\n -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)\n } 50% {\n transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);\n -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)\n } 100% {\n transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);\n -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);\n }\n}",
  57. nodes: {}
  58. };
  59.  
  60. (function() {
  61. var z;
  62. z = 0;
  63. return Object.defineProperty(g, "currentImageIndex", {
  64. set: function(x) {
  65. return z = Math.min(+g.images.length, Math.max(x, 0));
  66. },
  67. get: function() {
  68. return z;
  69. }
  70. });
  71. })();
  72.  
  73. $ = function(query, root) {
  74. if (!root) {
  75. root = d.body;
  76. }
  77. return root.querySelector(query);
  78. };
  79.  
  80. $.$ = function(query, root) {
  81. if (!root) {
  82. root = d.body;
  83. }
  84. return slice.call(root.querySelectorAll(query));
  85. };
  86.  
  87. $.asap = function(test, fn) {
  88. var callback;
  89. callback = function() {
  90. var err;
  91. try {
  92. return fn();
  93. } catch (_error) {
  94. err = _error;
  95. console.log(err.message);
  96. return console.log(err.stack);
  97. }
  98. };
  99. if (test()) {
  100. return callback();
  101. } else {
  102. return setTimeout($.asap, 25, test, callback);
  103. }
  104. };
  105.  
  106. $.addStyle = function(css, id) {
  107. var style;
  108. style = $.el('style', {
  109. textContent: css
  110. });
  111. if (id) {
  112. style.id = id;
  113. }
  114. $.asap((function() {
  115. return d.head;
  116. }), function() {
  117. return $.add(d.head, style);
  118. });
  119. return style;
  120. };
  121.  
  122. $.on = function(target, events, fun, once) {
  123. var event, fn, func, j, len1, ref;
  124. fn = function() {
  125. var err;
  126. try {
  127. return fun.apply(this, arguments);
  128. } catch (_error) {
  129. err = _error;
  130. console.log(err.message);
  131. return console.log(err.stack);
  132. }
  133. };
  134. func = once ? function() {
  135. $.off(target, events, func);
  136. return fn.apply(this, arguments);
  137. } : fn;
  138. ref = events.split(' ');
  139. for (j = 0, len1 = ref.length; j < len1; j++) {
  140. event = ref[j];
  141. target.addEventListener(event, func, false);
  142. }
  143. return func;
  144. };
  145.  
  146. $.off = function(target, events, fn) {
  147. var event, j, len1, ref;
  148. ref = events.split(' ');
  149. for (j = 0, len1 = ref.length; j < len1; j++) {
  150. event = ref[j];
  151. target.removeEventListener(event, fn, false);
  152. }
  153. return target;
  154. };
  155.  
  156. $.el = function(type, props) {
  157. var el, prop;
  158. el = d.createElement(type);
  159. for (prop in props) {
  160. if (props.hasOwnProperty(prop)) {
  161. el[prop] = props[prop];
  162. }
  163. }
  164. return el;
  165. };
  166.  
  167. $.nodes = function(nodes) {
  168. var frag, j, len1, node;
  169. if (!(nodes instanceof Array)) {
  170. return nodes;
  171. }
  172. frag = d.createDocumentFragment();
  173. for (j = 0, len1 = nodes.length; j < len1; j++) {
  174. node = nodes[j];
  175. frag.appendChild(node);
  176. }
  177. return frag;
  178. };
  179.  
  180. $.html = function(html) {
  181. var el;
  182. el = $.el('div', {
  183. innerHTML: html
  184. });
  185. return $.nodes(slice.call(el.children));
  186. };
  187.  
  188. $.add = function(root, nodes) {
  189. root.appendChild($.nodes(nodes));
  190. return root;
  191. };
  192.  
  193. $.replace = function(root, el) {
  194. return root.parentNode.replaceChild($.nodes(el), root);
  195. };
  196.  
  197. SimpleDict = (function() {
  198. function SimpleDict() {
  199. this.keys = [];
  200. }
  201.  
  202. SimpleDict.prototype.push = function(key, data) {
  203. key = "" + key;
  204. if (!this[key]) {
  205. this.keys.push(key);
  206. }
  207. this[key] = data;
  208. return this[key].key = key;
  209. };
  210.  
  211. SimpleDict.prototype.contains = function(obj) {
  212. return this.indexOf(obj) !== -1;
  213. };
  214.  
  215. SimpleDict.prototype.indexOf = function(obj) {
  216. var key;
  217. key = obj.key;
  218. if (key) {
  219. if (obj !== this[key]) {
  220. return -1;
  221. }
  222. return this.keys.indexOf(key);
  223. } else {
  224. return this.keys.indexOf(obj);
  225. }
  226. };
  227.  
  228. SimpleDict.prototype.rm = function(key) {
  229. var i;
  230. key = "" + key;
  231. i = this.keys.indexOf(key);
  232. if (i !== -1) {
  233. this.keys.splice(i, 1);
  234. return delete this[key];
  235. }
  236. };
  237.  
  238. SimpleDict.prototype.first = function() {
  239. return this[this.keys[0]];
  240. };
  241.  
  242. SimpleDict.prototype.forEach = function(fn) {
  243. var j, key, len1, ref;
  244. ref = slice.call(this.keys);
  245. for (j = 0, len1 = ref.length; j < len1; j++) {
  246. key = ref[j];
  247. fn.call(this, this[key]);
  248. }
  249. };
  250.  
  251. SimpleDict.prototype.forEachKey = function(fn) {
  252. var j, key, len1, ref;
  253. ref = slice.call(this.keys);
  254. for (j = 0, len1 = ref.length; j < len1; j++) {
  255. key = ref[j];
  256. fn.call(this, key);
  257. }
  258. };
  259.  
  260. Object.defineProperty(SimpleDict.prototype, 'length', {
  261. get: function() {
  262. return this.keys.length;
  263. }
  264. });
  265.  
  266. return SimpleDict;
  267.  
  268. })();
  269.  
  270. preload = function(image) {
  271. var galLength, i, len, results;
  272. galLength = g.images.length;
  273. i = g.currentImageIndex;
  274. len = Math.min(galLength, i + PRELOAD + 1);
  275. results = [];
  276. while (++i < len) {
  277. results.push($.el('img', {
  278. src: g.images[g.images.keys[i]].url
  279. }));
  280. }
  281. return results;
  282. };
  283.  
  284. loadGallery = function() {
  285. var close, count, err, gal, next, nodes, prev, thumbs;
  286. try {
  287. g.gallery = gal = $.el('div', {
  288. id: 'a-gallery',
  289. innerHTML: "<div class=\"gal-prev\"></div>\n<div class=\"gal-image\">\n <div>\n <div class=\"gal-info\">\n INFO\n <div class=\"gal-ex-info\">\n </div>\n </div>\n <div class=\"gal-close\">✖</div>\n <a class=\"current\"></a>\n </div>\n</div>\n<div class=\"gal-next\"></div>\n<div class=\"gal-thumbnails\"></div>"
  290. });
  291. nodes = g.nodes;
  292. nodes.prev = prev = $('.gal-prev', gal);
  293. nodes.next = next = $('.gal-next', gal);
  294. nodes.count = count = $('.gal-count', gal);
  295. nodes.thumbs = thumbs = $('.gal-thumbnails', gal);
  296. nodes.close = close = $('.gal-close', gal);
  297. $.on(close, 'click', cb.hideGallery);
  298. $.on(prev, 'click', cb.prev);
  299. $.on(next, 'click', cb.next);
  300. $.on(d, 'keydown', cb.keybinds);
  301. cb.hideGallery();
  302. return d.body.appendChild(gal);
  303. } catch (_error) {
  304. err = _error;
  305. console.log(err.message);
  306. return console.log(err.stack);
  307. }
  308. };
  309.  
  310. cb = {
  311. next: function() {
  312. ++g.currentImageIndex;
  313. return cb.updateImage();
  314. },
  315. prev: function() {
  316. --g.currentImageIndex;
  317. return cb.updateImage();
  318. },
  319. updateImage: function() {
  320. return setImage(g.images[g.images.keys[g.currentImageIndex]]);
  321. },
  322. showGallery: function() {
  323. g.gallery.style.display = 'flex';
  324. return d.body.style.overflow = 'hidden';
  325. },
  326. hideGallery: function() {
  327. cb.pause();
  328. g.gallery.style.display = 'none';
  329. g.currentImageIndex = 0;
  330. return d.body.style.overflow = 'auto';
  331. },
  332. highlight: function(image) {
  333. var gal, highlight, thumbs;
  334. if (!image) {
  335. if (!(image = g.images[g.images.keys[g.currentImageIndex]])) {
  336. return;
  337. }
  338. }
  339. gal = g.gallery;
  340. $('.gal-image', gal).scrollTop = 0;
  341. highlight = $('.gal-highlight', gal);
  342. if (highlight != null) {
  343. highlight.classList.remove('gal-highlight');
  344. }
  345. highlight = $("[data-id='" + image.id + "']", gal);
  346. if (highlight != null) {
  347. highlight.classList.add('gal-highlight');
  348. }
  349. thumbs = g.nodes.thumbs;
  350. return thumbs.scrollTop = highlight.offsetTop + highlight.offsetHeight / 2 - thumbs.clientHeight / 2;
  351. },
  352. toggleGallery: function() {
  353. return cb[g.gallery.style.display === 'block' ? 'hideGallery' : 'showGallery']();
  354. },
  355. keybinds: function(e) {
  356. var fn, key;
  357. if (!(key = e.keyCode)) {
  358. return;
  359. }
  360. fn = (function() {
  361. switch (key) {
  362. case 39:
  363. return cb.next;
  364. case 37:
  365. return cb.prev;
  366. case 27:
  367. return cb.hideGallery;
  368. }
  369. })();
  370. if (!fn) {
  371. return;
  372. }
  373. e.stopPropagation();
  374. e.preventDefault();
  375. return fn();
  376. },
  377. pause: function() {
  378. var current, el;
  379. current = $('.gal-image a', g.gallery);
  380. if (current) {
  381. el = current.firstElementChild;
  382. }
  383. if (el && el.pause) {
  384. return el.pause();
  385. }
  386. }
  387. };
  388.  
  389. fer = function(arr, fn) {
  390. var item, j, len1;
  391. for (j = 0, len1 = arr.length; j < len1; j++) {
  392. item = arr[j];
  393. fn(item);
  394. }
  395. };
  396.  
  397. clickThumb = function(e) {
  398. e.preventDefault();
  399. return $.asap((function() {
  400. return g.images.length;
  401. }), (function(_this) {
  402. return function() {
  403. var id, image, queryURL;
  404. id = _this.id.slice(1);
  405. image = g.images["" + id];
  406. cb.showGallery();
  407. if (!image) {
  408. queryURL = g.baseURL + "page=dapi&s=post&q=index&id=" + id;
  409. query("get", queryURL, function() {
  410. image = mkImage(this.response.childNodes[0].children[0]);
  411. return setImage(image);
  412. });
  413. return;
  414. }
  415. return setImage(image);
  416. };
  417. })(this));
  418. };
  419.  
  420. setImage = function(image) {
  421. var a, el, err, gal, i, img, info, j, len1, placeHolder, rating, ratingText, ready, ref, source, tag, tags;
  422. try {
  423. gal = g.gallery;
  424. cb.pause();
  425. el = $('.gal-image .current', gal);
  426. g.currentImageIndex = i = g.images.indexOf(image);
  427. a = $.el('a', {
  428. href: image.download,
  429. download: image.filename,
  430. className: 'current'
  431. });
  432. switch (image.type) {
  433. case "jpg":
  434. case "jpeg":
  435. case "gif":
  436. case "png":
  437. img = $.el('img', {
  438. src: image.url,
  439. alt: image.tags
  440. });
  441. ready = function() {
  442. return img.complete;
  443. };
  444. break;
  445. default:
  446. img = $.el('video', {
  447. src: image.url,
  448. poster: image.thumb,
  449. autoplay: true,
  450. loop: true,
  451. width: image.width,
  452. height: image.height
  453. });
  454. ready = function() {
  455. return img.readyState > 2;
  456. };
  457. }
  458. if (ready()) {
  459. $.add(a, img);
  460. preload();
  461. } else {
  462. placeHolder = $.el('div', {
  463. className: 'spinner'
  464. });
  465. $.add(a, placeHolder);
  466. $.asap(ready, function() {
  467. if (i !== g.currentImageIndex) {
  468. return;
  469. }
  470. $.replace(placeHolder, img);
  471. return preload();
  472. });
  473. }
  474. $.replace(el, a);
  475. a.parentElement.click();
  476. info = $('.gal-ex-info', gal);
  477. info.textContent = "ID: " + image.id + "\nScore: " + (image.score || 0) + "\nPosted: " + image.age + "\nWidth: " + image.width + "\nHeight: " + image.height + "\nType: " + (image.type.toUpperCase());
  478. info.innerHTML = "<p>" + (info.textContent.split('\n').join('</p><p>')) + "</p>";
  479. tags = $.el('p', {
  480. textContent: "Tags: "
  481. });
  482. ref = image.tags.split(' ');
  483. for (j = 0, len1 = ref.length; j < len1; j++) {
  484. tag = ref[j];
  485. $.add(tags, $.el('a', {
  486. href: g.baseURL + "page=post&s=list&tags=" + tag,
  487. textContent: tag,
  488. target: "_blank"
  489. }));
  490. $.add(tags, d.createTextNode(' '));
  491. }
  492. $.add(info, tags);
  493. ratingText = (function() {
  494. switch (image.rating) {
  495. case 'e':
  496. return 'explicit';
  497. case 's':
  498. return 'safe';
  499. default:
  500. return 'questionable';
  501. }
  502. })();
  503. rating = $.el('p', {
  504. textContent: "Rating: "
  505. });
  506. $.add(rating, $.el('a', {
  507. href: g.baseURL + "page=post&s=list&tags=rating:" + ratingText,
  508. textContent: ratingText,
  509. target: "_blank"
  510. }));
  511. $.add(info, rating);
  512. if (image.source) {
  513. source = $.el('p', {
  514. textContent: "Source: "
  515. });
  516. $.add(source, $.el('a', {
  517. href: image.source,
  518. textContent: image.source,
  519. target: "_blank"
  520. }));
  521. $.add(info, source);
  522. }
  523. cb.highlight(image);
  524. if (i + THRESHOLD > g.images.length) {
  525. return updateImages();
  526. }
  527. } catch (_error) {
  528. err = _error;
  529. console.log(err.message);
  530. return console.log(err.stack);
  531. }
  532. };
  533.  
  534. updateImages = function() {
  535. var queryURL;
  536. queryURL = mkURL(g.images.length / LIMIT);
  537. return queryImages(queryURL);
  538. };
  539.  
  540. setupImages = function() {
  541. var err, j, len1, parser, post, ref, response, results;
  542. try {
  543. if (this.status !== 200) {
  544. g.error = true;
  545. return alert(this.status + ": " + this.statusText);
  546. }
  547. parser = new DOMParser();
  548. response = parser.parseFromString(this.response, 'text/xml');
  549. ref = response.childNodes[0].children;
  550. results = [];
  551. for (j = 0, len1 = ref.length; j < len1; j++) {
  552. post = ref[j];
  553. results.push(mkImage(post));
  554. }
  555. return results;
  556. } catch (_error) {
  557. err = _error;
  558. console.log(err.message);
  559. return console.log(err.stack);
  560. }
  561. };
  562.  
  563. mkImage = function(post) {
  564. var a, download, extension, filename, image, item, j, len1, p, ref, ref1, tags, thumb, type;
  565. p = {};
  566. ref = post.attributes;
  567. for (j = 0, len1 = ref.length; j < len1; j++) {
  568. item = ref[j];
  569. p[item.name] = item.value;
  570. }
  571. a = $.el('a', {
  572. href: p.file_url
  573. });
  574. a.host = 'gelbooru.com';
  575. download = a.href;
  576. type = download.split('.');
  577. type = ("" + type[type.length - 1]).toLowerCase();
  578. extension = "." + type;
  579. tags = p.tags.split(' ');
  580. while (true) {
  581. filename = p.id + " - " + (tags.join(' ').trim());
  582. tags.pop();
  583. if (!(filename.length + extension.length > FNLIMIT)) {
  584. break;
  585. }
  586. }
  587. filename += extension;
  588. image = {
  589. thumb: p.preview_url,
  590. url: p.sample_url,
  591. rating: p.rating,
  592. source: p.source,
  593. width: p.width,
  594. height: p.height,
  595. score: p.score,
  596. tags: (ref1 = p.tags) != null ? ref1.trim() : void 0,
  597. id: p.id,
  598. age: p.created_at,
  599. filename: filename,
  600. download: download,
  601. type: type
  602. };
  603. thumb = $.el('a', {
  604. href: "javascript:;",
  605. className: 'gal-thumb',
  606. innerHTML: "<img src='" + image.thumb + "'>"
  607. });
  608. thumb.setAttribute('data-id', image.id);
  609. $.on(thumb, 'click', function() {
  610. g.currentImageIndex = g.images.indexOf(image);
  611. return setImage(image);
  612. });
  613. $.add(g.nodes.thumbs, thumb);
  614. g.images.push(p.id, image);
  615. return image;
  616. };
  617.  
  618. query = function(method, URL, callback) {
  619. var r;
  620. r = new XMLHttpRequest();
  621. r.open("get", URL, true);
  622. $.on(r, "load error abort", callback, true);
  623. r.send();
  624. return r;
  625. };
  626.  
  627. queryImages = function(URL) {
  628. if (g.error) {
  629. return;
  630. }
  631. return query("get", URL, setupImages);
  632. };
  633.  
  634. mkURL = function(pid) {
  635. var j, key, len1, queryURL, ref;
  636. if (pid) {
  637. g.attr.pid = pid;
  638. }
  639. queryURL = g.baseURL;
  640. ref = g.attr.keys;
  641. for (j = 0, len1 = ref.length; j < len1; j++) {
  642. key = ref[j];
  643. queryURL += key + "=" + g.attr[key] + "&";
  644. }
  645. return queryURL = queryURL.slice(0, -1);
  646. };
  647.  
  648. setup = function() {
  649. var attr, j, len1, ref;
  650. g.images = new SimpleDict();
  651. g.host = d.location;
  652. g.attr = new SimpleDict();
  653. ref = g.host.search.slice(1).split('&');
  654. for (j = 0, len1 = ref.length; j < len1; j++) {
  655. attr = ref[j];
  656. attr = attr.split('=');
  657. g.attr.push(attr[0].toLowerCase(), attr[1].toLowerCase());
  658. }
  659. if (g.attr.s === 'view') {
  660. return;
  661. }
  662. g.baseURL = g.host.protocol + "//" + g.host.hostname + "/index.php?";
  663. g.attr.push('page', 'dapi');
  664. g.attr.push('q', 'index');
  665. g.attr.push('s', 'post');
  666. g.attr.push('limit', 100);
  667. if (g.attr.tags === 'all') {
  668. g.attr.rm('tags');
  669. }
  670. if (g.attr.pid) {
  671. g.attr.pid = ~~(g.attr.pid / 100);
  672. } else {
  673. g.attr.push('pid', 0);
  674. }
  675. g.queryURL = mkURL();
  676. $.addStyle(g.galleryCSS);
  677. return $.asap((function() {
  678. var ref1;
  679. return (ref1 = d.readyState) === 'interactive' || ref1 === 'complete';
  680. }), function() {
  681. var k, len2, ref1, thumb;
  682. ref1 = $.$('.thumb a');
  683. for (k = 0, len2 = ref1.length; k < len2; k++) {
  684. thumb = ref1[k];
  685. $.on(thumb, 'click', clickThumb);
  686. }
  687. loadGallery();
  688. return queryImages(g.queryURL);
  689. });
  690. };
  691.  
  692. try {
  693. setup();
  694. } catch (_error) {
  695. err = _error;
  696. console.log(err.message);
  697. console.log(err.stack);
  698. }
  699.  
  700. }).call(this);