My Function library

enter something useful

当前为 2017-01-10 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/9160/168434/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.50
  6. // @description enter something useful
  7. // @grant GM_getValue
  8. // @grant GM_setValue
  9. // @grant GM_deleteValue
  10. // @grant GM_listValues
  11. // @grant GM_xmlhttpRequest
  12. // @run-at document-start
  13.  
  14. // @created 2015-04-06
  15. // @released 2014-00-00
  16. // @updated 2014-00-00
  17. // @history @version 0.25 - first version: public@released - 2015-04-12
  18. // @history @version 0.30 - Second version: public@released - 2015-12-10
  19. // @history @version 0.35 - Second version: public@released - 2016-03-04
  20. // @history @version 0.45 - Second version: public@released - 2016-09-24
  21. // @history @version 0.45 - third version: public@released - 2017-01-10
  22. // @compatible Greasemonkey, Tampermonkey
  23. // @license GNU GPL v3 (http://www.gnu.org/copyleft/gpl.html)
  24. // @copyright 2014+, Magnus Fohlström
  25. // ==/UserScript==
  26. /*global $, jQuery*/
  27. /*jshint -W014, -W030, -W082*/
  28. // -W014, laxbreak, Bad line breaking before '+'
  29. // -W030, Expected assignment or function call instead saw an expression
  30. // -W082, a function declaration inside a block statement
  31.  
  32. /*
  33. $("li").not(function() {
  34. // returns true for those elements with at least one span as child element
  35. return $(this).children('span').length > 0
  36. }).each(function() { /* ... })
  37. */
  38. //noinspection JSUnresolvedFunction,JSUnresolvedVariable,BadExpressionStatementJS
  39. performance;
  40.  
  41. function setGM(){
  42. console.log('setGM' );
  43. window.GM_getValue = function( key, def ){
  44. return localStorage[key] || def;
  45. };
  46. window.GM_setValue = function( key, value ){
  47. localStorage[key] = value;
  48. };
  49. window.GM_deleteValue = function( key ){
  50. delete localStorage[ key ];
  51. };
  52. window.GM_listValues = function( ){
  53. return Object.keys( localStorage );
  54. };
  55. window.GM_lister = function( remove, item ){
  56. var keys = GM_listValues(), i = 0, val;
  57. for ( i; i <= keys.length; i++ ) {
  58. val = keys[i];
  59. val !== undefined && (
  60. console.log( 'GM_ListItem: ' + val + ':', GM_getValue( val ) ),
  61. ( ( item !== undefined && val.inElem( item ) ) || item === undefined )
  62. && Boolean.parse( remove ) && GM_deleteValue( val ) );
  63. }
  64. };
  65. }
  66.  
  67. console.log('isFunction( GM_getValue() )', $.isFunction( window.GM_getValue ) );
  68.  
  69. !!$.isFunction( window.GM_getValue ) || setGM();
  70.  
  71. (function(){
  72.  
  73. var eventMatchers = {
  74. 'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
  75. 'MouseEvents': /^(?:click|mouse(?:down|up|over|move|enter|out))$/
  76. //'MouseEvents': /^(?:click|dblclick|hover|contextmenu|mouse(?:down|up|over|move|enter|leave|out))$/
  77. };
  78.  
  79. var defaultOptions = {
  80. pointerX: 0,
  81. pointerY: 0,
  82. button: 0,
  83. ctrlKey: false,
  84. altKey: false,
  85. shiftKey: false,
  86. metaKey: false,
  87. bubbles: true,
  88. cancelable: true
  89. };
  90.  
  91. jQuery.fn.simulate = function(eventName) {
  92. var element = this[0];
  93. var options = $.extend(true, defaultOptions, arguments[2] || { });
  94. var oEvent, eventType = null;
  95.  
  96. for (var name in eventMatchers) {
  97. if (eventMatchers[name].test(eventName)) { eventType = name; break; }
  98. }
  99.  
  100. if (!eventType)
  101. throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');
  102.  
  103. if (document.createEvent) {
  104. oEvent = document.createEvent(eventType);
  105. if (eventType == 'HTMLEvents') {
  106. oEvent.initEvent(eventName, options.bubbles, options.cancelable);
  107. }
  108. else {
  109. oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
  110. options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
  111. options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
  112. }
  113. element.dispatchEvent(oEvent);
  114. }
  115. else {
  116. options.clientX = options.pointerX;
  117. options.clientY = options.pointerY;
  118. oEvent = $.extend(document.createEventObject(), options);
  119. element.fireEvent('on' + eventName, oEvent);
  120. }
  121. return element;
  122. };
  123. })();
  124.  
  125. window.onerror = function (errorMsg, url, lineNumber, column, errorObj) {
  126. console.debug('Error: ' + errorMsg + '\nScript: ' + url + '\nLine: ' + lineNumber
  127. + '\nColumn: ' + column + '\nStackTrace: ' + errorObj);
  128. };
  129. /**
  130. * @namespace waitUntilExists_Intervals
  131. */
  132. $.fn.waitUntilExists = function (handler, shouldRunHandlerOnce, isChild){
  133. var found = 'found',
  134. $this = $(this.selector),
  135. $elements = $this.not(function () { return $(this).data(found); }).each(handler).data(found, true);
  136. if( !isChild ) {
  137. (window.waitUntilExists_Intervals = window.waitUntilExists_Intervals || {})[this.selector] =
  138. window.setInterval(function () {
  139. $this.waitUntilExists(
  140. handler, shouldRunHandlerOnce, true);
  141. }, 500);
  142. }
  143. else if (shouldRunHandlerOnce && $elements.length){
  144. window.clearInterval(window.waitUntilExists_Intervals[this.selector]);
  145. }
  146. return $this;
  147. };
  148.  
  149. $.extend( $.easing,{
  150. easeOutBounceSmall : function(x, t, b, c, d) {
  151. var ts=(t/=d)*t;
  152. var tc=ts*t;
  153. return b+c*(-16.195*tc*ts + 49.935*ts*ts + -53.785*tc + 21.795*ts + -0.75*t);
  154. },
  155. easeOutSmoothBounce : function(x, t, b, c, d) {
  156. var ts=(t/=d)*t;
  157. var tc=ts*t;
  158. return b+c*(-19.4293*tc*ts + 53.3838*ts*ts + -49.8485*tc + 15.8081*ts + 1.08586*t);
  159. },
  160. easeInOutCubic: function (x, t, b, c, d) {
  161. if ((t/=d/2) < 1) return c/2*t*t*t + b;
  162. return c/2*((t-=2)*t*t + 2) + b;
  163. }
  164. });
  165.  
  166. $.extend( $.fn, {
  167. // Name of our method & one argument (the parent selector)
  168. /**
  169. * Suppress all rules containing "unused" in this
  170. * class
  171. *
  172. * @SuppressWarnings("unused")
  173. */
  174. //noinspection JSUnusedProperty
  175. within: function( pSelector ) {
  176. // Returns a subset of items using jQuery.filter
  177. return this.filter(function(){
  178. // Return truthy/falsey based on presence in parent
  179. return $(this).closest( pSelector ).length;
  180. });
  181. /* Example
  182. $("li").within(".x").css("background", "red");
  183.  
  184. This selects all list items on the document, and then filters to only
  185. those that have .x as an ancestor. Because this uses jQuery internally,
  186. you could pass in a more complicated selector:
  187.  
  188. $("li").within(".x, .y").css("background", "red");
  189.  
  190. http://stackoverflow.com/questions/2389540/jquery-hasparent
  191. http://stackoverflow.com/a/2389549
  192. */
  193. }
  194. });
  195. $.fn.extend({
  196. ifExists : function ( fn ) {
  197. this.length && fn( this );
  198. return this.length && this;
  199. /*
  200. $("#element").ifExists( function( $this ){
  201. $this.addClass('someClass').animate({marginTop:20},function(){alert('ok')});
  202. });
  203. */
  204. }
  205. });
  206. $.fn.extend({
  207. exists : function () {
  208. return !!this.length;
  209. },
  210. Exists : function ( callback ) {
  211. var self = this;
  212. var wrapper = (function(){
  213. function notExists(){}
  214. //noinspection JSPotentiallyInvalidConstructorUsage
  215. notExists.prototype.ExistsNot = function( fallback ){
  216. !self.length && fallback.call(); };
  217. //noinspection JSPotentiallyInvalidConstructorUsage
  218. return new notExists;
  219. })();
  220. self.length && callback.call();
  221. return wrapper;
  222.  
  223. /* And now i can write code like this -
  224. $("#elem").Exists(function(){
  225. alert ("it exists");
  226. }).ExistsNot(function(){
  227. alert ("it doesn't exist");
  228. });
  229. */
  230. },
  231. ifExists : function ( fn ) {
  232. this.length && fn( this );
  233. return this.length && this;
  234. /*
  235. $("#element").ifExists( function( $this ){
  236. $this.addClass('someClass').animate({marginTop:20},function(){alert('ok')});
  237. });
  238. */
  239. },
  240. iff : function ( bool, fn ) {
  241. ( bool && this.length || !bool && !this.length) && fn( this );
  242. /*
  243. $("#element").if( true, function( $this ){);
  244. $("#element").if( false, function( $this ){);
  245. */
  246. },
  247. ifs : function ( fnTrue, fnFalse ) {
  248. fn( this.length ? fnTrue : fnFalse );
  249. /*
  250. $("#element").ifs( function( $this ){}, function( $this ){});
  251. */
  252. },
  253. swapClass : function ( replace, newClass) {
  254. this.className.replace(replace, newClass);
  255. },
  256. toggleClasses : function ( add, remove, if_none) {
  257. var $this = $(this.selector);
  258. if_none !== undefined && !$this.hasClass(add) && !$this.hasClass(remove) && $this.addClass(if_none);
  259. $this.addClass(add).removeClass(remove);
  260. },
  261. thisCompStyle : function ( cssStyle ) {
  262. return cssStyle !== undefined ? this.getComputedStyle().getPropertyValue( cssStyle ) : this.getComputedStyle();
  263. },
  264. refreshElement : function ( speed, parentBoolean ) {
  265. var $elem = parentBoolean ? this.parent() : this, data = $elem.html();
  266. $elem.hide( speed / 2 ).empty().html( data ).fadeIn( speed );
  267. },
  268. hasId : function ( id ) {
  269. return id === this.attr('id');
  270. },
  271. hasClasses : function ( classes, any ) {
  272. classes = classes.split( classes.inElem(',') ? ',' : ' ' );
  273. var check = 0, i = 0;
  274. for ( i; i < classes.length; i++ ) {
  275. this.hasClass( classes[ i ] ) && check++;
  276. if ( any !== undefined && check !== 0 ) return true;
  277. }
  278. return check === classes.length;
  279. },
  280. hasNoChildren : function ( selection ) {
  281. return $( this ).filter( function(){
  282. return $( this ).children( selection ).length === 0;
  283. });
  284. },
  285. /* hasParent : function( parentSelection ){
  286. return parentSelection.inElem('#')
  287. ? this.parent().hasId( parentSelection.split('#').shift() )
  288. : this.parent().hasClass( parentSelection.split('.').shift() );
  289. },
  290. */
  291. hasAncestor : function ( Ancestor ) {
  292. return this.filter(function() {
  293. return !!$( this ).closest( Ancestor ).length;
  294. });
  295. //$('.element').hasAncestor('.container').myAction();
  296. },
  297. hasParent : function ( selection ) {
  298. return !!$( this ).parent( selection ).length
  299. },
  300. hasParents : function ( selection ) {
  301. return !!$( this ).parents( selection ).length
  302. },
  303. hasQuery : function ( query ) {
  304. return d.querySelector(query).length;
  305. },
  306. hasAttr : function ( name, val ) {
  307. var thisAttr = $( this ).attr( name );
  308. thisAttr =
  309. val !== undefined
  310. ? thisAttr === val
  311. : thisAttr;
  312. return ( typeof thisAttr !== "undefined" && thisAttr !== false && thisAttr !== null );
  313.  
  314. //return val !== undefined
  315. // ? attrName === val
  316. // : typeof( attrName ) !== 'undefined'; //$( this )[0].hasAttribute( name );
  317. },
  318. isTag : function ( tag ) {
  319. var e = this[0] || $('<undefined/>');
  320. //noinspection JSValidateTypes,JSUnresolvedVariable,JSUnresolvedFunction
  321. return e.nodeName !== undefined && e.nodeName.toLowerCase() === tag.toLowerCase();
  322. },
  323. isNode : function ( node ) {
  324. var e = this[0] || $('<undefined/>');
  325. //noinspection JSValidateTypes
  326. return e.nodeName !== undefined && e.nodeName.toLowerCase() === node.toLowerCase();
  327. },
  328. searchAttr : function ( search, type, chkLen ) { //bool name value length or 1 2 3 4
  329. var Attributes = this[0].attributes;
  330.  
  331. if ( arguments.length === 0 ) {
  332. var obj = {};
  333. $.each( Attributes, function() {
  334. this.specified && ( obj[ this.name ] = this.value );
  335. });
  336. return obj;
  337. } else if( search != undefined ) {
  338. var name = '', val = '';
  339. //noinspection FunctionWithInconsistentReturnsJS
  340. $.each( Attributes, function() {
  341. if( this.specified && type == 'length' ) {
  342. if( this.name.length > chkLen ) {
  343. name = this.name;
  344. c.i('Attributes', Attributes);
  345. return false;
  346. }
  347. }
  348. else if( this.specified && this.name.inElem( search ) ) {
  349. name = this.name;
  350. val = this.value;
  351. return false;
  352. }
  353. });
  354. return ( type == 'bool' || type == 1 ) ? name.length ? true : false :
  355. ( type == 'name' || type == 2 ) ? name :
  356. ( type == 'value' || type == 3 ) ? val :
  357. ( type == 'length' || type == 4 ) && name;
  358. }
  359. },
  360. findClass : function ( Class ) {
  361. return this.find('.' + Class)
  362. },
  363. findNextSibling : function ( thisSelector, bool ) {
  364. bool = bool || true;
  365. return bool ? this.eq(0).nextAll( thisSelector ).eq(0) : this.nextAll( thisSelector ).eq(0) ;
  366. },
  367. findPrevSibling : function ( thisSelector, bool ) {
  368. bool = bool || true;
  369. return bool ? this.eq(0).prevAll( thisSelector ).eq(0) : this.prevAll( thisSelector ).eq(0) ;
  370. },
  371. href : function ( newURL ) {
  372. return arguments.length === 0 ? this.attr('href') : this.attr('href', newURL);
  373. },
  374. src : function ( newSRC ) {
  375. return arguments.length === 0 ? this.attr('src') : this.attr('src', newSRC);
  376. },
  377. equals : function ( compareTo ) {
  378. if (!compareTo || this.length != compareTo.length)
  379. return false;
  380.  
  381. for (var i = 0; i < this.length; ++i) {
  382. if (this[i] !== compareTo[i])
  383. return false;
  384. }
  385. return true;
  386. },
  387. justText : function ( newText, prepend ) {
  388. var $children = null,
  389. placement = prepend === undefined ? 'prepend':'append';
  390. if ( newText ) {
  391. $children = $( this )
  392. .children()
  393. .clone();
  394. $( this )
  395. .children()
  396. .remove()
  397. .end()
  398. .text( newText )
  399. [ placement ]( $children );
  400. return $(this);
  401. }
  402. else {
  403. return $.trim( $( this )
  404. .clone()
  405. .children()
  406. .remove()
  407. .end()
  408. .text());
  409. }
  410. },
  411. uncomment : function ( recurse ) {
  412. <!-- hidden --> // this will reveal, whats inside. In this case it will bi the word hidden
  413. $( this ).contents().each(function() {
  414. if ( recurse && this.hasChildNodes() ) {
  415. $( this ).uncomment(recurse);
  416. } else if ( this.nodeType == 8 ) {
  417. // Need to "evaluate" the HTML content,
  418. // otherwise simple text won't replace
  419. var e = $('<span>' + this.nodeValue + '</span>');
  420. $( this ).replaceWith( e.contents() );
  421. }
  422. });
  423. // $('#uncomment').uncomment( true );
  424. // http://stackoverflow.com/a/22439787
  425. },
  426. getComment : function ( getValue ) {
  427. var COMMENT_NODE = this.contents().filter(function(){
  428. return this.nodeType == Node.COMMENT_NODE;
  429. });
  430. return getValue ?
  431. COMMENT_NODE.each(function(){
  432. return $( this ).nodeValue.str2html();
  433. })
  434. : COMMENT_NODE;
  435. },
  436. //$.get('defaultComp/foot.html', function(dataContent) {$('#foot').replaceWith(dataContent); });
  437. getURL : function ( url, how ) {
  438. how = how || 'html';
  439. var that = this;
  440. $.get( url, function(dataContent) {
  441. $(that)[ how ](dataContent);
  442. });
  443. return this
  444. },
  445.  
  446. hasEvent : function ( event ) {
  447. var eventHandlerType;
  448. $( this ).on( event, clickEventHandler ).triggerHandler( event );
  449. function clickEventHandler( e ) {
  450. eventHandlerType = e.type;
  451. }
  452. return eventHandlerType === event;
  453. },
  454. scrollTuneAdv : function ( opt ){
  455. // $("body").scrollTune({ pps: 1700, pageY: config.pageY, easing:'easeOutSmoothBounce', hsc: true }).promise()
  456. // .done( function() { setTimeout(function(){ toggleClassState( config, 'fullPlayer', type ); },100); })
  457.  
  458. console.log('scrollTune');
  459.  
  460. var position,
  461. defaults = {
  462. tune: 0,
  463. speed: 0,
  464. pps: false, // pixel per second
  465. ppsM: 1000,
  466. pageYmini: 0,
  467. pageY: false, //{ pps: 300, pageY: event.pageY }
  468. hsc: false, // height speed compensation
  469. animate: false,
  470. // require http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js or jQueryUI - if other than ' swing or linear '
  471. easing: "easeInOutCubic", // easeInOutCubic easeInOutQuad easeInOutElastic http://easings.net/
  472. delay: 0,
  473. varStore: '',
  474. varAltStore:false,
  475. name: false,
  476. start: false,
  477. startTime: 0,
  478. step: false,
  479. stepTime: 0,
  480. complete: false,
  481. completeTime: 0,
  482. done: false,
  483. doneTime: 0,
  484. goTo: $('body')
  485. },
  486. heightSpeedComp = function(){ return opt.hsc ? 1 + ( ( $(document).height() / opt.pageY ) / 1.4 ) : 1 ; },
  487. varStore = function( action, step ){
  488. console.log(action,step);
  489. opt.name !== false
  490. ? opt.varAltStore !== false
  491. ? ( console.log('Store'), opt.varAltStore[opt.name][ action ](step) )
  492. : ( console.log('Store false'), opt.name[ action ](step) )
  493. : opt.pageYmini < opt.pageY || opt.varStore === config
  494. ? ( console.log('config'), opt.varStore[ action ](step) )
  495. : ( console.log('config false'), opt.varStore(step) );
  496. };
  497.  
  498. console.log('opt.pageY',opt.pageY);
  499. opt = $.extend( {}, defaults, opt );
  500. position = ( $( this ).offset().top + opt.tune ) + 'px';
  501.  
  502. opt.pps !== false || opt.animate !== false || ( typeof opt.speed === 'string' ? opt.speed.length !== 0 : opt.speed !== 0 )
  503. ? (
  504. opt.speed = opt.pps !== false ? parseInt( ( opt.pageY / opt.pps * heightSpeedComp() ) * opt.ppsM ) : opt.speed,
  505. opt.goTo.delay( opt.delay ).animate(
  506. { scrollTop : position },
  507. { duration : opt.speed, easing: opt.easing,
  508. start : function(){
  509. opt.start && setTimeout(function(){
  510. varStore('start');
  511. }, opt.startTime );
  512. },
  513. step : function(i){
  514. opt.step && setTimeout(function(){
  515. varStore('step',i);
  516. }, opt.stepTime );
  517. },
  518. complete : function(){
  519. opt.complete && setTimeout(function(){
  520. varStore('complete');
  521. }, opt.completeTime );
  522. },
  523. done : function(){
  524. opt.done && setTimeout(function(){
  525. varStore('done');
  526. }, opt.doneTime );
  527. }
  528. }
  529. )
  530. )
  531. : opt.goTo.scrollTop( position );
  532.  
  533. return this; // for chaining...
  534.  
  535. },
  536. scrollTuneNew : function ( opt ){
  537. var defaultOptions = {
  538. tune: 0,
  539. speed: 512,
  540. animate: true,
  541. easing: 'swing',
  542. goTo: $('html, body')
  543. },
  544. element = $( this ),
  545. options = $.extend({}, defaultOptions, $.fn.scrollTuneNew.changeDefaults, opt ),
  546. position = ( element.offset().top + options.tune ) + 'px';
  547.  
  548. options.animate
  549. ? options.goTo.animate({ scrollTop: position }, options.speed, options.easing )
  550. : options.goTo.scrollTop( position );
  551.  
  552. return element; // for chaining...
  553. },
  554. simulateMouseEvent : function ( MouseEvents ){
  555. var $this = this[0], evt,
  556. mEvent = MouseEvents || 'click';
  557. document.createEvent
  558. ? (
  559. evt = document.createEvent('MouseEvents'),
  560. evt.initEvent(mEvent, true, false),
  561. $this.dispatchEvent(evt)
  562. )
  563. : document.createEventObject ?
  564. $this.fireEvent('onclick')
  565. : typeof node['on' + mEvent] == 'function'
  566. && $this['on' + mEvent]();
  567. },
  568. simulateMouse : function ( typeOfEvent ){
  569. var evt = document.createEvent("MouseEvents"),
  570. mEvent = typeOfEvent || 'click';
  571. evt.initMouseEvent( mEvent, true, true, window,
  572. 0, 0, 0, 0, 0, false, false, false, false, 0, null);
  573. this[0] !== undefined && this[0].dispatchEvent(evt);
  574. return this;
  575. },
  576. qUnWrap : function (){
  577. $( this ).find(':first-child').unwrap();
  578. },
  579. designMode : function ( state, contenteditable ) {
  580. state = ( state === true || state === 1 || state === 'on' ) ? 'on' :
  581. ( state === false || state === 0 || state === 'off' ) && 'off';
  582. contenteditable = contenteditable || 'off';
  583. contenteditable !== 'off'
  584. ? contenteditable === 'document'
  585. ? document.designMode = state
  586. : contenteditable
  587. ? this.attr('contenteditable', true)
  588. : this.removeAttr('contenteditable')
  589. : this.contentWindow.document.designMode = state;
  590. }
  591. });
  592. //$.fn.scrollTune.changeDefault = {};
  593.  
  594. $.extend({
  595. confirm: function (title, message, yesText, noText, yesCallback) {
  596. //dialog needs jQueryUI
  597. /*
  598. $.confirm(
  599. "CONFIRM", //title
  600. "Delete " + filename + "?", //message
  601. "Delete", //button text
  602. deleteOk //"yes" callback
  603. );
  604. */
  605. $("<div></div>").dialog( {
  606. buttons: [{
  607. text: yesText,
  608. click: function() {
  609. yesCallback();
  610. $( this ).remove();
  611. }
  612. },
  613. {
  614. text: noText,
  615. click: function() {
  616. $( this ).remove();
  617. }
  618. }
  619. ],
  620. close: function (event, ui) { $(this).remove(); },
  621. resizable: false,
  622. title: title,
  623. modal: true
  624. }).text(message).parent().addClass("alert");
  625. }
  626. });
  627.  
  628. $.extend( $.expr[":"], {
  629. ldata: function(el, idx, selector) {
  630. var attr = selector[3].split(", ");
  631. return el.dataset[attr[0]] === attr[1];
  632. },
  633. value: function(el, idx, selector) {
  634. return el.value === selector[selector.length - 1];
  635. },
  636. isEmptyTrimmed: function(el){
  637. return !$.trim($(el).html());
  638. },
  639. data: $.expr.createPseudo
  640. ? $.expr.createPseudo(function( dataName ) {
  641. return function( elem ) {
  642. return !!$.data( elem, dataName );
  643. };
  644. })
  645. // support: jQuery <1.8
  646. : function( elem, i, match ) {
  647. return !!$.data( elem, match[ 3 ] );
  648. }
  649. });
  650.  
  651. $.isInArray = function( item, array ) {
  652. return !!~$.inArray(item, array);
  653. };
  654. $.allVar = function( array, value, all, atLeast ) {
  655. var count = 0,
  656. arrLength = array.length,
  657. isBool = typeof value === 'boolean';
  658.  
  659. $.each( array, function( i, e ){
  660. value === ( isBool ? !!e : e ) && count++;
  661. });
  662.  
  663. return all ? count === arrLength : count >= atLeast;
  664. };
  665. /*
  666. Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
  667. //$( selector ).get(0).playing;
  668. get: function(){
  669. return !!( this.currentTime > 0 && !this.paused && !this.ended && this.readyState > 2 );
  670. }
  671. });
  672. */
  673. /* Object.prototype.hasAttribute = function( attrName, val ){
  674. var thisAttr =
  675. this.attr
  676. ? val !== undefined
  677. ? this.attr( attrName ) === val
  678. : this.attr( attrName )
  679. : this.getAttribute( attrName );
  680. return ( typeof thisAttr !== "undefined" && thisAttr !== false && thisAttr !== null );
  681. };
  682. */
  683. Array.prototype.findArrayObj = function( findKey, exactValue ){
  684. return $.grep( this, function( obj ){
  685. return obj[ findKey ] === exactValue;
  686. })[0];
  687. //This prototype doesn't modify the array,
  688. // it gets the element that contains key with correct value and
  689. // the returns that element
  690. };
  691. Array.prototype.removeArrayObj = function( findKey, exactValue ){
  692. //my own example test: http://jsfiddle.net/aPH7m/82/
  693. //This prototype doesn't modify the array, needs to be overwritten or put into new var array
  694. return $.grep( this, function( obj ) {
  695. return obj[ findKey ] !== exactValue;
  696. });
  697. };
  698. Array.prototype.addKeyToArrayObj = function( findKey, exactValue, newKey, newValue ){
  699. return $.grep( this, function( obj ){
  700. return obj[ findKey ] === exactValue ? obj[ newKey ] = newValue : obj[ findKey ] !== exactValue;
  701. });
  702. // This prototype doesn't modify the array,
  703. // it gets the element that contains key with correct value and
  704. // adds a new key with its value to that element
  705. };
  706.  
  707. Array.prototype.filterArrayObj = function( doWhat, findKey, exactValue, newKey, newValue ){
  708. return doWhat === 'remove'
  709. ? this.filter(function( obj ) {
  710. return obj[ findKey ] !== exactValue;
  711. })
  712. : doWhat === 'addKey'
  713. ? this.filter(function( obj ){
  714. return obj[ findKey ] === exactValue
  715. ? obj[ newKey ] = newValue
  716. : obj[ findKey ] !== exactValue;
  717. })
  718. : doWhat === 'find'
  719. && this.filter(function( obj ){
  720. return obj[ findKey ] === exactValue;
  721. })[0];
  722. };
  723. Array.prototype.grepArrayObj = function( doWhat, idKey, uniqueValue, theKey, theValue ){
  724. doWhat = doWhat === 'updateKey' ? 'addKey' : doWhat;
  725. return doWhat === 'remove'
  726. ? $.grep( this, function( obj ){
  727. return obj[ idKey ] !== uniqueValue;
  728. })
  729. : doWhat === 'addKey'
  730. ? $.grep( this, function( obj ){
  731. return obj[ idKey ] === uniqueValue
  732. ? (
  733. obj[ theKey ] = theValue,
  734. obj[ idKey ] === uniqueValue
  735. )
  736. : obj[ idKey ] !== uniqueValue;
  737. })
  738. : doWhat === 'find'
  739. ? $.grep( this, function( obj ){
  740. return obj[ idKey ] === uniqueValue;
  741. })[0]
  742. : doWhat === 'deleteKey'
  743. && $.grep( this, function( obj ){
  744. return obj[ idKey ] === uniqueValue
  745. ? (
  746. delete obj[ theKey ],
  747. obj[ idKey ] === uniqueValue
  748. )
  749. : obj[ idKey ] !== uniqueValue;
  750. })
  751. };
  752. Array.prototype.sortObjArray = function( key, reverse ){
  753. this.sort(function(a, b){
  754. return ( reverse || false ) ? b[key] - a[key] : a[key] - b[key];
  755. })
  756. };
  757.  
  758. //noinspection JSPrimitiveTypeWrapperUsage
  759. Boolean.parse = function(val) {
  760. // http://stackoverflow.com/a/24744599
  761. var falsely = /^(?:f(?:alse)?|no?|0+)$/i;
  762. return !falsely.test(val) && !!val;
  763. };
  764.  
  765.  
  766. /*
  767. Object.prototype.isObjectType = function( type, showType ){ //"[object Number]"
  768. var objectString = Object.prototype.toString.call( this );
  769. return showType === 'show' ? objectString :
  770. showType === 'exact' ? objectString === type :
  771. showType === 'search' && objectString.toLowerCase().inElem( type.toLowerCase() );
  772. };
  773. */
  774.  
  775. String.prototype.splitEvery = function( splitter, every ){
  776. var array = this.split( splitter ), returnString = '';
  777. $.each( array, function( index, elem ){
  778. returnString += elem + ( index < array.length - 1 || index % every === 0 ) ? '' : splitter;
  779. });
  780. return returnString;
  781. };
  782. String.prototype.advSplit = function( chr, nbr ){
  783. var str = this.split(chr),
  784. strLen = str.length,
  785. chrLen = chr.length,
  786. returnStr = ['',''],
  787. newArr = [];
  788.  
  789. $.each( str, function( index ){
  790. returnStr[ index < nbr ? 0 : 1 ] += str[ index ] + chr;
  791. });
  792.  
  793. $.each( returnStr, function( index ){
  794. returnStr[ index ] = returnStr[ index ].slice(0, - chrLen);
  795. returnStr[ index ].length > 0 && newArr.push( returnStr[ index] );
  796. });
  797.  
  798. return newArr;
  799. };
  800. String.prototype.advSplitJoin = function( chr, nbr, ips ){
  801.  
  802. var str = this.split(chr),
  803. strLen = str.length,
  804. ipsLen = ips.length,
  805. returnStr = '',
  806. returnStrLen;
  807.  
  808. $.each( str, function( index ) {
  809. var add = index < strLen - 1
  810. ? chr
  811. : '';
  812. returnStr += index + 1 === nbr
  813. ? str[index] + ips
  814. : str[index] + add;
  815. });
  816.  
  817. returnStrLen = returnStr.length;
  818. returnStr.slice( returnStrLen - ipsLen ) === ips
  819. && ( returnStr = returnStr.slice( 0, returnStrLen - ipsLen ) );
  820.  
  821. return returnStr;
  822. };
  823. String.prototype.extract = function( start, end, inside, newWay ){
  824. var str = this,
  825. myArray = [ true, 1, 'yes', 'inside' ],
  826. startCharIndex = str.indexOf( start ),
  827. endCharIndex = str.indexOf( end );
  828.  
  829. newWay = newWay !== undefined ? $.inArray( newWay, myArray ) !== -1 : false;
  830. inside = inside !== undefined ? $.inArray( inside, myArray ) !== -1 : false;
  831.  
  832. function simpler() {
  833. return inside
  834. ? str.split( start ).pop().split( end ).shift()
  835. : start + str.split( start ).pop().split( end ).shift() + end;
  836. }
  837. function older() {
  838. return inside //old buggy way, some old scripts may depends on it
  839. ? str.replace( start, '').replace( end, '')
  840. : str.substr( startCharIndex, endCharIndex );
  841. }
  842. return newWay ? simpler() : older()
  843. };
  844. String.prototype.extractNew = function( start, end, inside ){
  845. var str = this;
  846. return inside !== undefined && inside
  847. ? str.split( start ).pop().split( end ).shift()
  848. : inside
  849. || start + str.split( start ).pop().split( end ).shift() + end;
  850. };
  851.  
  852. String.prototype.charTrim = function( char ){
  853. // alert("...their.here.".charTrim('.'));
  854. var first_pos = 0,
  855. last_pos = this.length- 1, i ;
  856. //find first non needle char position
  857. for( i = 0; i < this.length; i++ ){
  858. if( this.charAt( i ) !== char ){
  859. first_pos = ( i == 0 ? 0 : i );
  860. break;
  861. }
  862. }
  863. //find last non needle char position
  864. for( i = this.length - 1; i > 0; i-- ){
  865. if( this.charAt( i ) !== char ){
  866. last_pos = ( i == this.length ? this.length: i + 1 );
  867. break;
  868. }
  869. }
  870. return this.substring( first_pos, last_pos );
  871. };
  872. String.prototype.reduceWhiteSpace = function(){
  873. return this.replace(/\s+/g, ' ');
  874. };
  875. String.prototype.formatString = function(){
  876.  
  877. var inputStr = this.toString().reduceWhiteSpace()
  878. .split('!').join(' !').split('!;').join("!important;")
  879. .split(/\s+/g).join(' ')
  880. .split('{').join('{\n\t')
  881. .split('; ').join(';')
  882.  
  883.  
  884.  
  885. .split('( ').join('(')
  886. .split(' )').join(')')
  887.  
  888. .split(' :').join(':')
  889.  
  890. .split(';').join(';\n\t')
  891. .split('*/').join('*/\n')
  892. .split(')*(').join(') * (')
  893. .split('}').join('}\n'),
  894. returnStr = '\t', pop;
  895.  
  896. $.each( inputStr.split('\n'), function ( i, elem ) {
  897.  
  898. elem.search( '{' ) === -1 && elem.search( ': ' ) === -1
  899. && ( elem.search( ':' ) > 1
  900. ? ( pop = elem.split(': ').join(':').split( ':' ).pop(), elem = elem.split( pop ).shift() + ' ' + pop )
  901. : elem.search(':') === 1 && ( elem = elem.split(': ').join(':').split( ':' ).join( ': ' ) ) );
  902. // : elem.search( '{' ) === 1 && ( elem.search( ': ' ) !== -1 || elem.search( ' :' ) !== -1 || elem.search( ' : ' ) !== -1 )
  903. // && ( elem = elem.split( ': ' ).join( ' :' ).split( ' :' ).join( ':' ).split( ' : ' ).join( ': ' ) );
  904.  
  905. returnStr += elem + '\n\t';
  906. });
  907. returnStr = returnStr.split('>').join(' > ').split(' > ').join(' > ').split( ': //' ).join( '://' ).split( ':url' ).join( ': url' );
  908. return returnStr.slice( 0, returnStr.lastIndexOf('}') ) + '}';
  909. };
  910.  
  911. /**
  912. * Parses mixed type values into booleans. This is the same function as filter_var in PHP using boolean validation
  913. * //@returny {Boolean|Null}
  914. */
  915. String.prototype.parseBooleanStyle = function( nullOnFailure ){
  916. nullOnFailure = nullOnFailure || false;
  917. var bool, $this = this.toString().toLowerCase();
  918. switch( $this ){
  919. case 'true':
  920. case '1':
  921. case parseInt( $this ) > 0:
  922. case 'on':
  923. case 'yes':
  924. bool = true;
  925. break;
  926. case 'false':
  927. case '0':
  928. case 'off':
  929. case 'no':
  930. bool = false;
  931. break;
  932. default:
  933. bool = nullOnFailure ? null : false;
  934. break;
  935. }
  936. return bool;
  937. };
  938. String.prototype.parseBool = function(){
  939. var thisStr = parseInt( this ) ? this === 0 ? 'false' : 'true' : '' + this,
  940. trueArray = [ 'on', 'yes','y', 'j', 'true', true ],
  941. falseArray = [ 'off', 'no', 'n', 'false', false ];
  942.  
  943. thisStr = thisStr.toLowerCase().trim();
  944.  
  945. return $.inArray( thisStr, trueArray ) !== -1 ? true :
  946. $.inArray( thisStr, falseArray ) !== -1 ? false : this;
  947. };
  948.  
  949. String.prototype.isType = function( type ){
  950. return !!$.type( this ) === type
  951. };
  952. String.prototype.undef = function( replace ){
  953. return this === undefined ? replace : this;
  954. };
  955. String.prototype.isUndefined = function( state, replace ){
  956. state = state !== undefined ? state : true;
  957. replace = replace !== undefined ? replace : true;
  958. return state ? this === undefined ? replace : this : state;
  959. };
  960. String.prototype.isNumber = function ( float ) {
  961. var reg = new RegExp( "^[-]?[0-9]+[\.]?[0-9]+$" );
  962. return reg.test( this )
  963. };
  964.  
  965. String.prototype.inURL = function(){
  966. var winLoc = window.location.href;
  967. return winLoc.search(this) !== -1;
  968. };
  969. String.prototype.inString = function( string ){
  970. return string !== undefined ? string.search(this) !== -1 : false;
  971. };
  972. String.prototype.inElem = function( search ){
  973. return this !== undefined ? this.search(search) !== -1 : false;
  974. };
  975.  
  976. String.prototype.count = function( char, UpperCase ){
  977. var numberOf = this.toString().match( new RegExp( char, ( UpperCase ? "gi" : "g" ) ) );
  978. return numberOf != null ? numberOf.length : 0;
  979. };
  980. String.prototype.startsWith = function( str ){
  981. return this.slice(0, str.length) == str;
  982. };
  983. String.prototype.removeStarts = function( many ){
  984. return this.substring( many - 1, this.length );
  985. };
  986. String.prototype.removeEnds = function( many ){
  987. return this.substring( 0, this.length - many );
  988. };
  989. String.prototype.endsWith = function( str ){
  990. return this.slice( -str.length ) == str;
  991. };
  992. String.prototype.capitalizeFirst = function(){
  993. return this.charAt(0).toUpperCase() + this.slice(1);
  994. };
  995. String.prototype.lpad = function( padString, length ){
  996. var str = this;
  997. while ( str.length < length ) {
  998. str = padString + str; }
  999. return str;
  1000. };
  1001.  
  1002. // use full to convert String URL, so that you can use location commands
  1003. String.prototype.toLocation = function(){
  1004. var a = document.createElement('a');
  1005. a.href = this;
  1006. return a;
  1007. };
  1008. String.prototype.str2html = function(){
  1009. return $('<div/>').html( this ).contents();
  1010. };
  1011. String.prototype.toStyle = function( styleId, append ){
  1012. append = append || 'head';
  1013. var cssID,
  1014. cssSplit = this.split('¤'),
  1015. cssStyled = cssSplit.pop().formatString();
  1016. styleId = styleId !== undefined ? styleId : cssSplit.shift();
  1017. cssID = $( append + ' #' + styleId );
  1018. cssID.length
  1019. ? cssID.html( cssStyled )
  1020. : $( $( '<style/>',{ id: styleId, class:'mySuperStyles', html: cssStyled } ) ).appendTo( append );
  1021. };
  1022.  
  1023. //HTMLObjectElement.prototype.obj2Str = function(){var objArr = $.makeArray( this ); return objArr[0].outerHTML;};
  1024. /*
  1025. String.prototype.replaceAll = function( target, replacement ) {
  1026. return this.split(target).join(replacement);
  1027. };
  1028. */
  1029. function ScrollZoomTune( selection, zooms, tune, ani, speed ){
  1030. //ScrollZoomTune("div.thumb .title a",1,-25,1,'slow');
  1031. var body = $('body'), sel = $( selection), position;
  1032. //noinspection JSValidateTypes
  1033. sel.size() !== 0 && (
  1034. body.css('zoom',zooms),
  1035. position = sel.position().top + tune,
  1036. ani === 1
  1037. ? body.animate({ scrollTop: position * zooms }, speed )
  1038. : body.scrollTop( position * zooms )
  1039. );
  1040. }
  1041. function refreshElement( elem , speed ){ //refreshElement('.videoPlayer','slow');
  1042. var $elem = $( elem ), data = $elem.html();
  1043. $elem.empty().html( data ).fadeIn( speed );
  1044. }
  1045. function autoCopyToClipboard( input ){
  1046. var $copyThis = $( '#copyThis' );
  1047. $( 'body' ).append( $('<textarea/>',{ id:'copyThis', rows:"4", cols:"50", type:"text", value: input }) );
  1048. $copyThis.focus().select();
  1049. document.execCommand("copy");
  1050. $copyThis.remove();
  1051. }
  1052. function toStyle( styleId, str, append ){
  1053. append = append || 'head';
  1054. var $id = $( append + ' #' + styleId ),
  1055. cssID = str.formatString();
  1056.  
  1057. $id.length
  1058. ? $id.html( cssID )
  1059. : $( $( '<style/>',{ id: styleId, class:'mySuperStyles', html: cssID } ) ).appendTo( append );
  1060. }
  1061. function obj2Str( obj ){
  1062. var objArr = $.makeArray(obj);
  1063. return objArr[0].outerHTML;
  1064. }
  1065.  
  1066. function sortBy(key, reverse){
  1067. // Usage: array.sort( sortBy( key, reverse ) )
  1068.  
  1069. // Move smaller items towards the front
  1070. // or back of the array depending on if
  1071. // we want to sort the array in reverse
  1072. // order or not.
  1073. var moveSmaller = reverse ? 1 : -1;
  1074. // Move larger items towards the front
  1075. // or back of the array depending on if
  1076. // we want to sort the array in reverse
  1077. // order or not.
  1078. var moveLarger = reverse ? -1 : 1;
  1079. /**
  1080. * @param {*} a
  1081. * @param {*} b
  1082. * @return {Number}
  1083. */
  1084. return function (a, b) {
  1085. if (a[key] < b[key]) {
  1086. return moveSmaller;
  1087. }
  1088. if (a[key] > b[key]) {
  1089. return moveLarger;
  1090. }
  1091. return 0;
  1092. };
  1093. }
  1094.  
  1095. function VideoTitleA( elem , state ){
  1096. //VideoTitleA("div.thumb .title a",'on');
  1097. $( elem ).each(function(){
  1098. var $this = $(this),
  1099. strTitle = $this.attr('title'),
  1100. strText = $this.attr('data-text'),
  1101. strHtml = $this.text();
  1102. state === 'on' ? $this.text(strTitle).attr('data-text',strHtml) : $this.text(strText);
  1103. });
  1104. }
  1105. /**
  1106. * @return {string}
  1107. */
  1108. function MultiString( f ){
  1109. return f.toString().split('\n').slice(1, -1).join('\n');
  1110. }
  1111. function wrapWithTag( tag, text, selection ){
  1112. var thisAttr = selection != undefined && selection.startsWith('.') ? 'class' : selection.startsWith('#') && 'id',
  1113. thisTag = $('<' + tag + '/>', { text: text });
  1114. return thisAttr.length ? thisTag.attr( thisAttr, selection.splice( 1 ) ) : thisTag;
  1115. }
  1116.  
  1117. function clean( node ) {
  1118. /*
  1119. So to clean those unwanted nodes from inside the <body> element, you would simply do this:
  1120.  
  1121. clean(document.body);
  1122. Alternatively, to clean the entire document, you could do this:
  1123.  
  1124. clean(document);
  1125. */
  1126. for( var n = 0; n < node.childNodes.length; n ++ ){
  1127. var child = node.childNodes[ n ];
  1128. ( child.nodeType === 8 || ( child.nodeType === 3 && !/\S/.test( child.nodeValue ) ) )
  1129. ? (
  1130. node.removeChild( child ),
  1131. n --
  1132. )
  1133. : child.nodeType === 1 && clean( child );
  1134. }
  1135. }
  1136. function commentsCleaner( array ){
  1137. array = array === undefined ? [ '*', document, 'html' ] : array;
  1138.  
  1139. // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
  1140. // http://stackoverflow.com/a/2364760
  1141. $.each( array, function( i, e ) {
  1142. $( e ).contents().each( function() {
  1143. this.nodeType === Node.COMMENT_NODE && $( this ).remove(); }); });
  1144. }
  1145.  
  1146. function newUrlNoReload( title, url ){
  1147. window.history.pushState("string", title, url );
  1148. }
  1149. function inURLo( search, exact ){
  1150. exact = exact || false;
  1151. var winLoc = window.location.href;
  1152. return exact ? winLoc === search : winLoc.search( search ) !== -1;
  1153. }
  1154. function inURLe( search, exact ){
  1155. exact = exact || false;
  1156. var inArr,
  1157. winLoc = window.location.href,
  1158. tiA = function( search ){
  1159. inArr = false;
  1160. $.each( search, function(i,e){
  1161. if( winLoc.search( search ) !== -1 ){
  1162. inArr = true;
  1163. return false;
  1164. }
  1165. });
  1166. return inArr;
  1167. };
  1168. return exact ? winLoc === search : $.isArray( search ) ? tiA( search ) : winLoc.search( search ) !== -1;
  1169. }
  1170. function inURL( search, exact ){
  1171.  
  1172. var isAll,isNone,inArr,checkInArr,
  1173. winLoc = window.location.href,
  1174. countAll = 0, countNone = 0;
  1175.  
  1176. exact = exact || false;
  1177. isAll = exact === 'all';
  1178. isNone = exact === 'none';
  1179. exact = isNone || isAll ? false : exact;
  1180.  
  1181. checkInArr = function( search, all ){
  1182. inArr = false;
  1183. $.each( search, function(i,e){
  1184. if( winLoc.search( e ) !== -1 ){
  1185. inArr = true;
  1186. if( all ) countAll++; else return false;
  1187. }
  1188. else if( winLoc.search( e ) === -1 ){
  1189. inArr = true;
  1190. if( all ) countNone++; else return false;
  1191. }
  1192. });
  1193. return all ? inArr && ( search.length === countAll || search.length === countNone ) : inArr;
  1194. };
  1195.  
  1196. return exact
  1197. ? winLoc === search
  1198. : $.isArray( search )
  1199. ? checkInArr( search, isAll || isNone )
  1200. : isNone
  1201. ? winLoc.search( search ) === -1
  1202. : winLoc.search( search ) !== -1;
  1203.  
  1204. }
  1205. function loadDoc( href ){
  1206. $( location ).attr('href', href );
  1207. }
  1208.  
  1209. function isPrimitiveType( value ){
  1210. // will return true if the value is a primitive value
  1211. switch ( typeof value ) {
  1212. case 'string': case 'number': case 'boolean': case 'undefined': {
  1213. return true;
  1214. }
  1215. case 'object': {
  1216. return !value;
  1217. }
  1218. }
  1219. return false;
  1220. }
  1221. function checkDividedIsInteger( num, div ){
  1222. return ( num % div === 0 );
  1223. }
  1224. function isEven( value ){
  1225. return ( value % 2 === 0 );
  1226. }
  1227. function inDom( array, onElement ) {
  1228. var found = false,
  1229. isArrayFN = function(){
  1230. $.each( array, function( i, value ) {
  1231. value = onElement !== undefined
  1232. ? onElement + value
  1233. : value;
  1234. if( $( value ).length ) {
  1235. found = true;
  1236. return false;
  1237. }
  1238. })
  1239. };
  1240.  
  1241. $.isArray( array )
  1242. ? isArrayFN()
  1243. : $( array ).length && ( found = true );
  1244.  
  1245. /**
  1246. * @return {boolean}
  1247. */
  1248. return found;
  1249. }
  1250. function isHTMLObject( obj ){
  1251. obj = typeof obj == 'string' ? obj : $( obj );
  1252. return obj.length
  1253. ? !!( obj instanceof HTMLElement || obj[0] instanceof HTMLElement)
  1254. : !!( obj && ( obj.nodeName || ( obj.prop && obj.attr && obj.find ) ) );
  1255. }
  1256.  
  1257. function isFunction( functionToCheck ){
  1258. var getType = {};
  1259. return functionToCheck && getType.toString.call( functionToCheck ) === '[object Function]';
  1260. }
  1261. function isNumeric( value ){
  1262. return /^\d+$/.test( value );
  1263. }
  1264.  
  1265. function parseBoolean( Boolean , Type ) {
  1266. // http://stackoverflow.com/a/24744599
  1267. Type = Type || false;
  1268. var falsely = /^(?:f(?:alse)?|no?|0+)$/i,
  1269. truely = /^(?:t(?:rue)?|yes?|1+)$/i;
  1270. return Type ? !truely.test( Boolean ) && !!Boolean : !falsely.test( Boolean ) && !!Boolean;
  1271. }
  1272. function parseBooleanStyle( str, nullOnFailure ){
  1273. nullOnFailure = nullOnFailure || false;
  1274. str = str || '';
  1275. var bool, $this = str.toString().toLowerCase();
  1276. $this = parseInt( $this ) > 0 ? parseInt( $this ) : $this;
  1277. console.log('parseBooleanStyle',$this);
  1278. switch( $this ){
  1279. case 'true':
  1280. case '1':
  1281. case parseInt( $this ) > 0:
  1282. case 'on':
  1283. case 'yes':
  1284. bool = true;
  1285. break;
  1286. case 'false':
  1287. case '0':
  1288. case 'off':
  1289. case 'no':
  1290. bool = false;
  1291. break;
  1292. default:
  1293. bool = nullOnFailure ? null : false;
  1294. break;
  1295. }
  1296. return bool;
  1297. }
  1298. function getsComputedStyle( style, elem ) {
  1299. elem = elem || 'body';
  1300. return window.getComputedStyle( document[ elem ] )[ style ] !== undefined;
  1301. }
  1302. function isPropertySupported( property, elem ){
  1303. elem = elem || 'body';
  1304. return property in document[ elem ].style;
  1305. }
  1306. function cssPropertyValueSupported( prop, value, elem ) {
  1307. //cssPropertyValueSupported('width', '1px');
  1308. elem = elem || 'div';
  1309. var d = document.createElement( elem );
  1310. d.style[ prop ] = value;
  1311. return d.style[ prop ] === value;
  1312. }
  1313.  
  1314. var cssSupports = (function(){
  1315. // http://code.tutsplus.com/tutorials/quick-tip-detect-css3-support-in-browsers-with-javascript--net-16444
  1316. var div = document.createElement('div'),
  1317. vendors = 'Khtml Ms O Moz Webkit'.split(' '),
  1318. len = vendors.length;
  1319.  
  1320. return function(prop) {
  1321. if ( prop in div.style ) return true;
  1322.  
  1323. prop = prop.replace(/^[a-z]/, function(val) {
  1324. return val.toUpperCase();
  1325. });
  1326.  
  1327. while(len--) {
  1328. if ( vendors[len] + prop in div.style ) {
  1329. // browser supports box-shadow. Do what you need.
  1330. // Or use a bang (!) to test if the browser doesn't.
  1331. return true;
  1332. }
  1333. }
  1334. return false;
  1335. };
  1336. })();
  1337.  
  1338. function toggleClassState( config, Class, state, elem ){
  1339.  
  1340. config === undefined ? window.config = {} : config;
  1341. config = config || ( window.config = {} );
  1342.  
  1343. config[ Class ] = typeof state === 'string' ? !config[ Class ] : state;
  1344. $( elem || 'html' )[ config[ Class ] ? 'addClass' : 'removeClass' ]( Class );
  1345.  
  1346. }
  1347. function filterClick( e, $this ){
  1348. return e.which == 1 && e.target == $this;
  1349. }
  1350. function dispatchEventResize() {
  1351. //noinspection JSClosureCompilerSyntax,JSUnresolvedFunction
  1352. window.dispatchEvent(new Event('resize'));
  1353. }
  1354.  
  1355. /**
  1356. * @return {string}
  1357. */
  1358. function Undefined( check, replace ){
  1359. return check === undefined ? replace.toString() : check.toString();
  1360. }
  1361.  
  1362. function getGlobal(){
  1363. return (function(){
  1364. return this;
  1365. })();
  1366. }
  1367. function GM_lister( remove, item ){
  1368. var keys = GM_listValues();
  1369. for (var i = 0, key = null; key = keys[i]; i++) {
  1370. GM_listValues()[i] !== undefined && (
  1371. c.i('GM_ListItem: ' + GM_listValues()[i] + ':', GM_getValue(key)),
  1372. ( ( item !== undefined && GM_listValues()[i].inElem( item ) ) || item === undefined )
  1373. && ( remove === true || remove === 'yes' || remove === 1 ) && GM_deleteValue(key));
  1374. }
  1375. }
  1376.  
  1377. function roundFloat( num, dec ){
  1378. var d = 1;
  1379. for ( var i=0; i<dec; i++ ){
  1380. d += "0";
  1381. }
  1382. return Math.round(num * d) / d;
  1383. }
  1384. function randomFloatBetween( min, max, dec ){
  1385. dec = typeof( dec ) == 'undefined' ? 2 : dec;
  1386. return parseFloat( Math.min( min + ( Math.random() * ( max - min ) ), max ).toFixed( dec ) );
  1387. }
  1388. function random( max ) {
  1389. var min = 1,
  1390. rand = function(){
  1391. return Math.floor( Math.random() * ( max - min + 1 ) + min );
  1392. },
  1393. num1 = rand(),
  1394. num2 = rand();
  1395.  
  1396. return ( num1 > num2 ? num2/num1 : num1/num2 ) * max;
  1397. }
  1398. function roundNearPeace( number, peaces, dec ) {
  1399. return ( Math.round( number * peaces ) / peaces ).toFixed( dec );
  1400. }
  1401.  
  1402. var w = window,
  1403. glob = w,
  1404. $w = $( w ),
  1405. $l = $( location ),
  1406. locDoc = window.location.href,
  1407. d = document,
  1408. $d = $( d ),
  1409.  
  1410. c = {
  1411. defaultState: 3,
  1412. cute : function( type, msg, color ) {
  1413. color = color || "black";
  1414. var newColor, bgc = "White";
  1415. switch ( color ) {
  1416. case "success": newColor = "Green"; bgc = "LimeGreen"; break;
  1417. case "info": newColor = "DodgerBlue"; bgc = "Turquoise"; break;
  1418. case "error": newColor = "Red"; bgc = "Black"; break;
  1419. case "start": newColor = "OliveDrab"; bgc = "PaleGreen"; break;
  1420. case "warning": newColor = "Tomato"; bgc = "Black"; break;
  1421. case "end": newColor = "Orchid"; bgc = "MediumVioletRed"; break;
  1422. default: //noinspection SillyAssignmentJS
  1423. newColor = color;
  1424. }
  1425.  
  1426. typeof msg == "object" ?
  1427. window.console[ type ]( msg )
  1428. : typeof color == "object" ? (
  1429. window.console[ type ]("%c" + msg, "color: PowderBlue;font-weight:bold; background-color: RoyalBlue;"),
  1430. window.console[ type ]( newColor )
  1431. ) :
  1432. window.console[ type ]("%c" + msg, "color:" + newColor + "; background-color: " + bgc + ";")
  1433. },
  1434. show: function( showThis, type ){
  1435. var State = GM_getValue( type + 'StateValue' ) || this.defaultState;
  1436. return showThis !== 0 && State !== 0 && State === ( showThis || State ) || State === 'all';
  1437. },
  1438. pre: function( type, name, fn, line, color ){
  1439. line = line == undefined ? '' : line + ': ';
  1440. /**
  1441. * @return {string}
  1442. */
  1443. var Fn = function(){ return fn !== undefined ? fn : ''; };
  1444. typeof fn == "object"
  1445. ? window.console[ type ]( name, Fn() )
  1446. : c.cute( type, line + name + ': ' + Fn(), color );
  1447. },
  1448. type: function( type, name, fn, line, color, showThis ){
  1449. this.show( showThis, type ) && this.pre( type, name, fn, line, color );
  1450. },
  1451. l: function( name, fn, line, color, showThis ){
  1452. this.type( 'log', name, fn, line, color, showThis );
  1453. },
  1454. h: function( name, fn, line, color, showThis ){
  1455. this.type( 'handled', name, fn, line, color, showThis );
  1456. },
  1457. //c.l('name', 'fn'=='fn', 'line', 'blue')
  1458. i: function( name, fn, line, color, showThis ){
  1459. this.type( 'info', name, fn, line, color, showThis );
  1460. },
  1461. d: function( name, fn, line, color, showThis ){
  1462. this.type( 'debug', name, fn, line, color, showThis );
  1463. }
  1464. },
  1465. localStorageObj = {
  1466. name : 'setName', //important
  1467. localArray : function(){
  1468. return window.localStorage.getItem( this.name )
  1469. },
  1470. getArray : function(){
  1471. return this.localArray() === null ? [] : JSON.parse( this.localArray() )
  1472. },
  1473. stringify : function( array ){
  1474. c.i('[stringify]', JSON.stringify(array) );
  1475. window.localStorage.setItem( this.name, JSON.stringify(array) );
  1476. },
  1477. check : function( key, value ){
  1478. var array = this.getArray();
  1479. return array.grepArrayObj('find', key, value );
  1480. },
  1481. viewConsole : function( json ){
  1482. var array = this.getArray();
  1483. // $.toJSON() --- https://github.com/Krinkle/jquery-json/blob/master/src/jquery.json.js
  1484. // array.join('\n');
  1485. c.d( this.name, array ); //debug mode important to make this work
  1486. c.i( this.name, json ? isFunction( $.toJSON() ) ? $.toJSON( array ) : JSON.stringify( array ) : array.toSource() );
  1487. },
  1488. addTo : function() {
  1489.  
  1490. },
  1491. add : function( key, value, obj ){
  1492. var array = this.getArray(),
  1493. inA = array.toString();
  1494. c.i('[check array 1]', inA );
  1495. this.check( array, key, value )
  1496. || (
  1497. array.push( obj ),
  1498. c.i('[Added Object into array]', obj ),
  1499. c.i('[check array 2]', array )
  1500. );
  1501. this.stringify( array )
  1502. },
  1503. remove : function( key, value, obj ){
  1504. var array = this.getArray();
  1505. this.check( array, key, value )
  1506. && (
  1507. array = array.grepArrayObj('remove', key, value ),
  1508. c.i('[Removed Object from array]', obj )
  1509. );
  1510. this.stringify( array );
  1511. }
  1512. },
  1513. booleanTimer = {
  1514. timers : [],
  1515. start : function( name, ms ){
  1516. var that = this, value = name,
  1517. stop = setTimeout(function(){
  1518. that.stop( value );
  1519. }, ms );
  1520. this.timers.push( { 'name': value, stop:stop } );
  1521. //setTimeout(function(){that.stop( value );}, ms );
  1522. },
  1523. check : function( value ){
  1524. return this.timers.grepArrayObj( 'find', 'name', value ) !== undefined;
  1525. },
  1526. stop : function( value ){
  1527. this.timers = this.timers.grepArrayObj( 'remove', 'name', value );
  1528. }
  1529. },
  1530. advTimer = {
  1531. timers : [],
  1532. start : function( name, ms ){
  1533. var that = this, value = name,
  1534. stop = setTimeout(function(){
  1535. that.stop( value );
  1536. }, ms );
  1537. //noinspection JSUnresolvedVariable
  1538. this.timers.push({ 'name':value, start:window.performance.now(), timeout:ms, stop:stop });
  1539. },
  1540. check : function( value ){
  1541. var findObj = this.timers.grepArrayObj( 'find', 'name', value );
  1542. //noinspection JSUnresolvedVariable
  1543. return findObj !== undefined
  1544. ? findObj.timeout - ( window.performance.now() - findObj.start )
  1545. : false;
  1546. },
  1547. stop : function( value ){
  1548. this.timers = this.timers.grepArrayObj( 'remove', 'name', value );
  1549. }
  1550. },
  1551. lap = {
  1552. data : {},
  1553. tid : function(){
  1554. //noinspection JSUnresolvedVariable
  1555. return performance.now();
  1556. },
  1557. set : function(name){
  1558. this.data[name] = this.tid();
  1559. },
  1560. get : function(name){
  1561. return this.tid() - this.data[name];
  1562. },
  1563. end : function(name){
  1564. this.print(name);
  1565. this.del(name);
  1566. },
  1567. del : function(name){
  1568. delete this.data[name];
  1569. },
  1570. print: function(name){
  1571. var get = this.get( name );
  1572. c.i( 'Lap: ' + name, isNaN( get ) ? 'There is no such a name ' : get + 'ms' );
  1573. }
  1574. },
  1575. timer = {
  1576. ms : 0,
  1577. set : function(ms){
  1578. var that = this;
  1579. this.ms = ms;
  1580. setTimeout(function(){
  1581. that.ms = 0;
  1582. }, ms );
  1583. }
  1584. },
  1585. counter = {
  1586. data : {},
  1587. set : function(name, start, base){
  1588. this.data[name] = start || 0;
  1589. this.data[name+'Default'] = base || 1;
  1590. },
  1591. get : function(name){
  1592. return this.data[name]
  1593. },
  1594. is : function(name, count){
  1595. return this.data[name] === count
  1596. },
  1597. lessThen: function(name, count, equal ){
  1598. return ( equal || false ) ? this.data[name] <= count : this.data[name] < count
  1599. },
  1600. moreThen: function(name, count, equal){
  1601. return ( equal || false ) ? this.data[name] >= count : this.data[name] > count
  1602. },
  1603. del : function(name){
  1604. delete this.data[name]
  1605. },
  1606. exists : function(name) {
  1607. return this.data[name] !== undefined;
  1608. },
  1609. plus : function(name, num){
  1610. this.exists(name) || this.set(name);
  1611. this.data[name] = this.data[name] + ( num === undefined ? this.data[name+'Default'] : num )
  1612. },
  1613. minus : function(name, num){
  1614. this.exists(name) || this.set(name);
  1615. this.data[name] = this.data[name] - ( num === undefined ? this.data[name+'Default'] : num )
  1616. },
  1617. increase: function (name, num) {
  1618. this.plus(name, num)
  1619. },
  1620. decrease: function (name, num) {
  1621. this.minus(name, num)
  1622. },
  1623. '+' : function (name, num) {
  1624. this.plus(name, num)
  1625. },
  1626. '-' : function (name, num) {
  1627. this.minus(name, num)
  1628. },
  1629. up : function (name, num) {
  1630. this.plus(name, num)
  1631. },
  1632. down : function (name, num) {
  1633. this.minus(name, num)
  1634. },
  1635. add : function (name, num) {
  1636. this.plus(name, num)
  1637. },
  1638. subtract: function (name, num) {
  1639. this.minus(name, num)
  1640. },
  1641. withdraw: function (name, num) {
  1642. this.minus(name, num)
  1643. }
  1644. },
  1645. g = {
  1646. locDoc : window.location.href,
  1647. ms : 0,
  1648. timer : function(ms){
  1649. g.ms = ms;
  1650. setTimeout(function(){ g.ms = 0; }, ms );
  1651. },
  1652.  
  1653. GM : {
  1654. engine : function( mode, val, range ){
  1655. switch (mode){
  1656. case 'set': GM_setValue( val.name, val.default );
  1657. break;
  1658. case 'get': range ? config[ val.name ] = GM_getValue( val.name ):
  1659. ui.config[ val.name ] = GM_getValue( val.name );
  1660. break;
  1661. case 'del': GM_deleteValue( val.name );
  1662. }
  1663. },
  1664. manager : function( mode, array, range ){
  1665. $.each( array, function( i, val ){ this.engine( mode, val, range === undefined ); });
  1666. mode === 'del' && ( GM_deleteValue( 'firstRun' ), GM_deleteValue( 'yourVer' ) );
  1667. }
  1668. }
  1669. },
  1670.  
  1671. testPerformance = function( name, fn, testCycles ) {
  1672. lap.set( name );
  1673. var i = 0;
  1674. for ( i ; i < testCycles; i++ ){
  1675. fn();
  1676. }
  1677. lap.end( name );
  1678. },
  1679. perf = function (testName, fn) {
  1680. var startTime = new Date().getTime();
  1681. fn();
  1682. var endTime = new Date().getTime();
  1683. console.log( testName + ": " + ( endTime - startTime ) + "ms" );
  1684. };
  1685.  
  1686. $(document).on('click','*',function(e){
  1687. this == e.target && c.i('target:', $(this)[0]
  1688. ); });
  1689.  
  1690. c.i('my Function Library ö');
  1691. /*
  1692. isScrolledIntoView = (elem) ->
  1693. docViewTop = $(window).scrollTop()
  1694. docViewBottom = docViewTop + $(window).height()
  1695. elemTop = $(elem).offset().top
  1696. elemBottom = elemTop + $(elem).height()
  1697.  
  1698. (elemBottom - 200 < docViewBottom) and (elemBottom + $(elem).height() > docViewBottom )
  1699. */
  1700.  
  1701.