JAVASCRIPT   52

util js

Guest on 5th August 2022 06:56:22 AM

  1. (function($) {
  2.  
  3.         /**
  4.          * Generate an indented list of links from a nav. Meant for use with panel().
  5.          * @return {jQuery} jQuery object.
  6.          */
  7.         $.fn.navList = function() {
  8.  
  9.                 var     $this = $(this);
  10.                         $a = $this.find('a'),
  11.                         b = [];
  12.  
  13.                 $a.each(function() {
  14.  
  15.                         var     $this = $(this),
  16.                                 indent = Math.max(0, $this.parents('li').length - 1),
  17.                                 href = $this.attr('href'),
  18.                                 target = $this.attr('target');
  19.  
  20.                         b.push(
  21.                                 '<a ' +
  22.                                         'class="link depth-' + indent + '"' +
  23.                                         ( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
  24.                                         ( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
  25.                                 '>' +
  26.                                         '<span class="indent-' + indent + '"></span>' +
  27.                                         $this.text() +
  28.                                 '</a>'
  29.                         );
  30.  
  31.                 });
  32.  
  33.                 return b.join('');
  34.  
  35.         };
  36.  
  37.         /**
  38.          * Panel-ify an element.
  39.          * @param {object} userConfig User config.
  40.          * @return {jQuery} jQuery object.
  41.          */
  42.         $.fn.panel = function(userConfig) {
  43.  
  44.                 // No elements?
  45.                         if (this.length == 0)
  46.                                 return $this;
  47.  
  48.                 // Multiple elements?
  49.                         if (this.length > 1) {
  50.  
  51.                                 for (var i=0; i < this.length; i++)
  52.                                         $(this[i]).panel(userConfig);
  53.  
  54.                                 return $this;
  55.  
  56.                         }
  57.  
  58.                 // Vars.
  59.                         var     $this = $(this),
  60.                                 $body = $('body'),
  61.                                 $window = $(window),
  62.                                 id = $this.attr('id'),
  63.                                 config;
  64.  
  65.                 // Config.
  66.                         config = $.extend({
  67.  
  68.                                 // Delay.
  69.                                         delay: 0,
  70.  
  71.                                 // Hide panel on link click.
  72.                                         hideOnClick: false,
  73.  
  74.                                 // Hide panel on escape keypress.
  75.                                         hideOnEscape: false,
  76.  
  77.                                 // Hide panel on swipe.
  78.                                         hideOnSwipe: false,
  79.  
  80.                                 // Reset scroll position on hide.
  81.                                         resetScroll: false,
  82.  
  83.                                 // Reset forms on hide.
  84.                                         resetForms: false,
  85.  
  86.                                 // Side of viewport the panel will appear.
  87.                                         side: null,
  88.  
  89.                                 // Target element for "class".
  90.                                         target: $this,
  91.  
  92.                                 // Class to toggle.
  93.                                         visibleClass: 'visible'
  94.  
  95.                         }, userConfig);
  96.  
  97.                         // Expand "target" if it's not a jQuery object already.
  98.                                 if (typeof config.target != 'jQuery')
  99.                                         config.target = $(config.target);
  100.  
  101.                 // Panel.
  102.  
  103.                         // Methods.
  104.                                 $this._hide = function(event) {
  105.  
  106.                                         // Already hidden? Bail.
  107.                                                 if (!config.target.hasClass(config.visibleClass))
  108.                                                         return;
  109.  
  110.                                         // If an event was provided, cancel it.
  111.                                                 if (event) {
  112.  
  113.                                                         event.preventDefault();
  114.                                                         event.stopPropagation();
  115.  
  116.                                                 }
  117.  
  118.                                         // Hide.
  119.                                                 config.target.removeClass(config.visibleClass);
  120.  
  121.                                         // Post-hide stuff.
  122.                                                 window.setTimeout(function() {
  123.  
  124.                                                         // Reset scroll position.
  125.                                                                 if (config.resetScroll)
  126.                                                                         $this.scrollTop(0);
  127.  
  128.                                                         // Reset forms.
  129.                                                                 if (config.resetForms)
  130.                                                                         $this.find('form').each(function() {
  131.                                                                                 this.reset();
  132.                                                                         });
  133.  
  134.                                                 }, config.delay);
  135.  
  136.                                 };
  137.  
  138.                         // Vendor fixes.
  139.                                 $this
  140.                                         .css('-ms-overflow-style', '-ms-autohiding-scrollbar')
  141.                                         .css('-webkit-overflow-scrolling', 'touch');
  142.  
  143.                         // Hide on click.
  144.                                 if (config.hideOnClick) {
  145.  
  146.                                         $this.find('a')
  147.                                                 .css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');
  148.  
  149.                                         $this
  150.                                                 .on('click', 'a', function(event) {
  151.  
  152.                                                         var $a = $(this),
  153.                                                                 href = $a.attr('href'),
  154.                                                                 target = $a.attr('target');
  155.  
  156.                                                         if (!href || href == '#' || href == '' || href == '#' + id)
  157.                                                                 return;
  158.  
  159.                                                         // Cancel original event.
  160.                                                                 event.preventDefault();
  161.                                                                 event.stopPropagation();
  162.  
  163.                                                         // Hide panel.
  164.                                                                 $this._hide();
  165.  
  166.                                                         // Redirect to href.
  167.                                                                 window.setTimeout(function() {
  168.  
  169.                                                                         if (target == '_blank')
  170.                                                                                 window.open(href);
  171.                                                                         else
  172.                                                                                 window.location.href = href;
  173.  
  174.                                                                 }, config.delay + 10);
  175.  
  176.                                                 });
  177.  
  178.                                 }
  179.  
  180.                         // Event: Touch stuff.
  181.                                 $this.on('touchstart', function(event) {
  182.  
  183.                                         $this.touchPosX = event.originalEvent.touches[0].pageX;
  184.                                         $this.touchPosY = event.originalEvent.touches[0].pageY;
  185.  
  186.                                 })
  187.  
  188.                                 $this.on('touchmove', function(event) {
  189.  
  190.                                         if ($this.touchPosX === null
  191.                                         ||      $this.touchPosY === null)
  192.                                                 return;
  193.  
  194.                                         var     diffX = $this.touchPosX - event.originalEvent.touches[0].pageX,
  195.                                                 diffY = $this.touchPosY - event.originalEvent.touches[0].pageY,
  196.                                                 th = $this.outerHeight(),
  197.                                                 ts = ($this.get(0).scrollHeight - $this.scrollTop());
  198.  
  199.                                         // Hide on swipe?
  200.                                                 if (config.hideOnSwipe) {
  201.  
  202.                                                         var result = false,
  203.                                                                 boundary = 20,
  204.                                                                 delta = 50;
  205.  
  206.                                                         switch (config.side) {
  207.  
  208.                                                                 case 'left':
  209.                                                                         result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta);
  210.                                                                         break;
  211.  
  212.                                                                 case 'right':
  213.                                                                         result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta));
  214.                                                                         break;
  215.  
  216.                                                                 case 'top':
  217.                                                                         result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta);
  218.                                                                         break;
  219.  
  220.                                                                 case 'bottom':
  221.                                                                         result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta));
  222.                                                                         break;
  223.  
  224.                                                                 default:
  225.                                                                         break;
  226.  
  227.                                                         }
  228.  
  229.                                                         if (result) {
  230.  
  231.                                                                 $this.touchPosX = null;
  232.                                                                 $this.touchPosY = null;
  233.                                                                 $this._hide();
  234.  
  235.                                                                 return false;
  236.  
  237.                                                         }
  238.  
  239.                                                 }
  240.  
  241.                                         // Prevent vertical scrolling past the top or bottom.
  242.                                                 if (($this.scrollTop() < 0 && diffY < 0)
  243.                                                 || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) {
  244.  
  245.                                                         event.preventDefault();
  246.                                                         event.stopPropagation();
  247.  
  248.                                                 }
  249.  
  250.                                 });
  251.  
  252.                         // Event: Prevent certain events inside the panel from bubbling.
  253.                                 $this.on('click touchend touchstart touchmove', function(event) {
  254.                                         event.stopPropagation();
  255.                                 });
  256.  
  257.                         // Event: Hide panel if a child anchor tag pointing to its ID is clicked.
  258.                                 $this.on('click', 'a[href="#' + id + '"]', function(event) {
  259.  
  260.                                         event.preventDefault();
  261.                                         event.stopPropagation();
  262.  
  263.                                         config.target.removeClass(config.visibleClass);
  264.  
  265.                                 });
  266.  
  267.                 // Body.
  268.  
  269.                         // Event: Hide panel on body click/tap.
  270.                                 $body.on('click touchend', function(event) {
  271.                                         $this._hide(event);
  272.                                 });
  273.  
  274.                         // Event: Toggle.
  275.                                 $body.on('click', 'a[href="#' + id + '"]', function(event) {
  276.  
  277.                                         event.preventDefault();
  278.                                         event.stopPropagation();
  279.  
  280.                                         config.target.toggleClass(config.visibleClass);
  281.  
  282.                                 });
  283.  
  284.                 // Window.
  285.  
  286.                         // Event: Hide on ESC.
  287.                                 if (config.hideOnEscape)
  288.                                         $window.on('keydown', function(event) {
  289.  
  290.                                                 if (event.keyCode == 27)
  291.                                                         $this._hide(event);
  292.  
  293.                                         });
  294.  
  295.                 return $this;
  296.  
  297.         };
  298.  
  299.         /**
  300.          * Apply "placeholder" attribute polyfill to one or more forms.
  301.          * @return {jQuery} jQuery object.
  302.          */
  303.         $.fn.placeholder = function() {
  304.  
  305.                 // Browser natively supports placeholders? Bail.
  306.                         if (typeof (document.createElement('input')).placeholder != 'undefined')
  307.                                 return $(this);
  308.  
  309.                 // No elements?
  310.                         if (this.length == 0)
  311.                                 return $this;
  312.  
  313.                 // Multiple elements?
  314.                         if (this.length > 1) {
  315.  
  316.                                 for (var i=0; i < this.length; i++)
  317.                                         $(this[i]).placeholder();
  318.  
  319.                                 return $this;
  320.  
  321.                         }
  322.  
  323.                 // Vars.
  324.                         var $this = $(this);
  325.  
  326.                 // Text, TextArea.
  327.                         $this.find('input[type=text],textarea')
  328.                                 .each(function() {
  329.  
  330.                                         var i = $(this);
  331.  
  332.                                         if (i.val() == ''
  333.                                         ||  i.val() == i.attr('placeholder'))
  334.                                                 i
  335.                                                         .addClass('polyfill-placeholder')
  336.                                                         .val(i.attr('placeholder'));
  337.  
  338.                                 })
  339.                                 .on('blur', function() {
  340.  
  341.                                         var i = $(this);
  342.  
  343.                                         if (i.attr('name').match(/-polyfill-field$/))
  344.                                                 return;
  345.  
  346.                                         if (i.val() == '')
  347.                                                 i
  348.                                                         .addClass('polyfill-placeholder')
  349.                                                         .val(i.attr('placeholder'));
  350.  
  351.                                 })
  352.                                 .on('focus', function() {
  353.  
  354.                                         var i = $(this);
  355.  
  356.                                         if (i.attr('name').match(/-polyfill-field$/))
  357.                                                 return;
  358.  
  359.                                         if (i.val() == i.attr('placeholder'))
  360.                                                 i
  361.                                                         .removeClass('polyfill-placeholder')
  362.                                                         .val('');
  363.  
  364.                                 });
  365.  
  366.                 // Password.
  367.                         $this.find('input[type=password]')
  368.                                 .each(function() {
  369.  
  370.                                         var i = $(this);
  371.                                         var x = $(
  372.                                                                 $('<div>')
  373.                                                                         .append(i.clone())
  374.                                                                         .remove()
  375.                                                                         .html()
  376.                                                                         .replace(/type="password"/i, 'type="text"')
  377.                                                                         .replace(/type=password/i, 'type=text')
  378.                                         );
  379.  
  380.                                         if (i.attr('id') != '')
  381.                                                 x.attr('id', i.attr('id') + '-polyfill-field');
  382.  
  383.                                         if (i.attr('name') != '')
  384.                                                 x.attr('name', i.attr('name') + '-polyfill-field');
  385.  
  386.                                         x.addClass('polyfill-placeholder')
  387.                                                 .val(x.attr('placeholder')).insertAfter(i);
  388.  
  389.                                         if (i.val() == '')
  390.                                                 i.hide();
  391.                                         else
  392.                                                 x.hide();
  393.  
  394.                                         i
  395.                                                 .on('blur', function(event) {
  396.  
  397.                                                         event.preventDefault();
  398.  
  399.                                                         var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
  400.  
  401.                                                         if (i.val() == '') {
  402.  
  403.                                                                 i.hide();
  404.                                                                 x.show();
  405.  
  406.                                                         }
  407.  
  408.                                                 });
  409.  
  410.                                         x
  411.                                                 .on('focus', function(event) {
  412.  
  413.                                                         event.preventDefault();
  414.  
  415.                                                         var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']');
  416.  
  417.                                                         x.hide();
  418.  
  419.                                                         i
  420.                                                                 .show()
  421.                                                                 .focus();
  422.  
  423.                                                 })
  424.                                                 .on('keypress', function(event) {
  425.  
  426.                                                         event.preventDefault();
  427.                                                         x.val('');
  428.  
  429.                                                 });
  430.  
  431.                                 });
  432.  
  433.                 // Events.
  434.                         $this
  435.                                 .on('submit', function() {
  436.  
  437.                                         $this.find('input[type=text],input[type=password],textarea')
  438.                                                 .each(function(event) {
  439.  
  440.                                                         var i = $(this);
  441.  
  442.                                                         if (i.attr('name').match(/-polyfill-field$/))
  443.                                                                 i.attr('name', '');
  444.  
  445.                                                         if (i.val() == i.attr('placeholder')) {
  446.  
  447.                                                                 i.removeClass('polyfill-placeholder');
  448.                                                                 i.val('');
  449.  
  450.                                                         }
  451.  
  452.                                                 });
  453.  
  454.                                 })
  455.                                 .on('reset', function(event) {
  456.  
  457.                                         event.preventDefault();
  458.  
  459.                                         $this.find('select')
  460.                                                 .val($('option:first').val());
  461.  
  462.                                         $this.find('input,textarea')
  463.                                                 .each(function() {
  464.  
  465.                                                         var i = $(this),
  466.                                                                 x;
  467.  
  468.                                                         i.removeClass('polyfill-placeholder');
  469.  
  470.                                                         switch (this.type) {
  471.  
  472.                                                                 case 'submit':
  473.                                                                 case 'reset':
  474.                                                                         break;
  475.  
  476.                                                                 case 'password':
  477.                                                                         i.val(i.attr('defaultValue'));
  478.  
  479.                                                                         x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]');
  480.  
  481.                                                                         if (i.val() == '') {
  482.                                                                                 i.hide();
  483.                                                                                 x.show();
  484.                                                                         }
  485.                                                                         else {
  486.                                                                                 i.show();
  487.                                                                                 x.hide();
  488.                                                                         }
  489.  
  490.                                                                         break;
  491.  
  492.                                                                 case 'checkbox':
  493.                                                                 case 'radio':
  494.                                                                         i.attr('checked', i.attr('defaultValue'));
  495.                                                                         break;
  496.  
  497.                                                                 case 'text':
  498.                                                                 case 'textarea':
  499.                                                                         i.val(i.attr('defaultValue'));
  500.  
  501.                                                                         if (i.val() == '') {
  502.                                                                                 i.addClass('polyfill-placeholder');
  503.                                                                                 i.val(i.attr('placeholder'));
  504.                                                                         }
  505.  
  506.                                                                         break;
  507.  
  508.                                                                 default:
  509.                                                                         i.val(i.attr('defaultValue'));
  510.                                                                         break;
  511.  
  512.                                                         }
  513.                                                 });
  514.  
  515.                                 });
  516.  
  517.                 return $this;
  518.  
  519.         };
  520.  
  521.         /**
  522.          * Moves elements to/from the first positions of their respective parents.
  523.          * @param {jQuery} $elements Elements (or selector) to move.
  524.          * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations.
  525.          */
  526.         $.prioritize = function($elements, condition) {
  527.  
  528.                 var key = '__prioritize';
  529.  
  530.                 // Expand $elements if it's not already a jQuery object.
  531.                         if (typeof $elements != 'jQuery')
  532.                                 $elements = $($elements);
  533.  
  534.                 // Step through elements.
  535.                         $elements.each(function() {
  536.  
  537.                                 var     $e = $(this), $p,
  538.                                         $parent = $e.parent();
  539.  
  540.                                 // No parent? Bail.
  541.                                         if ($parent.length == 0)
  542.                                                 return;
  543.  
  544.                                 // Not moved? Move it.
  545.                                         if (!$e.data(key)) {
  546.  
  547.                                                 // Condition is false? Bail.
  548.                                                         if (!condition)
  549.                                                                 return;
  550.  
  551.                                                 // Get placeholder (which will serve as our point of reference for when this element needs to move back).
  552.                                                         $p = $e.prev();
  553.  
  554.                                                         // Couldn't find anything? Means this element's already at the top, so bail.
  555.                                                                 if ($p.length == 0)
  556.                                                                         return;
  557.  
  558.                                                 // Move element to top of parent.
  559.                                                         $e.prependTo($parent);
  560.  
  561.                                                 // Mark element as moved.
  562.                                                         $e.data(key, $p);
  563.  
  564.                                         }
  565.  
  566.                                 // Moved already?
  567.                                         else {
  568.  
  569.                                                 // Condition is true? Bail.
  570.                                                         if (condition)
  571.                                                                 return;
  572.  
  573.                                                 $p = $e.data(key);
  574.  
  575.                                                 // Move element back to its original location (using our placeholder).
  576.                                                         $e.insertAfter($p);
  577.  
  578.                                                 // Unmark element as moved.
  579.                                                         $e.removeData(key);
  580.  
  581.                                         }
  582.  
  583.                         });
  584.  
  585.         };
  586.  
  587. })(jQuery);

Raw Paste


Login or Register to edit or fork this paste. It's free.