My Function library

enter something useful

As of 2016-03-05. See the latest version.

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/9160/111519/My%20Function%20library.js

  1. "use strict";
  2. //// ==UserScript==
  3. // @name My Function library
  4. // @namespace http://use.i.E.your.homepage/
  5. // @version 0.35
  6. // @description enter something useful
  7. // @grant GM_getValue
  8. // @grant GM_setValue
  9. // @grant GM_deleteValue
  10. // @run-at document-start
  11.  
  12. // @created 2015-04-06
  13. // @released 2014-00-00
  14. // @updated 2014-00-00
  15. // @history @version 0.25 - first version: public@released - 2015-04-12
  16. // @history @version 0.30 - Second version: public@released - 2015-12-10
  17. // @history @version 0.35 - Second version: public@released - 2016-03-04
  18. // @compatible Greasemonkey, Tampermonkey
  19. // @license GNU GPL v3 (http://www.gnu.org/copyleft/gpl.html)
  20. // @copyright 2014+, Magnus Fohlström
  21. // ==/UserScript==
  22.  
  23. /*global $, jQuery*/
  24. /*jshint -W014, -W030, -W082*/
  25. // -W014, laxbreak, Bad line breaking before '+'
  26. // -W030, Expected assignment or function call instead saw an expression
  27. // -W082, a function declaration inside a block statement
  28.  
  29. /*
  30. $("li").not(function() {
  31. // returns true for those elements with at least one span as child element
  32. return $(this).children('span').length > 0
  33. }).each(function() { /* ... })
  34. */
  35.  
  36.  
  37. window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
  38. console.debug('Error: ' + errorMsg + '\nScript: ' + url + '\nLine: ' + lineNumber
  39. + '\nColumn: ' + column + '\nStackTrace: ' + errorObj);
  40. };
  41. /**
  42. * @namespace waitUntilExists_Intervals
  43. */
  44. $.fn.waitUntilExists = function (handler, shouldRunHandlerOnce, isChild){
  45. var found = 'found',
  46. $this = $(this.selector),
  47. $elements = $this.not(function () { return $(this).data(found); }).each(handler).data(found, true);
  48. if( !isChild ) {
  49. (window.waitUntilExists_Intervals = window.waitUntilExists_Intervals || {})[this.selector] =
  50. window.setInterval(function () {
  51. $this.waitUntilExists(
  52. handler, shouldRunHandlerOnce, true);
  53. }, 500);
  54. }
  55. else if (shouldRunHandlerOnce && $elements.length){
  56. window.clearInterval(window.waitUntilExists_Intervals[this.selector]);
  57. }
  58. return $this;
  59. };
  60.  
  61. $.fn.extend({
  62. exists : function () {
  63. return !!this.length;
  64. },
  65. swapClass : function (replace, newClass) {
  66. this.className.replace(replace, newClass);
  67. },
  68. toggleClasses : function (add, remove, if_none) {
  69. var $this = $(this.selector);
  70. if_none !== undefined && !$this.hasClass(add) && !$this.hasClass(remove) && $this.addClass(if_none);
  71. $this.addClass(add).removeClass(remove);
  72. },
  73. hasId : function (id) {
  74. return id === this.attr('id');
  75. },
  76. /* hasParent : function( parentSelection ){
  77. return parentSelection.inElem('#') ? this.parent().hasId( parentSelection.split('#').shift() ) : this.parent().hasClass( parentSelection.split('.').shift() );
  78. },
  79. */
  80. hasNoChildren : function ( element ) {
  81. return $( this ).filter( function(){ return !$( this ).children( element ).length; });
  82. //return !$( this ).children().length
  83. },
  84. hasParent : function (e) {
  85. return !$( this ).parent(e).length
  86. },
  87. hasParents : function (e) {
  88. return !$(this).parents(e).length
  89. },
  90. hasQuery : function (query) {
  91. return d.querySelector(query).length;
  92. },
  93. isTag : function (tag) {
  94. var e = this[0] || $('<undefined/>');
  95. //noinspection JSValidateTypes
  96. return e.nodeName !== undefined && e.nodeName.toLowerCase() === tag.toLowerCase();
  97. },
  98. isNode : function (node) {
  99. var e = this[0] || $('<undefined/>');
  100. //noinspection JSValidateTypes
  101. return e.nodeName !== undefined && e.nodeName.toLowerCase() === node.toLowerCase();
  102. },
  103. attrs : function (search, type, chklen) { //bool name value length or 1 2 3 4
  104. var attribs = this[0].attributes;
  105. c.i('attribs', attribs)
  106. if (arguments.length === 0) {
  107. var obj = {};
  108. $.each(attribs, function () {
  109. this.specified && ( obj[this.name] = this.value );
  110. });
  111. return obj;
  112. } else if (search != undefined) {
  113. var name = '', val = '';
  114. $.each(attribs, function () {
  115. if (this.specified && type == 'length') {
  116. if (this.name.length > chklen) {
  117. name = this.name;
  118. return false;
  119. }
  120. }
  121. else if (this.specified && this.name.inElem(search)) {
  122. name = this.name;
  123. val = this.value;
  124. return false;
  125. }
  126. });
  127. return ( type == 'bool' || type == 1) ? name.length ? true : false :
  128. ( type == 'name' || type == 2) ? name :
  129. ( type == 'value' || type == 3) ? val :
  130. ( type == 'length' || type == 4) && name;
  131. }
  132. },
  133. findClass : function (Class) {
  134. return this.find('.' + Class)
  135. },
  136. href : function (newURL) {
  137. return arguments.length === 0 ? this.attr('href') : this.attr('href', newURL);
  138. },
  139. src : function (newSRC) {
  140. return arguments.length === 0 ? this.attr('src') : this.attr('src', newSRC);
  141. },
  142. equals : function (compareTo) {
  143. if (!compareTo || this.length != compareTo.length)
  144. return false;
  145.  
  146. for (var i = 0; i < this.length; ++i) {
  147. if (this[i] !== compareTo[i])
  148. return false;
  149. }
  150. return true;
  151. },
  152. justText : function (newText) {
  153. var $children = null;
  154. if ( newText ) {
  155. $children = $( this )
  156. .children()
  157. .clone();
  158. $( this )
  159. .children()
  160. .remove()
  161. .end()
  162. .text( newText )
  163. .prepend( $children );
  164. return $(this);
  165. }
  166. else {
  167. return $.trim( $( this )
  168. .clone()
  169. .children()
  170. .remove()
  171. .end()
  172. .text());
  173. }
  174. }
  175. });
  176.  
  177. $.fn.ifExists = function( fn ) {
  178. this.length && fn( this );
  179. };
  180. /*
  181. $("#element").ifExists(
  182. function( $this ){
  183. $this.addClass('someClass').animate({marginTop:20},function(){alert('ok')});
  184. });
  185. */
  186. $.fn.Exists = function( callback ) {
  187. var self = this;
  188. var wrapper = (function(){
  189. function notExists(){}
  190. notExists.prototype.ExistsNot = function( fallback ){
  191. !self.length && fallback.call(); };
  192. return new notExists;
  193. })();
  194. self.length && callback.call();
  195. return wrapper;
  196. };
  197.  
  198. //And now i can write code like this -
  199. /* $("#elem").Exists(function(){
  200. alert ("it exists");
  201. }).ExistsNot(function(){
  202. alert ("it doesn't exist");
  203. });
  204. */
  205. $.extend($.expr[":"], {
  206. ldata: function(el, idx, selector) {
  207. var attr = selector[3].split(", ");
  208. return el.dataset[attr[0]] === attr[1];
  209. },
  210. value: function(el, idx, selector) {
  211. return el.value === selector[selector.length - 1];
  212. }
  213. });
  214.  
  215. $.extend({
  216. confirm: function (title, message, yesText, noText, yesCallback) {
  217. //dialog needs jQueryUI
  218. $("<div></div>").dialog( {
  219. buttons: [{
  220. text: yesText,
  221. click: function() {
  222. yesCallback();
  223. $( this ).remove();
  224. }
  225. },
  226. {
  227. text: noText,
  228. click: function() {
  229. $( this ).remove();
  230. }
  231. }
  232. ],
  233. close: function (event, ui) { $(this).remove(); },
  234. resizable: false,
  235. title: title,
  236. modal: true
  237. }).text(message).parent().addClass("alert");
  238. }
  239. });
  240. $.extend( $.expr[':'], {
  241. isEmptyTrimmed: function(el){
  242. return !$.trim($(el).html());
  243. },
  244. data: $.expr.createPseudo ?
  245. $.expr.createPseudo(function( dataName ) {
  246. return function( elem ) {
  247. return !!$.data( elem, dataName );
  248. };
  249. }) :
  250. // support: jQuery <1.8
  251. function( elem, i, match ) {
  252. return !!$.data( elem, match[ 3 ] );
  253. }
  254. });
  255. /*
  256. $.confirm(
  257. "CONFIRM", //title
  258. "Delete " + filename + "?", //message
  259. "Delete", //button text
  260. deleteOk //"yes" callback
  261. );
  262. */
  263.  
  264. //ScrollZoomTune("div.thumb .title a",1,-25,1,'slow');
  265. function ScrollZoomTune(selection, zooms, tune, ani, speed){
  266. var body = $('body'), sel = $( selection), position;
  267. //noinspection JSValidateTypes
  268. sel.size() !== 0 && (
  269. body.css('zoom',zooms),
  270. position = sel.position().top + tune,
  271. ani === 1 ?
  272. body.animate({ scrollTop: position * zooms }, speed ) :
  273. body.scrollTop( position * zooms )
  274. );
  275. }
  276.  
  277. function inURL( search ){
  278. var winLoc = window.location.href;
  279. return winLoc.search(search) !== -1;
  280. }
  281.  
  282. function loadDoc( href ){
  283. $(location).attr('href', href );
  284. }
  285.  
  286. function checkDividedIsInteger( num, div ){
  287. return ( num % div === 0 );
  288. }
  289.  
  290. function isEven( value ){
  291. return ( value % 2 === 0 );
  292. }
  293.  
  294. function autoCopyToClipboard( input ){
  295. $( 'body' ).append( $('<textarea/>',{ id:'copyThis', rows:"4", cols:"50", type:"text", value: input }) );
  296. $( '#copyThis').focus().select();
  297. document.execCommand("copy");
  298. $( '#copyThis' ).remove();
  299. }
  300.  
  301. function fn_arrayElemExistsInDom( array ) {
  302. var found = false;
  303. jQuery.each( array, function( i, value ) {
  304. $( value ).length && ( found = true );
  305. });
  306. return found;
  307. }
  308.  
  309. function toggleClassState( config, Class, state, elem ){
  310. config[ Class ] = typeof state === 'string' ? !config[ Class ] : state;
  311. $( elem || 'html' )[ config[ Class ] ? 'addClass' : 'removeClass' ]( Class );
  312. }
  313.  
  314. function wrapWithTag( tag, text, selection ){
  315. var thisAttr = selection != undefined && selection.startsWith('.') ? 'class' : selection.startsWith('#') && 'id',
  316. thisTag = $('<' + tag + '/>', { text: text });
  317. return thisAttr.length ? thisTag.attr( thisAttr, selection.splice( 1 ) ) : thisTag;
  318. }
  319.  
  320. // will return true if the value is a primitive value
  321. function isPrimitiveType( value ){
  322. switch ( typeof value ) {
  323. case 'string': case 'number': case 'boolean': case 'undefined': {
  324. return true;
  325. }
  326. case 'object': {
  327. return !value;
  328. }
  329. }
  330. return false;
  331. }
  332.  
  333. Array.prototype.findArrayObj = function( find, value ){
  334. return this.filter(function( obj ){
  335. return obj[ find ] === value;
  336. })[0];
  337. };
  338.  
  339. String.prototype.advSplit = function(chr,nbr) {
  340. var str = this.split(chr),
  341. strLen = str.length,
  342. chrLen = chr.length,
  343. newStr = ['',''],
  344. newArr = [];
  345.  
  346. $.each( str, function( index ) {
  347. newStr[ index < nbr ? 0 : 1 ] += str[ index ] + chr;
  348. });
  349.  
  350. $.each( newStr, function( index ) {
  351. newStr[ index ] = newStr[ index ].slice(0, - chrLen);
  352. newStr[ index ].length > 0 && newArr.push( newStr[ index] );
  353. });
  354.  
  355. return newArr;
  356. };
  357.  
  358. String.prototype.advSplitJoin = function(chr,nbr,ips) {
  359.  
  360. var str = this.split(chr),
  361. strLen = str.length,
  362. ipsLen = ips.length,
  363. newStr = '',
  364. newStrLen;
  365.  
  366. $.each( str, function( index ) {
  367. var add = index < strLen - 1 ? chr : '';
  368. newStr += index + 1 === nbr ? str[index] + ips : str[index] + add;
  369. });
  370.  
  371. newStrLen = newStr.length;
  372. newStr.slice( newStrLen - ipsLen ) === ips && ( newStr = newStr.slice( 0, newStrLen - ipsLen ) );
  373.  
  374. return newStr;
  375. };
  376.  
  377. String.prototype.lpad = function(padString, length) {
  378. var str = this;
  379. while ( str.length < length ) {
  380. str = padString + str; }
  381. return str;
  382. };
  383.  
  384. String.prototype.reduceWhiteSpace = function() {
  385. return this.replace(/\s+/g, ' ');
  386. };
  387.  
  388. String.prototype.formatString = function(){
  389. return this.toString()
  390. .split('!').join(' !').split('!;').join("!important;")
  391. .split(/\s+/g).join(' ')
  392. .split('{').join('{\n\t')
  393. .split('; ').join(';')
  394.  
  395. .split('( ').join('(')
  396. .split(' )').join(')')
  397.  
  398. .split(';').join(';\n\t')
  399. .split('*/').join('*/\n')
  400. .split(')*(').join(') * (')
  401. .split('}').join('}\n');
  402. };
  403.  
  404. String.prototype.inURL = function(){
  405. var winLoc = window.location.href;
  406. return winLoc.search(this) !== -1;
  407. };
  408.  
  409. String.prototype.inString = function(string){
  410. return string !== undefined ? string.search(this) !== -1 : false;
  411. };
  412.  
  413. String.prototype.inElem = function(search){
  414. return this !== undefined ? this.search(search) !== -1 : false;
  415. };
  416.  
  417. String.prototype.undef = function(replace){
  418. return this === undefined ? replace : this;
  419. };
  420.  
  421. String.prototype.extract = function( startChar, endChar, inside ){
  422. var str = this,
  423. startCharIndex = str.indexOf( startChar ),
  424. endCharIndex = str.indexOf( endChar );
  425.  
  426. str = ( inside === 'yes' || inside === 1 || inside === true || inside === 'inside' ) ?
  427. str.replace( startChar, '').replace( endChar, '') : str.substr( startCharIndex, endCharIndex);
  428.  
  429. return str;
  430. };
  431.  
  432. // use full to convert String URL, so that you can use location commands
  433. String.prototype.toLocation = function() {
  434. var a = document.createElement('a');
  435. a.href = this;
  436. return a;
  437. };
  438.  
  439. String.prototype.count = function( char, UpperCase ) {
  440. var numberOf = this.toString().match( new RegExp( char, ( UpperCase ? "gi" : "g" ) ) );
  441. return numberOf != null ? numberOf.length : 0;
  442. };
  443.  
  444. String.prototype.startsWith = function( str ){
  445. return this.slice(0, str.length) == str;
  446. };
  447.  
  448. String.prototype.endsWith = function( str ){
  449. return this.slice(-str.length) == str;
  450. };
  451.  
  452. String.prototype.capitalizeFirst = function(){
  453. return this.charAt(0).toUpperCase() + this.slice(1);
  454. };
  455.  
  456. String.prototype.str2html = function(){
  457. return $('<div/>').html( this ).contents();
  458. };
  459.  
  460. //HTMLObjectElement.prototype.obj2Str = function(){var objArr = $.makeArray( this );return objArr[0].outerHTML;};
  461.  
  462. /*
  463. String.prototype.replaceAll = function( target, replacement ) {
  464. return this.split(target).join(replacement);
  465. };
  466. */
  467.  
  468. /**
  469. * @return {string}
  470. */
  471. function Undefined(check,replace){
  472. return check === undefined ? replace.toString() : check.toString();
  473. }
  474.  
  475. function GM_lister( remove ){
  476. var keys = GM_listValues();
  477. for (var i = 0, key = null; key = keys[i]; i++) {
  478. GM_listValues()[i] !== undefined && c.i('GM_ListItem: ' + GM_listValues()[i] + ':', GM_getValue(key));
  479. ( remove === true || remove === 'yes' || remove === 1 ) && GM_deleteValue(key);
  480. }
  481. }
  482.  
  483. function filterClick( e, $this ){
  484. return e.which == 1 && e.target == $this;
  485. }
  486.  
  487. function roundFloat(num,dec){
  488. var d = 1;
  489. for (var i=0; i<dec; i++){
  490. d += "0";
  491. }
  492. return Math.round(num * d) / d;
  493. }
  494.  
  495. function randomFloatBetween( min, max, dec ){
  496. dec = typeof( dec ) == 'undefined' ? 2 : dec;
  497. return parseFloat( Math.min( min + ( Math.random() * ( max - min ) ), max ).toFixed( dec ) );
  498. }
  499.  
  500. function refreshElement( elem , speed ){ //refreshElement('.videoPlayer','slow');
  501. var $elem = $( elem ), data = $elem.html();
  502. $elem.empty().html( data ).fadeIn( speed );
  503. }
  504.  
  505. function getGlobal(){
  506. return (function(){
  507. return this;
  508. })();
  509. }
  510.  
  511. function random( max ){
  512. var min = 1,
  513. rand = function(){
  514. return Math.floor( Math.random() * ( max - min + 1 ) + min );
  515. },
  516. num1 = rand(),
  517. num2 = rand();
  518.  
  519. return ( num1 > num2 ? num2/num1 : num1/num2 ) * max;
  520. }
  521.  
  522. function roundNearPeace( number, peaces, dec ) {
  523. return ( Math.round( number * peaces ) / peaces ).toFixed( dec );
  524. }
  525.  
  526. function isFunction( functionToCheck ) {
  527. var getType = {};
  528. return functionToCheck && getType.toString.call( functionToCheck ) === '[object Function]';
  529. }
  530.  
  531. //VideoTitleA("div.thumb .title a",'on');
  532. var VideoTitleA = function( elem , state ){
  533. $( elem ).each(function(){
  534. var $this = $(this),
  535. strTitle = $this.attr('title'),
  536. strText = $this.attr('data-text'),
  537. strHtml = $this.text();
  538. state === 'on' ? $this.text(strTitle).attr('data-text',strHtml) : $this.text(strText);
  539. });
  540. },
  541. isNumeric = function( value ){
  542. return /^\d+$/.test( value );
  543. },
  544. obj2Str = function( obj ){
  545. var objArr = $.makeArray(obj);
  546. return objArr[0].outerHTML;
  547. },
  548. /**
  549. * @return {string}
  550. */
  551. MultiString = function(f){
  552. return f.toString().split('\n').slice(1, -1).join('\n');
  553. },
  554. w = window,
  555. glob = w,
  556. $w = $(w),
  557. $l = $(location),
  558. locDoc = window.location.href,
  559. d = document,
  560. $d = $(d),
  561. c = {
  562. defaultState: 3,
  563. cute : function( type, msg, color ) {
  564. color = color || "black";
  565. var newColor, bgc = "White";
  566. switch ( color ) {
  567. case "success": newColor = "Green"; bgc = "LimeGreen"; break;
  568. case "info": newColor = "DodgerBlue"; bgc = "Turquoise"; break;
  569. case "error": newColor = "Red"; bgc = "Black"; break;
  570. case "start": newColor = "OliveDrab"; bgc = "PaleGreen"; break;
  571. case "warning": newColor = "Tomato"; bgc = "Black"; break;
  572. case "end": newColor = "Orchid"; bgc = "MediumVioletRed"; break;
  573. default: //noinspection SillyAssignmentJS
  574. newColor = color;
  575. }
  576.  
  577. typeof msg == "object" ?
  578. window.console[ type ]( msg )
  579. : typeof color == "object" ? (
  580. window.console[ type ]("%c" + msg, "color: PowderBlue;font-weight:bold; background-color: RoyalBlue;"),
  581. window.console[ type ]( newColor )
  582. ):
  583. window.console[ type ]("%c" + msg, "color:" + newColor + "; background-color: " + bgc + ";")
  584. },
  585. show: function( showThis, type ){
  586. var State = GM_getValue( type + 'StateValue' ) || this.defaultState;
  587. return showThis !== 0 && State !== 0 && State === ( showThis || State ) || State === 'all';
  588. },
  589. pre: function( type, name, fn, line, color ){
  590. line = line == undefined ? '' : line + ': ';
  591. var Fn = function(){ return fn !== undefined ? fn : ''; };
  592. typeof fn == "object" ?
  593. window.console[ type ]( name, Fn() ) : c.cute( type, line + name + ': ' + Fn(), color );
  594. },
  595. l: function( name, fn, line, color, showThis ){
  596. var type = 'log';
  597. this.show( showThis, type ) && this.pre( type, name, fn, line, color );
  598. },
  599. h: function( name, fn, line, color, showThis ){
  600. var type = 'handled';
  601. this.show( showThis, type ) && this.pre( type, name, fn, line, color );
  602. },
  603. //c.l('name', 'fn'=='fn', 'line', 'blue')
  604. i: function( name, fn, line, color, showThis ){
  605. var type = 'info';
  606. this.show( showThis, type ) && this.pre( type, name, fn, line, color );
  607. },
  608. d: function( name, fn, line, color, showThis ){
  609. var type = 'debug';
  610. this.show( showThis, type ) && this.pre( type, name, fn, line, color );
  611. }
  612. },
  613. advTimer = {
  614. start : function( name, ms ){
  615. advTimer[name] = ms;
  616. setTimeout(function(){ advTimer[name] = 0; }, ms );
  617. },
  618. check : function( name ){
  619. advTimer[name] || ( advTimer[name] = 0 );
  620. return advTimer[name];
  621. },
  622. stop : function( name ){
  623. advTimer[name] = 0;
  624. }
  625. },
  626. g = {
  627. locDoc : window.location.href,
  628. ms : 0,
  629. timer : function(ms){
  630. g.ms = ms;
  631. setTimeout(function(){ g.ms = 0; },ms);
  632. },
  633. lap : {
  634. data : {},
  635. tid : function(){ return performance.now(); },
  636. set : function(name){ this.data[name] = this.tid(); },
  637. get : function(name){ this.print(name); },
  638. end : function(name){ this.print(name); this.del(name); },
  639. del : function(name){ delete this.data[name]; },
  640. print: function(name){ c.i( name, this.tid() - this.data[name] + 'ms'); }
  641. },
  642. GM : {
  643. engine : function( mode, val, range ){
  644. switch (mode){
  645. case 'set': GM_setValue( val.name, val.default );
  646. break;
  647. case 'get': range ? config[ val.name ] = GM_getValue( val.name ):
  648. ui.config[ val.name ] = GM_getValue( val.name );
  649. break;
  650. case 'del': GM_deleteValue( val.name );
  651. }
  652. },
  653. manager : function( mode, array, range ){
  654. $.each( array, function( i, val ){ this.engine( mode, val, range === undefined ); });
  655. mode === 'del' && ( GM_deleteValue( 'firstRun' ), GM_deleteValue( 'yourVer' ) );
  656. }
  657. }
  658. },
  659. testPerformance = function(name, fn, testCycles ) {
  660. g.lap.set( name );
  661. var i = 0;
  662. for ( i ; i < testCycles; i++ ){
  663. fn;
  664. }
  665. g.lap.end( name );
  666. };
  667.  
  668. var perf = function (testName, fn) {
  669. var startTime = new Date().getTime();
  670. fn();
  671. var endTime = new Date().getTime();
  672. console.log(testName + ": " + (endTime - startTime) + "ms");
  673. };
  674.  
  675. $(document).on('click','*',function(e){
  676. this == e.target && c.i('target:', e.target ); });
  677.  
  678. c.i('my Function Library ö');
  679. /*
  680. isScrolledIntoView = (elem) ->
  681. docViewTop = $(window).scrollTop()
  682. docViewBottom = docViewTop + $(window).height()
  683. elemTop = $(elem).offset().top
  684. elemBottom = elemTop + $(elem).height()
  685.  
  686. (elemBottom - 200 < docViewBottom) and (elemBottom + $(elem).height() > docViewBottom )
  687. */
  688.