1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 09:49:28 +02:00

Improving the get restream credentials

This commit is contained in:
DanieL 2022-05-20 16:22:54 -03:00
parent 654dda115a
commit 56cb1fd5cb
6058 changed files with 1166166 additions and 1430809 deletions

View file

@ -1,371 +1,371 @@
// core
( function( window, factory ) {
// universal module definition
if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
window,
require('ev-emitter'),
require('fizzy-ui-utils'),
);
} else {
// browser global
window.InfiniteScroll = factory(
window,
window.EvEmitter,
window.fizzyUIUtils,
);
}
}( window, function factory( window, EvEmitter, utils ) {
let jQuery = window.jQuery;
// internal store of all InfiniteScroll intances
let instances = {};
function InfiniteScroll( element, options ) {
let queryElem = utils.getQueryElement( element );
if ( !queryElem ) {
console.error( 'Bad element for InfiniteScroll: ' + ( queryElem || element ) );
return;
}
element = queryElem;
// do not initialize twice on same element
if ( element.infiniteScrollGUID ) {
let instance = instances[ element.infiniteScrollGUID ];
instance.option( options );
return instance;
}
this.element = element;
// options
this.options = { ...InfiniteScroll.defaults };
this.option( options );
// add jQuery
if ( jQuery ) {
this.$element = jQuery( this.element );
}
this.create();
}
// defaults
InfiniteScroll.defaults = {
// path: null,
// hideNav: null,
// debug: false,
};
// create & destroy methods
InfiniteScroll.create = {};
InfiniteScroll.destroy = {};
let proto = InfiniteScroll.prototype;
// inherit EvEmitter
Object.assign( proto, EvEmitter.prototype );
// -------------------------- -------------------------- //
// globally unique identifiers
let GUID = 0;
proto.create = function() {
// create core
// add id for InfiniteScroll.data
let id = this.guid = ++GUID;
this.element.infiniteScrollGUID = id; // expando
instances[ id ] = this; // associate via id
// properties
this.pageIndex = 1; // default to first page
this.loadCount = 0;
this.updateGetPath();
// bail if getPath not set, or returns falsey #776
let hasPath = this.getPath && this.getPath();
if ( !hasPath ) {
console.error('Disabling InfiniteScroll');
return;
}
this.updateGetAbsolutePath();
this.log( 'initialized', [ this.element.className ] );
this.callOnInit();
// create features
for ( let method in InfiniteScroll.create ) {
InfiniteScroll.create[ method ].call( this );
}
};
proto.option = function( opts ) {
Object.assign( this.options, opts );
};
// call onInit option, used for binding events on init
proto.callOnInit = function() {
let onInit = this.options.onInit;
if ( onInit ) {
onInit.call( this, this );
}
};
// ----- events ----- //
proto.dispatchEvent = function( type, event, args ) {
this.log( type, args );
let emitArgs = event ? [ event ].concat( args ) : args;
this.emitEvent( type, emitArgs );
// trigger jQuery event
if ( !jQuery || !this.$element ) {
return;
}
// namespace jQuery event
type += '.infiniteScroll';
let $event = type;
if ( event ) {
// create jQuery event
/* eslint-disable-next-line new-cap */
let jQEvent = jQuery.Event( event );
jQEvent.type = type;
$event = jQEvent;
}
this.$element.trigger( $event, args );
};
let loggers = {
initialized: ( className ) => `on ${className}`,
request: ( path ) => `URL: ${path}`,
load: ( response, path ) => `${response.title || ''}. URL: ${path}`,
error: ( error, path ) => `${error}. URL: ${path}`,
append: ( response, path, items ) => `${items.length} items. URL: ${path}`,
last: ( response, path ) => `URL: ${path}`,
history: ( title, path ) => `URL: ${path}`,
pageIndex: function( index, origin ) {
return `current page determined to be: ${index} from ${origin}`;
},
};
// log events
proto.log = function( type, args ) {
if ( !this.options.debug ) return;
let message = `[InfiniteScroll] ${type}`;
let logger = loggers[ type ];
if ( logger ) message += '. ' + logger.apply( this, args );
console.log( message );
};
// -------------------------- methods used amoung features -------------------------- //
proto.updateMeasurements = function() {
this.windowHeight = window.innerHeight;
let rect = this.element.getBoundingClientRect();
this.top = rect.top + window.scrollY;
};
proto.updateScroller = function() {
let elementScroll = this.options.elementScroll;
if ( !elementScroll ) {
// default, use window
this.scroller = window;
return;
}
// if true, set to element, otherwise use option
this.scroller = elementScroll === true ? this.element :
utils.getQueryElement( elementScroll );
if ( !this.scroller ) {
throw new Error(`Unable to find elementScroll: ${elementScroll}`);
}
};
// -------------------------- page path -------------------------- //
proto.updateGetPath = function() {
let optPath = this.options.path;
if ( !optPath ) {
console.error(`InfiniteScroll path option required. Set as: ${optPath}`);
return;
}
// function
let type = typeof optPath;
if ( type == 'function' ) {
this.getPath = optPath;
return;
}
// template string: '/pages/{{#}}.html'
let templateMatch = type == 'string' && optPath.match('{{#}}');
if ( templateMatch ) {
this.updateGetPathTemplate( optPath );
return;
}
// selector: '.next-page-selector'
this.updateGetPathSelector( optPath );
};
proto.updateGetPathTemplate = function( optPath ) {
// set getPath with template string
this.getPath = () => {
let nextIndex = this.pageIndex + 1;
return optPath.replace( '{{#}}', nextIndex );
};
// get pageIndex from location
// convert path option into regex to look for pattern in location
// escape query (?) in url, allows for parsing GET parameters
let regexString = optPath
.replace( /(\\\?|\?)/, '\\?' )
.replace( '{{#}}', '(\\d\\d?\\d?)' );
let templateRe = new RegExp( regexString );
let match = location.href.match( templateRe );
if ( match ) {
this.pageIndex = parseInt( match[1], 10 );
this.log( 'pageIndex', [ this.pageIndex, 'template string' ] );
}
};
let pathRegexes = [
// WordPress & Tumblr - example.com/page/2
// Jekyll - example.com/page2
/^(.*?\/?page\/?)(\d\d?\d?)(.*?$)/,
// Drupal - example.com/?page=1
/^(.*?\/?\?page=)(\d\d?\d?)(.*?$)/,
// catch all, last occurence of a number
/(.*?)(\d\d?\d?)(?!.*\d)(.*?$)/,
];
// try matching href to pathRegexes patterns
let getPathParts = InfiniteScroll.getPathParts = function( href ) {
if ( !href ) return;
for ( let regex of pathRegexes ) {
let match = href.match( regex );
if ( match ) {
let [ , begin, index, end ] = match;
return { begin, index, end };
}
}
};
proto.updateGetPathSelector = function( optPath ) {
// parse href of link: '.next-page-link'
let hrefElem = document.querySelector( optPath );
if ( !hrefElem ) {
console.error(`Bad InfiniteScroll path option. Next link not found: ${optPath}`);
return;
}
let href = hrefElem.getAttribute('href');
let pathParts = getPathParts( href );
if ( !pathParts ) {
console.error(`InfiniteScroll unable to parse next link href: ${href}`);
return;
}
let { begin, index, end } = pathParts;
this.isPathSelector = true; // flag for checkLastPage()
this.getPath = () => begin + ( this.pageIndex + 1 ) + end;
// get pageIndex from href
this.pageIndex = parseInt( index, 10 ) - 1;
this.log( 'pageIndex', [ this.pageIndex, 'next link' ] );
};
proto.updateGetAbsolutePath = function() {
let path = this.getPath();
// path doesn't start with http or /
let isAbsolute = path.match( /^http/ ) || path.match( /^\// );
if ( isAbsolute ) {
this.getAbsolutePath = this.getPath;
return;
}
let { pathname } = location;
// query parameter #829. example.com/?pg=2
let isQuery = path.match( /^\?/ );
// /foo/bar/index.html => /foo/bar
let directory = pathname.substring( 0, pathname.lastIndexOf('/') );
let pathStart = isQuery ? pathname : directory + '/';
this.getAbsolutePath = () => pathStart + this.getPath();
};
// -------------------------- nav -------------------------- //
// hide navigation
InfiniteScroll.create.hideNav = function() {
let nav = utils.getQueryElement( this.options.hideNav );
if ( !nav ) return;
nav.style.display = 'none';
this.nav = nav;
};
InfiniteScroll.destroy.hideNav = function() {
if ( this.nav ) this.nav.style.display = '';
};
// -------------------------- destroy -------------------------- //
proto.destroy = function() {
this.allOff(); // remove all event listeners
// call destroy methods
for ( let method in InfiniteScroll.destroy ) {
InfiniteScroll.destroy[ method ].call( this );
}
delete this.element.infiniteScrollGUID;
delete instances[ this.guid ];
// remove jQuery data. #807
if ( jQuery && this.$element ) {
jQuery.removeData( this.element, 'infiniteScroll' );
}
};
// -------------------------- utilities -------------------------- //
// https://remysharp.com/2010/07/21/throttling-function-calls
InfiniteScroll.throttle = function( fn, threshold ) {
threshold = threshold || 200;
let last, timeout;
return function() {
let now = +new Date();
let args = arguments;
let trigger = () => {
last = now;
fn.apply( this, args );
};
if ( last && now < last + threshold ) {
// hold on to it
clearTimeout( timeout );
timeout = setTimeout( trigger, threshold );
} else {
trigger();
}
};
};
InfiniteScroll.data = function( elem ) {
elem = utils.getQueryElement( elem );
let id = elem && elem.infiniteScrollGUID;
return id && instances[ id ];
};
// set internal jQuery, for Webpack + jQuery v3
InfiniteScroll.setJQuery = function( jqry ) {
jQuery = jqry;
};
// -------------------------- setup -------------------------- //
utils.htmlInit( InfiniteScroll, 'infinite-scroll' );
// add noop _init method for jQuery Bridget. #768
proto._init = function() {};
let { jQueryBridget } = window;
if ( jQuery && jQueryBridget ) {
jQueryBridget( 'infiniteScroll', InfiniteScroll, jQuery );
}
// -------------------------- -------------------------- //
return InfiniteScroll;
} ) );
// core
( function( window, factory ) {
// universal module definition
if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
window,
require('ev-emitter'),
require('fizzy-ui-utils'),
);
} else {
// browser global
window.InfiniteScroll = factory(
window,
window.EvEmitter,
window.fizzyUIUtils,
);
}
}( window, function factory( window, EvEmitter, utils ) {
let jQuery = window.jQuery;
// internal store of all InfiniteScroll intances
let instances = {};
function InfiniteScroll( element, options ) {
let queryElem = utils.getQueryElement( element );
if ( !queryElem ) {
console.error( 'Bad element for InfiniteScroll: ' + ( queryElem || element ) );
return;
}
element = queryElem;
// do not initialize twice on same element
if ( element.infiniteScrollGUID ) {
let instance = instances[ element.infiniteScrollGUID ];
instance.option( options );
return instance;
}
this.element = element;
// options
this.options = { ...InfiniteScroll.defaults };
this.option( options );
// add jQuery
if ( jQuery ) {
this.$element = jQuery( this.element );
}
this.create();
}
// defaults
InfiniteScroll.defaults = {
// path: null,
// hideNav: null,
// debug: false,
};
// create & destroy methods
InfiniteScroll.create = {};
InfiniteScroll.destroy = {};
let proto = InfiniteScroll.prototype;
// inherit EvEmitter
Object.assign( proto, EvEmitter.prototype );
// -------------------------- -------------------------- //
// globally unique identifiers
let GUID = 0;
proto.create = function() {
// create core
// add id for InfiniteScroll.data
let id = this.guid = ++GUID;
this.element.infiniteScrollGUID = id; // expando
instances[ id ] = this; // associate via id
// properties
this.pageIndex = 1; // default to first page
this.loadCount = 0;
this.updateGetPath();
// bail if getPath not set, or returns falsey #776
let hasPath = this.getPath && this.getPath();
if ( !hasPath ) {
console.error('Disabling InfiniteScroll');
return;
}
this.updateGetAbsolutePath();
this.log( 'initialized', [ this.element.className ] );
this.callOnInit();
// create features
for ( let method in InfiniteScroll.create ) {
InfiniteScroll.create[ method ].call( this );
}
};
proto.option = function( opts ) {
Object.assign( this.options, opts );
};
// call onInit option, used for binding events on init
proto.callOnInit = function() {
let onInit = this.options.onInit;
if ( onInit ) {
onInit.call( this, this );
}
};
// ----- events ----- //
proto.dispatchEvent = function( type, event, args ) {
this.log( type, args );
let emitArgs = event ? [ event ].concat( args ) : args;
this.emitEvent( type, emitArgs );
// trigger jQuery event
if ( !jQuery || !this.$element ) {
return;
}
// namespace jQuery event
type += '.infiniteScroll';
let $event = type;
if ( event ) {
// create jQuery event
/* eslint-disable-next-line new-cap */
let jQEvent = jQuery.Event( event );
jQEvent.type = type;
$event = jQEvent;
}
this.$element.trigger( $event, args );
};
let loggers = {
initialized: ( className ) => `on ${className}`,
request: ( path ) => `URL: ${path}`,
load: ( response, path ) => `${response.title || ''}. URL: ${path}`,
error: ( error, path ) => `${error}. URL: ${path}`,
append: ( response, path, items ) => `${items.length} items. URL: ${path}`,
last: ( response, path ) => `URL: ${path}`,
history: ( title, path ) => `URL: ${path}`,
pageIndex: function( index, origin ) {
return `current page determined to be: ${index} from ${origin}`;
},
};
// log events
proto.log = function( type, args ) {
if ( !this.options.debug ) return;
let message = `[InfiniteScroll] ${type}`;
let logger = loggers[ type ];
if ( logger ) message += '. ' + logger.apply( this, args );
console.log( message );
};
// -------------------------- methods used amoung features -------------------------- //
proto.updateMeasurements = function() {
this.windowHeight = window.innerHeight;
let rect = this.element.getBoundingClientRect();
this.top = rect.top + window.scrollY;
};
proto.updateScroller = function() {
let elementScroll = this.options.elementScroll;
if ( !elementScroll ) {
// default, use window
this.scroller = window;
return;
}
// if true, set to element, otherwise use option
this.scroller = elementScroll === true ? this.element :
utils.getQueryElement( elementScroll );
if ( !this.scroller ) {
throw new Error(`Unable to find elementScroll: ${elementScroll}`);
}
};
// -------------------------- page path -------------------------- //
proto.updateGetPath = function() {
let optPath = this.options.path;
if ( !optPath ) {
console.error(`InfiniteScroll path option required. Set as: ${optPath}`);
return;
}
// function
let type = typeof optPath;
if ( type == 'function' ) {
this.getPath = optPath;
return;
}
// template string: '/pages/{{#}}.html'
let templateMatch = type == 'string' && optPath.match('{{#}}');
if ( templateMatch ) {
this.updateGetPathTemplate( optPath );
return;
}
// selector: '.next-page-selector'
this.updateGetPathSelector( optPath );
};
proto.updateGetPathTemplate = function( optPath ) {
// set getPath with template string
this.getPath = () => {
let nextIndex = this.pageIndex + 1;
return optPath.replace( '{{#}}', nextIndex );
};
// get pageIndex from location
// convert path option into regex to look for pattern in location
// escape query (?) in url, allows for parsing GET parameters
let regexString = optPath
.replace( /(\\\?|\?)/, '\\?' )
.replace( '{{#}}', '(\\d\\d?\\d?)' );
let templateRe = new RegExp( regexString );
let match = location.href.match( templateRe );
if ( match ) {
this.pageIndex = parseInt( match[1], 10 );
this.log( 'pageIndex', [ this.pageIndex, 'template string' ] );
}
};
let pathRegexes = [
// WordPress & Tumblr - example.com/page/2
// Jekyll - example.com/page2
/^(.*?\/?page\/?)(\d\d?\d?)(.*?$)/,
// Drupal - example.com/?page=1
/^(.*?\/?\?page=)(\d\d?\d?)(.*?$)/,
// catch all, last occurence of a number
/(.*?)(\d\d?\d?)(?!.*\d)(.*?$)/,
];
// try matching href to pathRegexes patterns
let getPathParts = InfiniteScroll.getPathParts = function( href ) {
if ( !href ) return;
for ( let regex of pathRegexes ) {
let match = href.match( regex );
if ( match ) {
let [ , begin, index, end ] = match;
return { begin, index, end };
}
}
};
proto.updateGetPathSelector = function( optPath ) {
// parse href of link: '.next-page-link'
let hrefElem = document.querySelector( optPath );
if ( !hrefElem ) {
console.error(`Bad InfiniteScroll path option. Next link not found: ${optPath}`);
return;
}
let href = hrefElem.getAttribute('href');
let pathParts = getPathParts( href );
if ( !pathParts ) {
console.error(`InfiniteScroll unable to parse next link href: ${href}`);
return;
}
let { begin, index, end } = pathParts;
this.isPathSelector = true; // flag for checkLastPage()
this.getPath = () => begin + ( this.pageIndex + 1 ) + end;
// get pageIndex from href
this.pageIndex = parseInt( index, 10 ) - 1;
this.log( 'pageIndex', [ this.pageIndex, 'next link' ] );
};
proto.updateGetAbsolutePath = function() {
let path = this.getPath();
// path doesn't start with http or /
let isAbsolute = path.match( /^http/ ) || path.match( /^\// );
if ( isAbsolute ) {
this.getAbsolutePath = this.getPath;
return;
}
let { pathname } = location;
// query parameter #829. example.com/?pg=2
let isQuery = path.match( /^\?/ );
// /foo/bar/index.html => /foo/bar
let directory = pathname.substring( 0, pathname.lastIndexOf('/') );
let pathStart = isQuery ? pathname : directory + '/';
this.getAbsolutePath = () => pathStart + this.getPath();
};
// -------------------------- nav -------------------------- //
// hide navigation
InfiniteScroll.create.hideNav = function() {
let nav = utils.getQueryElement( this.options.hideNav );
if ( !nav ) return;
nav.style.display = 'none';
this.nav = nav;
};
InfiniteScroll.destroy.hideNav = function() {
if ( this.nav ) this.nav.style.display = '';
};
// -------------------------- destroy -------------------------- //
proto.destroy = function() {
this.allOff(); // remove all event listeners
// call destroy methods
for ( let method in InfiniteScroll.destroy ) {
InfiniteScroll.destroy[ method ].call( this );
}
delete this.element.infiniteScrollGUID;
delete instances[ this.guid ];
// remove jQuery data. #807
if ( jQuery && this.$element ) {
jQuery.removeData( this.element, 'infiniteScroll' );
}
};
// -------------------------- utilities -------------------------- //
// https://remysharp.com/2010/07/21/throttling-function-calls
InfiniteScroll.throttle = function( fn, threshold ) {
threshold = threshold || 200;
let last, timeout;
return function() {
let now = +new Date();
let args = arguments;
let trigger = () => {
last = now;
fn.apply( this, args );
};
if ( last && now < last + threshold ) {
// hold on to it
clearTimeout( timeout );
timeout = setTimeout( trigger, threshold );
} else {
trigger();
}
};
};
InfiniteScroll.data = function( elem ) {
elem = utils.getQueryElement( elem );
let id = elem && elem.infiniteScrollGUID;
return id && instances[ id ];
};
// set internal jQuery, for Webpack + jQuery v3
InfiniteScroll.setJQuery = function( jqry ) {
jQuery = jqry;
};
// -------------------------- setup -------------------------- //
utils.htmlInit( InfiniteScroll, 'infinite-scroll' );
// add noop _init method for jQuery Bridget. #768
proto._init = function() {};
let { jQueryBridget } = window;
if ( jQuery && jQueryBridget ) {
jQueryBridget( 'infiniteScroll', InfiniteScroll, jQuery );
}
// -------------------------- -------------------------- //
return InfiniteScroll;
} ) );