- // ==UserScript==
- // @name AJAX plugin - SkIvLib
- // @description AJAX plugin by Ivan Skvortsov
- // @description:ru AJAX плагин от Ivan Skvortsov
- // @include *://*
- // @author Ivan Skvortsov
- // @version 1.0.0
- // @grant none
- // ==/UserScript==
- (function(){
- if( !clog )
- var clog = console.log;
- var factory = [], queue = [], request_in_progress = false, queue_cleaned = true;
- function queue_status()
- {
- return "queue_status:\n" +
- "queue.length = " + queue.length + "\n" +
- "in_progress = " + request_in_progress + "\n" +
- "cleaned = " + queue_cleaned + "\n" +
- "--------------";
- }
- function request_status( request )
- {
- return "request_status:\n" +
- "method = " + request.method + "\n" +
- "url = " + request.url + "\n" +
- "async = " + request.async + "\n" +
- "data = " + request.data + "\n" +
- "onload = " + request.onload + "\n" +
- "--------------";
- }
- function createNewObject( obj )
- {
- var new_obj = {}, key, val;
- for( key in obj )
- {
- val = obj[key];
- if( Object.prototype.hasOwnProperty.call(obj, key) && val !== null )
- new_obj[key] = val;
- }
- return new_obj;
- }
- function initXHttpFactory()
- {
- if( factory && factory.length > 0 )
- return;
- clog( "initXHttpFactory : " + (factory ? factory.length : 0) );
- factory = [
- function(){ return new XMLHttpRequest();},
- function(){ return new ActiveXObject('Msxml3.XMLHTTP');},
- function(){ return new ActiveXObject('Msxml2.XMLHTTP.6.0');},
- function(){ return new ActiveXObject('Msxml2.XMLHTTP.3.0');},
- function(){ return new ActiveXObject('Msxml2.XMLHTTP');},
- function(){ return new ActiveXObject('Microsoft.XMLHTTP');},
- ];
- }
- function createXHttp()
- {
- clog("createXHttp");
- initXHttpFactory();
- for( let i = 0; i < factory.length; ++i )
- {
- try{
- return factory[i]();
- }catch(error){}
- }
- console.error("[createXHttp] can't create xhttp object");
- return null;
- }
- function ObjectToDataString( obj )
- {
- if( typeof obj === 'object' )
- {
- var data_str = '', val, key;
- for( key in obj )
- {
- val = obj[key];
- if( !Object.prototype.hasOwnProperty.call(obj, key) || !val )
- continue;
- data_str += key + '=' + val + '&';
- }
- return data_str.slice(0, -1);
- }
- else if( typeof obj === 'string' )
- return obj;
- else
- return ( obj ? (obj.toString && obj.toString()) : '' );
- }
- function getXHttpRequest()
- {
- clog("getXHttpRequest : queue.length = " + queue.length);
- var request = queue[0];
- request.method = request.method || 'GET';
- if( request.method.toUpperCase() === 'GET' && request.data && request.data !== '' )
- {
- request.url += '?' + request.data;
- request.data = '';
- }
- request.async = (request.async || true);
- clog( request_status(request) );
- return request;
- }
- function handleXHttpEvent( type, xhttp, request, event )
- {
- if( queue_cleaned )
- return;
- clog("handleXHttpEvent : url=" + request.url + ", type=" + type + "" +
- ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
- var context, response;
- if( request[type] )
- {
- response = {
- lengthComputable: xhttp.lengthComputable || event.lengthComputable || null,
- loaded: xhttp.loaded || event.loaded || 0,
- readyState: xhttp.readyState,
- responseHeaders: xhttp.responseHeaders ||
- (typeof xhttp.getAllResponseHeaders === 'function' ? xhttp.getAllResponseHeaders() : null ) || '',
- responseText: xhttp.responseText || xhttp.response,
- status: xhttp.status,
- statusText: xhttp.statusText,
- total: xhttp.total || event.total || 0,
- url: xhttp.finalUrl || request.url,
- };
- context = request.context || response;
- request[type].call( context, response );
- if( type === 'onerror' || type === 'onload' )
- {
- request_in_progress = false;
- request.delay = request.delay > 20 ? request.delay : 20;
- setTimeout( XHttpRequest, request.delay );
- }
- }
- }
- function initXHttpEvents( xhttp, request )
- {
- clog("initXHttpEvents: ", xhttp);
- var types = [
- 'onerror',
- 'onload',
- 'onloadend',
- 'onloadstart',
- 'onprogress',
- 'onreadystatechange',
- ];
- function setXHttpEventListener(type){
- xhttp[type] = function(event){ handleXHttpEvent(type, xhttp, request, event); };
- }
- types.forEach( setXHttpEventListener );
- }
- function initXHttp( xhttp, request )
- {
- initXHttpEvents( xhttp, request );
- for( let key in request.headers )
- {
- xhttp.setRequestHeader( key, request.headers[key] );
- }
- }
- function XHttpRequest()
- {
- clog("---> XHttpRequest <---");
- var request, xhttp;
- request = getXHttpRequest();
- if( request && (request_in_progress === false || request.async === true) && queue.length > 0 )
- {
- queue.shift();
- request_in_progress = true;
- xhttp = createXHttp();
- initXHttp( xhttp, request );
- clog("XHttpRequest : url=" + request.url +
- ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
- xhttp.open( request.method, request.url, request.async );
- xhttp.send( request.data || null );
- }
- }
- function addXHttpRequest( ...args )
- {
- var request, url, settings;
- switch( args.length )
- {
- case 0: return;
- case 1:
- request = args[0];
- if( request.length )
- request.forEach( function(req){ queue.push(req);} );
- else
- queue.push(request);
- //queue_cleaned = false;
- break;
- case 2:
- url = args[0];
- settings = args[1];
- if( url.length )
- url.forEach( function(u){queue.push(makeXHttpRequest(u, settings));});
- else
- queue.push( makeXHttpRequest(url, settings) );
- //queue_cleaned = false;
- break;
- default:
- return;
- //throw new Error("[addXHttpRequest] invalid arguments length: " + args.length );
- }
- /*
- if( request && request.length )
- {
- request.forEach( function(req){ queue.push(req);} );
- }
- else if( request )
- {
- queue.push(request);
- }
- else if( url && url.length )
- {
- url.forEach( function(u){queue.push(makeXHttpRequest(u, settings));});
- }
- else if( url )
- {
- queue.push( makeXHttpRequest(url, settings) );
- }
- else
- throw new Error("addXHttpRequest] can't add request, args: " + args);
- */
- queue_cleaned = false;
- }
- function makeXHttpRequest( url, settings )
- {
- var request = createNewObject(settings);
- request.url = url;
- return request;
- }
- function cleanXHttpQueue()
- {
- queue.length = 0;
- request_in_progress = false;
- queue_cleaned = true;
- }
- function queueLength()
- {
- return queue.length;
- }
- // AJAX API
- SkIvLib.ajaxClean = cleanXHttpQueue;
- SkIvLib.ajaxLength = queueLength;
- SkIvLib.ajaxStatus = queue_status;
- SkIvLib.ajaxAddXHR = addXHttpRequest;
- SkIvLib.ajax = function(...args)
- {
- addXHttpRequest(...args);
- XHttpRequest;
- }
- })();