PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.2
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.2
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / js / frame.js

frame.js in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.4.2, at js/frame.js

651 lines 25.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* global prompt */
2 /* global visualizer */
3 /* global alert */
4 /* global ajaxurl */
5 /* global CodeMirror */
6
7 (function ($) {
8 $(window).on('load', function(){
9 // scroll to the selected chart type.
10 if($('label.type-label.type-label-selected').length > 0) {
11 $('label.type-label.type-label-selected')[0].scrollIntoView();
12 }
13 });
14
15 $(document).ready(function () {
16 onReady();
17 });
18
19 function onReady() {
20 // open the correct source tab/sub-tab.
21 var source = $('#visualizer-chart-id').attr('data-chart-source');
22 $('li.viz-group.' + source).addClass('open');
23 $('li.viz-group.' + source + ' span.viz-section-title.' + source).addClass('open');
24 $('li.viz-group.' + source + ' span.viz-section-title.' + source + '.open').parent().find('div.viz-section-items').show();
25
26 init_permissions();
27
28 if(typeof visualizer !== 'undefined' && visualizer.is_pro) {
29 init_db_import();
30 init_filter_import();
31 }
32
33 init_json_import();
34
35 init_editor_table();
36
37 // update the manual configuation link to point to the correct chart type.
38 var type = $('#visualizer-chart-id').attr('data-chart-type');
39 var chart_type_in_api_link = type + 'chart';
40 switch (type) {
41 case "gauge":
42 case "table":
43 case "timeline":
44 chart_type_in_api_link = type;
45 break;
46 }
47
48 if($('span.viz-gvlink').length > 0) {
49 $('span.viz-gvlink').html($('span.viz-gvlink').html().replace('?', chart_type_in_api_link));
50 }
51
52 $('.type-radio').change(function () {
53 $('.type-label-selected').removeClass('type-label-selected');
54 $(this).parent().addClass('type-label-selected');
55 });
56
57 $('#vz-chart-settings h2').click(function () {
58 $("#vz-chart-source").hide();
59 $("#vz-chart-permissions").removeClass('open').addClass('bottom-fixed');
60 $(this).parent().removeClass('bottom-fixed').addClass('open');
61 $("#vz-chart-permissions .viz-group-header").hide();
62 return false;
63 });
64 $('#vz-chart-settings .customize-section-back').click(function () {
65 $("#vz-chart-source").show();
66 $(this).parent().parent().removeClass('open').addClass('bottom-fixed');
67
68 return false;
69 });
70
71 // collapse other open sections of this group
72 $(document).on('click', '.viz-group-title', function () {
73 var parent = $(this).parent();
74
75 if (parent.hasClass('open')) {
76 parent.removeClass('open');
77 } else {
78 parent.parent().find('.viz-group.open').removeClass('open');
79 parent.addClass('open');
80 }
81
82 // if the user wanted to perform an action
83 // and the chart is no longer showing because that particular screen is showing
84 // e.g. create parameters
85 // and then the user decided to click on another action
86 // let's invoke the show chart of the previous action so that the chart shows
87 // and the user does not get confused
88 $('input[type="button"][data-current!="chart"].show-chart-toggle').trigger('click');
89 });
90
91 // collapse other open subsections of this section
92 $(document).on('click', '.viz-section-title', function () {
93 var grandparent = $(this).parent().parent();
94 grandparent.find('.viz-section-title.open ~ .viz-section-items').hide();
95 grandparent.find('.viz-section-title.open').removeClass('open');
96 });
97
98 $('#view-remote-file').click(function () {
99 var url = $(this).parent().find('#vz-schedule-url').val();
100
101 if (url !== '') {
102 if (url.indexOf('localhost') !== -1 || /^([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(url)) {
103 if (url.substr(url.length - 8) === '/pubhtml') {
104 url = url.substring(0, url.length - 8) + '/export?format=csv';
105 }
106
107 $('#canvas').lock();
108 $(this).parent().submit();
109 } else {
110 alert(visualizer.l10n.invalid_source);
111 }
112 }
113 });
114
115 $('#vz-import-file').click(function (e) {
116 e.preventDefault();
117 if ($.trim($(this).parent().find("#csv-file").val()) !== '') {
118 $('#canvas').lock();
119 $(this).parent().submit();
120 }
121 });
122
123 $('#thehole').load(function () {
124 $('#canvas').unlock();
125 });
126
127 $(document).on('click', '.viz-section-title', function () {
128 $(this).toggleClass('open').parent().find('.viz-section-items').toggle();
129 });
130
131 $(document).on('click', '.more-info', function () {
132 $(this).parent().find('.viz-section-description:first').toggle();
133 return false;
134 });
135
136 $('#cancel-button').click(function () {
137 $('#cancel-form').submit();
138 });
139
140 init_type_vs_library();
141
142 $('.viz-abort').on('click', function(e){
143 e.preventDefault();
144 window.parent.postMessage('visualizer:mediaframe:close', '*');
145 });
146
147 }
148
149 function init_type_vs_library() {
150 var $data = $('select.viz-select-library').attr('data-type-vs-library');
151 if(typeof $data === 'undefined' || $data.length === 0){
152 return;
153 }
154 var $typeVsLibrary = JSON.parse( $('select.viz-select-library').attr('data-type-vs-library') );
155 // disable all unsupported libraries for the chart type.
156 $('input.type-radio').on('click', function(){
157 enable_libraries_for($(this).val(), $typeVsLibrary);
158 });
159
160 enable_libraries_for($('input.type-radio:checked').val(), $typeVsLibrary);
161 }
162
163 function enable_libraries_for($type, $typeVsLibrary) {
164 $('select.viz-select-library option').addClass('disabled').attr('disabled', 'disabled');
165 var $libs = $typeVsLibrary[$type];
166 $.each($libs, function( i, $lib ) {
167 $('select.viz-select-library option[value="' + $lib + '"]').removeClass('disabled').removeAttr('disabled');
168 });
169 $('select.viz-select-library').val( $('select.viz-select-library option:not(.disabled)').val() );
170 }
171
172 function init_permissions(){
173 $('#vz-chart-permissions h2').click(function () {
174 $("#vz-chart-source").hide();
175 $("#vz-chart-permissions .viz-group-header").show();
176 $("#vz-chart-settings").removeClass('open').addClass('bottom-fixed');
177
178 $('#settings-button').click(function(e) {
179 e.preventDefault();
180 $('#permissions-form').submit();
181 $('#settings-form').submit();
182 });
183
184 $(this).parent().removeClass('bottom-fixed').addClass('open');
185
186 return false;
187 });
188 $('#vz-chart-permissions .customize-section-back').click(function () {
189 $("#vz-chart-source").show();
190
191 $("#vz-chart-permissions .viz-group-header").hide();
192 $('#settings-button').click(function(e) {
193 e.preventDefault();
194 $('#settings-form').submit();
195 });
196
197 $(this).parent().parent().removeClass('open').addClass('bottom-fixed');
198
199 return false;
200 });
201
202 $('.visualizer-permission').chosen({
203 width : '50%',
204 search_contains : true
205 });
206
207 $('.visualizer-permission-type').each(function(x, y){
208 var type = $(y).attr('data-visualizer-permission-type');
209 var child = $('.visualizer-permission-' + type + '-specific');
210 if($(y).val() === 'all'){
211 child.next('div.chosen-container').hide();
212 return;
213 }
214 });
215
216 $('.visualizer-permission-type').on('change', function(evt, params) {
217 var type = $(this).attr('data-visualizer-permission-type');
218 var child = $('.visualizer-permission-' + type + '-specific');
219 child.empty();
220 if(params.selected === 'all'){
221 child.next('div.chosen-container').hide();
222 return;
223 } else {
224 child.next('div.chosen-container').show();
225 }
226 child.append('<option value="">' + visualizer.l10n['loading'] + '</option>').trigger('chosen:updated');
227 $.ajax({
228 url : visualizer.ajax['url'],
229 method : 'post',
230 data : {
231 'action' : visualizer.ajax['actions']['permissions'],
232 'nonce' : visualizer.ajax['nonces']['permissions'],
233 'type' : params.selected
234 },
235 success : function(d, textStatus, XMLHttpRequest){
236 if(d.success) {
237 child.empty();
238 $.each(d.data, function(k, v){
239 child.append('<option value="' + k + '">' + v + '</option>');
240 });
241 child.trigger('chosen:updated');
242 }
243 }
244 });
245 });
246 }
247
248 // https://codemirror.net/
249 function init_db_import_component(){
250 var table_columns = visualizer.db_query.tables;
251 var code_mirror = wp.CodeMirror || CodeMirror;
252 var cm = code_mirror.fromTextArea($('.visualizer-db-query').get(0), {
253 value: $('.visualizer-db-query').val(),
254 autofocus: true,
255 mode: 'text/x-mysql',
256 lineWrapping: true,
257 dragDrop: false,
258 matchBrackets: true,
259 autoCloseBrackets: true,
260 extraKeys: {"Ctrl-Space": "autocomplete"},
261 hintOptions: { tables: table_columns }
262 });
263
264 // force refresh so that the query shows on first time load. Otherwise you have to click on the editor for it to show.
265 $('body').on('visualizer:db:query:focus', function(event, data){
266 cm.refresh();
267 });
268
269 cm.focus();
270
271 // update text area.
272 cm.on('inputRead', function(x, y){
273 cm.save();
274 });
275
276 // backspace and delete do not register so the text box does not get empty if the entire query is deleted
277 // from the editor. Let's force this.
278 $('body').on('visualizer:db:query:update', function(event, data){
279 cm.save();
280 });
281
282 // clear the editor.
283 $('body').on('visualizer:db:query:setvalue', function(event, data){
284 cm.setValue(data.value);
285 cm.clearHistory();
286 cm.refresh();
287 });
288
289 // set an option at runtime?
290 $('body').on('visualizer:db:query:changeoption', function(event, data){
291 cm.setOption(data.name, data.value);
292 });
293 }
294
295 function init_filter_import() {
296 $( '#db-filter-save-button' ).on( 'click', function(){
297 $('#vz-filter-wizard').submit();
298 });
299 }
300
301 function init_db_import(){
302 $( '#visualizer-db-query' ).css("z-index", "-1").hide();
303
304 init_db_import_component();
305
306 $('#visualizer-query-fetch').on('click', function(e){
307
308 $('body').trigger('visualizer:db:query:update', {});
309 if($('.visualizer-db-query').val() === ''){
310 return;
311 }
312
313 start_ajax($('#visualizer-db-query'));
314 $('.db-wizard-results').empty();
315 $('.db-wizard-error').empty();
316 $.ajax({
317 url : ajaxurl,
318 method : 'post',
319 data : {
320 'action' : visualizer.ajax['actions']['db_get_data'],
321 'security' : visualizer.ajax['nonces']['db_get_data'],
322 'params' : $('#db-query-form').serialize()
323 },
324 success : function(data){
325 if(data.success){
326 $('.db-wizard-results').html(data.data.table);
327 $('#results').DataTable({
328 "paging": false
329 });
330 }else{
331 $('.db-wizard-error').html(data.data.msg);
332 }
333 },
334 complete: function(){
335 end_ajax($('#visualizer-db-query'));
336 }
337 });
338 });
339
340 $( '#db-chart-button' ).on( 'click', function(){
341 $('#content').css('width', 'calc(100% - 300px)');
342 if( $(this).attr( 'data-current' ) === 'chart'){
343 $(this).val( $(this).attr( 'data-t-filter' ) );
344 $(this).html( $(this).attr( 'data-t-filter' ) );
345 $(this).attr( 'data-current', 'filter' );
346 $( '.visualizer-editor-lhs' ).hide();
347 $( '#visualizer-db-query' ).css("z-index", "9999").show();
348 $('body').trigger('visualizer:db:query:focus', {});
349 $( '#canvas' ).hide();
350 }else{
351 var filter_button = $(this);
352 $( '#visualizer-db-query' ).css("z-index", "-1").hide();
353 $('#canvas').lock();
354 filter_button.val( filter_button.attr( 'data-t-chart' ) );
355 filter_button.html( filter_button.attr( 'data-t-chart' ) );
356 filter_button.attr( 'data-current', 'chart' );
357 $( '#canvas' ).css("z-index", "1").show();
358 $( '#db-chart-save-button' ).trigger('click');
359 }
360 } );
361
362 $( '#db-chart-save-button' ).on( 'click', function(){
363 // submit only if a query has been provided.
364 if($('#db-query-form .visualizer-db-query').val().length > 0){
365 $('#viz-db-wizard-params').val($('#db-query-form').serialize());
366 $('#vz-db-wizard').submit();
367 }else{
368 $('#canvas').unlock();
369 }
370 });
371 }
372
373 function init_json_import(){
374 if(typeof visualizer === 'undefined'){
375 return;
376 }
377
378 var regex = new RegExp(visualizer.json_tag_separator, 'g');
379
380 $( '#visualizer-json-screen' ).css("z-index", "-1").hide();
381 $('.visualizer-json-form').accordion({
382 heightStyle: 'content',
383 active: 0
384 });
385 $('.visualizer-json-subform').accordion({
386 heightStyle: 'content',
387 active: false,
388 collapsible: true
389 });
390
391 // toggle between chart and create/modify parameters
392 $( '#json-chart-button' ).on( 'click', function(){
393 var $bttn = $(this);
394 $('#content').css('width', 'calc(100% - 100px)');
395 if( $(this).attr( 'data-current' ) === 'chart'){
396 // toggle from chart to LHS form
397 $(this).val( $(this).attr( 'data-t-filter' ) );
398 $(this).html( $(this).attr( 'data-t-filter' ) );
399 $(this).attr( 'data-current', 'filter' );
400 $( '.visualizer-editor-lhs' ).hide();
401 $( '#visualizer-json-screen' ).css("z-index", "9999").show();
402 $( '#canvas' ).hide();
403 }else{
404 // toggle from LHS form to chart
405 $( '#json-conclude-form' ).trigger('submit');
406 }
407 } );
408
409 $('body').on('visualizer:json:form:submit', function() {
410 var filter_button = $( '#json-chart-button' );
411 $( '#visualizer-json-screen' ).css("z-index", "-1").hide();
412 $('#canvas').lock();
413 filter_button.val( filter_button.attr( 'data-t-chart' ) );
414 filter_button.html( filter_button.attr( 'data-t-chart' ) );
415 filter_button.attr( 'data-current', 'chart' );
416 end_ajax( $( '#visualizer-json-screen' ) );
417 $( '#canvas' ).css("z-index", "1").show();
418 });
419
420
421 // fetch the roots for the provided endpoint
422 $( '#visualizer-json-fetch' ).on( 'click', function(e){
423 e.preventDefault();
424 $('.visualizer-json-form').accordion( 'option', 'active', 0 );
425 $('.visualizer-json-form h3.viz-step:not(.step1)').addClass('ui-state-disabled');
426 $('.json-table').html('');
427 start_ajax( $( '#visualizer-json-screen' ) );
428 $.ajax({
429 url : ajaxurl,
430 method : 'post',
431 data : {
432 'action' : visualizer.ajax['actions']['json_get_roots'],
433 'security' : visualizer.ajax['nonces']['json_get_roots'],
434 'params' : $('#json-endpoint-form').serialize()
435 },
436 success : function(data){
437 if(data.success){
438 $('#vz-import-json-root').empty();
439 $.each(data.data.roots, function(i, name){
440 $('#vz-import-json-root').append('<option value="' + name + '">' + name.replace(regex, visualizer.json_tag_separator_view) + '</option>');
441 });
442 $('#json-root-form').fadeIn('medium');
443 json_accordion_activate(1, true);
444 }else{
445 alert(data.data.msg);
446 }
447 },
448 complete: function(){
449 end_ajax($('#visualizer-json-screen'));
450 }
451 });
452 });
453
454 // fetch the data for the chosen root
455 $( '#visualizer-json-parse' ).on( 'click', function(e){
456 e.preventDefault();
457 $('.visualizer-json-form h3.viz-step:not(.step1):not(.step2)').addClass('ui-state-disabled');
458 $('.json-table').html('');
459 start_ajax( $( '#visualizer-json-screen' ) );
460 $.ajax({
461 url : ajaxurl,
462 method : 'post',
463 data : {
464 'action' : visualizer.ajax['actions']['json_get_data'],
465 'security' : visualizer.ajax['nonces']['json_get_data'],
466 'params' : $('#json-root-form, #json-endpoint-form').serialize()
467 },
468 success : function(data){
469 if(data.success){
470 $('#vz-import-json-paging option:not(.static)').remove();
471 if(data.data.paging.length > 0){
472 var $template = $('#vz-import-json-paging').attr('data-template');
473 $.each(data.data.paging, function(i, name){
474 var display = name.replace(regex, visualizer.json_tag_separator_view);
475 display = $template.replace('?', display);
476 $('#vz-import-json-paging').append('<option value="' + name + '">' + display + '</option>');
477 });
478 $('.json-pagination').show();
479 }
480 $('#json-conclude-form .json-table').html(data.data.table);
481
482 var $table = create_editor_table( '#json-conclude-form' );
483
484 json_accordion_activate(3, true);
485 json_accordion_activate(2, false);
486 $table.columns.adjust().draw();
487 }else{
488 alert(data.data.msg);
489 }
490 },
491 complete: function(){
492 end_ajax($('#visualizer-json-screen'));
493 }
494 });
495 });
496
497 // when the data is set and the chart is updated, toggle the screen so that the chart is shown
498 $('#json-conclude-form').on( 'submit', function(e){
499 // at least one column has to be selected as non-excluded.
500 var count_selected = 0;
501 $('select.viz-select-data-type').each(function(i, element){
502 if($(element).prop('selectedIndex') > 0){
503 count_selected++;
504 }
505 });
506 if(count_selected === 0){
507 alert(visualizer.l10n.select_columns);
508 return false;
509 }
510
511 // populate the form elements that are in the other tabs.
512 $('#json-conclude-form-helper .json-form-element, #json-endpoint-form .json-form-element, #json-root-form .json-form-element, #vz-import-json .json-form-element').each(function(x, y){
513 $('#json-conclude-form').append('<input type="hidden" name="' + y.name + '" value="' + y.value + '">');
514 });
515
516 $('body').trigger('visualizer:json:form:submit');
517 });
518
519 // update the schedule
520 $('#json-chart-save-button').on('click', function(e){
521 e.preventDefault();
522 $('#canvas').lock();
523 $.ajax({
524 url : ajaxurl,
525 method : 'post',
526 data : {
527 'action' : visualizer.ajax['actions']['json_set_schedule'],
528 'security' : visualizer.ajax['nonces']['json_set_schedule'],
529 'chart' : $('#vz-json-time').attr('data-chart'),
530 'time' : $('#vz-json-time').val()
531 },
532 success : function(data){
533 // do nothing.
534 },
535 complete: function(){
536 $('#canvas').unlock();
537 }
538 });
539 });
540
541 }
542
543 function init_editor_table() {
544 $('body').on('visualizer:db:editor:table:init', function(event, data){
545 var $table = create_editor_table('.viz-table-editor', data.config);
546 $('body').on('visualizer:db:editor:table:redraw', function(event, data){
547 $table.draw();
548 });
549 });
550 }
551
552 function create_editor_table(element, config) {
553 var settings = {
554 paging: false,
555 searching: false,
556 ordering: false,
557 select: false,
558 scrollX: "100%",
559 scrollY: "400px",
560 info: false,
561 colReorder: {
562 fixedColumnsLeft: 1
563 }
564 };
565
566 // show column visibility button only when more than 6 columns are found (including the Label column)
567 if($(element + ' table.viz-editor-table thead tr th').length > 6){
568 $.extend( settings, {
569 dom: 'Bt',
570 buttons: [
571 {
572 extend: 'colvis',
573 columns: ':gt(0)',
574 collectionLayout: 'four-column'
575 }
576 ]
577 } );
578 }
579 if(config){
580 $.extend( settings, config );
581 }
582
583 var $table = $(element + ' .viz-editor-table').DataTable(settings);
584 return $table;
585 }
586
587 function json_accordion_activate($step, $activate){
588 $('.visualizer-json-form h3.viz-step.step' + ( $step + 1 )).removeClass('ui-state-disabled');
589 if($activate){
590 $('.visualizer-json-form').accordion( 'option', 'active', $step );
591 }
592 }
593
594 function start_ajax(element){
595 element.lock();
596 }
597
598 function end_ajax(element){
599 element.unlock();
600 }
601
602 })(jQuery);
603
604 (function ($) {
605 $.fn.lock = function () {
606 $(this).each(function () {
607 var $this = $(this);
608 var position = $this.css('position');
609
610 if (!position) {
611 position = 'static';
612 }
613
614 switch (position) {
615 case 'absolute':
616 case 'relative':
617 break;
618 default:
619 $this.css('position', 'relative');
620 break;
621 }
622 $this.data('position', position);
623
624 var width = $this.width(),
625 height = $this.height();
626
627 var locker = $('<div class="locker"></div>');
628 locker.width(width).height(height);
629
630 var loader = $('<div class="locker-loader"></div>');
631 loader.width(width).height(height);
632
633 locker.append(loader);
634 $this.append(locker);
635 $(window).resize(function () {
636 $this.find('.locker,.locker-loader').width($this.width()).height($this.height());
637 });
638 });
639
640 return $(this);
641 };
642
643 $.fn.unlock = function () {
644 $(this).each(function () {
645 $(this).find('.locker').remove();
646 $(this).css('position', $(this).data('position'));
647 });
648
649 return $(this);
650 };
651 })(jQuery);