This commit is contained in:
Flummi
2021-12-31 07:18:41 +01:00
parent a9116a52d9
commit 0399fa9e51
28 changed files with 2102 additions and 0 deletions

13
test2/lib/events.js Normal file
View File

@ -0,0 +1,13 @@
$(document).ready(() => {
$(window).on("resize", () => f.render());
$(window).bind('mousewheel DOMMouseScroll MozMousePixelScroll', event => {
f.page = (event.originalEvent.wheelDelta / 120 > 0)?-1:1;
});
$("div#up").on("click", () => {
f.page = -1;
});
$("div#down").on("click", () => {
f.page = 1;
});
});

178
test2/lib/f0ck.js Normal file
View File

@ -0,0 +1,178 @@
class f0ck {
constructor(hash = "") {
this.debug();
this.tpl = {
row: ({ items }) => `<ul class="posts">${items}</ul>`,
item: ({ id, title, stamp }) => `<li class="post"><a href="https://f0ck.me/${id}" title="${title} ; ${stamp}"><img class="thumb" src="https://f0ck.me/t/${id}.png" /></a></li>`,
};
this.numitems = this.sumItems();
this.items = {
items: [],
last: null,
first: null
};
this.tmphash = null;
this.hash = hash;
}
loadItems(init=false) {
this.getItems().then(
resolve => {
console.log("resolved", this.items);
//if(init) this.render(init);
},
reject => {
console.error("REJECTED!");
}
);
}
getItems() {
return new Promise((resolve, reject) => {
$.getJSON(`${this.tmphash.link},${(this.numitems.ipp*2)}`, data => {
console.log("received data", data);
this.items.last = data.meta.last;
this.items.first = data.meta.first;
for(let item in data.items) {
this.items.items[data.items[item].stamp] = data.items[item];
}
return resolve();
}).fail(err => {
return reject();
});
});
}
sumItems() {
let h = $(window).innerHeight();
let w = $(window).innerWidth();
let itemsize = 128;
let spacing = 10;
let header = 90;
let ipr = Math.floor( w / ( itemsize + spacing ) );
let rpp = Math.floor( ( h - header ) / ( itemsize + spacing ) );
let ipp = Math.floor( ipr * rpp );
return {
ipr: ipr, // items per row
rpp: rpp, // rows per page
ipp: ipp // items per page
};
}
render(init=false) {
let tmpnum = this.sumItems();
let container = $("div#con");
if(this.numitems.ipp !== tmpnum.ipp || init) {
console.log("rendering from", this.current);
if(typeof this.current !== "number")
return;
container.html("");
this.numitems = tmpnum;
let rowtpl = "";
let j, tmplast = 0;
for(var i = this.current+1; j < this.numitems.ipp; i--) {
if(this.items[i]) {
rowtpl += [{ id: this.items[i].id, title: this.items[i].mime, stamp: this.items[i].stamp }].map(this.tpl.item).join``;
j++;
tmplast = this.items[i].stamp;
}
if(this.items.length < i) {
j = this.numitems.ipp;
}
}
this.scope.last = tmplast;
console.log("finished rendering", container.length);
container.append( [{ items: rowtpl }].map(this.tpl.row).join`` );
}
}
set hash(val) {
console.log("hash changed");
let tmp = this.getlink(val);
this.tmphash = tmp;
//if(tmp.last < this.scope.first) {
this.current = tmp.last;
this.loadItems(true);
//}
//else if(tmp.last > this.scope.last || this.scope.last === 0) {
// this.current = tmp.last;
// this.loadItems(true);
//}
}
gethash() {
return this.tmphash;
}
debug() {
$(".navbar a").on("click", event => {
switch(event.target.innerText) {
case "page 1":
this.currentpage = 0;
this.render(true);
break;
case "page 2":
this.currentpage = 1;
this.render(true);
break;
case "page 3":
this.currentpage = 2;
this.render(true);
break;
default:
console.log("nope");
break;
}
$(".navbar span").html(`Page ${this.currentpage}`);
});
}
getlink(tmp) {
const tpl = {
user: ({ user, mime, last, eps }) => `user,${user},${mime},${last}`,
mime: ({ user, mime, last, eps }) => `mime,${mime},${user},${last}`,
new: ({ user, mime, last, eps }) => `items,${last}`,
};
let blah = {
mode: "",
user: "",
mime: "",
last: 0,
post: 0
};
let api = "/api/?";
if(!tmp.match(/\//)) {
tmp = "#new/";
}
tmp = (tmp.match(/,/)?tmp:`${tmp},`).substr(1).split(",");
console.log(tmp);
const args = {
l: tmp[0].split("/"),
r: tmp[1].split("/")
};
blah.mode = ( args.l[0].length === 0 )? "new" : args.l[0];
blah.last = parseInt(args.r[0]) || 0;
blah.post = parseInt(args.r[1]) || 0;
switch(blah.mode) {
case "user":
blah.user = ( args.l[1].length === 0 )? "" : args.l[1];
blah.mime = ( args.l[2].length === 0 )? "" : args.l[2];
break;
case "mime":
blah.user = ( args.l[2].length === 0 )? "" : args.l[2];
blah.mime = ( args.l[1].length === 0 )? "" : args.l[1];
break;
}
return {
link: api + [{ user: blah.user, mime: blah.mime, last: blah.last, eps: this.numitems.ipp }].map(tpl[blah.mode]).join``,
args: blah
};
}
}

View File

@ -0,0 +1,299 @@
/*!
* jQuery hashchange event - v1.3 - 7/21/2010
* http://benalman.com/projects/jquery-hashchange-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
// Script: jQuery hashchange event
//
// *Version: 1.3, Last updated: 7/21/2010*
//
// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
// GitHub - http://github.com/cowboy/jquery-hashchange/
// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped)
//
// About: License
//
// Copyright (c) 2010 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
//
// About: Examples
//
// These working examples, complete with fully commented code, illustrate a few
// ways in which this plugin can be used.
//
// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/
//
// About: Support and Testing
//
// Information about what version or versions of jQuery this plugin has been
// tested with, what browsers it has been tested in, and where the unit tests
// reside (so you can test it yourself).
//
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/
//
// About: Known issues
//
// While this jQuery hashchange event implementation is quite stable and
// robust, there are a few unfortunate browser bugs surrounding expected
// hashchange event-based behaviors, independent of any JavaScript
// window.onhashchange abstraction. See the following examples for more
// information:
//
// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
//
// Also note that should a browser natively support the window.onhashchange
// event, but not report that it does, the fallback polling loop will be used.
//
// About: Release History
//
// 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more
// "removable" for mobile-only development. Added IE6/7 document.title
// support. Attempted to make Iframe as hidden as possible by using
// techniques from http://www.paciellogroup.com/blog/?p=604. Added
// support for the "shortcut" format $(window).hashchange( fn ) and
// $(window).hashchange() like jQuery provides for built-in events.
// Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and
// lowered its default value to 50. Added <jQuery.fn.hashchange.domain>
// and <jQuery.fn.hashchange.src> properties plus document-domain.html
// file to address access denied issues when setting document.domain in
// IE6/7.
// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin
// from a page on another domain would cause an error in Safari 4. Also,
// IE6/7 Iframe is now inserted after the body (this actually works),
// which prevents the page from scrolling when the event is first bound.
// Event can also now be bound before DOM ready, but it won't be usable
// before then in IE6/7.
// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
// where browser version is incorrectly reported as 8.0, despite
// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
// window.onhashchange functionality into a separate plugin for users
// who want just the basic event & back button support, without all the
// extra awesomeness that BBQ provides. This plugin will be included as
// part of jQuery BBQ, but also be available separately.
(function($,window,undefined){
'$:nomunge'; // Used by YUI compressor.
// Reused string.
var str_hashchange = 'hashchange',
// Method / object references.
doc = document,
fake_onhashchange,
special = $.event.special,
// Does the browser support window.onhashchange? Note that IE8 running in
// IE7 compatibility mode reports true for 'onhashchange' in window, even
// though the event isn't supported, so also test document.documentMode.
doc_mode = doc.documentMode,
supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );
// Get location.hash (or what you'd expect location.hash to be) sans any
// leading #. Thanks for making this necessary, Firefox!
function get_fragment( url ) {
url = url || location.href;
return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
};
// Method: jQuery.fn.hashchange
//
// Bind a handler to the window.onhashchange event or trigger all bound
// window.onhashchange event handlers. This behavior is consistent with
// jQuery's built-in event handlers.
//
// Usage:
//
// > jQuery(window).hashchange( [ handler ] );
//
// Arguments:
//
// handler - (Function) Optional handler to be bound to the hashchange
// event. This is a "shortcut" for the more verbose form:
// jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
// all bound window.onhashchange event handlers will be triggered. This
// is a shortcut for the more verbose
// jQuery(window).trigger( 'hashchange' ). These forms are described in
// the <hashchange event> section.
//
// Returns:
//
// (jQuery) The initial jQuery collection of elements.
// Allow the "shortcut" format $(elem).hashchange( fn ) for binding and
// $(elem).hashchange() for triggering, like jQuery does for built-in events.
$.fn[ str_hashchange ] = function( fn ) {
return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
};
// Property: jQuery.fn.hashchange.delay
//
// The numeric interval (in milliseconds) at which the <hashchange event>
// polling loop executes. Defaults to 50.
// Property: jQuery.fn.hashchange.domain
//
// If you're setting document.domain in your JavaScript, and you want hash
// history to work in IE6/7, not only must this property be set, but you must
// also set document.domain BEFORE jQuery is loaded into the page. This
// property is only applicable if you are supporting IE6/7 (or IE8 operating
// in "IE7 compatibility" mode).
//
// In addition, the <jQuery.fn.hashchange.src> property must be set to the
// path of the included "document-domain.html" file, which can be renamed or
// modified if necessary (note that the document.domain specified must be the
// same in both your main JavaScript as well as in this file).
//
// Usage:
//
// jQuery.fn.hashchange.domain = document.domain;
// Property: jQuery.fn.hashchange.src
//
// If, for some reason, you need to specify an Iframe src file (for example,
// when setting document.domain as in <jQuery.fn.hashchange.domain>), you can
// do so using this property. Note that when using this property, history
// won't be recorded in IE6/7 until the Iframe src file loads. This property
// is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7
// compatibility" mode).
//
// Usage:
//
// jQuery.fn.hashchange.src = 'path/to/file.html';
$.fn[ str_hashchange ].delay = 50;
/*
$.fn[ str_hashchange ].domain = null;
$.fn[ str_hashchange ].src = null;
*/
// Event: hashchange event
//
// Fired when location.hash changes. In browsers that support it, the native
// HTML5 window.onhashchange event is used, otherwise a polling loop is
// initialized, running every <jQuery.fn.hashchange.delay> milliseconds to
// see if the hash has changed. In IE6/7 (and IE8 operating in "IE7
// compatibility" mode), a hidden Iframe is created to allow the back button
// and hash-based history to work.
//
// Usage as described in <jQuery.fn.hashchange>:
//
// > // Bind an event handler.
// > jQuery(window).hashchange( function(e) {
// > var hash = location.hash;
// > ...
// > });
// >
// > // Manually trigger the event handler.
// > jQuery(window).hashchange();
//
// A more verbose usage that allows for event namespacing:
//
// > // Bind an event handler.
// > jQuery(window).bind( 'hashchange', function(e) {
// > var hash = location.hash;
// > ...
// > });
// >
// > // Manually trigger the event handler.
// > jQuery(window).trigger( 'hashchange' );
//
// Additional Notes:
//
// * The polling loop and Iframe are not created until at least one handler
// is actually bound to the 'hashchange' event.
// * If you need the bound handler(s) to execute immediately, in cases where
// a location.hash exists on page load, via bookmark or page refresh for
// example, use jQuery(window).hashchange() or the more verbose
// jQuery(window).trigger( 'hashchange' ).
// * The event can be bound before DOM ready, but since it won't be usable
// before then in IE6/7 (due to the necessary Iframe), recommended usage is
// to bind it inside a DOM ready handler.
// Override existing $.event.special.hashchange methods (allowing this plugin
// to be defined after jQuery BBQ in BBQ's source code).
special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
// Called only when the first 'hashchange' event is bound to window.
setup: function() {
// If window.onhashchange is supported natively, there's nothing to do..
if ( supports_onhashchange ) { return false; }
// Otherwise, we need to create our own. And we don't want to call this
// until the user binds to the event, just in case they never do, since it
// will create a polling loop and possibly even a hidden Iframe.
$( fake_onhashchange.start );
},
// Called only when the last 'hashchange' event is unbound from window.
teardown: function() {
// If window.onhashchange is supported natively, there's nothing to do..
if ( supports_onhashchange ) { return false; }
// Otherwise, we need to stop ours (if possible).
$( fake_onhashchange.stop );
}
});
// fake_onhashchange does all the work of triggering the window.onhashchange
// event for browsers that don't natively support it, including creating a
// polling loop to watch for hash changes and in IE 6/7 creating a hidden
// Iframe to enable back and forward.
fake_onhashchange = (function(){
var self = {},
timeout_id,
// Remember the initial hash so it doesn't get triggered immediately.
last_hash = get_fragment(),
fn_retval = function(val){ return val; },
history_set = fn_retval,
history_get = fn_retval;
// Start the polling loop.
self.start = function() {
timeout_id || poll();
};
// Stop the polling loop.
self.stop = function() {
timeout_id && clearTimeout( timeout_id );
timeout_id = undefined;
};
// This polling loop checks every $.fn.hashchange.delay milliseconds to see
// if location.hash has changed, and triggers the 'hashchange' event on
// window when necessary.
function poll() {
var hash = get_fragment(),
history_hash = history_get( last_hash );
if ( hash !== last_hash ) {
history_set( last_hash = hash, history_hash );
$(window).trigger( str_hashchange );
} else if ( history_hash !== last_hash ) {
location.href = location.href.replace( /#.*/, '' ) + history_hash;
}
timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
};
return self;
})();
})(jQuery,this);

35
test2/lib/lib.js Normal file
View File

@ -0,0 +1,35 @@
var getlink = tmp => {
const tpl = {
user: ({ user, mime, last, eps }) => `user,${user},${mime},${last},${eps}`,
mime: ({ user, mime, last, eps }) => `mime,${mime},${user},${last},${eps}`,
new: ({ user, mime, last, eps }) => `items,${last},${eps}`,
};
let api = "/api/?";
tmp = (tmp.match(/,/)?tmp:`${tmp},`).substr(1).split(",");
const args = {
l: tmp[0].split("/"),
r: tmp[1].split("/")
};
tmp = {
mode: "",
user: "",
mime: "",
last: 0,
post: 0
};
tmp.mode = ( args.l[0].length === 0 )? "new" : args.l[0];
tmp.last = parseInt(args.r[0]) || 0;
tmp.post = parseInt(args.r[1]) || 0;
switch(tmp.mode) {
case "user":
tmp.user = ( args.l[1].length === 0 )? "" : args.l[1];
tmp.mime = ( args.l[2].length === 0 )? "" : args.l[2];
break;
case "mime":
tmp.user = ( args.l[2].length === 0 )? "" : args.l[2];
tmp.mime = ( args.l[1].length === 0 )? "" : args.l[1];
break;
}
return api + [{ user: tmp.user, mime: tmp.mime, last: tmp.last, eps: 3 }].map(tpl[tmp.mode]).join``;
};