Simple Calendar – Google Calendar Plugin - Version 0.4.1

Version Description

  • Fix / workaround for the long-running timezone bug. Please take a look at this for more information.
  • Added additional 'Maximum no. events to display' option to widget / shortcode (mainly to address a further issue caused by the above fix)
  • i18n related bug fix
  • Added support for widget_title filter (courtesy of James)
  • Added Hungarian (hu_HU) translation (danieltakacs)
  • Now using minified version of jQuery qTip script
Download this release

Release Info

Developer rosshanney
Plugin Icon 128x128 Simple Calendar – Google Calendar Plugin
Version 0.4.1
Comparing to
See all releases

Code changes from version 0.4 to 0.4.1

admin/add.php CHANGED
@@ -82,7 +82,7 @@ function gce_add_show_past_events_field(){
82
  //Max events
83
  function gce_add_max_events_field(){
84
  ?>
85
- <span class="description"><?php _e('The default number of events to retrieve from a Google Calendar feed is 25, but you may want less for a list, or more for a calendar grid.', GCE_TEXT_DOMAIN); ?></span>
86
  <br />
87
  <input type="text" name="gce_options[max_events]" value="25" size="3" />
88
  <?php
82
  //Max events
83
  function gce_add_max_events_field(){
84
  ?>
85
+ <span class="description"><?php _e('Set this to a few more than you actually want to display (due to caching and timezone issues). The exact number to display can be configured per shortcode / widget.', GCE_TEXT_DOMAIN); ?></span>
86
  <br />
87
  <input type="text" name="gce_options[max_events]" value="25" size="3" />
88
  <?php
admin/edit.php CHANGED
@@ -83,7 +83,7 @@ function gce_edit_max_events_field(){
83
  $options = get_option(GCE_OPTIONS_NAME);
84
  $options = $options[$_GET['id']];
85
  ?>
86
- <span class="description"><?php _e('The default number of events to retrieve from a Google Calendar feed is 25, but you may want less for a list, or more for a calendar grid.', GCE_TEXT_DOMAIN); ?></span>
87
  <br />
88
  <input type="text" name="gce_options[max_events]" value="<?php echo $options['max_events']; ?>" size="3" />
89
  <?php
83
  $options = get_option(GCE_OPTIONS_NAME);
84
  $options = $options[$_GET['id']];
85
  ?>
86
+ <span class="description"><?php _e('Set this to a few more than you actually want to display (due to caching and timezone issues). The exact number to display can be configured per shortcode / widget.', GCE_TEXT_DOMAIN); ?></span>
87
  <br />
88
  <input type="text" name="gce_options[max_events]" value="<?php echo $options['max_events']; ?>" size="3" />
89
  <?php
google-calendar-events.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Google Calendar Events
4
  Plugin URI: http://www.rhanney.co.uk/plugins/google-calendar-events
5
  Description: Parses Google Calendar feeds and displays the events as a calendar grid or list on a page, post or widget.
6
- Version: 0.4
7
  Author: Ross Hanney
8
  Author URI: http://www.rhanney.co.uk
9
  License: GPL2
@@ -96,8 +96,15 @@ if(!class_exists('Google_Calendar_Events')){
96
  );
97
 
98
  //Update old display_start / display_end values
99
- $saved_feed_options['display_start'] = ($saved_feed_options['display_start'] == 'on' ? 'time' : 'none');
100
- $saved_feed_options['display_end'] = ($saved_feed_options['display_end'] == 'on' ? 'time-date' : 'none');
 
 
 
 
 
 
 
101
 
102
  //Merge saved options with defaults
103
  foreach($saved_feed_options as $option_name => $option){
@@ -139,7 +146,7 @@ if(!class_exists('Google_Calendar_Events')){
139
 
140
  function init_plugin(){
141
  //Load text domain for i18n
142
- load_plugin_textdomain(GCE_TEXT_DOMAIN, false, 'languages');
143
  if(get_option('timezone_string') != '') date_default_timezone_set(get_option('timezone_string'));
144
  }
145
 
@@ -330,7 +337,8 @@ if(!class_exists('Google_Calendar_Events')){
330
  extract(shortcode_atts(array(
331
  'id' => '1',
332
  'type' => 'grid',
333
- 'title' => false
 
334
  ), $atts));
335
 
336
  //Break comma delimited list of feed ids into array
@@ -348,6 +356,9 @@ if(!class_exists('Google_Calendar_Events')){
348
  if(isset($options[$feed_id])) $no_feeds_exist = false;
349
  }
350
 
 
 
 
351
  //Check that at least one valid feed id has been entered
352
  if(count((array)$feed_ids) == 0 || $no_feeds_exist){
353
  return __('No valid Feed IDs have been entered for this shortcode. Please check that you have entered the IDs correctly and that the Feeds have not been deleted.', GCE_TEXT_DOMAIN);
@@ -359,10 +370,10 @@ if(!class_exists('Google_Calendar_Events')){
359
  $title_text = ($title === false ? null : $title);
360
 
361
  switch($type){
362
- case 'grid': return gce_print_grid($feed_ids, $title_text);
363
- case 'ajax': return gce_print_grid($feed_ids, $title_text, true);
364
- case 'list': return gce_print_list($feed_ids, $title_text);
365
- case 'list-grouped': return gce_print_list($feed_ids, $title_text, true);
366
  }
367
  }
368
  }else{
@@ -406,10 +417,10 @@ if(!class_exists('Google_Calendar_Events')){
406
  if(isset($_GET['gce_feed_ids'])){
407
  if($_GET['gce_type'] == 'page'){
408
  //The page grid markup to be returned via AJAX
409
- echo gce_print_grid($_GET['gce_feed_ids'], $_GET['gce_title_text'], true, $_GET['gce_month'], $_GET['gce_year']);
410
  }elseif($_GET['gce_type'] == 'widget'){
411
  //The widget grid markup to be returned via AJAX
412
- gce_widget_content_grid($_GET['gce_feed_ids'], $_GET['gce_title_text'], $_GET['gce_widget_id'], true, $_GET['gce_month'], $_GET['gce_year']);
413
  }
414
  die();
415
  }
@@ -417,9 +428,9 @@ if(!class_exists('Google_Calendar_Events')){
417
  }
418
  }
419
 
420
- function gce_print_list($feed_ids, $title_text, $grouped = false){
421
  //Create new GCE_Parser object, passing array of feed id(s)
422
- $list = new GCE_Parser(explode('-', $feed_ids), $title_text);
423
 
424
  //If the feed(s) parsed ok, return the list markup, otherwise return an error message
425
  if(count($list->get_errors()) == 0){
@@ -429,16 +440,16 @@ function gce_print_list($feed_ids, $title_text, $grouped = false){
429
  }
430
  }
431
 
432
- function gce_print_grid($feed_ids, $title_text, $ajaxified = false, $month = null, $year = null){
433
  //Create new GCE_Parser object, passing array of feed id(s) returned from gce_get_feed_ids()
434
- $grid = new GCE_Parser(explode('-', $feed_ids), $title_text);
435
 
436
  //If the feed(s) parsed ok, return the grid markup, otherwise return an error message
437
  if(count($grid->get_errors()) == 0){
438
  $markup = '<div class="gce-page-grid" id="gce-page-grid-' . $feed_ids .'">';
439
 
440
  //Add AJAX script if required
441
- if($ajaxified) $markup .= '<script type="text/javascript">jQuery(document).ready(function($){gce_ajaxify("gce-page-grid-' . $feed_ids . '", "' . $feed_ids . '", "' . $title_text . '", "page");});</script>';
442
 
443
  return $markup . $grid->get_grid($year, $month, $ajaxified) . '</div>';
444
  }else{
3
  Plugin Name: Google Calendar Events
4
  Plugin URI: http://www.rhanney.co.uk/plugins/google-calendar-events
5
  Description: Parses Google Calendar feeds and displays the events as a calendar grid or list on a page, post or widget.
6
+ Version: 0.4.1
7
  Author: Ross Hanney
8
  Author URI: http://www.rhanney.co.uk
9
  License: GPL2
96
  );
97
 
98
  //Update old display_start / display_end values
99
+ if(!isset($saved_feed_options['display_start']))
100
+ $saved_feed_options['display_start'] = 'none';
101
+ elseif($saved_feed_options['display_start'] == 'on')
102
+ $saved_feed_options['display_start'] = 'time';
103
+
104
+ if(!isset($saved_feed_options['display_end']))
105
+ $saved_feed_options['display_end'] = 'none';
106
+ elseif($saved_feed_options['display_end'] == 'on')
107
+ $saved_feed_options['display_end'] = 'time-date';
108
 
109
  //Merge saved options with defaults
110
  foreach($saved_feed_options as $option_name => $option){
146
 
147
  function init_plugin(){
148
  //Load text domain for i18n
149
+ load_plugin_textdomain(GCE_TEXT_DOMAIN, false, dirname(plugin_basename(__FILE__)) . '/languages');
150
  if(get_option('timezone_string') != '') date_default_timezone_set(get_option('timezone_string'));
151
  }
152
 
337
  extract(shortcode_atts(array(
338
  'id' => '1',
339
  'type' => 'grid',
340
+ 'title' => false,
341
+ 'max' => 0
342
  ), $atts));
343
 
344
  //Break comma delimited list of feed ids into array
356
  if(isset($options[$feed_id])) $no_feeds_exist = false;
357
  }
358
 
359
+ //Ensure max events is a positive integer
360
+ $max_events = absint($max);
361
+
362
  //Check that at least one valid feed id has been entered
363
  if(count((array)$feed_ids) == 0 || $no_feeds_exist){
364
  return __('No valid Feed IDs have been entered for this shortcode. Please check that you have entered the IDs correctly and that the Feeds have not been deleted.', GCE_TEXT_DOMAIN);
370
  $title_text = ($title === false ? null : $title);
371
 
372
  switch($type){
373
+ case 'grid': return gce_print_grid($feed_ids, $title_text, $max_events);
374
+ case 'ajax': return gce_print_grid($feed_ids, $title_text, $max_events, true);
375
+ case 'list': return gce_print_list($feed_ids, $title_text, $max_events);
376
+ case 'list-grouped': return gce_print_list($feed_ids, $title_text, $max_events, true);
377
  }
378
  }
379
  }else{
417
  if(isset($_GET['gce_feed_ids'])){
418
  if($_GET['gce_type'] == 'page'){
419
  //The page grid markup to be returned via AJAX
420
+ echo gce_print_grid($_GET['gce_feed_ids'], $_GET['gce_title_text'], $_GET['gce_max_events'], true, $_GET['gce_month'], $_GET['gce_year']);
421
  }elseif($_GET['gce_type'] == 'widget'){
422
  //The widget grid markup to be returned via AJAX
423
+ gce_widget_content_grid($_GET['gce_feed_ids'], $_GET['gce_title_text'], $_GET['gce_max_events'], $_GET['gce_widget_id'], true, $_GET['gce_month'], $_GET['gce_year']);
424
  }
425
  die();
426
  }
428
  }
429
  }
430
 
431
+ function gce_print_list($feed_ids, $title_text, $max_events, $grouped = false){
432
  //Create new GCE_Parser object, passing array of feed id(s)
433
+ $list = new GCE_Parser(explode('-', $feed_ids), $title_text, $max_events);
434
 
435
  //If the feed(s) parsed ok, return the list markup, otherwise return an error message
436
  if(count($list->get_errors()) == 0){
440
  }
441
  }
442
 
443
+ function gce_print_grid($feed_ids, $title_text, $max_events, $ajaxified = false, $month = null, $year = null){
444
  //Create new GCE_Parser object, passing array of feed id(s) returned from gce_get_feed_ids()
445
+ $grid = new GCE_Parser(explode('-', $feed_ids), $title_text, $max_events);
446
 
447
  //If the feed(s) parsed ok, return the grid markup, otherwise return an error message
448
  if(count($grid->get_errors()) == 0){
449
  $markup = '<div class="gce-page-grid" id="gce-page-grid-' . $feed_ids .'">';
450
 
451
  //Add AJAX script if required
452
+ if($ajaxified) $markup .= '<script type="text/javascript">jQuery(document).ready(function($){gce_ajaxify("gce-page-grid-' . $feed_ids . '", "' . $feed_ids . '", "' . $max_events . '", "' . $title_text . '", "page");});</script>';
453
 
454
  return $markup . $grid->get_grid($year, $month, $ajaxified) . '</div>';
455
  }else{
inc/gce-feed.php CHANGED
@@ -3,11 +3,12 @@ require_once(ABSPATH . WPINC . '/class-feed.php');
3
  require_once('simplepie-gcalendar.php');
4
 
5
  class GCE_Feed extends SimplePie_GCalendar{
6
- var $feed_id;
7
- var $d_format;
8
- var $t_format;
9
- var $display_opts;
10
- var $multi_day;
 
11
 
12
  function GCE_Feed(){
13
  $this->__construct();
@@ -41,6 +42,11 @@ class GCE_Feed extends SimplePie_GCalendar{
41
  $this->multi_day = $multiple_day;
42
  }
43
 
 
 
 
 
 
44
  //Getters
45
 
46
  function get_feed_id(){
@@ -62,5 +68,9 @@ class GCE_Feed extends SimplePie_GCalendar{
62
  function get_multi_day(){
63
  return $this->multi_day;
64
  }
 
 
 
 
65
  }
66
  ?>
3
  require_once('simplepie-gcalendar.php');
4
 
5
  class GCE_Feed extends SimplePie_GCalendar{
6
+ private $feed_id;
7
+ private $d_format;
8
+ private $t_format;
9
+ private $display_opts;
10
+ private $multi_day;
11
+ private $feed_start;
12
 
13
  function GCE_Feed(){
14
  $this->__construct();
42
  $this->multi_day = $multiple_day;
43
  }
44
 
45
+ function set_start_date($start_date){
46
+ $this->feed_start = $start_date;
47
+ parent::set_start_date($start_date);
48
+ }
49
+
50
  //Getters
51
 
52
  function get_feed_id(){
68
  function get_multi_day(){
69
  return $this->multi_day;
70
  }
71
+
72
+ function get_start_date(){
73
+ return $this->feed_start;
74
+ }
75
  }
76
  ?>
inc/gce-parser.php CHANGED
@@ -5,13 +5,15 @@ class GCE_Parser{
5
  var $feeds = array();
6
  var $merged_feed_data = array();
7
  var $title = null;
 
8
 
9
- function GCE_Parser($feed_ids, $title_text = null){
10
- $this->__construct($feed_ids, $title_text);
11
  }
12
 
13
- function __construct($feed_ids, $title_text = null){
14
  $this->title = $title_text;
 
15
 
16
  //Get the feed options
17
  $options = get_option(GCE_OPTIONS_NAME);
@@ -31,11 +33,11 @@ class GCE_Parser{
31
  $feed->set_cache_duration($feed_options['cache_duration']);
32
  //Set the timezone if anything other than default
33
  if($feed_options['timezone'] != 'default') $feed->set_timezone($feed_options['timezone']);
34
- //If show past events is true, set start date to 1st of this month. Otherwise, set start date to today
35
  if($feed_options['show_past_events'] == 'true'){
36
- $feed->set_start_date(mktime(0, 0, 0, date('m'), 1, date('Y')));
37
  }else{
38
- $feed->set_start_date(mktime(0, 0, 0, date('m'), date('j'), date('Y')));
39
  }
40
  //Set date and time formats. If they have not been set by user, set to global WordPress formats
41
  $feed->set_date_format($feed_options['date_format'] == '' ? get_option('date_format') : $feed_options['date_format']);
@@ -92,28 +94,44 @@ class GCE_Parser{
92
  function get_event_days(){
93
  $event_days = array();
94
 
95
- foreach($this->merged_feed_data as $item){
96
- $start_date = $item->get_start_date();
97
-
98
- //Round start date to nearest day
99
- $start_date = mktime(0, 0, 0, date('m', $start_date), date('d', $start_date) , date('Y', $start_date));
100
-
101
- //If multiple day events should be handled, add multiple day event to required days
102
- if($item->get_feed()->get_multi_day()){
103
- $on_next_day = true;
104
- $next_day = $start_date + 86400;
105
- while($on_next_day){
106
- if($item->get_end_date() > $next_day){
107
- $event_days[$next_day][] = $item;
108
- }else{
109
- $on_next_day = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  }
111
- $next_day += 86400;
112
  }
113
- }
114
 
115
- //Add item into array of events for that day
116
- $event_days[$start_date][] = $item;
 
 
 
 
117
  }
118
 
119
  return $event_days;
@@ -209,6 +227,7 @@ class GCE_Parser{
209
 
210
  function get_list($grouped = false){
211
  $event_days = $this->get_event_days();
 
212
  //If event_days is empty, there are no events in the feed(s), so return a message indicating this
213
  if(count((array)$event_days) == 0) return '<p>' . __('There are currently no upcoming events.', GCE_TEXT_DOMAIN) . '</p>';
214
 
@@ -308,7 +327,7 @@ class GCE_Parser{
308
  }
309
 
310
  //If link should be displayed add to $markup
311
- if(isset($display_options['display_link'])){ //Below: add target="_blank" if required
312
  $markup .= '<p class="gce-' . $type . '-link"><a href="' . $event->get_link() . '&amp;ctz=' . $feed->get_timezone() . '"' . (isset($display_options['display_link_target']) ? ' target="_blank"' : '') . '>' . $display_options['display_link_text'] . '</a></p>';
313
  }
314
 
5
  var $feeds = array();
6
  var $merged_feed_data = array();
7
  var $title = null;
8
+ var $max_events_display = 0;
9
 
10
+ function GCE_Parser($feed_ids, $title_text = null, $max_events = 0){
11
+ $this->__construct($feed_ids, $title_text, $max_events);
12
  }
13
 
14
+ function __construct($feed_ids, $title_text = null, $max_events = 0){
15
  $this->title = $title_text;
16
+ $this->max_events_display = $max_events;
17
 
18
  //Get the feed options
19
  $options = get_option(GCE_OPTIONS_NAME);
33
  $feed->set_cache_duration($feed_options['cache_duration']);
34
  //Set the timezone if anything other than default
35
  if($feed_options['timezone'] != 'default') $feed->set_timezone($feed_options['timezone']);
36
+ //If show past events is true, set start date to 1st of this month. Otherwise, set start date to today. (Adjust for timezone)
37
  if($feed_options['show_past_events'] == 'true'){
38
+ $feed->set_start_date(mktime(0, 0, 0, date('m'), 1, date('Y')) - date('Z'));
39
  }else{
40
+ $feed->set_start_date(mktime(0, 0, 0, date('m'), date('j'), date('Y')) - date('Z'));
41
  }
42
  //Set date and time formats. If they have not been set by user, set to global WordPress formats
43
  $feed->set_date_format($feed_options['date_format'] == '' ? get_option('date_format') : $feed_options['date_format']);
94
  function get_event_days(){
95
  $event_days = array();
96
 
97
+ //Total number of events retrieved
98
+ $count = count($this->merged_feed_data);
99
+
100
+ //If maximum events to display is 0 (unlimited) set $max to 1, otherwise use maximum of events specified by user
101
+ $max = $this->max_events_display == 0 ? 1 : $this->max_events_display;
102
+
103
+ //Loop through entire array of events, or until maximum number of events to be displayed has been reached
104
+ for($i = 0; $i < $count && $max > 0; $i++){
105
+ $item = $this->merged_feed_data[$i];
106
+
107
+ //Check that event end time isn't before start time of feed (ignores events from before start time that may have been inadvertently retrieved)
108
+ if($item->get_end_date() > ($item->get_feed()->get_start_date() + date('Z'))){
109
+
110
+ $start_date = $item->get_start_date();
111
+
112
+ //Round start date to nearest day
113
+ $start_date = mktime(0, 0, 0, date('m', $start_date), date('d', $start_date) , date('Y', $start_date));
114
+
115
+ //If multiple day events should be handled, add multiple day event to required days
116
+ if($item->get_feed()->get_multi_day()){
117
+ $on_next_day = true;
118
+ $next_day = $start_date + 86400;
119
+ while($on_next_day){
120
+ if($item->get_end_date() > $next_day){
121
+ $event_days[$next_day][] = $item;
122
+ }else{
123
+ $on_next_day = false;
124
+ }
125
+ $next_day += 86400;
126
  }
 
127
  }
 
128
 
129
+ //Add item into array of events for that day
130
+ $event_days[$start_date][] = $item;
131
+
132
+ //If maximum events to display isn't 0 (unlimited) decrement $max counter
133
+ if($this->max_events_display != 0) $max--;
134
+ }
135
  }
136
 
137
  return $event_days;
227
 
228
  function get_list($grouped = false){
229
  $event_days = $this->get_event_days();
230
+
231
  //If event_days is empty, there are no events in the feed(s), so return a message indicating this
232
  if(count((array)$event_days) == 0) return '<p>' . __('There are currently no upcoming events.', GCE_TEXT_DOMAIN) . '</p>';
233
 
327
  }
328
 
329
  //If link should be displayed add to $markup
330
+ if(isset($display_options['display_link'])){ //Below: add target="_blank" if required
331
  $markup .= '<p class="gce-' . $type . '-link"><a href="' . $event->get_link() . '&amp;ctz=' . $feed->get_timezone() . '"' . (isset($display_options['display_link_target']) ? ' target="_blank"' : '') . '>' . $display_options['display_link_text'] . '</a></p>';
332
  }
333
 
inc/simplepie-gcalendar.php CHANGED
@@ -107,7 +107,14 @@ class SimplePie_GCalendar extends SimplePie {
107
  * @param $value must php timestamp
108
  */
109
  function set_start_date($value = 0){
110
- $this->start_date = strftime('%Y-%m-%dT%H:%M:%S',$value);
 
 
 
 
 
 
 
111
  }
112
 
113
  /**
107
  * @param $value must php timestamp
108
  */
109
  function set_start_date($value = 0){
110
+ //$test = date('P');
111
+ //$test = str_replace('+', '&#43;', $test);
112
+ //$blah = strftime('%Y-%m-%dT%H:%M:%S',$value);
113
+ //$this->start_date = $blah . $test;
114
+ //echo $this->start_date;
115
+ //$this->start_date = date('c');
116
+
117
+ $this->start_date = strftime('%Y-%m-%dT%H:%M:%S',$value);
118
  }
119
 
120
  /**
js/gce-script.js CHANGED
@@ -1,4 +1,4 @@
1
- function gce_ajaxify(target, feed_ids, title_text, type){
2
  //Add click event to change month links
3
  jQuery('#' + target + ' .gce-change-month').click(function(){
4
  //Extract month and year
@@ -12,6 +12,7 @@ function gce_ajaxify(target, feed_ids, title_text, type){
12
  gce_feed_ids:feed_ids,
13
  gce_title_text:title_text,
14
  gce_widget_id:target,
 
15
  gce_month:month_year[0],
16
  gce_year:month_year[1]
17
  }, function(data){
1
+ function gce_ajaxify(target, feed_ids, max_events, title_text, type){
2
  //Add click event to change month links
3
  jQuery('#' + target + ' .gce-change-month').click(function(){
4
  //Extract month and year
12
  gce_feed_ids:feed_ids,
13
  gce_title_text:title_text,
14
  gce_widget_id:target,
15
+ gce_max_events:max_events,
16
  gce_month:month_year[0],
17
  gce_year:month_year[1]
18
  }, function(data){
js/jquery-qtip.js CHANGED
@@ -12,2138 +12,4 @@
12
  * Released: Tuesday 12th May, 2009 - 00:00
13
  * Debug: jquery.qtip.debug.js
14
  */
15
- (function($)
16
- {
17
- // Implementation
18
- $.fn.qtip = function(options, blanket)
19
- {
20
- var i, id, interfaces, opts, obj, command, config, api;
21
-
22
- // Return API / Interfaces if requested
23
- if(typeof options == 'string')
24
- {
25
- // Make sure API data exists if requested
26
- if(typeof $(this).data('qtip') !== 'object')
27
- $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.NO_TOOLTIP_PRESENT, false);
28
-
29
- // Return requested object
30
- if(options == 'api')
31
- return $(this).data('qtip').interfaces[ $(this).data('qtip').current ];
32
- else if(options == 'interfaces')
33
- return $(this).data('qtip').interfaces;
34
- }
35
-
36
- // Validate provided options
37
- else
38
- {
39
- // Set null options object if no options are provided
40
- if(!options) options = {};
41
-
42
- // Sanitize option data
43
- if(typeof options.content !== 'object' || (options.content.jquery && options.content.length > 0)) options.content = { text: options.content };
44
- if(typeof options.content.title !== 'object') options.content.title = { text: options.content.title };
45
- if(typeof options.position !== 'object') options.position = { corner: options.position };
46
- if(typeof options.position.corner !== 'object') options.position.corner = { target: options.position.corner, tooltip: options.position.corner };
47
- if(typeof options.show !== 'object') options.show = { when: options.show };
48
- if(typeof options.show.when !== 'object') options.show.when = { event: options.show.when };
49
- if(typeof options.show.effect !== 'object') options.show.effect = { type: options.show.effect };
50
- if(typeof options.hide !== 'object') options.hide = { when: options.hide };
51
- if(typeof options.hide.when !== 'object') options.hide.when = { event: options.hide.when };
52
- if(typeof options.hide.effect !== 'object') options.hide.effect = { type: options.hide.effect };
53
- if(typeof options.style !== 'object') options.style = { name: options.style };
54
- options.style = sanitizeStyle(options.style);
55
-
56
- // Build main options object
57
- opts = $.extend(true, {}, $.fn.qtip.defaults, options);
58
-
59
- // Inherit all style properties into one syle object and include original options
60
- opts.style = buildStyle.call({ options: opts }, opts.style);
61
- opts.user = $.extend(true, {}, options);
62
- };
63
-
64
- // Iterate each matched element
65
- return $(this).each(function() // Return original elements as per jQuery guidelines
66
- {
67
- // Check for API commands
68
- if(typeof options == 'string')
69
- {
70
- command = options.toLowerCase();
71
- interfaces = $(this).qtip('interfaces');
72
-
73
- // Make sure API data exists$('.qtip').qtip('destroy')
74
- if(typeof interfaces == 'object')
75
- {
76
- // Check if API call is a BLANKET DESTROY command
77
- if(blanket === true && command == 'destroy')
78
- while(interfaces.length > 0) interfaces[interfaces.length-1].destroy();
79
-
80
- // API call is not a BLANKET DESTROY command
81
- else
82
- {
83
- // Check if supplied command effects this tooltip only (NOT BLANKET)
84
- if(blanket !== true) interfaces = [ $(this).qtip('api') ];
85
-
86
- // Execute command on chosen qTips
87
- for(i = 0; i < interfaces.length; i++)
88
- {
89
- // Destroy command doesn't require tooltip to be rendered
90
- if(command == 'destroy') interfaces[i].destroy();
91
-
92
- // Only call API if tooltip is rendered and it wasn't a destroy call
93
- else if(interfaces[i].status.rendered === true)
94
- {
95
- if(command == 'show') interfaces[i].show();
96
- else if(command == 'hide') interfaces[i].hide();
97
- else if(command == 'focus') interfaces[i].focus();
98
- else if(command == 'disable') interfaces[i].disable(true);
99
- else if(command == 'enable') interfaces[i].disable(false);
100
- };
101
- };
102
- };
103
- };
104
- }
105
-
106
- // No API commands, continue with qTip creation
107
- else
108
- {
109
- // Create unique configuration object
110
- config = $.extend(true, {}, opts);
111
- config.hide.effect.length = opts.hide.effect.length;
112
- config.show.effect.length = opts.show.effect.length;
113
-
114
- // Sanitize target options
115
- if(config.position.container === false) config.position.container = $(document.body);
116
- if(config.position.target === false) config.position.target = $(this);
117
- if(config.show.when.target === false) config.show.when.target = $(this);
118
- if(config.hide.when.target === false) config.hide.when.target = $(this);
119
-
120
- // Determine tooltip ID (Reuse array slots if possible)
121
- id = $.fn.qtip.interfaces.length;
122
- for(i = 0; i < id; i++)
123
- {
124
- if(typeof $.fn.qtip.interfaces[i] == 'undefined'){ id = i; break; };
125
- };
126
-
127
- // Instantiate the tooltip
128
- obj = new qTip($(this), config, id);
129
-
130
- // Add API references
131
- $.fn.qtip.interfaces[id] = obj;
132
-
133
- // Check if element already has qTip data assigned
134
- if(typeof $(this).data('qtip') == 'object' && $(this).data('qtip'))
135
- {
136
- // Set new current interface id
137
- if(typeof $(this).attr('qtip') === 'undefined')
138
- $(this).data('qtip').current = $(this).data('qtip').interfaces.length;
139
-
140
- // Push new API interface onto interfaces array
141
- $(this).data('qtip').interfaces.push(obj);
142
- }
143
-
144
- // No qTip data is present, create now
145
- else $(this).data('qtip', { current: 0, interfaces: [obj] });
146
-
147
- // If prerendering is disabled, create tooltip on showEvent
148
- if(config.content.prerender === false && config.show.when.event !== false && config.show.ready !== true)
149
- {
150
- config.show.when.target.bind(config.show.when.event+'.qtip-'+id+'-create', { qtip: id }, function(event)
151
- {
152
- // Retrieve API interface via passed qTip Id
153
- api = $.fn.qtip.interfaces[ event.data.qtip ];
154
-
155
- // Unbind show event and cache mouse coords
156
- api.options.show.when.target.unbind(api.options.show.when.event+'.qtip-'+event.data.qtip+'-create');
157
- api.cache.mouse = { x: event.pageX, y: event.pageY };
158
-
159
- // Render tooltip and start the event sequence
160
- construct.call( api );
161
- api.options.show.when.target.trigger(api.options.show.when.event);
162
- });
163
- }
164
-
165
- // Prerendering is enabled, create tooltip now
166
- else
167
- {
168
- // Set mouse position cache to top left of the element
169
- obj.cache.mouse = {
170
- x: config.show.when.target.offset().left,
171
- y: config.show.when.target.offset().top
172
- };
173
-
174
- // Construct the tooltip
175
- construct.call(obj);
176
- }
177
- };
178
- });
179
- };
180
-
181
- // Instantiator
182
- function qTip(target, options, id)
183
- {
184
- // Declare this reference
185
- var self = this;
186
-
187
- // Setup class attributes
188
- self.id = id;
189
- self.options = options;
190
- self.status = {
191
- animated: false,
192
- rendered: false,
193
- disabled: false,
194
- focused: false
195
- };
196
- self.elements = {
197
- target: target.addClass(self.options.style.classes.target),
198
- tooltip: null,
199
- wrapper: null,
200
- content: null,
201
- contentWrapper: null,
202
- title: null,
203
- button: null,
204
- tip: null,
205
- bgiframe: null
206
- };
207
- self.cache = {
208
- mouse: {},
209
- position: {},
210
- toggle: 0
211
- };
212
- self.timers = {};
213
-
214
- // Define exposed API methods
215
- $.extend(self, self.options.api,
216
- {
217
- show: function(event)
218
- {
219
- var returned, solo;
220
-
221
- // Make sure tooltip is rendered and if not, return
222
- if(!self.status.rendered)
223
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'show');
224
-
225
- // Only continue if element is visible
226
- if(self.elements.tooltip.css('display') !== 'none') return self;
227
-
228
- // Clear animation queue
229
- self.elements.tooltip.stop(true, false);
230
-
231
- // Call API method and if return value is false, halt
232
- returned = self.beforeShow.call(self, event);
233
- if(returned === false) return self;
234
-
235
- // Define afterShow callback method
236
- function afterShow()
237
- {
238
- // Call API method and focus if it isn't static
239
- if(self.options.position.type !== 'static') self.focus();
240
- self.onShow.call(self, event);
241
-
242
- // Prevent antialias from disappearing in IE7 by removing filter attribute
243
- if($.browser.msie) self.elements.tooltip.get(0).style.removeAttribute('filter');
244
- };
245
-
246
- // Maintain toggle functionality if enabled
247
- self.cache.toggle = 1;
248
-
249
- // Update tooltip position if it isn't static
250
- if(self.options.position.type !== 'static')
251
- self.updatePosition(event, (self.options.show.effect.length > 0));
252
-
253
- // Hide other tooltips if tooltip is solo
254
- if(typeof self.options.show.solo == 'object') solo = $(self.options.show.solo);
255
- else if(self.options.show.solo === true) solo = $('div.qtip').not(self.elements.tooltip);
256
- if(solo) solo.each(function(){ if($(this).qtip('api').status.rendered === true) $(this).qtip('api').hide(); });
257
-
258
- // Show tooltip
259
- if(typeof self.options.show.effect.type == 'function')
260
- {
261
- self.options.show.effect.type.call(self.elements.tooltip, self.options.show.effect.length);
262
- self.elements.tooltip.queue(function(){ afterShow(); $(this).dequeue(); });
263
- }
264
- else
265
- {
266
- switch(self.options.show.effect.type.toLowerCase())
267
- {
268
- case 'fade':
269
- self.elements.tooltip.fadeIn(self.options.show.effect.length, afterShow);
270
- break;
271
- case 'slide':
272
- self.elements.tooltip.slideDown(self.options.show.effect.length, function()
273
- {
274
- afterShow();
275
- if(self.options.position.type !== 'static') self.updatePosition(event, true);
276
- });
277
- break;
278
- case 'grow':
279
- self.elements.tooltip.show(self.options.show.effect.length, afterShow);
280
- break;
281
- default:
282
- self.elements.tooltip.show(null, afterShow);
283
- break;
284
- };
285
-
286
- // Add active class to tooltip
287
- self.elements.tooltip.addClass(self.options.style.classes.active);
288
- };
289
-
290
- // Log event and return
291
- return $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_SHOWN, 'show');
292
- },
293
-
294
- hide: function(event)
295
- {
296
- var returned;
297
-
298
- // Make sure tooltip is rendered and if not, return
299
- if(!self.status.rendered)
300
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'hide');
301
-
302
- // Only continue if element is visible
303
- else if(self.elements.tooltip.css('display') === 'none') return self;
304
-
305
- // Stop show timer and animation queue
306
- clearTimeout(self.timers.show);
307
- self.elements.tooltip.stop(true, false);
308
-
309
- // Call API method and if return value is false, halt
310
- returned = self.beforeHide.call(self, event);
311
- if(returned === false) return self;
312
-
313
- // Define afterHide callback method
314
- function afterHide(){ self.onHide.call(self, event); };
315
-
316
- // Maintain toggle functionality if enabled
317
- self.cache.toggle = 0;
318
-
319
- // Hide tooltip
320
- if(typeof self.options.hide.effect.type == 'function')
321
- {
322
- self.options.hide.effect.type.call(self.elements.tooltip, self.options.hide.effect.length);
323
- self.elements.tooltip.queue(function(){ afterHide(); $(this).dequeue(); });
324
- }
325
- else
326
- {
327
- switch(self.options.hide.effect.type.toLowerCase())
328
- {
329
- case 'fade':
330
- self.elements.tooltip.fadeOut(self.options.hide.effect.length, afterHide);
331
- break;
332
- case 'slide':
333
- self.elements.tooltip.slideUp(self.options.hide.effect.length, afterHide);
334
- break;
335
- case 'grow':
336
- self.elements.tooltip.hide(self.options.hide.effect.length, afterHide);
337
- break;
338
- default:
339
- self.elements.tooltip.hide(null, afterHide);
340
- break;
341
- };
342
-
343
- // Remove active class to tooltip
344
- self.elements.tooltip.removeClass(self.options.style.classes.active);
345
- };
346
-
347
- // Log event and return
348
- return $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_HIDDEN, 'hide');
349
- },
350
-
351
- updatePosition: function(event, animate)
352
- {
353
- var i, target, tooltip, coords, mapName, imagePos, newPosition, ieAdjust, ie6Adjust, borderAdjust, mouseAdjust, offset, curPosition, returned
354
-
355
- // Make sure tooltip is rendered and if not, return
356
- if(!self.status.rendered)
357
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'updatePosition');
358
-
359
- // If tooltip is static, return
360
- else if(self.options.position.type == 'static')
361
- return $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.CANNOT_POSITION_STATIC, 'updatePosition');
362
-
363
- // Define property objects
364
- target = {
365
- position: { left: 0, top: 0 },
366
- dimensions: { height: 0, width: 0 },
367
- corner: self.options.position.corner.target
368
- };
369
- tooltip = {
370
- position: self.getPosition(),
371
- dimensions: self.getDimensions(),
372
- corner: self.options.position.corner.tooltip
373
- };
374
-
375
- // Target is an HTML element
376
- if(self.options.position.target !== 'mouse')
377
- {
378
- // If the HTML element is AREA, calculate position manually
379
- if(self.options.position.target.get(0).nodeName.toLowerCase() == 'area')
380
- {
381
- // Retrieve coordinates from coords attribute and parse into integers
382
- coords = self.options.position.target.attr('coords').split(',');
383
- for(i = 0; i < coords.length; i++) coords[i] = parseInt(coords[i]);
384
-
385
- // Setup target position object
386
- mapName = self.options.position.target.parent('map').attr('name');
387
- imagePos = $('img[usemap="#'+mapName+'"]:first').offset();
388
- target.position = {
389
- left: Math.floor(imagePos.left + coords[0]),
390
- top: Math.floor(imagePos.top + coords[1])
391
- };
392
-
393
- // Determine width and height of the area
394
- switch(self.options.position.target.attr('shape').toLowerCase())
395
- {
396
- case 'rect':
397
- target.dimensions = {
398
- width: Math.ceil(Math.abs(coords[2] - coords[0])),
399
- height: Math.ceil(Math.abs(coords[3] - coords[1]))
400
- };
401
- break;
402
-
403
- case 'circle':
404
- target.dimensions = {
405
- width: coords[2] + 1,
406
- height: coords[2] + 1
407
- };
408
- break;
409
-
410
- case 'poly':
411
- target.dimensions = {
412
- width: coords[0],
413
- height: coords[1]
414
- };
415
-
416
- for(i = 0; i < coords.length; i++)
417
- {
418
- if(i % 2 == 0)
419
- {
420
- if(coords[i] > target.dimensions.width)
421
- target.dimensions.width = coords[i];
422
- if(coords[i] < coords[0])
423
- target.position.left = Math.floor(imagePos.left + coords[i]);
424
- }
425
- else
426
- {
427
- if(coords[i] > target.dimensions.height)
428
- target.dimensions.height = coords[i];
429
- if(coords[i] < coords[1])
430
- target.position.top = Math.floor(imagePos.top + coords[i]);
431
- };
432
- };
433
-
434
- target.dimensions.width = target.dimensions.width - (target.position.left - imagePos.left);
435
- target.dimensions.height = target.dimensions.height - (target.position.top - imagePos.top);
436
- break;
437
-
438
- default:
439
- return $.fn.qtip.log.error.call(self, 4, $.fn.qtip.constants.INVALID_AREA_SHAPE, 'updatePosition');
440
- break;
441
- };
442
-
443
- // Adjust position by 2 pixels (Positioning bug?)
444
- target.dimensions.width -= 2; target.dimensions.height -= 2;
445
- }
446
-
447
- // Target is the document
448
- else if(self.options.position.target.add(document.body).length === 1)
449
- {
450
- target.position = { left: $(document).scrollLeft(), top: $(document).scrollTop() };
451
- target.dimensions = { height: $(window).height(), width: $(window).width() };
452
- }
453
-
454
- // Target is a regular HTML element, find position normally
455
- else
456
- {
457
- // Check if the target is another tooltip. If its animated, retrieve position from newPosition data
458
- if(typeof self.options.position.target.attr('qtip') !== 'undefined')
459
- target.position = self.options.position.target.qtip('api').cache.position;
460
- else
461
- target.position = self.options.position.target.offset();
462
-
463
- // Setup dimensions objects
464
- target.dimensions = {
465
- height: self.options.position.target.outerHeight(),
466
- width: self.options.position.target.outerWidth()
467
- };
468
- };
469
-
470
- // Calculate correct target corner position
471
- newPosition = $.extend({}, target.position);
472
- if(target.corner.search(/right/i) !== -1)
473
- newPosition.left += target.dimensions.width;
474
-
475
- if(target.corner.search(/bottom/i) !== -1)
476
- newPosition.top += target.dimensions.height;
477
-
478
- if(target.corner.search(/((top|bottom)Middle)|center/) !== -1)
479
- newPosition.left += (target.dimensions.width / 2);
480
-
481
- if(target.corner.search(/((left|right)Middle)|center/) !== -1)
482
- newPosition.top += (target.dimensions.height / 2);
483
- }
484
-
485
- // Mouse is the target, set position to current mouse coordinates
486
- else
487
- {
488
- // Setup target position and dimensions objects
489
- target.position = newPosition = { left: self.cache.mouse.x, top: self.cache.mouse.y };
490
- target.dimensions = { height: 1, width: 1 };
491
- };
492
-
493
- // Calculate correct target corner position
494
- if(tooltip.corner.search(/right/i) !== -1)
495
- newPosition.left -= tooltip.dimensions.width;
496
-
497
- if(tooltip.corner.search(/bottom/i) !== -1)
498
- newPosition.top -= tooltip.dimensions.height;
499
-
500
- if(tooltip.corner.search(/((top|bottom)Middle)|center/) !== -1)
501
- newPosition.left -= (tooltip.dimensions.width / 2);
502
-
503
- if(tooltip.corner.search(/((left|right)Middle)|center/) !== -1)
504
- newPosition.top -= (tooltip.dimensions.height / 2);
505
-
506
- // Setup IE adjustment variables (Pixel gap bugs)
507
- ieAdjust = ($.browser.msie) ? 1 : 0; // And this is why I hate IE...
508
- ie6Adjust = ($.browser.msie && parseInt($.browser.version.charAt(0)) === 6) ? 1 : 0; // ...and even more so IE6!
509
-
510
- // Adjust for border radius
511
- if(self.options.style.border.radius > 0)
512
- {
513
- if(tooltip.corner.search(/Left/) !== -1)
514
- newPosition.left -= self.options.style.border.radius;
515
- else if(tooltip.corner.search(/Right/) !== -1)
516
- newPosition.left += self.options.style.border.radius;
517
-
518
- if(tooltip.corner.search(/Top/) !== -1)
519
- newPosition.top -= self.options.style.border.radius;
520
- else if(tooltip.corner.search(/Bottom/) !== -1)
521
- newPosition.top += self.options.style.border.radius;
522
- };
523
-
524
- // IE only adjustments (Pixel perfect!)
525
- if(ieAdjust)
526
- {
527
- if(tooltip.corner.search(/top/) !== -1)
528
- newPosition.top -= ieAdjust
529
- else if(tooltip.corner.search(/bottom/) !== -1)
530
- newPosition.top += ieAdjust
531
-
532
- if(tooltip.corner.search(/left/) !== -1)
533
- newPosition.left -= ieAdjust
534
- else if(tooltip.corner.search(/right/) !== -1)
535
- newPosition.left += ieAdjust
536
-
537
- if(tooltip.corner.search(/leftMiddle|rightMiddle/) !== -1)
538
- newPosition.top -= 1
539
- };
540
-
541
- // If screen adjustment is enabled, apply adjustments
542
- if(self.options.position.adjust.screen === true)
543
- newPosition = screenAdjust.call(self, newPosition, target, tooltip);
544
-
545
- // If mouse is the target, prevent tooltip appearing directly under the mouse
546
- if(self.options.position.target === 'mouse' && self.options.position.adjust.mouse === true)
547
- {
548
- if(self.options.position.adjust.screen === true && self.elements.tip)
549
- mouseAdjust = self.elements.tip.attr('rel');
550
- else
551
- mouseAdjust = self.options.position.corner.tooltip;
552
-
553
- newPosition.left += (mouseAdjust.search(/right/i) !== -1) ? -6 : 6;
554
- newPosition.top += (mouseAdjust.search(/bottom/i) !== -1) ? -6 : 6;
555
- }
556
-
557
- // Initiate bgiframe plugin in IE6 if tooltip overlaps a select box or object element
558
- if(!self.elements.bgiframe && $.browser.msie && parseInt($.browser.version.charAt(0)) == 6)
559
- {
560
- $('select, object').each(function()
561
- {
562
- offset = $(this).offset();
563
- offset.bottom = offset.top + $(this).height();
564
- offset.right = offset.left + $(this).width();
565
-
566
- if(newPosition.top + tooltip.dimensions.height >= offset.top
567
- && newPosition.left + tooltip.dimensions.width >= offset.left)
568
- bgiframe.call(self);
569
- });
570
- };
571
-
572
- // Add user xy adjustments
573
- newPosition.left += self.options.position.adjust.x;
574
- newPosition.top += self.options.position.adjust.y;
575
-
576
- // Set new tooltip position if its moved, animate if enabled
577
- curPosition = self.getPosition();
578
- if(newPosition.left != curPosition.left || newPosition.top != curPosition.top)
579
- {
580
- // Call API method and if return value is false, halt
581
- returned = self.beforePositionUpdate.call(self, event);
582
- if(returned === false) return self;
583
-
584
- // Cache new position
585
- self.cache.position = newPosition;
586
-
587
- // Check if animation is enabled
588
- if(animate === true)
589
- {
590
- // Set animated status
591
- self.status.animated = true;
592
-
593
- // Animate and reset animated status on animation end
594
- self.elements.tooltip.animate(newPosition, 200, 'swing', function(){ self.status.animated = false });
595
- }
596
-
597
- // Set new position via CSS
598
- else self.elements.tooltip.css(newPosition);
599
-
600
- // Call API method and log event if its not a mouse move
601
- self.onPositionUpdate.call(self, event);
602
- if(typeof event !== 'undefined' && event.type && event.type !== 'mousemove')
603
- $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_POSITION_UPDATED, 'updatePosition');
604
- };
605
-
606
- return self;
607
- },
608
-
609
- updateWidth: function(newWidth)
610
- {
611
- var hidden;
612
-
613
- // Make sure tooltip is rendered and if not, return
614
- if(!self.status.rendered)
615
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'updateWidth');
616
-
617
- // Make sure supplied width is a number and if not, return
618
- else if(newWidth && typeof newWidth !== 'number')
619
- return $.fn.qtip.log.error.call(self, 2, 'newWidth must be of type number', 'updateWidth');
620
-
621
- // Setup elements which must be hidden during width update
622
- hidden = self.elements.contentWrapper.siblings().add(self.elements.tip).add(self.elements.button);
623
-
624
- // Calculate the new width if one is not supplied
625
- if(!newWidth)
626
- {
627
- // Explicit width is set
628
- if(typeof self.options.style.width.value == 'number')
629
- newWidth = self.options.style.width.value;
630
-
631
- // No width is set, proceed with auto detection
632
- else
633
- {
634
- // Set width to auto initally to determine new width and hide other elements
635
- self.elements.tooltip.css({ width: 'auto' });
636
- hidden.hide();
637
-
638
- // Set position and zoom to defaults to prevent IE hasLayout bug
639
- if($.browser.msie)
640
- self.elements.wrapper.add(self.elements.contentWrapper.children()).css({ zoom: 'normal' });
641
-
642
- // Set the new width
643
- newWidth = self.getDimensions().width + 1;
644
-
645
- // Make sure its within the maximum and minimum width boundries
646
- if(!self.options.style.width.value)
647
- {
648
- if(newWidth > self.options.style.width.max) newWidth = self.options.style.width.max
649
- if(newWidth < self.options.style.width.min) newWidth = self.options.style.width.min
650
- };
651
- };
652
- };
653
-
654
- // Adjust newWidth by 1px if width is odd (IE6 rounding bug fix)
655
- if(newWidth % 2 !== 0) newWidth -= 1;
656
-
657
- // Set the new calculated width and unhide other elements
658
- self.elements.tooltip.width(newWidth);
659
- hidden.show();
660
-
661
- // Set the border width, if enabled
662
- if(self.options.style.border.radius)
663
- {
664
- self.elements.tooltip.find('.qtip-betweenCorners').each(function(i)
665
- {
666
- $(this).width(newWidth - (self.options.style.border.radius * 2));
667
- })
668
- };
669
-
670
- // IE only adjustments
671
- if($.browser.msie)
672
- {
673
- // Reset position and zoom to give the wrapper layout (IE hasLayout bug)
674
- self.elements.wrapper.add(self.elements.contentWrapper.children()).css({ zoom: '1' });
675
-
676
- // Set the new width
677
- self.elements.wrapper.width(newWidth);
678
-
679
- // Adjust BGIframe height and width if enabled
680
- if(self.elements.bgiframe) self.elements.bgiframe.width(newWidth).height(self.getDimensions.height);
681
- };
682
-
683
- // Log event and return
684
- return $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_WIDTH_UPDATED, 'updateWidth');
685
- },
686
-
687
- updateStyle: function(name)
688
- {
689
- var tip, borders, context, corner, coordinates;
690
-
691
- // Make sure tooltip is rendered and if not, return
692
- if(!self.status.rendered)
693
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'updateStyle');
694
-
695
- // Return if style is not defined or name is not a string
696
- else if(typeof name !== 'string' || !$.fn.qtip.styles[name])
697
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.STYLE_NOT_DEFINED, 'updateStyle');
698
-
699
- // Set the new style object
700
- self.options.style = buildStyle.call(self, $.fn.qtip.styles[name], self.options.user.style);
701
-
702
- // Update initial styles of content and title elements
703
- self.elements.content.css( jQueryStyle(self.options.style) );
704
- if(self.options.content.title.text !== false)
705
- self.elements.title.css( jQueryStyle(self.options.style.title, true) );
706
-
707
- // Update CSS border colour
708
- self.elements.contentWrapper.css({ borderColor: self.options.style.border.color });
709
-
710
- // Update tip color if enabled
711
- if(self.options.style.tip.corner !== false)
712
- {
713
- if($('<canvas>').get(0).getContext)
714
- {
715
- // Retrieve canvas context and clear
716
- tip = self.elements.tooltip.find('.qtip-tip canvas:first');
717
- context = tip.get(0).getContext('2d');
718
- context.clearRect(0,0,300,300);
719
-
720
- // Draw new tip
721
- corner = tip.parent('div[rel]:first').attr('rel');
722
- coordinates = calculateTip(corner, self.options.style.tip.size.width, self.options.style.tip.size.height);
723
- drawTip.call(self, tip, coordinates, self.options.style.tip.color || self.options.style.border.color);
724
- }
725
- else if($.browser.msie)
726
- {
727
- // Set new fillcolor attribute
728
- tip = self.elements.tooltip.find('.qtip-tip [nodeName="shape"]');
729
- tip.attr('fillcolor', self.options.style.tip.color || self.options.style.border.color);
730
- };
731
- };
732
-
733
- // Update border colors if enabled
734
- if(self.options.style.border.radius > 0)
735
- {
736
- self.elements.tooltip.find('.qtip-betweenCorners').css({ backgroundColor: self.options.style.border.color });
737
-
738
- if($('<canvas>').get(0).getContext)
739
- {
740
- borders = calculateBorders(self.options.style.border.radius)
741
- self.elements.tooltip.find('.qtip-wrapper canvas').each(function()
742
- {
743
- // Retrieve canvas context and clear
744
- context = $(this).get(0).getContext('2d');
745
- context.clearRect(0,0,300,300);
746
-
747
- // Draw new border
748
- corner = $(this).parent('div[rel]:first').attr('rel')
749
- drawBorder.call(self, $(this), borders[corner],
750
- self.options.style.border.radius, self.options.style.border.color);
751
- });
752
- }
753
- else if($.browser.msie)
754
- {
755
- // Set new fillcolor attribute on each border corner
756
- self.elements.tooltip.find('.qtip-wrapper [nodeName="arc"]').each(function()
757
- {
758
- $(this).attr('fillcolor', self.options.style.border.color)
759
- });
760
- };
761
- };
762
-
763
- // Log event and return
764
- return $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_STYLE_UPDATED, 'updateStyle');
765
- },
766
-
767
- updateContent: function(content, reposition)
768
- {
769
- var parsedContent, images, loadedImages;
770
-
771
- // Make sure tooltip is rendered and if not, return
772
- if(!self.status.rendered)
773
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'updateContent');
774
-
775
- // Make sure content is defined before update
776
- else if(!content)
777
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.NO_CONTENT_PROVIDED, 'updateContent');
778
-
779
- // Call API method and set new content if a string is returned
780
- parsedContent = self.beforeContentUpdate.call(self, content);
781
- if(typeof parsedContent == 'string') content = parsedContent;
782
- else if(parsedContent === false) return;
783
-
784
- // Set position and zoom to defaults to prevent IE hasLayout bug
785
- if($.browser.msie) self.elements.contentWrapper.children().css({ zoom: 'normal' });
786
-
787
- // Append new content if its a DOM array and show it if hidden
788
- if(content.jquery && content.length > 0)
789
- content.clone(true).appendTo(self.elements.content).show();
790
-
791
- // Content is a regular string, insert the new content
792
- else self.elements.content.html(content);
793
-
794
- // Check if images need to be loaded before position is updated to prevent mis-positioning
795
- images = self.elements.content.find('img[complete=false]');
796
- if(images.length > 0)
797
- {
798
- loadedImages = 0;
799
- images.each(function(i)
800
- {
801
- $('<img src="'+ $(this).attr('src') +'" />')
802
- .load(function(){ if(++loadedImages == images.length) afterLoad(); });
803
- });
804
- }
805
- else afterLoad();
806
-
807
- function afterLoad()
808
- {
809
- // Update the tooltip width
810
- self.updateWidth();
811
-
812
- // If repositioning is enabled, update positions
813
- if(reposition !== false)
814
- {
815
- // Update position if tooltip isn't static
816
- if(self.options.position.type !== 'static')
817
- self.updatePosition(self.elements.tooltip.is(':visible'), true);
818
-
819
- // Reposition the tip if enabled
820
- if(self.options.style.tip.corner !== false)
821
- positionTip.call(self);
822
- };
823
- };
824
-
825
- // Call API method and log event
826
- self.onContentUpdate.call(self);
827
- return $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_CONTENT_UPDATED, 'loadContent');
828
- },
829
-
830
- loadContent: function(url, data, method)
831
- {
832
- var returned;
833
-
834
- // Make sure tooltip is rendered and if not, return
835
- if(!self.status.rendered)
836
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'loadContent');
837
-
838
- // Call API method and if return value is false, halt
839
- returned = self.beforeContentLoad.call(self);
840
- if(returned === false) return self;
841
-
842
- // Load content using specified request type
843
- if(method == 'post')
844
- $.post(url, data, setupContent);
845
- else
846
- $.get(url, data, setupContent);
847
-
848
- function setupContent(content)
849
- {
850
- // Call API method and log event
851
- self.onContentLoad.call(self);
852
- $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_CONTENT_LOADED, 'loadContent');
853
-
854
- // Update the content
855
- self.updateContent(content);
856
- };
857
-
858
- return self;
859
- },
860
-
861
- updateTitle: function(content)
862
- {
863
- // Make sure tooltip is rendered and if not, return
864
- if(!self.status.rendered)
865
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'updateTitle');
866
-
867
- // Make sure content is defined before update
868
- else if(!content)
869
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.NO_CONTENT_PROVIDED, 'updateTitle');
870
-
871
- // Call API method and if return value is false, halt
872
- returned = self.beforeTitleUpdate.call(self);
873
- if(returned === false) return self;
874
-
875
- // Set the new content and reappend the button if enabled
876
- if(self.elements.button) self.elements.button = self.elements.button.clone(true);
877
- self.elements.title.html(content)
878
- if(self.elements.button) self.elements.title.prepend(self.elements.button);
879
-
880
- // Call API method and log event
881
- self.onTitleUpdate.call(self);
882
- return $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_TITLE_UPDATED, 'updateTitle');
883
- },
884
-
885
- focus: function(event)
886
- {
887
- var curIndex, newIndex, elemIndex, returned;
888
-
889
- // Make sure tooltip is rendered and if not, return
890
- if(!self.status.rendered)
891
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'focus');
892
-
893
- else if(self.options.position.type == 'static')
894
- return $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.CANNOT_FOCUS_STATIC, 'focus');
895
-
896
- // Set z-index variables
897
- curIndex = parseInt( self.elements.tooltip.css('z-index') );
898
- newIndex = 6000 + $('div.qtip[qtip]').length - 1;
899
-
900
- // Only update the z-index if it has changed and tooltip is not already focused
901
- if(!self.status.focused && curIndex !== newIndex)
902
- {
903
- // Call API method and if return value is false, halt
904
- returned = self.beforeFocus.call(self, event);
905
- if(returned === false) return self;
906
-
907
- // Loop through all other tooltips
908
- $('div.qtip[qtip]').not(self.elements.tooltip).each(function()
909
- {
910
- if($(this).qtip('api').status.rendered === true)
911
- {
912
- elemIndex = parseInt($(this).css('z-index'));
913
-
914
- // Reduce all other tooltip z-index by 1
915
- if(typeof elemIndex == 'number' && elemIndex > -1)
916
- $(this).css({ zIndex: parseInt( $(this).css('z-index') ) - 1 });
917
-
918
- // Set focused status to false
919
- $(this).qtip('api').status.focused = false;
920
- }
921
- })
922
-
923
- // Set the new z-index and set focus status to true
924
- self.elements.tooltip.css({ zIndex: newIndex });
925
- self.status.focused = true;
926
-
927
- // Call API method and log event
928
- self.onFocus.call(self, event);
929
- $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_FOCUSED, 'focus');
930
- };
931
-
932
- return self;
933
- },
934
-
935
- disable: function(state)
936
- {
937
- // Make sure tooltip is rendered and if not, return
938
- if(!self.status.rendered)
939
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'disable');
940
-
941
- if(state)
942
- {
943
- // Tooltip is not already disabled, proceed
944
- if(!self.status.disabled)
945
- {
946
- // Set the disabled flag and log event
947
- self.status.disabled = true;
948
- $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_DISABLED, 'disable');
949
- }
950
-
951
- // Tooltip is already disabled, inform user via log
952
- else $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.TOOLTIP_ALREADY_DISABLED, 'disable');
953
- }
954
- else
955
- {
956
- // Tooltip is not already enabled, proceed
957
- if(self.status.disabled)
958
- {
959
- // Reassign events, set disable status and log
960
- self.status.disabled = false;
961
- $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_ENABLED, 'disable');
962
- }
963
-
964
- // Tooltip is already enabled, inform the user via log
965
- else $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.TOOLTIP_ALREADY_ENABLED, 'disable');
966
- };
967
-
968
- return self;
969
- },
970
-
971
- destroy: function()
972
- {
973
- var i, returned, interfaces;
974
-
975
- // Call API method and if return value is false, halt
976
- returned = self.beforeDestroy.call(self);
977
- if(returned === false) return self;
978
-
979
- // Check if tooltip is rendered
980
- if(self.status.rendered)
981
- {
982
- // Remove event handlers and remove element
983
- self.options.show.when.target.unbind('mousemove.qtip', self.updatePosition);
984
- self.options.show.when.target.unbind('mouseout.qtip', self.hide);
985
- self.options.show.when.target.unbind(self.options.show.when.event + '.qtip');
986
- self.options.hide.when.target.unbind(self.options.hide.when.event + '.qtip');
987
- self.elements.tooltip.unbind(self.options.hide.when.event + '.qtip');
988
- self.elements.tooltip.unbind('mouseover.qtip', self.focus);
989
- self.elements.tooltip.remove();
990
- }
991
-
992
- // Tooltip isn't yet rendered, remove render event
993
- else self.options.show.when.target.unbind(self.options.show.when.event+'.qtip-create');
994
-
995
- // Check to make sure qTip data is present on target element
996
- if(typeof self.elements.target.data('qtip') == 'object')
997
- {
998
- // Remove API references from interfaces object
999
- interfaces = self.elements.target.data('qtip').interfaces;
1000
- if(typeof interfaces == 'object' && interfaces.length > 0)
1001
- {
1002
- // Remove API from interfaces array
1003
- for(i = 0; i < interfaces.length - 1; i++)
1004
- if(interfaces[i].id == self.id) interfaces.splice(i, 1)
1005
- }
1006
- }
1007
- delete $.fn.qtip.interfaces[self.id];
1008
-
1009
- // Set qTip current id to previous tooltips API if available
1010
- if(typeof interfaces == 'object' && interfaces.length > 0)
1011
- self.elements.target.data('qtip').current = interfaces.length -1;
1012
- else
1013
- self.elements.target.removeData('qtip');
1014
-
1015
- // Call API method and log destroy
1016
- self.onDestroy.call(self);
1017
- $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_DESTROYED, 'destroy');
1018
-
1019
- return self.elements.target
1020
- },
1021
-
1022
- getPosition: function()
1023
- {
1024
- var show, offset;
1025
-
1026
- // Make sure tooltip is rendered and if not, return
1027
- if(!self.status.rendered)
1028
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'getPosition');
1029
-
1030
- show = (self.elements.tooltip.css('display') !== 'none') ? false : true;
1031
-
1032
- // Show and hide tooltip to make sure coordinates are returned
1033
- if(show) self.elements.tooltip.css({ visiblity: 'hidden' }).show();
1034
- offset = self.elements.tooltip.offset();
1035
- if(show) self.elements.tooltip.css({ visiblity: 'visible' }).hide();
1036
-
1037
- return offset;
1038
- },
1039
-
1040
- getDimensions: function()
1041
- {
1042
- var show, dimensions;
1043
-
1044
- // Make sure tooltip is rendered and if not, return
1045
- if(!self.status.rendered)
1046
- return $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.TOOLTIP_NOT_RENDERED, 'getDimensions');
1047
-
1048
- show = (!self.elements.tooltip.is(':visible')) ? true : false;
1049
-
1050
- // Show and hide tooltip to make sure dimensions are returned
1051
- if(show) self.elements.tooltip.css({ visiblity: 'hidden' }).show();
1052
- dimensions = {
1053
- height: self.elements.tooltip.outerHeight(),
1054
- width: self.elements.tooltip.outerWidth()
1055
- };
1056
- if(show) self.elements.tooltip.css({ visiblity: 'visible' }).hide();
1057
-
1058
- return dimensions;
1059
- }
1060
- });
1061
- };
1062
-
1063
- // Define priamry construct function
1064
- function construct()
1065
- {
1066
- var self, adjust, content, url, data, method, tempLength;
1067
- self = this;
1068
-
1069
- // Call API method
1070
- self.beforeRender.call(self);
1071
-
1072
- // Set rendered status to true
1073
- self.status.rendered = true;
1074
-
1075
- // Create initial tooltip elements
1076
- self.elements.tooltip = '<div qtip="'+self.id+'" ' +
1077
- 'class="qtip '+(self.options.style.classes.tooltip || self.options.style)+'"' +
1078
- 'style="display:none; -moz-border-radius:0; -webkit-border-radius:0; border-radius:0;' +
1079
- 'position:'+self.options.position.type+';">' +
1080
- ' <div class="qtip-wrapper" style="position:relative; overflow:hidden; text-align:left;">' +
1081
- ' <div class="qtip-contentWrapper" style="overflow:hidden;">' +
1082
- ' <div class="qtip-content '+self.options.style.classes.content+'"></div>' +
1083
- '</div></div></div>';
1084
-
1085
- // Append to container element
1086
- self.elements.tooltip = $(self.elements.tooltip);
1087
- self.elements.tooltip.appendTo(self.options.position.container)
1088
-
1089
- // Setup tooltip qTip data
1090
- self.elements.tooltip.data('qtip', { current: 0, interfaces: [self] });
1091
-
1092
- // Setup element references
1093
- self.elements.wrapper = self.elements.tooltip.children('div:first');
1094
- self.elements.contentWrapper = self.elements.wrapper.children('div:first').css({ background: self.options.style.background });
1095
- self.elements.content = self.elements.contentWrapper.children('div:first').css( jQueryStyle(self.options.style) );
1096
-
1097
- // Apply IE hasLayout fix to wrapper and content elements
1098
- if($.browser.msie) self.elements.wrapper.add(self.elements.content).css({ zoom: 1 });
1099
-
1100
- // Setup tooltip attributes
1101
- if(self.options.hide.when.event == 'unfocus') self.elements.tooltip.attr('unfocus', true);
1102
-
1103
- // If an explicit width is set, updateWidth prior to setting content to prevent dirty rendering
1104
- if(typeof self.options.style.width.value == 'number') self.updateWidth();
1105
-
1106
- // Create borders and tips if supported by the browser
1107
- if($('<canvas>').get(0).getContext || $.browser.msie)
1108
- {
1109
- // Create border
1110
- if(self.options.style.border.radius > 0)
1111
- createBorder.call(self);
1112
- else
1113
- self.elements.contentWrapper.css({ border: self.options.style.border.width+'px solid '+self.options.style.border.color });
1114
-
1115
- // Create tip if enabled
1116
- if(self.options.style.tip.corner !== false)
1117
- createTip.call(self);
1118
- }
1119
-
1120
- // Neither canvas or VML is supported, tips and borders cannot be drawn!
1121
- else
1122
- {
1123
- // Set defined border width
1124
- self.elements.contentWrapper.css({ border: self.options.style.border.width+'px solid '+self.options.style.border.color });
1125
-
1126
- // Reset border radius and tip
1127
- self.options.style.border.radius = 0;
1128
- self.options.style.tip.corner = false;
1129
-
1130
- // Inform via log
1131
- $.fn.qtip.log.error.call(self, 2, $.fn.qtip.constants.CANVAS_VML_NOT_SUPPORTED, 'render');
1132
- };
1133
-
1134
- // Use the provided content string or DOM array
1135
- if((typeof self.options.content.text == 'string' && self.options.content.text.length > 0)
1136
- || (self.options.content.text.jquery && self.options.content.text.length > 0))
1137
- content = self.options.content.text;
1138
-
1139
- // Use title string for content if present
1140
- else if(typeof self.elements.target.attr('title') == 'string' && self.elements.target.attr('title').length > 0)
1141
- {
1142
- content = self.elements.target.attr('title').replace("\\n", '<br />');
1143
- self.elements.target.attr('title', ''); // Remove title attribute to prevent default tooltip showing
1144
- }
1145
-
1146
- // No title is present, use alt attribute instead
1147
- else if(typeof self.elements.target.attr('alt') == 'string' && self.elements.target.attr('alt').length > 0)
1148
- {
1149
- content = self.elements.target.attr('alt').replace("\\n", '<br />');
1150
- self.elements.target.attr('alt', ''); // Remove alt attribute to prevent default tooltip showing
1151
- }
1152
-
1153
- // No valid content was provided, inform via log
1154
- else
1155
- {
1156
- content = ' ';
1157
- $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.NO_VALID_CONTENT, 'render');
1158
- };
1159
-
1160
- // Set the tooltips content and create title if enabled
1161
- if(self.options.content.title.text !== false) createTitle.call(self);
1162
- self.updateContent(content);
1163
-
1164
- // Assign events and toggle tooltip with focus
1165
- assignEvents.call(self);
1166
- if(self.options.show.ready === true) self.show();
1167
-
1168
- // Retrieve ajax content if provided
1169
- if(self.options.content.url !== false)
1170
- {
1171
- url = self.options.content.url;
1172
- data = self.options.content.data;
1173
- method = self.options.content.method || 'get';
1174
- self.loadContent(url, data, method);
1175
- };
1176
-
1177
- // Call API method and log event
1178
- self.onRender.call(self);
1179
- $.fn.qtip.log.error.call(self, 1, $.fn.qtip.constants.EVENT_RENDERED, 'render');
1180
- };
1181
-
1182
- // Create borders using canvas and VML
1183
- function createBorder()
1184
- {
1185
- var self, i, width, radius, color, coordinates, containers, size, betweenWidth, betweenCorners, borderTop, borderBottom, borderCoord, sideWidth, vertWidth;
1186
- self = this;
1187
-
1188
- // Destroy previous border elements, if present
1189
- self.elements.wrapper.find('.qtip-borderBottom, .qtip-borderTop').remove();
1190
-
1191
- // Setup local variables
1192
- width = self.options.style.border.width;
1193
- radius = self.options.style.border.radius;
1194
- color = self.options.style.border.color || self.options.style.tip.color;
1195
-
1196
- // Calculate border coordinates
1197
- coordinates = calculateBorders(radius);
1198
-
1199
- // Create containers for the border shapes
1200
- containers = {};
1201
- for(i in coordinates)
1202
- {
1203
- // Create shape container
1204
- containers[i] = '<div rel="'+i+'" style="'+((i.search(/Left/) !== -1) ? 'left' : 'right') + ':0; ' +
1205
- 'position:absolute; height:'+radius+'px; width:'+radius+'px; overflow:hidden; line-height:0.1px; font-size:1px">';
1206
-
1207
- // Canvas is supported
1208
- if($('<canvas>').get(0).getContext)
1209
- containers[i] += '<canvas height="'+radius+'" width="'+radius+'" style="vertical-align: top"></canvas>';
1210
-
1211
- // No canvas, but if it's IE use VML
1212
- else if($.browser.msie)
1213
- {
1214
- size = radius * 2 + 3;
1215
- containers[i] += '<v:arc stroked="false" fillcolor="'+color+'" startangle="'+coordinates[i][0]+'" endangle="'+coordinates[i][1]+'" ' +
1216
- 'style="width:'+size+'px; height:'+size+'px; margin-top:'+((i.search(/bottom/) !== -1) ? -2 : -1)+'px; ' +
1217
- 'margin-left:'+((i.search(/Right/) !== -1) ? coordinates[i][2] - 3.5 : -1)+'px; ' +
1218
- 'vertical-align:top; display:inline-block; behavior:url(#default#VML)"></v:arc>';
1219
-
1220
- };
1221
-
1222
- containers[i] += '</div>';
1223
- };
1224
-
1225
- // Create between corners elements
1226
- betweenWidth = self.getDimensions().width - (Math.max(width, radius) * 2);
1227
- betweenCorners = '<div class="qtip-betweenCorners" style="height:'+radius+'px; width:'+betweenWidth+'px; ' +
1228
- 'overflow:hidden; background-color:'+color+'; line-height:0.1px; font-size:1px;">';
1229
-
1230
- // Create top border container
1231
- borderTop = '<div class="qtip-borderTop" dir="ltr" style="height:'+radius+'px; ' +
1232
- 'margin-left:'+radius+'px; line-height:0.1px; font-size:1px; padding:0;">' +
1233
- containers['topLeft'] + containers['topRight'] + betweenCorners;
1234
- self.elements.wrapper.prepend(borderTop);
1235
-
1236
- // Create bottom border container
1237
- borderBottom = '<div class="qtip-borderBottom" dir="ltr" style="height:'+radius+'px; ' +
1238
- 'margin-left:'+radius+'px; line-height:0.1px; font-size:1px; padding:0;">' +
1239
- containers['bottomLeft'] + containers['bottomRight'] + betweenCorners;
1240
- self.elements.wrapper.append(borderBottom);
1241
-
1242
- // Draw the borders if canvas were used (Delayed til after DOM creation)
1243
- if($('<canvas>').get(0).getContext)
1244
- {
1245
- self.elements.wrapper.find('canvas').each(function()
1246
- {
1247
- borderCoord = coordinates[ $(this).parent('[rel]:first').attr('rel') ];
1248
- drawBorder.call(self, $(this), borderCoord, radius, color);
1249
- })
1250
- }
1251
-
1252
- // Create a phantom VML element (IE won't show the last created VML element otherwise)
1253
- else if($.browser.msie) self.elements.tooltip.append('<v:image style="behavior:url(#default#VML);"></v:image>');
1254
-
1255
- // Setup contentWrapper border
1256
- sideWidth = Math.max(radius, (radius + (width - radius)) )
1257
- vertWidth = Math.max(width - radius, 0);
1258
- self.elements.contentWrapper.css({
1259
- border: '0px solid ' + color,
1260
- borderWidth: vertWidth + 'px ' + sideWidth + 'px'
1261
- })
1262
- };
1263
-
1264
- // Border canvas draw method
1265
- function drawBorder(canvas, coordinates, radius, color)
1266
- {
1267
- // Create corner
1268
- var context = canvas.get(0).getContext('2d');
1269
- context.fillStyle = color;
1270
- context.beginPath();
1271
- context.arc(coordinates[0], coordinates[1], radius, 0, Math.PI * 2, false);
1272
- context.fill();
1273
- };
1274
-
1275
- // Create tip using canvas and VML
1276
- function createTip(corner)
1277
- {
1278
- var self, color, coordinates, coordsize, path;
1279
- self = this;
1280
-
1281
- // Destroy previous tip, if there is one
1282
- if(self.elements.tip !== null) self.elements.tip.remove();
1283
-
1284
- // Setup color and corner values
1285
- color = self.options.style.tip.color || self.options.style.border.color;
1286
- if(self.options.style.tip.corner === false) return;
1287
- else if(!corner) corner = self.options.style.tip.corner;
1288
-
1289
- // Calculate tip coordinates
1290
- coordinates = calculateTip(corner, self.options.style.tip.size.width, self.options.style.tip.size.height);
1291
-
1292
- // Create tip element
1293
- self.elements.tip = '<div class="'+self.options.style.classes.tip+'" dir="ltr" rel="'+corner+'" style="position:absolute; ' +
1294
- 'height:'+self.options.style.tip.size.height+'px; width:'+self.options.style.tip.size.width+'px; ' +
1295
- 'margin:0 auto; line-height:0.1px; font-size:1px;">';
1296
-
1297
- // Use canvas element if supported
1298
- if($('<canvas>').get(0).getContext)
1299
- self.elements.tip += '<canvas height="'+self.options.style.tip.size.height+'" width="'+self.options.style.tip.size.width+'"></canvas>';
1300
-
1301
- // Canvas not supported - Use VML (IE)
1302
- else if($.browser.msie)
1303
- {
1304
- // Create coordize and tip path using tip coordinates
1305
- coordsize = self.options.style.tip.size.width + ',' + self.options.style.tip.size.height;
1306
- path = 'm' + coordinates[0][0] + ',' + coordinates[0][1];
1307
- path += ' l' + coordinates[1][0] + ',' + coordinates[1][1];
1308
- path += ' ' + coordinates[2][0] + ',' + coordinates[2][1];
1309
- path += ' xe';
1310
-
1311
- // Create VML element
1312
- self.elements.tip += '<v:shape fillcolor="'+color+'" stroked="false" filled="true" path="'+path+'" coordsize="'+coordsize+'" ' +
1313
- 'style="width:'+self.options.style.tip.size.width+'px; height:'+self.options.style.tip.size.height+'px; ' +
1314
- 'line-height:0.1px; display:inline-block; behavior:url(#default#VML); ' +
1315
- 'vertical-align:'+((corner.search(/top/) !== -1) ? 'bottom' : 'top')+'"></v:shape>';
1316
-
1317
- // Create a phantom VML element (IE won't show the last created VML element otherwise)
1318
- self.elements.tip += '<v:image style="behavior:url(#default#VML);"></v:image>';
1319
-
1320
- // Prevent tooltip appearing above the content (IE z-index bug)
1321
- self.elements.contentWrapper.css('position', 'relative');
1322
- };
1323
-
1324
- // Attach new tip to tooltip element
1325
- self.elements.tooltip.prepend(self.elements.tip + '</div>');
1326
-
1327
- // Create element reference and draw the canvas tip (Delayed til after DOM creation)
1328
- self.elements.tip = self.elements.tooltip.find('.'+self.options.style.classes.tip).eq(0);
1329
- if($('<canvas>').get(0).getContext)
1330
- drawTip.call(self, self.elements.tip.find('canvas:first'), coordinates, color);
1331
-
1332
- // Fix IE small tip bug
1333
- if(corner.search(/top/) !== -1 && $.browser.msie && parseInt($.browser.version.charAt(0)) === 6)
1334
- self.elements.tip.css({ marginTop: -4 });
1335
-
1336
- // Set the tip position
1337
- positionTip.call(self, corner);
1338
- };
1339
-
1340
- // Canvas tip drawing method
1341
- function drawTip(canvas, coordinates, color)
1342
- {
1343
- // Setup properties
1344
- var context = canvas.get(0).getContext('2d');
1345
- context.fillStyle = color;
1346
-
1347
- // Create tip
1348
- context.beginPath();
1349
- context.moveTo(coordinates[0][0], coordinates[0][1]);
1350
- context.lineTo(coordinates[1][0], coordinates[1][1]);
1351
- context.lineTo(coordinates[2][0], coordinates[2][1]);
1352
- context.fill();
1353
- };
1354
-
1355
- function positionTip(corner)
1356
- {
1357
- var self, ieAdjust, paddingCorner, paddingSize, newMargin;
1358
- self = this;
1359
-
1360
- // Return if tips are disabled or tip is not yet rendered
1361
- if(self.options.style.tip.corner === false || !self.elements.tip) return;
1362
- if(!corner) corner = self.elements.tip.attr('rel');
1363
-
1364
- // Setup adjustment variables
1365
- ieAdjust = positionAdjust = ($.browser.msie) ? 1 : 0;
1366
-
1367
- // Set initial position
1368
- self.elements.tip.css(corner.match(/left|right|top|bottom/)[0], 0);
1369
-
1370
- // Set position of tip to correct side
1371
- if(corner.search(/top|bottom/) !== -1)
1372
- {
1373
- // Adjustments for IE6 - 0.5px border gap bug
1374
- if($.browser.msie)
1375
- {
1376
- if(parseInt($.browser.version.charAt(0)) === 6)
1377
- positionAdjust = (corner.search(/top/) !== -1) ? -3 : 1;
1378
- else
1379
- positionAdjust = (corner.search(/top/) !== -1) ? 1 : 2;
1380
- };
1381
-
1382
- if(corner.search(/Middle/) !== -1)
1383
- self.elements.tip.css({ left: '50%', marginLeft: -(self.options.style.tip.size.width / 2) });
1384
-
1385
- else if(corner.search(/Left/) !== -1)
1386
- self.elements.tip.css({ left: self.options.style.border.radius - ieAdjust });
1387
-
1388
- else if(corner.search(/Right/) !== -1)
1389
- self.elements.tip.css({ right: self.options.style.border.radius + ieAdjust });
1390
-
1391
- if(corner.search(/top/) !== -1)
1392
- self.elements.tip.css({ top: -positionAdjust });
1393
- else
1394
- self.elements.tip.css({ bottom: positionAdjust });
1395
-
1396
- }
1397
- else if(corner.search(/left|right/) !== -1)
1398
- {
1399
- // Adjustments for IE6 - 0.5px border gap bug
1400
- if($.browser.msie)
1401
- positionAdjust = (parseInt($.browser.version.charAt(0)) === 6) ? 1 : ((corner.search(/left/) !== -1) ? 1 : 2);
1402
-
1403
- if(corner.search(/Middle/) !== -1)
1404
- self.elements.tip.css({ top: '50%', marginTop: -(self.options.style.tip.size.height / 2) });
1405
-
1406
- else if(corner.search(/Top/) !== -1)
1407
- self.elements.tip.css({ top: self.options.style.border.radius - ieAdjust });
1408
-
1409
- else if(corner.search(/Bottom/) !== -1)
1410
- self.elements.tip.css({ bottom: self.options.style.border.radius + ieAdjust });
1411
-
1412
- if(corner.search(/left/) !== -1)
1413
- self.elements.tip.css({ left: -positionAdjust });
1414
- else
1415
- self.elements.tip.css({ right: positionAdjust });
1416
- };
1417
-
1418
- // Adjust tooltip padding to compensate for tip
1419
- paddingCorner = 'padding-' + corner.match(/left|right|top|bottom/)[0];
1420
- paddingSize = self.options.style.tip.size[ (paddingCorner.search(/left|right/) !== -1) ? 'width' : 'height' ];
1421
- self.elements.tooltip.css('padding', 0);
1422
- self.elements.tooltip.css(paddingCorner, paddingSize);
1423
-
1424
- // Match content margin to prevent gap bug in IE6 ONLY
1425
- if($.browser.msie && parseInt($.browser.version.charAt(0)) == 6)
1426
- {
1427
- newMargin = parseInt(self.elements.tip.css('margin-top')) || 0;
1428
- newMargin += parseInt(self.elements.content.css('margin-top')) || 0;
1429
-
1430
- self.elements.tip.css({ marginTop: newMargin });
1431
- };
1432
- };
1433
-
1434
- // Create title bar for content
1435
- function createTitle()
1436
- {
1437
- var self = this;
1438
-
1439
- // Destroy previous title element, if present
1440
- if(self.elements.title !== null) self.elements.title.remove();
1441
-
1442
- // Create title element
1443
- self.elements.title = $('<div class="'+self.options.style.classes.title+'">')
1444
- .css( jQueryStyle(self.options.style.title, true) )
1445
- .css({ zoom: ($.browser.msie) ? 1 : 0 })
1446
- .prependTo(self.elements.contentWrapper);
1447
-
1448
- // Update title with contents if enabled
1449
- if(self.options.content.title.text) self.updateTitle.call(self, self.options.content.title.text);
1450
-
1451
- // Create title close buttons if enabled
1452
- if(self.options.content.title.button !== false
1453
- && typeof self.options.content.title.button == 'string')
1454
- {
1455
- self.elements.button = $('<a class="'+self.options.style.classes.button+'" style="float:right; position: relative"></a>')
1456
- .css( jQueryStyle(self.options.style.button, true) )
1457
- .html(self.options.content.title.button)
1458
- .prependTo(self.elements.title)
1459
- .click(function(event){ if(!self.status.disabled) self.hide(event) });
1460
- };
1461
- };
1462
-
1463
- // Assign hide and show events
1464
- function assignEvents()
1465
- {
1466
- var self, showTarget, hideTarget, inactiveEvents;
1467
- self = this;
1468
-
1469
- // Setup event target variables
1470
- showTarget = self.options.show.when.target;
1471
- hideTarget = self.options.hide.when.target;
1472
-
1473
- // Add tooltip as a hideTarget is its fixed
1474
- if(self.options.hide.fixed) hideTarget = hideTarget.add(self.elements.tooltip);
1475
-
1476
- // Check if the hide event is special 'inactive' type
1477
- if(self.options.hide.when.event == 'inactive')
1478
- {
1479
- // Define events which reset the 'inactive' event handler
1480
- inactiveEvents = ['click', 'dblclick', 'mousedown', 'mouseup', 'mousemove',
1481
- 'mouseout', 'mouseenter', 'mouseleave', 'mouseover' ];
1482
-
1483
- // Define 'inactive' event timer method
1484
- function inactiveMethod(event)
1485
- {
1486
- if(self.status.disabled === true) return;
1487
-
1488
- //Clear and reset the timer
1489
- clearTimeout(self.timers.inactive);
1490
- self.timers.inactive = setTimeout(function()
1491
- {
1492
- // Unassign 'inactive' events
1493
- $(inactiveEvents).each(function()
1494
- {
1495
- hideTarget.unbind(this+'.qtip-inactive');
1496
- self.elements.content.unbind(this+'.qtip-inactive');
1497
- });
1498
-
1499
- // Hide the tooltip
1500
- self.hide(event);
1501
- }
1502
- , self.options.hide.delay);
1503
- };
1504
- }
1505
-
1506
- // Check if the tooltip is 'fixed'
1507
- else if(self.options.hide.fixed === true)
1508
- {
1509
- self.elements.tooltip.bind('mouseover.qtip', function()
1510
- {
1511
- if(self.status.disabled === true) return;
1512
-
1513
- // Reset the hide timer
1514
- clearTimeout(self.timers.hide);
1515
- });
1516
- };
1517
-
1518
- // Define show event method
1519
- function showMethod(event)
1520
- {
1521
- if(self.status.disabled === true) return;
1522
-
1523
- // If set, hide tooltip when inactive for delay period
1524
- if(self.options.hide.when.event == 'inactive')
1525
- {
1526
- // Assign each reset event
1527
- $(inactiveEvents).each(function()
1528
- {
1529
- hideTarget.bind(this+'.qtip-inactive', inactiveMethod);
1530
- self.elements.content.bind(this+'.qtip-inactive', inactiveMethod);
1531
- });
1532
-
1533
- // Start the inactive timer
1534
- inactiveMethod();
1535
- };
1536
-
1537
- // Clear hide timers
1538
- clearTimeout(self.timers.show);
1539
- clearTimeout(self.timers.hide);
1540
-
1541
- // Start show timer
1542
- self.timers.show = setTimeout(function(){ self.show(event); }, self.options.show.delay);
1543
- };
1544
-
1545
- // Define hide event method
1546
- function hideMethod(event)
1547
- {
1548
- if(self.status.disabled === true) return;
1549
-
1550
- // Prevent hiding if tooltip is fixed and event target is the tooltip
1551
- if(self.options.hide.fixed === true
1552
- && self.options.hide.when.event.search(/mouse(out|leave)/i) !== -1
1553
- && $(event.relatedTarget).parents('div.qtip[qtip]').length > 0)
1554
- {
1555
- // Prevent default and popagation
1556
- event.stopPropagation();
1557
- event.preventDefault();
1558
-
1559
- // Reset the hide timer
1560
- clearTimeout(self.timers.hide);
1561
- return false;
1562
- };
1563
-
1564
- // Clear timers and stop animation queue
1565
- clearTimeout(self.timers.show);
1566
- clearTimeout(self.timers.hide);
1567
- self.elements.tooltip.stop(true, true);
1568
-
1569
- // If tooltip has displayed, start hide timer
1570
- self.timers.hide = setTimeout(function(){ self.hide(event); }, self.options.hide.delay);
1571
- };
1572
-
1573
- // Both events and targets are identical, apply events using a toggle
1574
- if((self.options.show.when.target.add(self.options.hide.when.target).length === 1
1575
- && self.options.show.when.event == self.options.hide.when.event
1576
- && self.options.hide.when.event !== 'inactive')
1577
- || self.options.hide.when.event == 'unfocus')
1578
- {
1579
- self.cache.toggle = 0;
1580
- // Use a toggle to prevent hide/show conflicts
1581
- showTarget.bind(self.options.show.when.event + '.qtip', function(event)
1582
- {
1583
- if(self.cache.toggle == 0) showMethod(event);
1584
- else hideMethod(event);
1585
- });
1586
- }
1587
-
1588
- // Events are not identical, bind normally
1589
- else
1590
- {
1591
- showTarget.bind(self.options.show.when.event + '.qtip', showMethod);
1592
-
1593
- // If the hide event is not 'inactive', bind the hide method
1594
- if(self.options.hide.when.event !== 'inactive')
1595
- hideTarget.bind(self.options.hide.when.event + '.qtip', hideMethod);
1596
- };
1597
-
1598
- // Focus the tooltip on mouseover
1599
- if(self.options.position.type.search(/(fixed|absolute)/) !== -1)
1600
- self.elements.tooltip.bind('mouseover.qtip', self.focus);
1601
-
1602
- // If mouse is the target, update tooltip position on mousemove
1603
- if(self.options.position.target === 'mouse' && self.options.position.type !== 'static')
1604
- {
1605
- showTarget.bind('mousemove.qtip', function(event)
1606
- {
1607
- // Set the new mouse positions if adjustment is enabled
1608
- self.cache.mouse = { x: event.pageX, y: event.pageY };
1609
-
1610
- // Update the tooltip position only if the tooltip is visible and adjustment is enabled
1611
- if(self.status.disabled === false
1612
- && self.options.position.adjust.mouse === true
1613
- && self.options.position.type !== 'static'
1614
- && self.elements.tooltip.css('display') !== 'none')
1615
- self.updatePosition(event);
1616
- });
1617
- };
1618
- };
1619
-
1620
- // Screen position adjustment
1621
- function screenAdjust(position, target, tooltip)
1622
- {
1623
- var self, adjustedPosition, adjust, newCorner, overflow, corner;
1624
- self = this;
1625
-
1626
- // Setup corner and adjustment variable
1627
- if(tooltip.corner == 'center') return target.position // TODO: 'center' corner adjustment
1628
- adjustedPosition = $.extend({}, position);
1629
- newCorner = { x: false, y: false };
1630
-
1631
- // Define overflow properties
1632
- overflow = {
1633
- left: (adjustedPosition.left < $.fn.qtip.cache.screen.scroll.left),
1634
- right: (adjustedPosition.left + tooltip.dimensions.width + 2 >= $.fn.qtip.cache.screen.width + $.fn.qtip.cache.screen.scroll.left),
1635
- top: (adjustedPosition.top < $.fn.qtip.cache.screen.scroll.top),
1636
- bottom: (adjustedPosition.top + tooltip.dimensions.height + 2 >= $.fn.qtip.cache.screen.height + $.fn.qtip.cache.screen.scroll.top)
1637
- };
1638
-
1639
- // Determine new positioning properties
1640
- adjust = {
1641
- left: (overflow.left && (tooltip.corner.search(/right/i) != -1 || (tooltip.corner.search(/right/i) == -1 && !overflow.right))),
1642
- right: (overflow.right && (tooltip.corner.search(/left/i) != -1 || (tooltip.corner.search(/left/i) == -1 && !overflow.left))),
1643
- top: (overflow.top && tooltip.corner.search(/top/i) == -1),
1644
- bottom: (overflow.bottom && tooltip.corner.search(/bottom/i) == -1)
1645
- };
1646
-
1647
- // Tooltip overflows off the left side of the screen
1648
- if(adjust.left)
1649
- {
1650
- if(self.options.position.target !== 'mouse')
1651
- adjustedPosition.left = target.position.left + target.dimensions.width;
1652
- else
1653
- adjustedPosition.left = self.cache.mouse.x
1654
-
1655
- newCorner.x = 'Left';
1656
- }
1657
-
1658
- // Tooltip overflows off the right side of the screen
1659
- else if(adjust.right)
1660
- {
1661
- if(self.options.position.target !== 'mouse')
1662
- adjustedPosition.left = target.position.left - tooltip.dimensions.width;
1663
- else
1664
- adjustedPosition.left = self.cache.mouse.x - tooltip.dimensions.width;
1665
-
1666
- newCorner.x = 'Right';
1667
- };
1668
-
1669
- // Tooltip overflows off the top of the screen
1670
- if(adjust.top)
1671
- {
1672
- if(self.options.position.target !== 'mouse')
1673
- adjustedPosition.top = target.position.top + target.dimensions.height;
1674
- else
1675
- adjustedPosition.top = self.cache.mouse.y
1676
-
1677
- newCorner.y = 'top';
1678
- }
1679
-
1680
- // Tooltip overflows off the bottom of the screen
1681
- else if(adjust.bottom)
1682
- {
1683
- if(self.options.position.target !== 'mouse')
1684
- adjustedPosition.top = target.position.top - tooltip.dimensions.height;
1685
- else
1686
- adjustedPosition.top = self.cache.mouse.y - tooltip.dimensions.height;
1687
-
1688
- newCorner.y = 'bottom';
1689
- };
1690
-
1691
- // Don't adjust if resulting position is negative
1692
- if(adjustedPosition.left < 0)
1693
- {
1694
- adjustedPosition.left = position.left;
1695
- newCorner.x = false;
1696
- };
1697
- if(adjustedPosition.top < 0)
1698
- {
1699
- adjustedPosition.top = position.top;
1700
- newCorner.y = false;
1701
- };
1702
-
1703
- // Change tip corner if positioning has changed and tips are enabled
1704
- if(self.options.style.tip.corner !== false)
1705
- {
1706
- // Determine new corner properties
1707
- adjustedPosition.corner = new String(tooltip.corner);
1708
- if(newCorner.x !== false) adjustedPosition.corner = adjustedPosition.corner.replace(/Left|Right|Middle/, newCorner.x);
1709
- if(newCorner.y !== false) adjustedPosition.corner = adjustedPosition.corner.replace(/top|bottom/, newCorner.y);
1710
-
1711
- // Adjust tip if position has changed and tips are enabled
1712
- if(adjustedPosition.corner !== self.elements.tip.attr('rel'))
1713
- createTip.call(self, adjustedPosition.corner);
1714
- };
1715
-
1716
- return adjustedPosition;
1717
- };
1718
-
1719
- // Build a jQuery style object from supplied style object
1720
- function jQueryStyle(style, sub)
1721
- {
1722
- var styleObj, i;
1723
-
1724
- styleObj = $.extend(true, {}, style);
1725
- for(i in styleObj)
1726
- {
1727
- if(sub === true && i.search(/(tip|classes)/i) !== -1)
1728
- delete styleObj[i];
1729
- else if(!sub && i.search(/(width|border|tip|title|classes|user)/i) !== -1)
1730
- delete styleObj[i];
1731
- };
1732
-
1733
- return styleObj;
1734
- };
1735
-
1736
- // Sanitize styles
1737
- function sanitizeStyle(style)
1738
- {
1739
- if(typeof style.tip !== 'object') style.tip = { corner: style.tip };
1740
- if(typeof style.tip.size !== 'object') style.tip.size = { width: style.tip.size, height: style.tip.size };
1741
- if(typeof style.border !== 'object') style.border = { width: style.border };
1742
- if(typeof style.width !== 'object') style.width = { value: style.width };
1743
- if(typeof style.width.max == 'string') style.width.max = parseInt(style.width.max.replace(/([0-9]+)/i, "$1"));
1744
- if(typeof style.width.min == 'string') style.width.min = parseInt(style.width.min.replace(/([0-9]+)/i, "$1"));
1745
-
1746
- // Convert deprecated x and y tip values to width/height
1747
- if(typeof style.tip.size.x == 'number')
1748
- {
1749
- style.tip.size.width = style.tip.size.x;
1750
- delete style.tip.size.x;
1751
- };
1752
- if(typeof style.tip.size.y == 'number')
1753
- {
1754
- style.tip.size.height = style.tip.size.y;
1755
- delete style.tip.size.y;
1756
- };
1757
-
1758
- return style;
1759
- };
1760
-
1761
- // Build styles recursively with inheritance
1762
- function buildStyle()
1763
- {
1764
- var self, i, styleArray, styleExtend, finalStyle, ieAdjust;
1765
- self = this;
1766
-
1767
- // Build style options from supplied arguments
1768
- styleArray = [true, {}];
1769
- for(i = 0; i < arguments.length; i++)
1770
- styleArray.push(arguments[i]);
1771
- styleExtend = [ $.extend.apply($, styleArray) ];
1772
-
1773
- // Loop through each named style inheritance
1774
- while(typeof styleExtend[0].name == 'string')
1775
- {
1776
- // Sanitize style data and append to extend array
1777
- styleExtend.unshift( sanitizeStyle($.fn.qtip.styles[ styleExtend[0].name ]) );
1778
- };
1779
-
1780
- // Make sure resulting tooltip className represents final style
1781
- styleExtend.unshift(true, {classes:{ tooltip: 'qtip-' + (arguments[0].name || 'defaults') }}, $.fn.qtip.styles.defaults);
1782
-
1783
- // Extend into a single style object
1784
- finalStyle = $.extend.apply($, styleExtend);
1785
-
1786
- // Adjust tip size if needed (IE 1px adjustment bug fix)
1787
- ieAdjust = ($.browser.msie) ? 1 : 0;
1788
- finalStyle.tip.size.width += ieAdjust;
1789
- finalStyle.tip.size.height += ieAdjust;
1790
-
1791
- // Force even numbers for pixel precision
1792
- if(finalStyle.tip.size.width % 2 > 0) finalStyle.tip.size.width += 1;
1793
- if(finalStyle.tip.size.height % 2 > 0) finalStyle.tip.size.height += 1;
1794
-
1795
- // Sanitize final styles tip corner value
1796
- if(finalStyle.tip.corner === true)
1797
- finalStyle.tip.corner = (self.options.position.corner.tooltip === 'center') ? false : self.options.position.corner.tooltip;
1798
-
1799
- return finalStyle;
1800
- };
1801
-
1802
- // Tip coordinates calculator
1803
- function calculateTip(corner, width, height)
1804
- {
1805
- // Define tip coordinates in terms of height and width values
1806
- var tips = {
1807
- bottomRight: [[0,0], [width,height], [width,0]],
1808
- bottomLeft: [[0,0], [width,0], [0,height]],
1809
- topRight: [[0,height], [width,0], [width,height]],
1810
- topLeft: [[0,0], [0,height], [width,height]],
1811
- topMiddle: [[0,height], [width / 2,0], [width,height]],
1812
- bottomMiddle: [[0,0], [width,0], [width / 2,height]],
1813
- rightMiddle: [[0,0], [width,height / 2], [0,height]],
1814
- leftMiddle: [[width,0], [width,height], [0,height / 2]]
1815
- };
1816
- tips.leftTop = tips.bottomRight;
1817
- tips.rightTop = tips.bottomLeft;
1818
- tips.leftBottom = tips.topRight;
1819
- tips.rightBottom = tips.topLeft;
1820
-
1821
- return tips[corner];
1822
- };
1823
-
1824
- // Border coordinates calculator
1825
- function calculateBorders(radius)
1826
- {
1827
- var borders;
1828
-
1829
- // Use canvas element if supported
1830
- if($('<canvas>').get(0).getContext)
1831
- {
1832
- borders = {
1833
- topLeft: [radius,radius], topRight: [0,radius],
1834
- bottomLeft: [radius,0], bottomRight: [0,0]
1835
- };
1836
- }
1837
-
1838
- // Canvas not supported - Use VML (IE)
1839
- else if($.browser.msie)
1840
- {
1841
- borders = {
1842
- topLeft: [-90,90,0], topRight: [-90,90,-radius],
1843
- bottomLeft: [90,270,0], bottomRight: [90, 270,-radius]
1844
- };
1845
- };
1846
-
1847
- return borders;
1848
- };
1849
-
1850
- // BGIFRAME JQUERY PLUGIN ADAPTION
1851
- // Special thanks to Brandon Aaron for this plugin
1852
- // http://plugins.jquery.com/project/bgiframe
1853
- function bgiframe()
1854
- {
1855
- var self, html, dimensions;
1856
- self = this;
1857
- dimensions = self.getDimensions();
1858
-
1859
- // Setup iframe HTML string
1860
- html = '<iframe class="qtip-bgiframe" frameborder="0" tabindex="-1" src="javascript:false" '+
1861
- 'style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=\'0\'); border: 1px solid red; ' +
1862
- 'height:'+dimensions.height+'px; width:'+dimensions.width+'px" />';
1863
-
1864
- // Append the new HTML and setup element reference
1865
- self.elements.bgiframe = self.elements.wrapper.prepend(html).children('.qtip-bgiframe:first');
1866
- };
1867
-
1868
- // Assign cache and event initialisation on document load
1869
- $(document).ready(function()
1870
- {
1871
- // Setup library cache with window scroll and dimensions of document
1872
- $.fn.qtip.cache = {
1873
- screen: {
1874
- scroll: { left: $(window).scrollLeft(), top: $(window).scrollTop() },
1875
- width: $(window).width(),
1876
- height: $(window).height()
1877
- }
1878
- };
1879
-
1880
- // Adjust positions of the tooltips on window resize or scroll if enabled
1881
- var adjustTimer;
1882
- $(window).bind('resize scroll', function(event)
1883
- {
1884
- clearTimeout(adjustTimer);
1885
- adjustTimer = setTimeout(function()
1886
- {
1887
- // Readjust cached screen values
1888
- if(event.type === 'scroll')
1889
- $.fn.qtip.cache.screen.scroll = { left: $(window).scrollLeft(), top: $(window).scrollTop() };
1890
- else
1891
- {
1892
- $.fn.qtip.cache.screen.width = $(window).width();
1893
- $.fn.qtip.cache.screen.height = $(window).height();
1894
- };
1895
-
1896
- for(i = 0; i < $.fn.qtip.interfaces.length; i++)
1897
- {
1898
- // Access current elements API
1899
- var api = $.fn.qtip.interfaces[i];
1900
-
1901
- // Update position if resize or scroll adjustments are enabled
1902
- if(api.status.rendered === true
1903
- && (api.options.position.type !== 'static'
1904
- || api.options.position.adjust.scroll && event.type === 'scroll'
1905
- || api.options.position.adjust.resize && event.type === 'resize'))
1906
- {
1907
- // Queue the animation so positions are updated correctly
1908
- api.updatePosition(event, true);
1909
- }
1910
- };
1911
- }
1912
- , 100);
1913
- })
1914
-
1915
- // Hide unfocus toolipts on document mousedown
1916
- $(document).bind('mousedown.qtip', function(event)
1917
- {
1918
- if($(event.target).parents('div.qtip').length === 0)
1919
- {
1920
- $('.qtip[unfocus]').each(function()
1921
- {
1922
- var api = $(this).qtip("api");
1923
-
1924
- // Only hide if its visible and not the tooltips target
1925
- if($(this).is(':visible') && !api.status.disabled
1926
- && $(event.target).add(api.elements.target).length > 1)
1927
- api.hide(event);
1928
- })
1929
- };
1930
- })
1931
- });
1932
-
1933
- // Define qTip API interfaces array
1934
- $.fn.qtip.interfaces = []
1935
-
1936
- // Define log and constant place holders
1937
- $.fn.qtip.log = { error: function(){ return this; } };
1938
- $.fn.qtip.constants = {};
1939
-
1940
- // Define configuration defaults
1941
- $.fn.qtip.defaults = {
1942
- // Content
1943
- content: {
1944
- prerender: false,
1945
- text: false,
1946
- url: false,
1947
- data: null,
1948
- title: {
1949
- text: false,
1950
- button: false
1951
- }
1952
- },
1953
- // Position
1954
- position: {
1955
- target: false,
1956
- corner: {
1957
- target: 'bottomRight',
1958
- tooltip: 'topLeft'
1959
- },
1960
- adjust: {
1961
- x: 0, y: 0,
1962
- mouse: true,
1963
- screen: false,
1964
- scroll: true,
1965
- resize: true
1966
- },
1967
- type: 'absolute',
1968
- container: false
1969
- },
1970
- // Effects
1971
- show: {
1972
- when: {
1973
- target: false,
1974
- event: 'mouseover'
1975
- },
1976
- effect: {
1977
- type: 'fade',
1978
- length: 100
1979
- },
1980
- delay: 140,
1981
- solo: false,
1982
- ready: false
1983
- },
1984
- hide: {
1985
- when: {
1986
- target: false,
1987
- event: 'mouseout'
1988
- },
1989
- effect: {
1990
- type: 'fade',
1991
- length: 100
1992
- },
1993
- delay: 0,
1994
- fixed: false
1995
- },
1996
- // Callbacks
1997
- api: {
1998
- beforeRender: function(){},
1999
- onRender: function(){},
2000
- beforePositionUpdate: function(){},
2001
- onPositionUpdate: function(){},
2002
- beforeShow: function(){},
2003
- onShow: function(){},
2004
- beforeHide: function(){},
2005
- onHide: function(){},
2006
- beforeContentUpdate: function(){},
2007
- onContentUpdate: function(){},
2008
- beforeContentLoad: function(){},
2009
- onContentLoad: function(){},
2010
- beforeTitleUpdate: function(){},
2011
- onTitleUpdate: function(){},
2012
- beforeDestroy: function(){},
2013
- onDestroy: function(){},
2014
- beforeFocus: function(){},
2015
- onFocus: function(){}
2016
- }
2017
- };
2018
-
2019
- $.fn.qtip.styles = {
2020
- defaults: {
2021
- background: 'white',
2022
- color: '#111',
2023
- overflow: 'hidden',
2024
- textAlign: 'left',
2025
- width: {
2026
- min: 0,
2027
- max: 250
2028
- },
2029
- padding: '5px 9px',
2030
- border: {
2031
- width: 1,
2032
- radius: 0,
2033
- color: '#d3d3d3'
2034
- },
2035
- tip: {
2036
- corner: false,
2037
- color: false,
2038
- size: { width: 13, height: 13 },
2039
- opacity: 1
2040
- },
2041
- title: {
2042
- background: '#e1e1e1',
2043
- fontWeight: 'bold',
2044
- padding: '7px 12px'
2045
- },
2046
- button: {
2047
- cursor: 'pointer'
2048
- },
2049
- classes: {
2050
- target: '',
2051
- tip: 'qtip-tip',
2052
- title: 'qtip-title',
2053
- button: 'qtip-button',
2054
- content: 'qtip-content',
2055
- active: 'qtip-active'
2056
- }
2057
- },
2058
- cream: {
2059
- border: {
2060
- width: 3,
2061
- radius: 0,
2062
- color: '#F9E98E'
2063
- },
2064
- title: {
2065
- background: '#F0DE7D',
2066
- color: '#A27D35'
2067
- },
2068
- background: '#FBF7AA',
2069
- color: '#A27D35',
2070
-
2071
- classes: { tooltip: 'qtip-cream' }
2072
- },
2073
- light: {
2074
- border: {
2075
- width: 3,
2076
- radius: 0,
2077
- color: '#E2E2E2'
2078
- },
2079
- title: {
2080
- background: '#f1f1f1',
2081
- color: '#454545'
2082
- },
2083
- background: 'white',
2084
- color: '#454545',
2085
-
2086
- classes: { tooltip: 'qtip-light' }
2087
- },
2088
- dark: {
2089
- border: {
2090
- width: 3,
2091
- radius: 0,
2092
- color: '#303030'
2093
- },
2094
- title: {
2095
- background: '#404040',
2096
- color: '#f3f3f3'
2097
- },
2098
- background: '#505050',
2099
- color: '#f3f3f3',
2100
-
2101
- classes: { tooltip: 'qtip-dark' }
2102
- },
2103
- red: {
2104
- border: {
2105
- width: 3,
2106
- radius: 0,
2107
- color: '#CE6F6F'
2108
- },
2109
- title: {
2110
- background: '#f28279',
2111
- color: '#9C2F2F'
2112
- },
2113
- background: '#F79992',
2114
- color: '#9C2F2F',
2115
-
2116
- classes: { tooltip: 'qtip-red' }
2117
- },
2118
- green: {
2119
- border: {
2120
- width: 3,
2121
- radius: 0,
2122
- color: '#A9DB66'
2123
- },
2124
- title: {
2125
- background: '#b9db8c',
2126
- color: '#58792E'
2127
- },
2128
- background: '#CDE6AC',
2129
- color: '#58792E',
2130
-
2131
- classes: { tooltip: 'qtip-green' }
2132
- },
2133
- blue: {
2134
- border: {
2135
- width: 3,
2136
- radius: 0,
2137
- color: '#ADD9ED'
2138
- },
2139
- title: {
2140
- background: '#D0E9F5',
2141
- color: '#5E99BD'
2142
- },
2143
- background: '#E5F6FE',
2144
- color: '#4D9FBF',
2145
-
2146
- classes: { tooltip: 'qtip-blue' }
2147
- }
2148
- };
2149
- })(jQuery);
12
  * Released: Tuesday 12th May, 2009 - 00:00
13
  * Debug: jquery.qtip.debug.js
14
  */
15
+ (function(f){f.fn.qtip=function(B,u){var y,t,A,s,x,w,v,z;if(typeof B=="string"){if(typeof f(this).data("qtip")!=="object"){f.fn.qtip.log.error.call(self,1,f.fn.qtip.constants.NO_TOOLTIP_PRESENT,false)}if(B=="api"){return f(this).data("qtip").interfaces[f(this).data("qtip").current]}else{if(B=="interfaces"){return f(this).data("qtip").interfaces}}}else{if(!B){B={}}if(typeof B.content!=="object"||(B.content.jquery&&B.content.length>0)){B.content={text:B.content}}if(typeof B.content.title!=="object"){B.content.title={text:B.content.title}}if(typeof B.position!=="object"){B.position={corner:B.position}}if(typeof B.position.corner!=="object"){B.position.corner={target:B.position.corner,tooltip:B.position.corner}}if(typeof B.show!=="object"){B.show={when:B.show}}if(typeof B.show.when!=="object"){B.show.when={event:B.show.when}}if(typeof B.show.effect!=="object"){B.show.effect={type:B.show.effect}}if(typeof B.hide!=="object"){B.hide={when:B.hide}}if(typeof B.hide.when!=="object"){B.hide.when={event:B.hide.when}}if(typeof B.hide.effect!=="object"){B.hide.effect={type:B.hide.effect}}if(typeof B.style!=="object"){B.style={name:B.style}}B.style=c(B.style);s=f.extend(true,{},f.fn.qtip.defaults,B);s.style=a.call({options:s},s.style);s.user=f.extend(true,{},B)}return f(this).each(function(){if(typeof B=="string"){w=B.toLowerCase();A=f(this).qtip("interfaces");if(typeof A=="object"){if(u===true&&w=="destroy"){while(A.length>0){A[A.length-1].destroy()}}else{if(u!==true){A=[f(this).qtip("api")]}for(y=0;y<A.length;y++){if(w=="destroy"){A[y].destroy()}else{if(A[y].status.rendered===true){if(w=="show"){A[y].show()}else{if(w=="hide"){A[y].hide()}else{if(w=="focus"){A[y].focus()}else{if(w=="disable"){A[y].disable(true)}else{if(w=="enable"){A[y].disable(false)}}}}}}}}}}}else{v=f.extend(true,{},s);v.hide.effect.length=s.hide.effect.length;v.show.effect.length=s.show.effect.length;if(v.position.container===false){v.position.container=f(document.body)}if(v.position.target===false){v.position.target=f(this)}if(v.show.when.target===false){v.show.when.target=f(this)}if(v.hide.when.target===false){v.hide.when.target=f(this)}t=f.fn.qtip.interfaces.length;for(y=0;y<t;y++){if(typeof f.fn.qtip.interfaces[y]=="undefined"){t=y;break}}x=new d(f(this),v,t);f.fn.qtip.interfaces[t]=x;if(typeof f(this).data("qtip")==="object"&&f(this).data("qtip")){if(typeof f(this).attr("qtip")==="undefined"){f(this).data("qtip").current=f(this).data("qtip").interfaces.length}f(this).data("qtip").interfaces.push(x)}else{f(this).data("qtip",{current:0,interfaces:[x]})}if(v.content.prerender===false&&v.show.when.event!==false&&v.show.ready!==true){v.show.when.target.bind(v.show.when.event+".qtip-"+t+"-create",{qtip:t},function(C){z=f.fn.qtip.interfaces[C.data.qtip];z.options.show.when.target.unbind(z.options.show.when.event+".qtip-"+C.data.qtip+"-create");z.cache.mouse={x:C.pageX,y:C.pageY};p.call(z);z.options.show.when.target.trigger(z.options.show.when.event)})}else{x.cache.mouse={x:v.show.when.target.offset().left,y:v.show.when.target.offset().top};p.call(x)}}})};function d(u,t,v){var s=this;s.id=v;s.options=t;s.status={animated:false,rendered:false,disabled:false,focused:false};s.elements={target:u.addClass(s.options.style.classes.target),tooltip:null,wrapper:null,content:null,contentWrapper:null,title:null,button:null,tip:null,bgiframe:null};s.cache={mouse:{},position:{},toggle:0};s.timers={};f.extend(s,s.options.api,{show:function(y){var x,z;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"show")}if(s.elements.tooltip.css("display")!=="none"){return s}s.elements.tooltip.stop(true,false);x=s.beforeShow.call(s,y);if(x===false){return s}function w(){if(s.options.position.type!=="static"){s.focus()}s.onShow.call(s,y);if(f.browser.msie){s.elements.tooltip.get(0).style.removeAttribute("filter")}}s.cache.toggle=1;if(s.options.position.type!=="static"){s.updatePosition(y,(s.options.show.effect.length>0))}if(typeof s.options.show.solo=="object"){z=f(s.options.show.solo)}else{if(s.options.show.solo===true){z=f("div.qtip").not(s.elements.tooltip)}}if(z){z.each(function(){if(f(this).qtip("api").status.rendered===true){f(this).qtip("api").hide()}})}if(typeof s.options.show.effect.type=="function"){s.options.show.effect.type.call(s.elements.tooltip,s.options.show.effect.length);s.elements.tooltip.queue(function(){w();f(this).dequeue()})}else{switch(s.options.show.effect.type.toLowerCase()){case"fade":s.elements.tooltip.fadeIn(s.options.show.effect.length,w);break;case"slide":s.elements.tooltip.slideDown(s.options.show.effect.length,function(){w();if(s.options.position.type!=="static"){s.updatePosition(y,true)}});break;case"grow":s.elements.tooltip.show(s.options.show.effect.length,w);break;default:s.elements.tooltip.show(null,w);break}s.elements.tooltip.addClass(s.options.style.classes.active)}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_SHOWN,"show")},hide:function(y){var x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"hide")}else{if(s.elements.tooltip.css("display")==="none"){return s}}clearTimeout(s.timers.show);s.elements.tooltip.stop(true,false);x=s.beforeHide.call(s,y);if(x===false){return s}function w(){s.onHide.call(s,y)}s.cache.toggle=0;if(typeof s.options.hide.effect.type=="function"){s.options.hide.effect.type.call(s.elements.tooltip,s.options.hide.effect.length);s.elements.tooltip.queue(function(){w();f(this).dequeue()})}else{switch(s.options.hide.effect.type.toLowerCase()){case"fade":s.elements.tooltip.fadeOut(s.options.hide.effect.length,w);break;case"slide":s.elements.tooltip.slideUp(s.options.hide.effect.length,w);break;case"grow":s.elements.tooltip.hide(s.options.hide.effect.length,w);break;default:s.elements.tooltip.hide(null,w);break}s.elements.tooltip.removeClass(s.options.style.classes.active)}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_HIDDEN,"hide")},updatePosition:function(w,x){var C,G,L,J,H,E,y,I,B,D,K,A,F,z;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updatePosition")}else{if(s.options.position.type=="static"){return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.CANNOT_POSITION_STATIC,"updatePosition")}}G={position:{left:0,top:0},dimensions:{height:0,width:0},corner:s.options.position.corner.target};L={position:s.getPosition(),dimensions:s.getDimensions(),corner:s.options.position.corner.tooltip};if(s.options.position.target!=="mouse"){if(s.options.position.target.get(0).nodeName.toLowerCase()=="area"){J=s.options.position.target.attr("coords").split(",");for(C=0;C<J.length;C++){J[C]=parseInt(J[C])}H=s.options.position.target.parent("map").attr("name");E=f('img[usemap="#'+H+'"]:first').offset();G.position={left:Math.floor(E.left+J[0]),top:Math.floor(E.top+J[1])};switch(s.options.position.target.attr("shape").toLowerCase()){case"rect":G.dimensions={width:Math.ceil(Math.abs(J[2]-J[0])),height:Math.ceil(Math.abs(J[3]-J[1]))};break;case"circle":G.dimensions={width:J[2]+1,height:J[2]+1};break;case"poly":G.dimensions={width:J[0],height:J[1]};for(C=0;C<J.length;C++){if(C%2==0){if(J[C]>G.dimensions.width){G.dimensions.width=J[C]}if(J[C]<J[0]){G.position.left=Math.floor(E.left+J[C])}}else{if(J[C]>G.dimensions.height){G.dimensions.height=J[C]}if(J[C]<J[1]){G.position.top=Math.floor(E.top+J[C])}}}G.dimensions.width=G.dimensions.width-(G.position.left-E.left);G.dimensions.height=G.dimensions.height-(G.position.top-E.top);break;default:return f.fn.qtip.log.error.call(s,4,f.fn.qtip.constants.INVALID_AREA_SHAPE,"updatePosition");break}G.dimensions.width-=2;G.dimensions.height-=2}else{if(s.options.position.target.add(document.body).length===1){G.position={left:f(document).scrollLeft(),top:f(document).scrollTop()};G.dimensions={height:f(window).height(),width:f(window).width()}}else{if(typeof s.options.position.target.attr("qtip")!=="undefined"){G.position=s.options.position.target.qtip("api").cache.position}else{G.position=s.options.position.target.offset()}G.dimensions={height:s.options.position.target.outerHeight(),width:s.options.position.target.outerWidth()}}}y=f.extend({},G.position);if(G.corner.search(/right/i)!==-1){y.left+=G.dimensions.width}if(G.corner.search(/bottom/i)!==-1){y.top+=G.dimensions.height}if(G.corner.search(/((top|bottom)Middle)|center/)!==-1){y.left+=(G.dimensions.width/2)}if(G.corner.search(/((left|right)Middle)|center/)!==-1){y.top+=(G.dimensions.height/2)}}else{G.position=y={left:s.cache.mouse.x,top:s.cache.mouse.y};G.dimensions={height:1,width:1}}if(L.corner.search(/right/i)!==-1){y.left-=L.dimensions.width}if(L.corner.search(/bottom/i)!==-1){y.top-=L.dimensions.height}if(L.corner.search(/((top|bottom)Middle)|center/)!==-1){y.left-=(L.dimensions.width/2)}if(L.corner.search(/((left|right)Middle)|center/)!==-1){y.top-=(L.dimensions.height/2)}I=(f.browser.msie)?1:0;B=(f.browser.msie&&parseInt(f.browser.version.charAt(0))===6)?1:0;if(s.options.style.border.radius>0){if(L.corner.search(/Left/)!==-1){y.left-=s.options.style.border.radius}else{if(L.corner.search(/Right/)!==-1){y.left+=s.options.style.border.radius}}if(L.corner.search(/Top/)!==-1){y.top-=s.options.style.border.radius}else{if(L.corner.search(/Bottom/)!==-1){y.top+=s.options.style.border.radius}}}if(I){if(L.corner.search(/top/)!==-1){y.top-=I}else{if(L.corner.search(/bottom/)!==-1){y.top+=I}}if(L.corner.search(/left/)!==-1){y.left-=I}else{if(L.corner.search(/right/)!==-1){y.left+=I}}if(L.corner.search(/leftMiddle|rightMiddle/)!==-1){y.top-=1}}if(s.options.position.adjust.screen===true){y=o.call(s,y,G,L)}if(s.options.position.target==="mouse"&&s.options.position.adjust.mouse===true){if(s.options.position.adjust.screen===true&&s.elements.tip){K=s.elements.tip.attr("rel")}else{K=s.options.position.corner.tooltip}y.left+=(K.search(/right/i)!==-1)?-6:6;y.top+=(K.search(/bottom/i)!==-1)?-6:6}if(!s.elements.bgiframe&&f.browser.msie&&parseInt(f.browser.version.charAt(0))==6){f("select, object").each(function(){A=f(this).offset();A.bottom=A.top+f(this).height();A.right=A.left+f(this).width();if(y.top+L.dimensions.height>=A.top&&y.left+L.dimensions.width>=A.left){k.call(s)}})}y.left+=s.options.position.adjust.x;y.top+=s.options.position.adjust.y;F=s.getPosition();if(y.left!=F.left||y.top!=F.top){z=s.beforePositionUpdate.call(s,w);if(z===false){return s}s.cache.position=y;if(x===true){s.status.animated=true;s.elements.tooltip.animate(y,200,"swing",function(){s.status.animated=false})}else{s.elements.tooltip.css(y)}s.onPositionUpdate.call(s,w);if(typeof w!=="undefined"&&w.type&&w.type!=="mousemove"){f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_POSITION_UPDATED,"updatePosition")}}return s},updateWidth:function(w){var x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateWidth")}else{if(w&&typeof w!=="number"){return f.fn.qtip.log.error.call(s,2,"newWidth must be of type number","updateWidth")}}x=s.elements.contentWrapper.siblings().add(s.elements.tip).add(s.elements.button);if(!w){if(typeof s.options.style.width.value=="number"){w=s.options.style.width.value}else{s.elements.tooltip.css({width:"auto"});x.hide();if(f.browser.msie){s.elements.wrapper.add(s.elements.contentWrapper.children()).css({zoom:"normal"})}w=s.getDimensions().width+1;if(!s.options.style.width.value){if(w>s.options.style.width.max){w=s.options.style.width.max}if(w<s.options.style.width.min){w=s.options.style.width.min}}}}if(w%2!==0){w-=1}s.elements.tooltip.width(w);x.show();if(s.options.style.border.radius){s.elements.tooltip.find(".qtip-betweenCorners").each(function(y){f(this).width(w-(s.options.style.border.radius*2))})}if(f.browser.msie){s.elements.wrapper.add(s.elements.contentWrapper.children()).css({zoom:"1"});s.elements.wrapper.width(w);if(s.elements.bgiframe){s.elements.bgiframe.width(w).height(s.getDimensions.height)}}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_WIDTH_UPDATED,"updateWidth")},updateStyle:function(w){var z,A,x,y,B;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateStyle")}else{if(typeof w!=="string"||!f.fn.qtip.styles[w]){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.STYLE_NOT_DEFINED,"updateStyle")}}s.options.style=a.call(s,f.fn.qtip.styles[w],s.options.user.style);s.elements.content.css(q(s.options.style));if(s.options.content.title.text!==false){s.elements.title.css(q(s.options.style.title,true))}s.elements.contentWrapper.css({borderColor:s.options.style.border.color});if(s.options.style.tip.corner!==false){if(f("<canvas>").get(0).getContext){z=s.elements.tooltip.find(".qtip-tip canvas:first");x=z.get(0).getContext("2d");x.clearRect(0,0,300,300);y=z.parent("div[rel]:first").attr("rel");B=b(y,s.options.style.tip.size.width,s.options.style.tip.size.height);h.call(s,z,B,s.options.style.tip.color||s.options.style.border.color)}else{if(f.browser.msie){z=s.elements.tooltip.find('.qtip-tip [nodeName="shape"]');z.attr("fillcolor",s.options.style.tip.color||s.options.style.border.color)}}}if(s.options.style.border.radius>0){s.elements.tooltip.find(".qtip-betweenCorners").css({backgroundColor:s.options.style.border.color});if(f("<canvas>").get(0).getContext){A=g(s.options.style.border.radius);s.elements.tooltip.find(".qtip-wrapper canvas").each(function(){x=f(this).get(0).getContext("2d");x.clearRect(0,0,300,300);y=f(this).parent("div[rel]:first").attr("rel");r.call(s,f(this),A[y],s.options.style.border.radius,s.options.style.border.color)})}else{if(f.browser.msie){s.elements.tooltip.find('.qtip-wrapper [nodeName="arc"]').each(function(){f(this).attr("fillcolor",s.options.style.border.color)})}}}return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_STYLE_UPDATED,"updateStyle")},updateContent:function(A,y){var z,x,w;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateContent")}else{if(!A){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.NO_CONTENT_PROVIDED,"updateContent")}}z=s.beforeContentUpdate.call(s,A);if(typeof z=="string"){A=z}else{if(z===false){return}}if(f.browser.msie){s.elements.contentWrapper.children().css({zoom:"normal"})}if(A.jquery&&A.length>0){A.clone(true).appendTo(s.elements.content).show()}else{s.elements.content.html(A)}x=s.elements.content.find("img[complete=false]");if(x.length>0){w=0;x.each(function(C){f('<img src="'+f(this).attr("src")+'" />').load(function(){if(++w==x.length){B()}})})}else{B()}function B(){s.updateWidth();if(y!==false){if(s.options.position.type!=="static"){s.updatePosition(s.elements.tooltip.is(":visible"),true)}if(s.options.style.tip.corner!==false){n.call(s)}}}s.onContentUpdate.call(s);return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_CONTENT_UPDATED,"loadContent")},loadContent:function(w,z,A){var y;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"loadContent")}y=s.beforeContentLoad.call(s);if(y===false){return s}if(A=="post"){f.post(w,z,x)}else{f.get(w,z,x)}function x(B){s.onContentLoad.call(s);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_CONTENT_LOADED,"loadContent");s.updateContent(B)}return s},updateTitle:function(w){if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"updateTitle")}else{if(!w){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.NO_CONTENT_PROVIDED,"updateTitle")}}returned=s.beforeTitleUpdate.call(s);if(returned===false){return s}if(s.elements.button){s.elements.button=s.elements.button.clone(true)}s.elements.title.html(w);if(s.elements.button){s.elements.title.prepend(s.elements.button)}s.onTitleUpdate.call(s);return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_TITLE_UPDATED,"updateTitle")},focus:function(A){var y,x,w,z;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"focus")}else{if(s.options.position.type=="static"){return f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.CANNOT_FOCUS_STATIC,"focus")}}y=parseInt(s.elements.tooltip.css("z-index"));x=6000+f("div.qtip[qtip]").length-1;if(!s.status.focused&&y!==x){z=s.beforeFocus.call(s,A);if(z===false){return s}f("div.qtip[qtip]").not(s.elements.tooltip).each(function(){if(f(this).qtip("api").status.rendered===true){w=parseInt(f(this).css("z-index"));if(typeof w=="number"&&w>-1){f(this).css({zIndex:parseInt(f(this).css("z-index"))-1})}f(this).qtip("api").status.focused=false}});s.elements.tooltip.css({zIndex:x});s.status.focused=true;s.onFocus.call(s,A);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_FOCUSED,"focus")}return s},disable:function(w){if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"disable")}if(w){if(!s.status.disabled){s.status.disabled=true;f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_DISABLED,"disable")}else{f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.TOOLTIP_ALREADY_DISABLED,"disable")}}else{if(s.status.disabled){s.status.disabled=false;f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_ENABLED,"disable")}else{f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.TOOLTIP_ALREADY_ENABLED,"disable")}}return s},destroy:function(){var w,x,y;x=s.beforeDestroy.call(s);if(x===false){return s}if(s.status.rendered){s.options.show.when.target.unbind("mousemove.qtip",s.updatePosition);s.options.show.when.target.unbind("mouseout.qtip",s.hide);s.options.show.when.target.unbind(s.options.show.when.event+".qtip");s.options.hide.when.target.unbind(s.options.hide.when.event+".qtip");s.elements.tooltip.unbind(s.options.hide.when.event+".qtip");s.elements.tooltip.unbind("mouseover.qtip",s.focus);s.elements.tooltip.remove()}else{s.options.show.when.target.unbind(s.options.show.when.event+".qtip-create")}if(typeof s.elements.target.data("qtip")=="object"){y=s.elements.target.data("qtip").interfaces;if(typeof y=="object"&&y.length>0){for(w=0;w<y.length-1;w++){if(y[w].id==s.id){y.splice(w,1)}}}}delete f.fn.qtip.interfaces[s.id];if(typeof y=="object"&&y.length>0){s.elements.target.data("qtip").current=y.length-1}else{s.elements.target.removeData("qtip")}s.onDestroy.call(s);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_DESTROYED,"destroy");return s.elements.target},getPosition:function(){var w,x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"getPosition")}w=(s.elements.tooltip.css("display")!=="none")?false:true;if(w){s.elements.tooltip.css({visiblity:"hidden"}).show()}x=s.elements.tooltip.offset();if(w){s.elements.tooltip.css({visiblity:"visible"}).hide()}return x},getDimensions:function(){var w,x;if(!s.status.rendered){return f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.TOOLTIP_NOT_RENDERED,"getDimensions")}w=(!s.elements.tooltip.is(":visible"))?true:false;if(w){s.elements.tooltip.css({visiblity:"hidden"}).show()}x={height:s.elements.tooltip.outerHeight(),width:s.elements.tooltip.outerWidth()};if(w){s.elements.tooltip.css({visiblity:"visible"}).hide()}return x}})}function p(){var s,w,u,t,v,y,x;s=this;s.beforeRender.call(s);s.status.rendered=true;s.elements.tooltip='<div qtip="'+s.id+'" class="qtip '+(s.options.style.classes.tooltip||s.options.style)+'"style="display:none; -moz-border-radius:0; -webkit-border-radius:0; border-radius:0;position:'+s.options.position.type+';"> <div class="qtip-wrapper" style="position:relative; overflow:hidden; text-align:left;"> <div class="qtip-contentWrapper" style="overflow:hidden;"> <div class="qtip-content '+s.options.style.classes.content+'"></div></div></div></div>';s.elements.tooltip=f(s.elements.tooltip);s.elements.tooltip.appendTo(s.options.position.container);s.elements.tooltip.data("qtip",{current:0,interfaces:[s]});s.elements.wrapper=s.elements.tooltip.children("div:first");s.elements.contentWrapper=s.elements.wrapper.children("div:first").css({background:s.options.style.background});s.elements.content=s.elements.contentWrapper.children("div:first").css(q(s.options.style));if(f.browser.msie){s.elements.wrapper.add(s.elements.content).css({zoom:1})}if(s.options.hide.when.event=="unfocus"){s.elements.tooltip.attr("unfocus",true)}if(typeof s.options.style.width.value=="number"){s.updateWidth()}if(f("<canvas>").get(0).getContext||f.browser.msie){if(s.options.style.border.radius>0){m.call(s)}else{s.elements.contentWrapper.css({border:s.options.style.border.width+"px solid "+s.options.style.border.color})}if(s.options.style.tip.corner!==false){e.call(s)}}else{s.elements.contentWrapper.css({border:s.options.style.border.width+"px solid "+s.options.style.border.color});s.options.style.border.radius=0;s.options.style.tip.corner=false;f.fn.qtip.log.error.call(s,2,f.fn.qtip.constants.CANVAS_VML_NOT_SUPPORTED,"render")}if((typeof s.options.content.text=="string"&&s.options.content.text.length>0)||(s.options.content.text.jquery&&s.options.content.text.length>0)){u=s.options.content.text}else{if(typeof s.elements.target.attr("title")=="string"&&s.elements.target.attr("title").length>0){u=s.elements.target.attr("title").replace("\\n","<br />");s.elements.target.attr("title","")}else{if(typeof s.elements.target.attr("alt")=="string"&&s.elements.target.attr("alt").length>0){u=s.elements.target.attr("alt").replace("\\n","<br />");s.elements.target.attr("alt","")}else{u=" ";f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.NO_VALID_CONTENT,"render")}}}if(s.options.content.title.text!==false){j.call(s)}s.updateContent(u);l.call(s);if(s.options.show.ready===true){s.show()}if(s.options.content.url!==false){t=s.options.content.url;v=s.options.content.data;y=s.options.content.method||"get";s.loadContent(t,v,y)}s.onRender.call(s);f.fn.qtip.log.error.call(s,1,f.fn.qtip.constants.EVENT_RENDERED,"render")}function m(){var F,z,t,B,x,E,u,G,D,y,w,C,A,s,v;F=this;F.elements.wrapper.find(".qtip-borderBottom, .qtip-borderTop").remove();t=F.options.style.border.width;B=F.options.style.border.radius;x=F.options.style.border.color||F.options.style.tip.color;E=g(B);u={};for(z in E){u[z]='<div rel="'+z+'" style="'+((z.search(/Left/)!==-1)?"left":"right")+":0; position:absolute; height:"+B+"px; width:"+B+'px; overflow:hidden; line-height:0.1px; font-size:1px">';if(f("<canvas>").get(0).getContext){u[z]+='<canvas height="'+B+'" width="'+B+'" style="vertical-align: top"></canvas>'}else{if(f.browser.msie){G=B*2+3;u[z]+='<v:arc stroked="false" fillcolor="'+x+'" startangle="'+E[z][0]+'" endangle="'+E[z][1]+'" style="width:'+G+"px; height:"+G+"px; margin-top:"+((z.search(/bottom/)!==-1)?-2:-1)+"px; margin-left:"+((z.search(/Right/)!==-1)?E[z][2]-3.5:-1)+'px; vertical-align:top; display:inline-block; behavior:url(#default#VML)"></v:arc>'}}u[z]+="</div>"}D=F.getDimensions().width-(Math.max(t,B)*2);y='<div class="qtip-betweenCorners" style="height:'+B+"px; width:"+D+"px; overflow:hidden; background-color:"+x+'; line-height:0.1px; font-size:1px;">';w='<div class="qtip-borderTop" dir="ltr" style="height:'+B+"px; margin-left:"+B+'px; line-height:0.1px; font-size:1px; padding:0;">'+u.topLeft+u.topRight+y;F.elements.wrapper.prepend(w);C='<div class="qtip-borderBottom" dir="ltr" style="height:'+B+"px; margin-left:"+B+'px; line-height:0.1px; font-size:1px; padding:0;">'+u.bottomLeft+u.bottomRight+y;F.elements.wrapper.append(C);if(f("<canvas>").get(0).getContext){F.elements.wrapper.find("canvas").each(function(){A=E[f(this).parent("[rel]:first").attr("rel")];r.call(F,f(this),A,B,x)})}else{if(f.browser.msie){F.elements.tooltip.append('<v:image style="behavior:url(#default#VML);"></v:image>')}}s=Math.max(B,(B+(t-B)));v=Math.max(t-B,0);F.elements.contentWrapper.css({border:"0px solid "+x,borderWidth:v+"px "+s+"px"})}function r(u,w,s,t){var v=u.get(0).getContext("2d");v.fillStyle=t;v.beginPath();v.arc(w[0],w[1],s,0,Math.PI*2,false);v.fill()}function e(v){var t,s,x,u,w;t=this;if(t.elements.tip!==null){t.elements.tip.remove()}s=t.options.style.tip.color||t.options.style.border.color;if(t.options.style.tip.corner===false){return}else{if(!v){v=t.options.style.tip.corner}}x=b(v,t.options.style.tip.size.width,t.options.style.tip.size.height);t.elements.tip='<div class="'+t.options.style.classes.tip+'" dir="ltr" rel="'+v+'" style="position:absolute; height:'+t.options.style.tip.size.height+"px; width:"+t.options.style.tip.size.width+'px; margin:0 auto; line-height:0.1px; font-size:1px;">';if(f("<canvas>").get(0).getContext){t.elements.tip+='<canvas height="'+t.options.style.tip.size.height+'" width="'+t.options.style.tip.size.width+'"></canvas>'}else{if(f.browser.msie){u=t.options.style.tip.size.width+","+t.options.style.tip.size.height;w="m"+x[0][0]+","+x[0][1];w+=" l"+x[1][0]+","+x[1][1];w+=" "+x[2][0]+","+x[2][1];w+=" xe";t.elements.tip+='<v:shape fillcolor="'+s+'" stroked="false" filled="true" path="'+w+'" coordsize="'+u+'" style="width:'+t.options.style.tip.size.width+"px; height:"+t.options.style.tip.size.height+"px; line-height:0.1px; display:inline-block; behavior:url(#default#VML); vertical-align:"+((v.search(/top/)!==-1)?"bottom":"top")+'"></v:shape>';t.elements.tip+='<v:image style="behavior:url(#default#VML);"></v:image>';t.elements.contentWrapper.css("position","relative")}}t.elements.tooltip.prepend(t.elements.tip+"</div>");t.elements.tip=t.elements.tooltip.find("."+t.options.style.classes.tip).eq(0);if(f("<canvas>").get(0).getContext){h.call(t,t.elements.tip.find("canvas:first"),x,s)}if(v.search(/top/)!==-1&&f.browser.msie&&parseInt(f.browser.version.charAt(0))===6){t.elements.tip.css({marginTop:-4})}n.call(t,v)}function h(t,v,s){var u=t.get(0).getContext("2d");u.fillStyle=s;u.beginPath();u.moveTo(v[0][0],v[0][1]);u.lineTo(v[1][0],v[1][1]);u.lineTo(v[2][0],v[2][1]);u.fill()}function n(u){var t,w,s,x,v;t=this;if(t.options.style.tip.corner===false||!t.elements.tip){return}if(!u){u=t.elements.tip.attr("rel")}w=positionAdjust=(f.browser.msie)?1:0;t.elements.tip.css(u.match(/left|right|top|bottom/)[0],0);if(u.search(/top|bottom/)!==-1){if(f.browser.msie){if(parseInt(f.browser.version.charAt(0))===6){positionAdjust=(u.search(/top/)!==-1)?-3:1}else{positionAdjust=(u.search(/top/)!==-1)?1:2}}if(u.search(/Middle/)!==-1){t.elements.tip.css({left:"50%",marginLeft:-(t.options.style.tip.size.width/2)})}else{if(u.search(/Left/)!==-1){t.elements.tip.css({left:t.options.style.border.radius-w})}else{if(u.search(/Right/)!==-1){t.elements.tip.css({right:t.options.style.border.radius+w})}}}if(u.search(/top/)!==-1){t.elements.tip.css({top:-positionAdjust})}else{t.elements.tip.css({bottom:positionAdjust})}}else{if(u.search(/left|right/)!==-1){if(f.browser.msie){positionAdjust=(parseInt(f.browser.version.charAt(0))===6)?1:((u.search(/left/)!==-1)?1:2)}if(u.search(/Middle/)!==-1){t.elements.tip.css({top:"50%",marginTop:-(t.options.style.tip.size.height/2)})}else{if(u.search(/Top/)!==-1){t.elements.tip.css({top:t.options.style.border.radius-w})}else{if(u.search(/Bottom/)!==-1){t.elements.tip.css({bottom:t.options.style.border.radius+w})}}}if(u.search(/left/)!==-1){t.elements.tip.css({left:-positionAdjust})}else{t.elements.tip.css({right:positionAdjust})}}}s="padding-"+u.match(/left|right|top|bottom/)[0];x=t.options.style.tip.size[(s.search(/left|right/)!==-1)?"width":"height"];t.elements.tooltip.css("padding",0);t.elements.tooltip.css(s,x);if(f.browser.msie&&parseInt(f.browser.version.charAt(0))==6){v=parseInt(t.elements.tip.css("margin-top"))||0;v+=parseInt(t.elements.content.css("margin-top"))||0;t.elements.tip.css({marginTop:v})}}function j(){var s=this;if(s.elements.title!==null){s.elements.title.remove()}s.elements.title=f('<div class="'+s.options.style.classes.title+'">').css(q(s.options.style.title,true)).css({zoom:(f.browser.msie)?1:0}).prependTo(s.elements.contentWrapper);if(s.options.content.title.text){s.updateTitle.call(s,s.options.content.title.text)}if(s.options.content.title.button!==false&&typeof s.options.content.title.button=="string"){s.elements.button=f('<a class="'+s.options.style.classes.button+'" style="float:right; position: relative"></a>').css(q(s.options.style.button,true)).html(s.options.content.title.button).prependTo(s.elements.title).click(function(t){if(!s.status.disabled){s.hide(t)}})}}function l(){var t,v,u,s;t=this;v=t.options.show.when.target;u=t.options.hide.when.target;if(t.options.hide.fixed){u=u.add(t.elements.tooltip)}if(t.options.hide.when.event=="inactive"){s=["click","dblclick","mousedown","mouseup","mousemove","mouseout","mouseenter","mouseleave","mouseover"];function y(z){if(t.status.disabled===true){return}clearTimeout(t.timers.inactive);t.timers.inactive=setTimeout(function(){f(s).each(function(){u.unbind(this+".qtip-inactive");t.elements.content.unbind(this+".qtip-inactive")});t.hide(z)},t.options.hide.delay)}}else{if(t.options.hide.fixed===true){t.elements.tooltip.bind("mouseover.qtip",function(){if(t.status.disabled===true){return}clearTimeout(t.timers.hide)})}}function x(z){if(t.status.disabled===true){return}if(t.options.hide.when.event=="inactive"){f(s).each(function(){u.bind(this+".qtip-inactive",y);t.elements.content.bind(this+".qtip-inactive",y)});y()}clearTimeout(t.timers.show);clearTimeout(t.timers.hide);t.timers.show=setTimeout(function(){t.show(z)},t.options.show.delay)}function w(z){if(t.status.disabled===true){return}if(t.options.hide.fixed===true&&t.options.hide.when.event.search(/mouse(out|leave)/i)!==-1&&f(z.relatedTarget).parents("div.qtip[qtip]").length>0){z.stopPropagation();z.preventDefault();clearTimeout(t.timers.hide);return false}clearTimeout(t.timers.show);clearTimeout(t.timers.hide);t.elements.tooltip.stop(true,true);t.timers.hide=setTimeout(function(){t.hide(z)},t.options.hide.delay)}if((t.options.show.when.target.add(t.options.hide.when.target).length===1&&t.options.show.when.event==t.options.hide.when.event&&t.options.hide.when.event!=="inactive")||t.options.hide.when.event=="unfocus"){t.cache.toggle=0;v.bind(t.options.show.when.event+".qtip",function(z){if(t.cache.toggle==0){x(z)}else{w(z)}})}else{v.bind(t.options.show.when.event+".qtip",x);if(t.options.hide.when.event!=="inactive"){u.bind(t.options.hide.when.event+".qtip",w)}}if(t.options.position.type.search(/(fixed|absolute)/)!==-1){t.elements.tooltip.bind("mouseover.qtip",t.focus)}if(t.options.position.target==="mouse"&&t.options.position.type!=="static"){v.bind("mousemove.qtip",function(z){t.cache.mouse={x:z.pageX,y:z.pageY};if(t.status.disabled===false&&t.options.position.adjust.mouse===true&&t.options.position.type!=="static"&&t.elements.tooltip.css("display")!=="none"){t.updatePosition(z)}})}}function o(u,v,A){var z,s,x,y,t,w;z=this;if(A.corner=="center"){return v.position}s=f.extend({},u);y={x:false,y:false};t={left:(s.left<f.fn.qtip.cache.screen.scroll.left),right:(s.left+A.dimensions.width+2>=f.fn.qtip.cache.screen.width+f.fn.qtip.cache.screen.scroll.left),top:(s.top<f.fn.qtip.cache.screen.scroll.top),bottom:(s.top+A.dimensions.height+2>=f.fn.qtip.cache.screen.height+f.fn.qtip.cache.screen.scroll.top)};x={left:(t.left&&(A.corner.search(/right/i)!=-1||(A.corner.search(/right/i)==-1&&!t.right))),right:(t.right&&(A.corner.search(/left/i)!=-1||(A.corner.search(/left/i)==-1&&!t.left))),top:(t.top&&A.corner.search(/top/i)==-1),bottom:(t.bottom&&A.corner.search(/bottom/i)==-1)};if(x.left){if(z.options.position.target!=="mouse"){s.left=v.position.left+v.dimensions.width}else{s.left=z.cache.mouse.x}y.x="Left"}else{if(x.right){if(z.options.position.target!=="mouse"){s.left=v.position.left-A.dimensions.width}else{s.left=z.cache.mouse.x-A.dimensions.width}y.x="Right"}}if(x.top){if(z.options.position.target!=="mouse"){s.top=v.position.top+v.dimensions.height}else{s.top=z.cache.mouse.y}y.y="top"}else{if(x.bottom){if(z.options.position.target!=="mouse"){s.top=v.position.top-A.dimensions.height}else{s.top=z.cache.mouse.y-A.dimensions.height}y.y="bottom"}}if(s.left<0){s.left=u.left;y.x=false}if(s.top<0){s.top=u.top;y.y=false}if(z.options.style.tip.corner!==false){s.corner=new String(A.corner);if(y.x!==false){s.corner=s.corner.replace(/Left|Right|Middle/,y.x)}if(y.y!==false){s.corner=s.corner.replace(/top|bottom/,y.y)}if(s.corner!==z.elements.tip.attr("rel")){e.call(z,s.corner)}}return s}function q(u,t){var v,s;v=f.extend(true,{},u);for(s in v){if(t===true&&s.search(/(tip|classes)/i)!==-1){delete v[s]}else{if(!t&&s.search(/(width|border|tip|title|classes|user)/i)!==-1){delete v[s]}}}return v}function c(s){if(typeof s.tip!=="object"){s.tip={corner:s.tip}}if(typeof s.tip.size!=="object"){s.tip.size={width:s.tip.size,height:s.tip.size}}if(typeof s.border!=="object"){s.border={width:s.border}}if(typeof s.width!=="object"){s.width={value:s.width}}if(typeof s.width.max=="string"){s.width.max=parseInt(s.width.max.replace(/([0-9]+)/i,"$1"))}if(typeof s.width.min=="string"){s.width.min=parseInt(s.width.min.replace(/([0-9]+)/i,"$1"))}if(typeof s.tip.size.x=="number"){s.tip.size.width=s.tip.size.x;delete s.tip.size.x}if(typeof s.tip.size.y=="number"){s.tip.size.height=s.tip.size.y;delete s.tip.size.y}return s}function a(){var s,t,u,x,v,w;s=this;u=[true,{}];for(t=0;t<arguments.length;t++){u.push(arguments[t])}x=[f.extend.apply(f,u)];while(typeof x[0].name=="string"){x.unshift(c(f.fn.qtip.styles[x[0].name]))}x.unshift(true,{classes:{tooltip:"qtip-"+(arguments[0].name||"defaults")}},f.fn.qtip.styles.defaults);v=f.extend.apply(f,x);w=(f.browser.msie)?1:0;v.tip.size.width+=w;v.tip.size.height+=w;if(v.tip.size.width%2>0){v.tip.size.width+=1}if(v.tip.size.height%2>0){v.tip.size.height+=1}if(v.tip.corner===true){v.tip.corner=(s.options.position.corner.tooltip==="center")?false:s.options.position.corner.tooltip}return v}function b(v,u,t){var s={bottomRight:[[0,0],[u,t],[u,0]],bottomLeft:[[0,0],[u,0],[0,t]],topRight:[[0,t],[u,0],[u,t]],topLeft:[[0,0],[0,t],[u,t]],topMiddle:[[0,t],[u/2,0],[u,t]],bottomMiddle:[[0,0],[u,0],[u/2,t]],rightMiddle:[[0,0],[u,t/2],[0,t]],leftMiddle:[[u,0],[u,t],[0,t/2]]};s.leftTop=s.bottomRight;s.rightTop=s.bottomLeft;s.leftBottom=s.topRight;s.rightBottom=s.topLeft;return s[v]}function g(s){var t;if(f("<canvas>").get(0).getContext){t={topLeft:[s,s],topRight:[0,s],bottomLeft:[s,0],bottomRight:[0,0]}}else{if(f.browser.msie){t={topLeft:[-90,90,0],topRight:[-90,90,-s],bottomLeft:[90,270,0],bottomRight:[90,270,-s]}}}return t}function k(){var s,t,u;s=this;u=s.getDimensions();t='<iframe class="qtip-bgiframe" frameborder="0" tabindex="-1" src="javascript:false" style="display:block; position:absolute; z-index:-1; filter:alpha(opacity=\'0\'); border: 1px solid red; height:'+u.height+"px; width:"+u.width+'px" />';s.elements.bgiframe=s.elements.wrapper.prepend(t).children(".qtip-bgiframe:first")}f(document).ready(function(){f.fn.qtip.cache={screen:{scroll:{left:f(window).scrollLeft(),top:f(window).scrollTop()},width:f(window).width(),height:f(window).height()}};var s;f(window).bind("resize scroll",function(t){clearTimeout(s);s=setTimeout(function(){if(t.type==="scroll"){f.fn.qtip.cache.screen.scroll={left:f(window).scrollLeft(),top:f(window).scrollTop()}}else{f.fn.qtip.cache.screen.width=f(window).width();f.fn.qtip.cache.screen.height=f(window).height()}for(i=0;i<f.fn.qtip.interfaces.length;i++){var u=f.fn.qtip.interfaces[i];if(u.status.rendered===true&&(u.options.position.type!=="static"||u.options.position.adjust.scroll&&t.type==="scroll"||u.options.position.adjust.resize&&t.type==="resize")){u.updatePosition(t,true)}}},100)});f(document).bind("mousedown.qtip",function(t){if(f(t.target).parents("div.qtip").length===0){f(".qtip[unfocus]").each(function(){var u=f(this).qtip("api");if(f(this).is(":visible")&&!u.status.disabled&&f(t.target).add(u.elements.target).length>1){u.hide(t)}})}})});f.fn.qtip.interfaces=[];f.fn.qtip.log={error:function(){return this}};f.fn.qtip.constants={};f.fn.qtip.defaults={content:{prerender:false,text:false,url:false,data:null,title:{text:false,button:false}},position:{target:false,corner:{target:"bottomRight",tooltip:"topLeft"},adjust:{x:0,y:0,mouse:true,screen:false,scroll:true,resize:true},type:"absolute",container:false},show:{when:{target:false,event:"mouseover"},effect:{type:"fade",length:100},delay:140,solo:false,ready:false},hide:{when:{target:false,event:"mouseout"},effect:{type:"fade",length:100},delay:0,fixed:false},api:{beforeRender:function(){},onRender:function(){},beforePositionUpdate:function(){},onPositionUpdate:function(){},beforeShow:function(){},onShow:function(){},beforeHide:function(){},onHide:function(){},beforeContentUpdate:function(){},onContentUpdate:function(){},beforeContentLoad:function(){},onContentLoad:function(){},beforeTitleUpdate:function(){},onTitleUpdate:function(){},beforeDestroy:function(){},onDestroy:function(){},beforeFocus:function(){},onFocus:function(){}}};f.fn.qtip.styles={defaults:{background:"white",color:"#111",overflow:"hidden",textAlign:"left",width:{min:0,max:250},padding:"5px 9px",border:{width:1,radius:0,color:"#d3d3d3"},tip:{corner:false,color:false,size:{width:13,height:13},opacity:1},title:{background:"#e1e1e1",fontWeight:"bold",padding:"7px 12px"},button:{cursor:"pointer"},classes:{target:"",tip:"qtip-tip",title:"qtip-title",button:"qtip-button",content:"qtip-content",active:"qtip-active"}},cream:{border:{width:3,radius:0,color:"#F9E98E"},title:{background:"#F0DE7D",color:"#A27D35"},background:"#FBF7AA",color:"#A27D35",classes:{tooltip:"qtip-cream"}},light:{border:{width:3,radius:0,color:"#E2E2E2"},title:{background:"#f1f1f1",color:"#454545"},background:"white",color:"#454545",classes:{tooltip:"qtip-light"}},dark:{border:{width:3,radius:0,color:"#303030"},title:{background:"#404040",color:"#f3f3f3"},background:"#505050",color:"#f3f3f3",classes:{tooltip:"qtip-dark"}},red:{border:{width:3,radius:0,color:"#CE6F6F"},title:{background:"#f28279",color:"#9C2F2F"},background:"#F79992",color:"#9C2F2F",classes:{tooltip:"qtip-red"}},green:{border:{width:3,radius:0,color:"#A9DB66"},title:{background:"#b9db8c",color:"#58792E"},background:"#CDE6AC",color:"#58792E",classes:{tooltip:"qtip-green"}},blue:{border:{width:3,radius:0,color:"#ADD9ED"},title:{background:"#D0E9F5",color:"#5E99BD"},background:"#E5F6FE",color:"#4D9FBF",classes:{tooltip:"qtip-blue"}}}})(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
languages/google-calendar-events-hu_HU.mo ADDED
Binary file
languages/google-calendar-events-hu_HU.po ADDED
@@ -0,0 +1,500 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Translation of the WordPress plugin Google Calendar Events 0.4 by Ross Hanney.
2
+ # Copyright (C) 2010 Ross Hanney
3
+ # This file is distributed under the same license as the Google Calendar Events package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
5
+ #
6
+ msgid ""
7
+ msgstr ""
8
+ "Project-Id-Version: Google Calendar Events 0.4\n"
9
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/google-calendar-events\n"
10
+ "POT-Creation-Date: 2010-08-19 10:31+0000\n"
11
+ "PO-Revision-Date: 2010-08-31 09:01+0100\n"
12
+ "Last-Translator: Takács Dániel <daniel.takacs@gmail.com>\n"
13
+ "Language-Team: Hungarian <daniel.takacs@gmail.com>\n"
14
+ "MIME-Version: 1.0\n"
15
+ "Content-Type: text/plain; charset=utf-8\n"
16
+ "Content-Transfer-Encoding: 8bit\n"
17
+ "X-Poedit-Language: Hungarian\n"
18
+ "X-Poedit-Country: Hungary\n"
19
+
20
+ #: admin/add.php:9
21
+ msgid "Add a Feed"
22
+ msgstr "Csatorna hozzáadása"
23
+
24
+ #: admin/add.php:11
25
+ #: admin/delete.php:11
26
+ #: admin/edit.php:11
27
+ msgid "Feed ID"
28
+ msgstr "Csatorna azonosítója"
29
+
30
+ #: admin/add.php:12
31
+ #: admin/delete.php:12
32
+ #: admin/edit.php:12
33
+ msgid "Feed Title"
34
+ msgstr "Csatorna címe"
35
+
36
+ #: admin/add.php:13
37
+ #: admin/edit.php:13
38
+ msgid "Feed URL"
39
+ msgstr "Csatorna URL"
40
+
41
+ #: admin/add.php:14
42
+ #: admin/edit.php:14
43
+ msgid "Retrieve past events for current month?"
44
+ msgstr "A jelenlegi hónapban történt, de már eltelt eseményeket is lekérdezzem?"
45
+
46
+ #: admin/add.php:15
47
+ #: admin/edit.php:15
48
+ msgid "Maximum number of events to retrieve"
49
+ msgstr "A lekérdezendő események maximális száma"
50
+
51
+ #: admin/add.php:16
52
+ #: admin/edit.php:16
53
+ msgid "Number of days in the future to retrieve events for"
54
+ msgstr "A lekérdezendő következő napok száma"
55
+
56
+ #: admin/add.php:17
57
+ #: admin/edit.php:17
58
+ msgid "Date format"
59
+ msgstr "Dátum formátuma"
60
+
61
+ #: admin/add.php:18
62
+ #: admin/edit.php:18
63
+ msgid "Time format"
64
+ msgstr "Idő formátuma"
65
+
66
+ #: admin/add.php:19
67
+ #: admin/edit.php:19
68
+ msgid "Timezone adjustment"
69
+ msgstr "Időzóna beállítása"
70
+
71
+ #: admin/add.php:20
72
+ #: admin/edit.php:20
73
+ msgid "Cache duration"
74
+ msgstr "Tároló frissítése"
75
+
76
+ #: admin/add.php:21
77
+ #: admin/edit.php:21
78
+ msgid "Show multiple day events on each day?"
79
+ msgstr "A több napos események minden nap külön látszódjanak?"
80
+
81
+ #: admin/add.php:23
82
+ #: admin/edit.php:23
83
+ msgid "Display Options"
84
+ msgstr "Megjelenítési beállítások"
85
+
86
+ #: admin/add.php:24
87
+ #: admin/edit.php:24
88
+ msgid "Display start time / date?"
89
+ msgstr "Látszódjon a kezdő idő / dátum?"
90
+
91
+ #: admin/add.php:25
92
+ #: admin/edit.php:25
93
+ msgid "Display end time / date?"
94
+ msgstr "Látszódjon a befejező idő / dátum?"
95
+
96
+ #: admin/add.php:26
97
+ #: admin/edit.php:26
98
+ msgid "Separator text / characters"
99
+ msgstr "Elválasztó szöveg / karakterek"
100
+
101
+ #: admin/add.php:27
102
+ #: admin/edit.php:27
103
+ msgid "Display location?"
104
+ msgstr "Látszódjon a hely?"
105
+
106
+ #: admin/add.php:28
107
+ #: admin/edit.php:28
108
+ msgid "Display description?"
109
+ msgstr "Látszódjon a leírás?"
110
+
111
+ #: admin/add.php:29
112
+ #: admin/edit.php:29
113
+ msgid "Display link to event?"
114
+ msgstr "Látszódjon az eseményre mutató linK:"
115
+
116
+ #: admin/add.php:34
117
+ msgid "Enter the feed details below, then click the Add Feed button."
118
+ msgstr "Addja meg a csatorna részleteit, majd nyomja meg a Csatorna hozzáadása gombot."
119
+
120
+ #: admin/add.php:58
121
+ #: admin/edit.php:53
122
+ msgid "Anything you like. 'Upcoming Club Events', for example."
123
+ msgstr "Ami tetszik, pl. \"A következő Klub programok.\""
124
+
125
+ #: admin/add.php:67
126
+ #: admin/edit.php:64
127
+ msgid "This will probably be something like: <code>http://www.google.com/calendar/feeds/your-email@gmail.com/public/full</code>."
128
+ msgstr "Ez valahogy így fog kinézni: <code>http://www.google.com/calendar/feeds/your-email@gmail.com/public/full</code>."
129
+
130
+ #: admin/add.php:76
131
+ #: admin/edit.php:75
132
+ msgid "If checked, events will be retrieved from the first of this month onwards. If unchecked, events will be retrieved from today onwards."
133
+ msgstr "Ha be van jelölve, akkor a jelenlegi hónap első napjától lesznek listázva az események, ha nem, akkor csak az adott naptól."
134
+
135
+ #: admin/add.php:85
136
+ #: admin/edit.php:86
137
+ msgid "The default number of events to retrieve from a Google Calendar feed is 25, but you may want less for a list, or more for a calendar grid."
138
+ msgstr "A Google Naptár csatornájának alapértelmezett beállítása 25 esemény lekérdezése egyszerre, de ennél lehet többet és kevesebbet is beállítani."
139
+
140
+ #: admin/add.php:94
141
+ #: admin/edit.php:97
142
+ msgid "The number of days in the future to retrieve events for (from 12:00am today). Leave blank for no day limit."
143
+ msgstr "Ahány napot lekérdezzen a jövőben (ma déli 12 órától kezdve). Hagyja üresen, ha nem akar limitet beállítani."
144
+
145
+ #: admin/add.php:103
146
+ #: admin/edit.php:108
147
+ msgid "In <a href=\"http://php.net/manual/en/function.date.php\">PHP date format</a>. Leave this blank if you'd rather stick with the default format for your blog."
148
+ msgstr "<a href=\"http://php.net/manual/en/function.date.php\">PHP dátum formátum</a>. Hagyja üresen, ha a honlap alapértelmezését szeretné meghagyni."
149
+
150
+ #: admin/add.php:112
151
+ #: admin/edit.php:119
152
+ msgid "In <a href=\"http://php.net/manual/en/function.date.php\">PHP date format</a>. Again, leave this blank to stick with the default."
153
+ msgstr "<a href=\"http://php.net/manual/en/function.date.php\">PHP dátum formátum</a>. Hagyja üresen ezt is, ha a honlap alapértelmezését szeretné meghagyni."
154
+
155
+ #: admin/add.php:125
156
+ #: admin/edit.php:134
157
+ msgid "If you are having problems with dates and times displaying in the wrong timezone, select a city in your required timezone here."
158
+ msgstr "Ha valami probléma adódik a dátumokkal és az idővel, itt tudja kiválasztani az időzónájának megfelelő várost."
159
+
160
+ #: admin/add.php:134
161
+ #: admin/edit.php:145
162
+ msgid "The length of time, in seconds, to cache the feed (43200 = 12 hours). If this feed changes regularly, you may want to reduce the cache duration."
163
+ msgstr "A tároló lejáratának ideje, másodpercben (43200 másodperc = 1 óra). Ha a csatorna rendszeresen frissül, érdemes kisebb időközre állítani."
164
+
165
+ #: admin/add.php:143
166
+ #: admin/edit.php:156
167
+ msgid "Show events that span multiple days on each day that they span (There are some limitations of this feature to be aware of)."
168
+ msgstr "A több napon keresztül tartó események az időtartamuk alatt minden egyes nap külön jelenjenek meg. (Néhány korlátozást figyelembe kell venni ennél a lehetőségnél.)"
169
+
170
+ #: admin/add.php:154
171
+ #: admin/edit.php:167
172
+ msgid "These settings control what information will be displayed for this feed in the tooltip (for grids), or in a list."
173
+ msgstr "Ezek a beállítások adják meg azt, hogy milyen információk jelenjenek meg a csatornáról a tippek közt (a naptárdobozban) vagy egy listában."
174
+
175
+ #: admin/add.php:155
176
+ #: admin/edit.php:168
177
+ msgid "You can use some HTML in the text fields, but ensure it is valid or things might go wonky. Text fields can be empty too."
178
+ msgstr "Használhat HTML-t is a szövegmezőkben, de mindig győződjön meg, hogy szabványos kódot adott meg, különben könnyen összekuszálódhatnak a dolgok. A szövegmezők üresen is maradhatnak."
179
+
180
+ #: admin/add.php:161
181
+ #: admin/edit.php:176
182
+ msgid "Select how to display the start date / time."
183
+ msgstr "Válassza ki, hogyan jelenjen meg a kezdő idő / dátum."
184
+
185
+ #: admin/add.php:164
186
+ #: admin/edit.php:179
187
+ msgid "Don't display start time or date"
188
+ msgstr "Ne mutassa a kezdő időt vagy dátumot"
189
+
190
+ #: admin/add.php:165
191
+ #: admin/edit.php:180
192
+ msgid "Display start time"
193
+ msgstr "Mutassa a kezdő időt"
194
+
195
+ #: admin/add.php:166
196
+ #: admin/edit.php:181
197
+ msgid "Display start date"
198
+ msgstr "Mutassa a kezdő dátumot"
199
+
200
+ #: admin/add.php:167
201
+ #: admin/edit.php:182
202
+ msgid "Display start time and date (in that order)"
203
+ msgstr "Mutassa a kezdő időt és dátumot (ebben a sorrendben)"
204
+
205
+ #: admin/add.php:168
206
+ #: admin/edit.php:183
207
+ msgid "Display start date and time (in that order)"
208
+ msgstr "Mutassa a kezdő dátumot és időt (ebben a sorrendben)"
209
+
210
+ #: admin/add.php:171
211
+ #: admin/edit.php:186
212
+ msgid "Text to display before the start time."
213
+ msgstr "A kezdő idő előtt megjelenítendő szöveg."
214
+
215
+ #: admin/add.php:179
216
+ #: admin/edit.php:196
217
+ msgid "Select how to display the end date / time."
218
+ msgstr "Válassza ki, hogyan jelenjen meg a befejező idő / dátum."
219
+
220
+ #: admin/add.php:182
221
+ #: admin/edit.php:199
222
+ msgid "Don't display end time or date"
223
+ msgstr "Ne mutassa a befejező időt vagy dátumot"
224
+
225
+ #: admin/add.php:183
226
+ #: admin/edit.php:200
227
+ msgid "Display end time"
228
+ msgstr "Mutassa a befejező időt"
229
+
230
+ #: admin/add.php:184
231
+ #: admin/edit.php:201
232
+ msgid "Display end date"
233
+ msgstr "Mutassa a befejező dátumot"
234
+
235
+ #: admin/add.php:185
236
+ #: admin/edit.php:202
237
+ msgid "Display end time and date (in that order)"
238
+ msgstr "Mutassa a befejező időt és dátumot (ebben a sorrendben)"
239
+
240
+ #: admin/add.php:186
241
+ #: admin/edit.php:203
242
+ msgid "Display end date and time (in that order)"
243
+ msgstr "Mutassa a befejező dátumot és időt (ebben a sorrendben)"
244
+
245
+ #: admin/add.php:189
246
+ #: admin/edit.php:206
247
+ msgid "Text to display before the end time."
248
+ msgstr "A befejező idő előtt megjelenítendő szöveg."
249
+
250
+ #: admin/add.php:197
251
+ #: admin/edit.php:216
252
+ msgid "If you have chosen to display both the time and date above, enter the text / characters to display between the time and date here (including any spaces)."
253
+ msgstr "Ha azt választotta feljebb, hogy mind az idő, mind a dátum látszódjék, írja be az elválasztó szöveget / karaktereket, ami az idő és a dátum közt legyen (akármennyi szóközzel)."
254
+
255
+ #: admin/add.php:206
256
+ #: admin/edit.php:227
257
+ msgid "Show the location of events?"
258
+ msgstr "Látszódjon az esemény helye?"
259
+
260
+ #: admin/add.php:208
261
+ #: admin/edit.php:229
262
+ msgid "Text to display before the location."
263
+ msgstr "A hely előtt megjelenítendő szöveg."
264
+
265
+ #: admin/add.php:217
266
+ msgid "Show the description of events? (URLs in the description will be made into links)."
267
+ msgstr "Látszódjon az esemény leírása? (A leírásban lévő URL-ek linkként jelennek meg)."
268
+
269
+ #: admin/add.php:219
270
+ #: admin/edit.php:242
271
+ msgid "Text to display before the description."
272
+ msgstr "A leírás előtt megjelenítendő szöveg."
273
+
274
+ #: admin/add.php:223
275
+ #: admin/edit.php:246
276
+ msgid "Maximum number of words to show from description. Leave blank for no limit."
277
+ msgstr "A leírásból megjelenítendő szavak maximális száma. Hagyja üresen, ha nem akar limitet beállítani."
278
+
279
+ #: admin/add.php:232
280
+ #: admin/edit.php:257
281
+ msgid "Show a link to the Google Calendar page for an event?"
282
+ msgstr "Mutasson link a Google Naptárra az eseményeknél?"
283
+
284
+ #: admin/add.php:235
285
+ #: admin/edit.php:260
286
+ msgid "Links open in a new window / tab?"
287
+ msgstr "A link új ablakon / fülön nyíljon?"
288
+
289
+ #: admin/add.php:237
290
+ #: admin/edit.php:262
291
+ msgid "The link text to be displayed."
292
+ msgstr "A megjelenítendő link szövege"
293
+
294
+ #: admin/delete.php:9
295
+ #: google-calendar-events.php:201
296
+ msgid "Delete Feed"
297
+ msgstr "Csatorna törlése"
298
+
299
+ #: admin/delete.php:17
300
+ msgid "Are you want you want to delete this feed? (Remember to remove / adjust any widgets or shortcodes associated with this feed)."
301
+ msgstr "Biztosan törölni akarja a csatornát? (Ne felejtse el eltávolítani vagy módosítani a csatornára hivatkozó összes dobozt vagy kódrészletet)."
302
+
303
+ #: admin/edit.php:9
304
+ msgid "Edit Feed"
305
+ msgstr "Csatorna szerkesztése"
306
+
307
+ #: admin/edit.php:34
308
+ msgid "Make any changes you require to the feed details below, then click the Save Changes button."
309
+ msgstr "Végezze el a szükséges módosításokat alább, majd nyomja meg a Változtatások mentése gombot."
310
+
311
+ #: admin/edit.php:240
312
+ msgid "Show the description of events? (URLs in the description will be made into links)."
313
+ msgstr "Látszódjon az esemény leírása? (A leírásban lévő URL-ek linkként jelennek meg)."
314
+
315
+ #: admin/main.php:2
316
+ msgid "Add a New Feed"
317
+ msgstr "Új csatorna hozzáadása"
318
+
319
+ #: admin/main.php:4
320
+ msgid "Click here to add a new feed"
321
+ msgstr "Kattintson ide új csatorna hozzáadásához"
322
+
323
+ #: admin/main.php:4
324
+ #: google-calendar-events.php:186
325
+ msgid "Add Feed"
326
+ msgstr "Csatorna hozzáadása"
327
+
328
+ #: admin/main.php:7
329
+ msgid "Current Feeds"
330
+ msgstr "Jelenlegi csatornák"
331
+
332
+ #: admin/main.php:16
333
+ msgid "You haven't added any Google Calendar feeds yet."
334
+ msgstr "Még nem adott hozzá egyetlen Google Naptár csatornát sem."
335
+
336
+ #: admin/main.php:24
337
+ #: admin/main.php:32
338
+ msgid "ID"
339
+ msgstr "Azonosító"
340
+
341
+ #: admin/main.php:25
342
+ #: admin/main.php:33
343
+ msgid "Title"
344
+ msgstr "Cím"
345
+
346
+ #: admin/main.php:26
347
+ #: admin/main.php:34
348
+ msgid "URL"
349
+ msgstr "URL"
350
+
351
+ #: admin/main.php:47
352
+ msgid "Edit"
353
+ msgstr "Szerkeszt"
354
+
355
+ #: admin/main.php:47
356
+ msgid "Delete"
357
+ msgstr "Töröl"
358
+
359
+ #: admin/main.php:61
360
+ msgid "General Options"
361
+ msgstr "Beállítások"
362
+
363
+ #: admin/main.php:65
364
+ msgid "Custom stylesheet URL"
365
+ msgstr "Saját stíluslap elérési útvonala"
366
+
367
+ #: admin/main.php:67
368
+ msgid ""
369
+ "If you want to make changes to the default CSS, make a copy of <code>google-calendar-events/css/gce-style.css</code> on your server. Make any \r\n"
370
+ "\t\t\t\tchanges to the copy. Enter the URL to the copied file below."
371
+ msgstr ""
372
+ "Ha szeretné megváltoztatni az eredeti CSS-t, készítsen egy másolatot a <code>google-calendar-events/css/gce-style.css</code> fájlról a szerveren. \r\n"
373
+ "\t\t\t\tVégezze el a módosításokat, majd írja be a másolat URL-jét alább."
374
+
375
+ #: admin/main.php:73
376
+ msgid "Add JavaScript to footer?"
377
+ msgstr "Adhatok JavaScriptet a lábléchez?"
378
+
379
+ #: admin/main.php:75
380
+ msgid "If you are having issues with tooltips not appearing or the AJAX functionality not working, try ticking the checkbox below."
381
+ msgstr "Ha nem jelennek meg a tippek, vagy az AJAX-funkciók nem működnek, próbálkozzon az alábbi jelölőnégyzet kipipálásával."
382
+
383
+ #: admin/main.php:80
384
+ msgid "Loading text"
385
+ msgstr "Töltés közbeni szöveg"
386
+
387
+ #: admin/main.php:82
388
+ msgid "Text to display while calendar data is loading (on AJAX requests)"
389
+ msgstr "Az AJAX-kérések töltődése során megjelenő szöveg."
390
+
391
+ #: admin/main.php:91
392
+ msgid "Save"
393
+ msgstr "Mentés"
394
+
395
+ #: google-calendar-events.php:148
396
+ msgid "Settings"
397
+ msgstr "Beállítások"
398
+
399
+ #: google-calendar-events.php:163
400
+ msgid "New Feed Added Successfully."
401
+ msgstr "Az új csatorná sikeresen hozzáadta."
402
+
403
+ #: google-calendar-events.php:166
404
+ msgid "Feed Details Updated Successfully."
405
+ msgstr "A csatorna részletei sikeresen frissültek."
406
+
407
+ #: google-calendar-events.php:169
408
+ msgid "Feed Deleted Successfully."
409
+ msgstr "A csatorna sikeresen törlődött."
410
+
411
+ #. #-#-#-#-# plugin.pot (Google Calendar Events 0.3.1) #-#-#-#-#
412
+ #. Plugin Name of the plugin/theme
413
+ #: google-calendar-events.php:176
414
+ #: widget/gce-widget.php:6
415
+ msgid "Google Calendar Events"
416
+ msgstr "Google Naptár Események"
417
+
418
+ #: google-calendar-events.php:187
419
+ #: google-calendar-events.php:195
420
+ #: google-calendar-events.php:202
421
+ msgid "Cancel"
422
+ msgstr "Mégsem"
423
+
424
+ #: google-calendar-events.php:194
425
+ msgid "Save Changes"
426
+ msgstr "Változások mentése"
427
+
428
+ #: google-calendar-events.php:353
429
+ msgid "No valid Feed IDs have been entered for this shortcode. Please check that you have entered the IDs correctly and that the Feeds have not been deleted."
430
+ msgstr "Nincs érvényes Csatornaazonosító megadva ehhez a kódrészlethez. Kérem, ellenőrizze, hogy az azonosítót helyesen adta-e meg, és hogy a csatornát nem törölte-e."
431
+
432
+ #: google-calendar-events.php:369
433
+ #: widget/gce-widget.php:76
434
+ msgid "No feeds have been added yet. You can add a feed in the Google Calendar Events settings."
435
+ msgstr "Még nem adott meg csatornát. Csatornát a Google Naptár Események beállításánál tud hozzáadni."
436
+
437
+ #: google-calendar-events.php:428
438
+ #: google-calendar-events.php:445
439
+ #: widget/gce-widget.php:146
440
+ #: widget/gce-widget.php:158
441
+ #, php-format
442
+ msgid "The following feeds were not parsed successfully: %s. Please check that the feed URLs are correct and that the feeds have public sharing enabled."
443
+ msgstr "A következő csatornákat nem lehetett feldolgozni: %s. Kérem, ellenőrizze, hogy a csatornák URL-je helyes-e, és hogy a csatornák nyilvánossá lettek-e téve."
444
+
445
+ #: inc/gce-parser.php:213
446
+ msgid "There are currently no upcoming events."
447
+ msgstr "Nincs esemény a közeljövőben."
448
+
449
+ #: widget/gce-widget.php:6
450
+ msgid "Display a list or calendar grid of events from one or more Google Calendar feeds you have added"
451
+ msgstr "Listát vagy hagyományos naptárat jelenít meg a megadott Google Naptár csatornából vagy csatornákból."
452
+
453
+ #: widget/gce-widget.php:40
454
+ msgid "No valid Feed IDs have been entered for this widget. Please check that you have entered the IDs correctly and that the Feeds have not been deleted."
455
+ msgstr "Nincs érvényes azonosító adva ehhez a dobozhoz. Kérem, ellenőrizze, hogy helyesen adta-e meg az azonosítót, és hogy a csatoránt nem törölte-e."
456
+
457
+ #: widget/gce-widget.php:99
458
+ msgid "No feeds have been added yet. You can add feeds in the Google Calendar Events settings."
459
+ msgstr "Még nem adott meg csatornát. Csatornát a Google Naptár Események beállításánál tud hozzáadni."
460
+
461
+ #: widget/gce-widget.php:113
462
+ msgid "Feed IDs to display in this widget, separated by commas (e.g. 1, 2, 4):"
463
+ msgstr "A dobozban megjelenítendő csatornák azonosítója, vesszővel elválasztva (pl. 1, 2, 4):"
464
+
465
+ #: widget/gce-widget.php:117
466
+ msgid "Display as:"
467
+ msgstr "Megjelenítés mint:"
468
+
469
+ #: widget/gce-widget.php:119
470
+ msgid "Calendar Grid"
471
+ msgstr "Naptárdoboz"
472
+
473
+ #: widget/gce-widget.php:120
474
+ msgid "Calendar Grid - with AJAX"
475
+ msgstr "Naptárdoboz - AJAX"
476
+
477
+ #: widget/gce-widget.php:121
478
+ msgid "List"
479
+ msgstr "Lista"
480
+
481
+ #: widget/gce-widget.php:122
482
+ msgid "List - grouped by date"
483
+ msgstr "Lista dátum szerint csoportosítva"
484
+
485
+ #. Plugin URI of the plugin/theme
486
+ msgid "http://www.rhanney.co.uk/plugins/google-calendar-events"
487
+ msgstr "http://www.rhanney.co.uk/plugins/google-calendar-events"
488
+
489
+ #. Description of the plugin/theme
490
+ msgid "Parses Google Calendar feeds and displays the events as a calendar grid or list on a page, post or widget."
491
+ msgstr "Google Naptár csatornákat dolgoz fel és jeleníti meg naptárdobozként vagy listában a megadott oldalon, bejegyzésben vagy dobozban."
492
+
493
+ #. Author of the plugin/theme
494
+ msgid "Ross Hanney"
495
+ msgstr "Ross Hanney"
496
+
497
+ #. Author URI of the plugin/theme
498
+ msgid "http://www.rhanney.co.uk"
499
+ msgstr "http://www.rhanney.co.uk"
500
+
readme.txt CHANGED
@@ -1,9 +1,10 @@
1
  === Google Calendar Events ===
2
  Contributors: rosshanney
 
3
  Tags: google, google calendar, calendar, event, events, ajax, widget
4
  Requires at least: 2.9.2
5
- Tested up to: 3.0.1
6
- Stable tag: 0.4
7
 
8
  Parses Google Calendar feeds and displays the events as a calendar grid or list on a page, post or widget.
9
 
@@ -21,8 +22,6 @@ Parses Google Calendar feeds and displays the events as a calendar grid or list
21
  * Options to change the information displayed (start time, location, description etc.).
22
  * Calendar grids can have the ability to change the month displayed, utilising AJAX
23
 
24
- Anyone upgrading from a version earlier than 0.3 should note that the 'Display title?' option has been moved from the feed settings to the widget / shortcode settings. You will need to re-enter any titles you specified.
25
-
26
  Please visit the plugin homepage for how to get started and other help:
27
 
28
  * [Plugin Homepage](http://www.rhanney.co.uk/plugins/google-calendar-events)
@@ -31,9 +30,9 @@ There is also a demonstration page showing the plugin in action:
31
 
32
  * [Demo Page](http://www.rhanney.co.uk/plugins/google-calendar-events/gce-demo)
33
 
34
- For a summary of the new features in 0.4, visit:
35
 
36
- * [0.4 Features](http://www.rhanney.co.uk/2010/08/19/google-calendar-events-0-4)
37
 
38
  == Installation ==
39
 
@@ -57,6 +56,15 @@ You can now start adding feeds. Visit the [plugin homepage](http://www.rhanney.c
57
 
58
  == Changelog ==
59
 
 
 
 
 
 
 
 
 
 
60
  = 0.4 =
61
  * More control over how start and end dates / times are displayed
62
  * Events can now be limited to a specified timeframe (number of days)
@@ -106,8 +114,8 @@ You can now start adding feeds. Visit the [plugin homepage](http://www.rhanney.c
106
 
107
  == Upgrade Notice ==
108
 
109
- = 0.4 =
110
- New features and a few bug fixes.
111
 
112
  == Frequently Asked Questions ==
113
 
1
  === Google Calendar Events ===
2
  Contributors: rosshanney
3
+ Donate link: http://www.rhanney.co.uk/plugins/google-calendar-events/#donate
4
  Tags: google, google calendar, calendar, event, events, ajax, widget
5
  Requires at least: 2.9.2
6
+ Tested up to: 3.1
7
+ Stable tag: 0.4.1
8
 
9
  Parses Google Calendar feeds and displays the events as a calendar grid or list on a page, post or widget.
10
 
22
  * Options to change the information displayed (start time, location, description etc.).
23
  * Calendar grids can have the ability to change the month displayed, utilising AJAX
24
 
 
 
25
  Please visit the plugin homepage for how to get started and other help:
26
 
27
  * [Plugin Homepage](http://www.rhanney.co.uk/plugins/google-calendar-events)
30
 
31
  * [Demo Page](http://www.rhanney.co.uk/plugins/google-calendar-events/gce-demo)
32
 
33
+ For those upgrading to 0.4.1; there are a few slight changes to be aware of:
34
 
35
+ * [0.4.1 Changes](http://www.rhanney.co.uk/2011/01/16/google-calendar-events-0-4-1)
36
 
37
  == Installation ==
38
 
56
 
57
  == Changelog ==
58
 
59
+ = 0.4.1 =
60
+
61
+ * Fix / workaround for the long-running timezone bug. Please take a look at [this](http://www.rhanney.co.uk/2011/01/16/google-calendar-events-0-4-1) for more information.
62
+ * Added additional 'Maximum no. events to display' option to widget / shortcode (mainly to address a further issue caused by the above fix)
63
+ * i18n related bug fix
64
+ * Added support for widget_title filter (courtesy of [James](http://lunasea-studios.com))
65
+ * Added Hungarian (hu_HU) translation ([danieltakacs](http://ek.klog.hu))
66
+ * Now using minified version of jQuery qTip script
67
+
68
  = 0.4 =
69
  * More control over how start and end dates / times are displayed
70
  * Events can now be limited to a specified timeframe (number of days)
114
 
115
  == Upgrade Notice ==
116
 
117
+ = 0.4.1 =
118
+ Bug fixes.
119
 
120
  == Frequently Asked Questions ==
121
 
widget/gce-widget.php CHANGED
@@ -18,7 +18,8 @@ class GCE_Widget extends WP_Widget{
18
  //Check whether any feeds have been added yet
19
  if(is_array($options) && !empty($options)){
20
  //Output title stuff
21
- echo $before_title . $instance['title'] . $after_title;
 
22
 
23
  //Break comma delimited list of feed ids into array
24
  $feed_ids = explode(',', str_replace(' ', '', $instance['id']));
@@ -44,30 +45,32 @@ class GCE_Widget extends WP_Widget{
44
 
45
  $title_text = $instance['display_title'] ? $instance['display_title_text'] : null;
46
 
 
 
47
  //Output correct widget content based on display type chosen
48
  switch($instance['display_type']){
49
  case 'grid':
50
  echo '<div class="gce-widget-grid" id="' . $args['widget_id'] . '-container">';
51
  //Output main widget content as grid (no AJAX)
52
- gce_widget_content_grid($feed_ids, $title_text, $args['widget_id'] . '-container');
53
  echo '</div>';
54
  break;
55
  case 'ajax':
56
  echo '<div class="gce-widget-grid" id="' . $args['widget_id'] . '-container">';
57
  //Output main widget content as grid (with AJAX)
58
- gce_widget_content_grid($feed_ids, $title_text, $args['widget_id'] . '-container', true);
59
  echo '</div>';
60
  break;
61
  case 'list':
62
  echo '<div class="gce-widget-list" id="' . $args['widget_id'] . '-container">';
63
  //Output main widget content as list
64
- gce_widget_content_list($feed_ids, $title_text);
65
  echo '</div>';
66
  break;
67
  case 'list-grouped':
68
  echo '<div class="gce-widget-list" id="' . $args['widget_id'] . '-container">';
69
  //Output main widget content as a grouped list
70
- gce_widget_content_list($feed_ids, $title_text, true);
71
  echo '</div>';
72
  break;
73
  }
@@ -85,6 +88,7 @@ class GCE_Widget extends WP_Widget{
85
  $instance['title'] = esc_html($new_instance['title']);
86
  $instance['id'] = esc_html($new_instance['id']);
87
  $instance['display_type'] = esc_html($new_instance['display_type']);
 
88
  $instance['display_title'] = $new_instance['display_title'] == 'on' ? true : false;
89
  $instance['display_title_text'] = wp_filter_kses($new_instance['display_title_text']);
90
  return $instance;
@@ -102,6 +106,7 @@ class GCE_Widget extends WP_Widget{
102
  $title = isset($instance['title']) ? $instance['title'] : '';
103
  $ids = isset($instance['id']) ? $instance['id'] : '';
104
  $display_type = isset($instance['display_type']) ? $instance['display_type'] : 'grid';
 
105
  $display_title = isset($instance['display_title']) ? $instance['display_title'] : true;
106
  $title_text = isset($instance['display_title_text']) ? $instance['display_title_text'] : 'Events on';
107
  ?>
@@ -121,6 +126,9 @@ class GCE_Widget extends WP_Widget{
121
  <option value="list"<?php selected($display_type, 'list');?>><?php _e('List', GCE_TEXT_DOMAIN); ?></option>
122
  <option value="list-grouped"<?php selected($display_type, 'list-grouped');?>><?php _e('List - grouped by date', GCE_TEXT_DOMAIN); ?></option>
123
  </select>
 
 
 
124
  </p><p>
125
  <label for="<?php echo $this->get_field_id('display_title'); ?>">Display title on tooltip / list item? (e.g. 'Events on 7th March') Grouped lists always have a title displayed.</label>
126
  <br />
@@ -132,14 +140,14 @@ class GCE_Widget extends WP_Widget{
132
  }
133
  }
134
 
135
- function gce_widget_content_grid($feed_ids, $title_text, $widget_id, $ajaxified = false, $month = null, $year = null){
136
  //Create new GCE_Parser object, passing array of feed id(s)
137
- $grid = new GCE_Parser(explode('-', $feed_ids), $title_text);
138
 
139
  //If the feed(s) parsed ok, output the grid markup, otherwise output an error message
140
  if(count($grid->get_errors()) == 0){
141
  //Add AJAX script if required
142
- if($ajaxified) ?><script type="text/javascript">jQuery(document).ready(function($){gce_ajaxify("<?php echo $widget_id; ?>", "<?php echo $feed_ids; ?>", "<?php echo $title_text; ?>", "widget");});</script><?php
143
 
144
  echo $grid->get_grid($year, $month, $ajaxified);
145
  }else{
@@ -147,9 +155,9 @@ function gce_widget_content_grid($feed_ids, $title_text, $widget_id, $ajaxified
147
  }
148
  }
149
 
150
- function gce_widget_content_list($feed_ids, $title_text, $grouped = false){
151
  //Create new GCE_Parser object, passing array of feed id(s)
152
- $list = new GCE_Parser(explode('-', $feed_ids), $title_text);
153
 
154
  //If the feed(s) parsed ok, output the list markup, otherwise output an error message
155
  if(count($list->get_errors()) == 0){
18
  //Check whether any feeds have been added yet
19
  if(is_array($options) && !empty($options)){
20
  //Output title stuff
21
+ $title = empty($instance['title']) ? '' : apply_filters('widget_title', $instance['title']);
22
+ if(!empty($title)) echo $before_title . $title . $after_title;
23
 
24
  //Break comma delimited list of feed ids into array
25
  $feed_ids = explode(',', str_replace(' ', '', $instance['id']));
45
 
46
  $title_text = $instance['display_title'] ? $instance['display_title_text'] : null;
47
 
48
+ $max_events = $instance['max_events'];
49
+
50
  //Output correct widget content based on display type chosen
51
  switch($instance['display_type']){
52
  case 'grid':
53
  echo '<div class="gce-widget-grid" id="' . $args['widget_id'] . '-container">';
54
  //Output main widget content as grid (no AJAX)
55
+ gce_widget_content_grid($feed_ids, $title_text, $max_events, $args['widget_id'] . '-container');
56
  echo '</div>';
57
  break;
58
  case 'ajax':
59
  echo '<div class="gce-widget-grid" id="' . $args['widget_id'] . '-container">';
60
  //Output main widget content as grid (with AJAX)
61
+ gce_widget_content_grid($feed_ids, $title_text, $max_events, $args['widget_id'] . '-container', true);
62
  echo '</div>';
63
  break;
64
  case 'list':
65
  echo '<div class="gce-widget-list" id="' . $args['widget_id'] . '-container">';
66
  //Output main widget content as list
67
+ gce_widget_content_list($feed_ids, $title_text, $max_events);
68
  echo '</div>';
69
  break;
70
  case 'list-grouped':
71
  echo '<div class="gce-widget-list" id="' . $args['widget_id'] . '-container">';
72
  //Output main widget content as a grouped list
73
+ gce_widget_content_list($feed_ids, $title_text, $max_events, true);
74
  echo '</div>';
75
  break;
76
  }
88
  $instance['title'] = esc_html($new_instance['title']);
89
  $instance['id'] = esc_html($new_instance['id']);
90
  $instance['display_type'] = esc_html($new_instance['display_type']);
91
+ $instance['max_events'] = absint($new_instance['max_events']);
92
  $instance['display_title'] = $new_instance['display_title'] == 'on' ? true : false;
93
  $instance['display_title_text'] = wp_filter_kses($new_instance['display_title_text']);
94
  return $instance;
106
  $title = isset($instance['title']) ? $instance['title'] : '';
107
  $ids = isset($instance['id']) ? $instance['id'] : '';
108
  $display_type = isset($instance['display_type']) ? $instance['display_type'] : 'grid';
109
+ $max_events = isset($instance['max_events']) ? $instance['max_events'] : 0;
110
  $display_title = isset($instance['display_title']) ? $instance['display_title'] : true;
111
  $title_text = isset($instance['display_title_text']) ? $instance['display_title_text'] : 'Events on';
112
  ?>
126
  <option value="list"<?php selected($display_type, 'list');?>><?php _e('List', GCE_TEXT_DOMAIN); ?></option>
127
  <option value="list-grouped"<?php selected($display_type, 'list-grouped');?>><?php _e('List - grouped by date', GCE_TEXT_DOMAIN); ?></option>
128
  </select>
129
+ </p><p>
130
+ <label for="<?php echo $this->get_field_id('max_events'); ?>"><?php _e('Maximum no. events to display. Enter 0 to show all retrieved.'); ?></label>
131
+ <input type="text" id="<?php echo $this->get_field_id('max_events'); ?>" name="<?php echo $this->get_field_name('max_events'); ?>" value="<?php echo $max_events; ?>" class="widefat" />
132
  </p><p>
133
  <label for="<?php echo $this->get_field_id('display_title'); ?>">Display title on tooltip / list item? (e.g. 'Events on 7th March') Grouped lists always have a title displayed.</label>
134
  <br />
140
  }
141
  }
142
 
143
+ function gce_widget_content_grid($feed_ids, $title_text, $max_events, $widget_id, $ajaxified = false, $month = null, $year = null){
144
  //Create new GCE_Parser object, passing array of feed id(s)
145
+ $grid = new GCE_Parser(explode('-', $feed_ids), $title_text, $max_events);
146
 
147
  //If the feed(s) parsed ok, output the grid markup, otherwise output an error message
148
  if(count($grid->get_errors()) == 0){
149
  //Add AJAX script if required
150
+ if($ajaxified) ?><script type="text/javascript">jQuery(document).ready(function($){gce_ajaxify("<?php echo $widget_id; ?>", "<?php echo $feed_ids; ?>", "<?php echo $max_events; ?>", "<?php echo $title_text; ?>", "widget");});</script><?php
151
 
152
  echo $grid->get_grid($year, $month, $ajaxified);
153
  }else{
155
  }
156
  }
157
 
158
+ function gce_widget_content_list($feed_ids, $title_text, $max_events, $grouped = false){
159
  //Create new GCE_Parser object, passing array of feed id(s)
160
+ $list = new GCE_Parser(explode('-', $feed_ids), $title_text, $max_events);
161
 
162
  //If the feed(s) parsed ok, output the list markup, otherwise output an error message
163
  if(count($list->get_errors()) == 0){