PageSourceSearch

http://www.ilectureonline.com/ilectureonline/static/js/web2py.js

js ilectureonline.com collected 2026-09-27 21:14:07 UTC 28,342 bytes, 733 lines download raw bytes

1(function($, undefined) {
2  /*
3   * Unobtrusive scripting adapter for jQuery, largely taken from
4   * the wonderful https://github.com/rails/jquery-ujs
5   *
6   *
7   * Released under the MIT license
8   *
9   */
10  if($.web2py !== undefined) {
11    $.error('web2py.js has already been loaded!');
12  }
13
14
15  String.prototype.reverse = function() {
16    return this.split('').reverse().join('');
17  };
18  var web2py;
19
20  $.web2py = web2py = {
21
22      popup: function(url) {
23        /* popup a window */
24        newwindow = window.open(url, 'name', 'height=400,width=600');
25        if(window.focus) newwindow.focus();
26        return false;
27      },
28      collapse: function(id) {
29        /* toggle an element */
30        $('#' + id).slideToggle();
31      },
32      fade: function(id, value) {
33        /*fade something*/
34        if(value > 0) $('#' + id).hide().fadeIn('slow');
35        else $('#' + id).show().fadeOut('slow');
36      },
37      ajax: function(u, s, t) {
38        /*simple ajax function*/
39        query = '';
40        if(typeof s == "string") {
41          d = $(s).serialize();
42          if(d) {
43            query = d;
44          }
45        } else {
46          pcs = [];
47          if(s != null && s != undefined)
48            for(i = 0; i < s.length; i++) {
49              q = $("[name=" + s[i] + "]").serialize();
50              if(q) {
51                pcs.push(q);
52              }
53            }
54          if(pcs.length > 0) {
55            query = pcs.join("&");
56          }
57        }
58        $.ajax({
59          type: "POST",
60          url: u,
61          data: query,
62          success: function(msg) {
63            if(t) {
64              if(t == ':eval') eval(msg);
65              else if(typeof t == 'string') $("#" + t).html(msg);
66              else t(msg);
67            }
68          }
69        });
70      },
71      ajax_fields: function(target) {
72        /*
73         *this attaches something to a newly loaded fragment/page
74         * Ideally all events should be bound to the document, so we can avoid calling
75         * this over and over... all will be bound to the document
76         */
77        /*adds btn class to buttons*/
78        $('button', target).addClass('btn');
79        $('form input[type="submit"], form input[type="button"]', target).addClass('btn');
80        /* javascript for PasswordWidget*/
81        $('input[type=password][data-w2p_entropy]', target).each(function() {
82          web2py.validate_entropy($(this));
83        });
84        /* javascript for ListWidget*/
85        $('ul.w2p_list', target).each(function() {
86          function pe(ul, e) {
87            var new_line = ml(ul);
88            rel(ul);
89            if($(e.target).parent().is(':visible')) {
90              /* make sure we didn't delete the element before we insert after */
91              new_line.insertAfter($(e.target).parent());
92            } else {
93              /* the line we clicked on was deleted, just add to end of list */
94              new_line.appendTo(ul);
95            }
96            new_line.find(":text").focus();
97            return false;
98          }
99
100          function rl(ul, e) {
101            if($(ul).children().length > 1) {
102              /* only remove if we have more than 1 item so the list is never empty */
103              $(e.target).parent().remove();
104            }
105          }
106
107          function ml(ul) {
108            /* clone the first field */
109            var line = $(ul).find("li:first").clone(true);
110            line.find(':text').val('');
111            return line;
112          }
113
114          function rel(ul) {
115            /* keep only as many as needed*/
116            $(ul).find("li").each(function() {
117              var trimmed = $.trim($(this.firstChild).val());
118              if(trimmed == '') $(this).remove();
119              else $(this.firstChild).val(trimmed);
120            });
121          }
122          var ul = this;
123          $(ul).find(":text").after('<a href="#">+</a>&nbsp;<a href="#">-</a>').keypress(function(e) {
124            return(e.which == 13) ? pe(ul, e) : true;
125          }).next().click(function(e) {
126            pe(ul, e);
127            e.preventDefault();
128          }).next().click(function(e) {
129            rl(ul, e);
130            e.preventDefault();
131          });
132        });
133      },
134      ajax_init: function(target) {
135        /*called whenever a fragment gets loaded */
136        $('.hidden', target).hide();
137        web2py.manage_errors(target);
138        web2py.ajax_fields(target);
139        web2py.show_if_handler(target);
140        web2py.component_handler(target);
141      },
142      /* manage errors in forms */
143      manage_errors: function(target) {
144        $('div.error', target).hide().slideDown('slow');
145      },
146      after_ajax: function(xhr) {
147        /* called whenever an ajax request completes */
148        var command = xhr.getResponseHeader('web2py-component-command');
149        var flash = xhr.getResponseHeader('web2py-component-flash');
150        if(command !== null) {
151          eval(decodeURIComponent(command));
152        }
153        if(flash) {
154          web2py.flash(decodeURIComponent(flash))
155        }
156      },
157      event_handlers: function() {
158        /*
159         * This is called once for page
160         * Ideally it should bound all the things that are needed
161         * and require no dom manipulations
162         */
163        var doc = $(document);
164        doc.on('click', '.flash', function(e) {
165          var t = $(this);
166          if(t.css('top') == '0px') t.slideUp('slow');
167          else t.fadeOut();
168        });
169        doc.on('keyup', 'input.integer', function() {
170          var nvalue = this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g, '').reverse();
171          if(this.value != nvalue) this.value = nvalue;
172        });
173        doc.on('keyup', 'input.double, input.decimal', function() {
174          var nvalue = this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g, '').reverse();
175          if(this.value != nvalue) this.value = nvalue;
176        });
177        var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
178        doc.on('click', "input[type='checkbox'].delete", function() {
179          if(this.checked)
180            if(!web2py.confirm(confirm_message)) this.checked = false;
181        });
182        var datetime_format = (typeof w2p_ajax_datetime_format != 'undefined') ? w2p_ajax_datetime_format : "%Y-%m-%d %H:%M:%S";
183        doc.on('click', "input.datetime", function() {
184          var tformat = $(this).data('w2p_datetime_format');
185          var active = $(this).data('w2p_datetime');
186          var format = (typeof tformat != 'undefined') ? tformat : datetime_format;
187          if(active === undefined) {
188            Calendar.setup({
189              inputField: this,
190              ifFormat: format,
191              showsTime: true,
192              timeFormat: "24"
193            });
194            $(this).attr('autocomplete', 'off');
195            $(this).data('w2p_datetime', 1);
196            $(this).trigger('click');
197          }
198        });
199        var date_format = (typeof w2p_ajax_date_format != 'undefined') ? w2p_ajax_date_format : "%Y-%m-%d";
200        doc.on('click', "input.date", function() {
201          var tformat = $(this).data('w2p_date_format');
202          var active = $(this).data('w2p_date');
203          var format = (typeof tformat != 'undefined') ? tformat : date_format;
204          if(active === undefined) {
205            Calendar.setup({
206              inputField: this,
207              ifFormat: format,
208              showsTime: false
209            });
210            $(this).data('w2p_date', 1);
211            $(this).attr('autocomplete', 'off');
212            $(this).trigger('click');
213          }
214        });
215        doc.on('focus', "input.time", function() {
216          var active = $(this).data('w2p_time');
217          if(active === undefined) {
218            $(this).timeEntry({
219              spinnerImage: ''
220            }).attr('autocomplete', 'off');
221            $(this).data('w2p_time', 1);
222          }
223        });
224        /* help preventing double form submission for normal form (not LOADed) */
225        $(doc).on('submit', 'form', function() {
226          var submit_button = $(this).find(web2py.formInputClickSelector);
227          web2py.disableElement(submit_button);
228        });
229        doc.ajaxSuccess(function(e, xhr) {
230          var redirect = xhr.getResponseHeader('web2py-redirect-location');
231          if(redirect !== null) {
232            window.location = redirect;
233          };
234          /* run this here only if this Ajax request is NOT for a web2py component. */
235          if(xhr.getResponseHeader('web2py-component-content') == null) {
236            web2py.after_ajax(xhr);
237          };
238        });
239
240        doc.ajaxError(function(e, xhr, settings, exception) {
241          /*personally I don't like it.
242           *if there's an error it it flashed and can be removed
243           *as any other message
244           *doc.off('click', '.flash')
245           */
246          switch(xhr.status) {
247            case 500:
248              web2py.flash(ajax_error_500);
249          }
250        });
251
252      },
253      trap_form: function(action, target) {
254        /* traps any LOADed form */
255        $('#' + target + ' form').each(function(i) {
256          var form = $(this);
257          if(form.hasClass('no_trap')) {
258            return;
259          }
260          form.attr('data-w2p_target', target);
261          var url = form.attr('action');
262          if((url === "") || (url === "#") || (typeof url === 'undefined')) {
263            /* form has no action. Use component url. */
264            url = action;
265          }
266          form.submit(function(e) {
267            web2py.disableElement(form.find(web2py.formInputClickSelector));
268            web2py.hide_flash();
269            web2py.ajax_page('post', url, form.serialize(), target, form);
270            e.preventDefault();
271          });
272          form.on('click', web2py.formInputClickSelector, function(e) {
273            e.preventDefault();
274            var input_name = $(this).attr('name');
275            if(input_name != undefined) {
276              $('<input type="hidden" />').attr('name', input_name)
277                .attr('value', $(this).val()).appendTo(form)
278            }
279            form.trigger('submit');
280          });
281        });
282      },
283      ajax_page: function(method, action, data, target, element) {
284        /* element is a new parameter, but should be put be put in front */
285        if(element == undefined) element = $(document);
286        /* if target is not there, fill it with something that there isn't in the page*/
287        if(target == undefined || target == '') target = 'w2p_none';
288        if(web2py.fire(element, 'ajax:before', null, target)) { /*test a usecase, should stop here if returns false */
289          $.ajax({
290            'type': method,
291            'url': action,
292            'data': data,
293            'beforeSend': function(xhr, settings) {
294              xhr.setRequestHeader('web2py-component-location', document.location);
295              xhr.setRequestHeader('web2py-component-element', target);
296              return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false
297            },
298            'success': function(data, status, xhr) {
299              /*bummer for form submissions....the element is not there after complete
300               *because it gets replaced by the new response....
301               */
302              web2py.fire(element, 'ajax:success', [data, status, xhr], target);
303            },
304            'error': function(xhr, status, error) {
305              /*bummer for form submissions....in addition to the element being not there after
306               *complete because it gets replaced by the new response, standard form
307               *handling just returns the same status code for good and bad
308               *form submissions (i.e. that triggered a validator error)
309               */
310              web2py.fire(element, 'ajax:error', [xhr, status, error], target);
311            },
312            'complete': function(xhr, status) {
313              web2py.fire(element, 'ajax:complete', [xhr, status], target);
314              web2py.updatePage(xhr, target); /* Parse and load the html received */
315              web2py.trap_form(action, target);
316              web2py.ajax_init('#' + target);
317              web2py.after_ajax(xhr);
318            }
319          });
320        }
321      },
322      component: function(action, target, timeout, times, el) {
323        /* element is a new parameter, but should be put in front */
324        $(function() {
325          var jelement = $("#" + target);
326          var element = jelement.get(0);
327          var statement = "jQuery('#" + target + "').get(0).reload();";
328          element.reload = function() {
329            /* Continue if times is Infinity or
330             * the times limit is not reached
331             */
332            if(element.reload_check()) {
333              web2py.ajax_page('get', action, null, target, el);
334            }
335          };
336          /* Method to check timing limit */
337          element.reload_check = function() {
338            if(jelement.hasClass('w2p_component_stop')) {
339              clearInterval(this.timing);
340              return false;
341            }
342            if(this.reload_counter == Infinity) {
343              return true;
344            } else {
345              if(!isNaN(this.reload_counter)) {
346                this.reload_counter -= 1;
347                if(this.reload_counter < 0) {
348                  if(!this.run_once) {
349                    clearInterval(this.timing);
350                    return false;
351                  }
352                } else {
353                  return true;
354                }
355              }
356            }
357            return false;
358          };
359          if(!isNaN(timeout)) {
360            element.timeout = timeout;
361            element.reload_counter = times;
362            if(times > 1) {
363              /* Multiple or infinite reload
364               * Run first iteration
365               */
366              web2py.ajax_page('get', action, null, target, el);
367              element.run_once = false;
368              element.timing = setInterval(statement, timeout);
369              element.reload_counter -= 1;
370            } else if(times == 1) {
371              /* Run once with timeout */
372              element.run_once = true;
373              element.setTimeout = setTimeout;
374              element.timing = setTimeout(statement, timeout);
375            }
376          } else {
377            /* run once (no timeout specified) */
378            element.reload_counter = Infinity;
379            web2py.ajax_page('get', action, null, target, el);
380          }
381        });
382      },
383      updatePage: function(xhr, target) {
384        var t = $('#' + target);
385        var html = $.parseHTML(xhr.responseText, document, true);
386        var title_elements = $(html).filter('title').add($(html).find('title'));
387        var title = title_elements.last().text();
388        if(title) {
389          title_elements.remove(); /* Remove any title elements from the response */
390          document.title = $.trim(title); /* Set the new document title */
391        }
392        var content = xhr.getResponseHeader('web2py-component-content');
393        if(content == 'prepend') t.prepend(xhr.responseText);
394        else if(content == 'append') t.append(xhr.responseText);
395        else if(content != 'hide') t.html(html);
396      },
397      calc_entropy: function(mystring) {
398        /* calculate a simple entropy for a given string */
399        var csets = new Array(
400          'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
401          '0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/',
402          '0123456789abcdefghijklmnopqrstuvwxyz');
403        var score = 0,
404          other = {},
405          seen = {},
406          lastset = null,
407          mystringlist = mystring.split('');
408        for(var i = 0; i < mystringlist.length; i++) { /* classify this character */
409          var c = mystringlist[i],
410            inset = 5;
411          for(var j = 0; j < csets.length; j++)
412            if(csets[j].indexOf(c) != -1) {
413              inset = j;
414              break;
415            }
416            /*calculate effect of character on alphabet size */
417          if(!(inset in seen)) {
418            seen[inset] = 1;
419            score += csets[inset].length;
420          } else if(!(c in other)) {
421            score += 1;
422            other[c] = 1;
423          }
424          if(inset != lastset) {
425            score += 1;
426            lastset = inset;
427          }
428        }
429        var entropy = mystring.length * Math.log(score) / 0.6931471805599453;
430        return Math.round(entropy * 100) / 100
431      },
432      validate_entropy: function(myfield, req_entropy) {
433        if(myfield.data('w2p_entropy') != undefined) req_entropy = myfield.data('w2p_entropy');
434        var validator = function() {
435          var v = (web2py.calc_entropy(myfield.val()) || 0) / req_entropy;
436          var r = 0,
437            g = 0,
438            b = 0,
439            rs = function(x) {
440              return Math.round(x * 15).toString(16)
441            };
442          if(v <= 0.5) {
443            r = 1.0;
444            g = 2.0 * v;
445          } else {
446            r = (1.0 - 2.0 * (Math.max(v, 0) - 0.5));
447            g = 1.0;
448          }
449          var color = '#' + rs(r) + rs(g) + rs(b);
450          myfield.css('background-color', color);
451          entropy_callback = myfield.data('entropy_callback');
452          if(entropy_callback) entropy_callback(v);
453        }
454        if(!myfield.hasClass('entropy_check')) myfield.on('keyup', validator).on('keydown', validator).addClass('entropy_check');
455      },
456      web2py_websocket: function(url, onmessage, onopen, onclose) {
457        if("WebSocket" in window) {
458          var ws = new WebSocket(url);
459          ws.onopen = onopen ? onopen : (function() {});
460          ws.onmessage = onmessage;
461          ws.onclose = onclose ? onclose : (function() {});
462          return true; /* supported */
463        } else return false; /* not supported */
464      },
465      /* new from here */
466      /* Form input elements bound by web2py.js */
467      formInputClickSelector: 'input[type=submit], input[type=image], button[type=submit], button:not([type])',
468      /* Form input elements disabled during form submission */
469      disableSelector: 'input, button, textarea, select',
470      /* Form input elements re-enabled after form submission */
471      enableSelector: 'input:disabled, button:disabled, textarea:disabled, select:disabled',
472      /* Triggers an event on an element and returns false if the event result is false */
473      fire: function(obj, type, data, target) {
474        var event = $.Event(type, {
475          'containerTarget': $('#' + target)[0]
476        });
477        obj.trigger(event, data);
478        return event.result !== false;
479      },
480      /* Helper function, needed to provide consistent behavior in IE */
481      stopEverything: function(e) {
482        $(e.target).trigger('w2p:everythingStopped');
483        e.stopImmediatePropagation();
484        return false;
485      },
486      confirm: function(message) {
487        return confirm(message);
488      },
489      /* replace element's html with the 'data-disable-with' after storing original html
490       * and prevent clicking on it */
491      disableElement: function(el) {
492        el.addClass('disabled');
493        var method = el.is('button') ? 'html' : 'val';
494        //method = el.attr('name') ? 'html' : 'val';
495        var disable_with_message = (typeof w2p_ajax_disable_with_message != 'undefined') ? w2p_ajax_disable_with_message : "Working...";
496        /*store enabled state if not already disabled */
497        if(el.data('w2p:enable-with') === undefined) {
498          el.data('w2p:enable-with', el[method]());
499        }
500        /*if you don't want to see "working..." on buttons, replace the following
501         * two lines with this one
502         * el.data('w2p_disable_with', el[method]());
503         */
504        if((el.data('w2p_disable_with') == 'default') || (el.data('w2p_disable_with') === undefined)) {
505          el.data('w2p_disable_with', disable_with_message);
506        }
507
508        /* set to disabled state*/
509        el[method](el.data('w2p_disable_with'));
510
511        el.bind('click.w2pDisable', function(e) { /* prevent further clicking*/
512          return web2py.stopEverything(e);
513        });
514      },
515
516      /* restore element to its original state which was disabled by 'disableElement' above*/
517      enableElement: function(el) {
518        var method = el.is('button') ? 'val' : 'html';
519        if(el.data('w2p:enable-with') !== undefined) {
520          /* set to old enabled state */
521          el[method](el.data('w2p:enable-with'));
522          el.removeData('w2p:enable-with');
523        }
524        el.removeClass('disabled');
525        el.unbind('click.w2pDisable');
526      },
527      /*convenience wrapper, internal use only */
528      simple_component: function(action, target, element) {
529        web2py.component(action, target, 0, 1, element);
530      },
531      /*helper for flash messages*/
532      flash: function(message, status) {
533        var flash = $('.flash');
534        web2py.hide_flash();
535        flash.html(message).addClass(status);
536        if(flash.html()) flash.append('<span id="closeflash"> &times; </span>').slideDown();
537      },
538      hide_flash: function() {
539        $('.flash').fadeOut(0).html('');
540      },
541      show_if_handler: function(target) {
542        var triggers = {};
543        var show_if = function() {
544          var t = $(this);
545          var id = t.attr('id');
546          t.attr('value', t.val());
547          for(var k = 0; k < triggers[id].length; k++) {
548            var dep = $('#' + triggers[id][k], target);
549            var tr = $('#' + triggers[id][k] + '__row', target);
550            if(t.is(dep.attr('data-show-if'))) tr.slideDown();
551            else tr.hide();
552          }
553        };
554        $('[data-show-trigger]', target).each(function() {
555          var name = $(this).attr('data-show-trigger');
556          // The field exists only when creating/editing a row
557          if($('#' + name).length) {
558            if(!triggers[name]) triggers[name] = [];
559            triggers[name].push($(this).attr('id'));
560          }
561        });
562        for(var name in triggers) {
563          $('#' + name, target).change(show_if).keyup(show_if);
564          show_if.call($('#' + name, target));
565        };
566      },
567      component_handler: function(target) {
568        $('div[data-w2p_remote]', target).each(function() {
569          var remote, times, timeout, target;
570          var el = $(this);
571          remote = el.data('w2p_remote');
572          times = el.data('w2p_times');
573          timeout = el.data('w2p_timeout');
574          target = el.attr('id');
575          web2py.component(remote, target, timeout, times, $(this));
576        })
577      },
578      a_handler: function(el, e) {
579        e.preventDefault();
580        var method = el.data('w2p_method');
581        var action = el.attr('href');
582        var target = el.data('w2p_target');
583        var confirm_message = el.data('w2p_confirm');
584
585        var pre_call = el.data('w2p_pre_call');
586        if(pre_call != undefined) {
587          eval(pre_call);
588        }
589        if(confirm_message != undefined) {
590          if(confirm_message == 'default') confirm_message = w2p_ajax_confirm_message || 'Are you sure you want to delete this object?';
591          if(!web2py.confirm(confirm_message)) {
592            web2py.stopEverything(e);
593            return;
594          }
595        }
596        if(target == undefined) {
597          if(method == 'GET') {
598            web2py.ajax_page('get', action, [], '', el);
599          } else if(method == 'POST') {
600            web2py.ajax_page('post', action, [], '', el);
601          }
602        } else {
603          if(method == 'GET') {
604            web2py.ajax_page('get', action, [], target, el);
605          } else if(method == 'POST') {
606            web2py.ajax_page('post', action, [], target, el);
607          }
608        }
609      },
610      a_handlers: function() {
611        var el = $(document);
612        el.on('click', 'a[data-w2p_method]', function(e) {
613          web2py.a_handler($(this), e);
614        });
615        /* removal of element should happen only on success */
616        el.on('ajax:success', 'a[data-w2p_method][data-w2p_remove]', function(e) {
617          var el = $(this);
618          var toremove = el.data('w2p_remove');
619          if(toremove != undefined) {
620            toremove = el.closest(toremove);
621            if(!toremove.length) {
622              /*this enables removal of whatever selector if a closest is not found */
623              toremove = $(toremove);
624            }
625            toremove.remove();
626          }
627        });
628        el.on('ajax:beforeSend', 'a[data-w2p_method][data-w2p_disable_with]', function(e) {
629          web2py.disableElement($(this));
630        });
631        /*re-enable click on completion*/
632        el.on('ajax:complete', 'a[data-w2p_method][data-w2p_disable_with]', function(e) {
633          web2py.enableElement($(this));
634        });
635      },
636      /* Disables form elements:
637  - Caches element value in 'w2p:enable-with' data store
638  - Replaces element text with value of 'data-disable-with' attribute
639  - Sets disabled property to true
640    */
641      disableFormElements: function(form) {
642        form.find(web2py.disableSelector).each(function() {
643          var element = $(this),
644            method = element.is('button') ? 'html' : 'val';
645          var disable_with = element.data('w2p_disable_with');
646          if(disable_with == undefined) {
647            element.data('w2p_disable_with', element[method]())
648          }
649          if(element.data('w2p:enable-with') === undefined) {
650            element.data('w2p:enable-with', element[method]());
651          }
652          element[method](element.data('w2p_disable_with'));
653          element.prop('disabled', true);
654        });
655      },
656
657      /* Re-enables disabled form elements:
658  -     Replaces element text with cached value from 'w2p:enable-with' data store (created in `disableFormElements`)
659  -     Sets disabled property to false
660    */
661      enableFormElements: function(form) {
662        form.find(web2py.enableSelector).each(function() {
663          var element = $(this),
664            method = element.is('button') ? 'html' : 'val';
665          if(element.data('w2p:enable-with')) {
666            element[method](element.data('w2p:enable-with'));
667            element.removeData('w2p:enable-with');
668          }
669          element.prop('disabled', false);
670        });
671      },
672      form_handlers: function() {
673        var el = $(document);
674        el.on('ajax:beforeSend', 'form[data-w2p_target]', function(e) {
675          web2py.disableFormElements($(this));
676        });
677        el.on('ajax:complete', 'form[data-w2p_target]', function(e) {
678          web2py.enableFormElements($(this));
679        });
680      },
681      /* Invalidate and force reload of a web2py component
682       */
683      invalidate: function(target) {
684        $('div[data-w2p_remote]', target).each(function() {
685          var el = $('#' + $(this).attr('id')).get(0);
686          if(el.timing !== undefined) { // Block triggering regular routines
687            clearInterval(el.timing);
688          }
689        });
690        $.web2py.component_handler(target);
691      },
692      main_hook: function() {
693        var flash = $('.flash');
694        flash.hide();
695        if(flash.html()) web2py.flash(flash.html());
696        web2py.ajax_init(document);
697        web2py.event_handlers();
698        web2py.a_handlers();
699        web2py.form_handlers();
700      }
701    }
702    /*end of functions */
703    /*main hook*/
704  $(function() {
705    web2py.main_hook();
706  });
707
708})(jQuery);
709
710/* compatibility code - start */
711ajax = jQuery.web2py.ajax;
712web2py_component = jQuery.web2py.component;
713web2py_websocket = jQuery.web2py.web2py_websocket;
714web2py_ajax_page = jQuery.web2py.ajax_page;
715/*needed for IS_STRONG(entropy)*/
716web2py_validate_entropy = jQuery.web2py.validate_entropy;
717/*needed for crud.search and SQLFORM.grid's search*/
718web2py_ajax_fields = jQuery.web2py.ajax_fields;
719/*used for LOAD(ajax=False)*/
720web2py_trap_form = jQuery.web2py.trap_form;
721
722/*undocumented - rare*/
723popup = jQuery.web2py.popup;
724collapse = jQuery.web2py.collapse;
725fade = jQuery.web2py.fade;
726
727/* internals - shouldn't be needed
728web2py_ajax_init = jQuery.web2py.ajax_init;
729web2py_event_handlers = jQuery.web2py.event_handlers;
730web2py_trap_link = jQuery.web2py.trap_link;
731web2py_calc_entropy = jQuery.web2py.calc_entropy;
732*/
733/* compatibility code - end*/

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.