keithsalisbury-subtrac 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +7 -0
  3. data/Rakefile +56 -0
  4. data/VERSION.yml +4 -0
  5. data/bin/subtrac +40 -0
  6. data/lib/subtrac.rb +245 -0
  7. data/lib/subtrac/common/clients/index.wsgi +89 -0
  8. data/lib/subtrac/common/favicon.ico +0 -0
  9. data/lib/subtrac/common/images/trac/banner_bg.jpg +0 -0
  10. data/lib/subtrac/common/images/trac/bar_bg.gif +0 -0
  11. data/lib/subtrac/common/images/trac/footer_back.png +0 -0
  12. data/lib/subtrac/common/images/trac/main_bg.gif +0 -0
  13. data/lib/subtrac/common/images/trac/saint_logo_small.png +0 -0
  14. data/lib/subtrac/common/static/404.html +14 -0
  15. data/lib/subtrac/common/styles/trac.css +222 -0
  16. data/lib/subtrac/common/trac.ini +178 -0
  17. data/lib/subtrac/config/config.yml +54 -0
  18. data/lib/subtrac/passwords +1 -0
  19. data/lib/subtrac/shared/trac.ini +178 -0
  20. data/lib/subtrac/templates/location.erb +16 -0
  21. data/lib/subtrac/templates/projects/blank/svn/branches/README +0 -0
  22. data/lib/subtrac/templates/projects/blank/svn/tags/README +0 -0
  23. data/lib/subtrac/templates/projects/blank/svn/trunk/README +0 -0
  24. data/lib/subtrac/templates/projects/blank/trac/wiki/WikiStart +57 -0
  25. data/lib/subtrac/templates/projects/new/svn/trunk/trac/wiki/WikiStart +46 -0
  26. data/lib/subtrac/templates/projects/new/trac/wiki/WikiStart +23 -0
  27. data/lib/subtrac/templates/projects/trac_theme/svn/trunk/index/index.html +22 -0
  28. data/lib/subtrac/templates/projects/trac_theme/svn/trunk/templates/layout.html +56 -0
  29. data/lib/subtrac/templates/projects/trac_theme/svn/trunk/templates/site.html +27 -0
  30. data/lib/subtrac/templates/projects/trac_theme/svn/trunk/templates/theme.html +86 -0
  31. data/lib/subtrac/templates/projects/trac_theme/trac/wiki/WikiStart +4 -0
  32. data/lib/subtrac/templates/trac.erb +25 -0
  33. data/lib/subtrac/templates/vhost.erb +35 -0
  34. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/advancedworkflow/__init__.py +0 -0
  35. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/advancedworkflow/controller.py +419 -0
  36. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/setup.cfg +3 -0
  37. data/lib/subtrac/trac-plugins/advancedticketworkflowplugin/setup.py +20 -0
  38. data/lib/subtrac/trac-plugins/clientsplugin/clients/__init__.py +0 -0
  39. data/lib/subtrac/trac-plugins/clientsplugin/clients/action.py +28 -0
  40. data/lib/subtrac/trac-plugins/clientsplugin/clients/action_email.py +168 -0
  41. data/lib/subtrac/trac-plugins/clientsplugin/clients/action_zendesk_forum.py +137 -0
  42. data/lib/subtrac/trac-plugins/clientsplugin/clients/admin.py +91 -0
  43. data/lib/subtrac/trac-plugins/clientsplugin/clients/api.py +199 -0
  44. data/lib/subtrac/trac-plugins/clientsplugin/clients/client.py +105 -0
  45. data/lib/subtrac/trac-plugins/clientsplugin/clients/events.py +287 -0
  46. data/lib/subtrac/trac-plugins/clientsplugin/clients/eventsadmin.py +71 -0
  47. data/lib/subtrac/trac-plugins/clientsplugin/clients/htdocs/clients.css +4 -0
  48. data/lib/subtrac/trac-plugins/clientsplugin/clients/model.py +135 -0
  49. data/lib/subtrac/trac-plugins/clientsplugin/clients/processor.py +70 -0
  50. data/lib/subtrac/trac-plugins/clientsplugin/clients/reportmanager.py +142 -0
  51. data/lib/subtrac/trac-plugins/clientsplugin/clients/reports.py +231 -0
  52. data/lib/subtrac/trac-plugins/clientsplugin/clients/summary.py +27 -0
  53. data/lib/subtrac/trac-plugins/clientsplugin/clients/summary_milestone.py +152 -0
  54. data/lib/subtrac/trac-plugins/clientsplugin/clients/summary_ticketchanges.py +160 -0
  55. data/lib/subtrac/trac-plugins/clientsplugin/clients/templates/admin_client_events.html +124 -0
  56. data/lib/subtrac/trac-plugins/clientsplugin/clients/templates/admin_clients.html +134 -0
  57. data/lib/subtrac/trac-plugins/clientsplugin/cron/changes.xslt +132 -0
  58. data/lib/subtrac/trac-plugins/clientsplugin/cron/run-client-event +97 -0
  59. data/lib/subtrac/trac-plugins/clientsplugin/cron/summary.xslt +161 -0
  60. data/lib/subtrac/trac-plugins/clientsplugin/setup.py +43 -0
  61. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/__init__.py +4 -0
  62. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/burndownchart.py +273 -0
  63. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/hoursinplaceeditor.py +44 -0
  64. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/hoursremaining.py +36 -0
  65. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery-1.2.3.min.js +32 -0
  66. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery.jeditable.js +409 -0
  67. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/htdocs/jquery.jeditable.mini.js +30 -0
  68. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/templates/edithours.html +53 -0
  69. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/burndownchart.py +181 -0
  70. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/hoursremaining.py +66 -0
  71. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/tests/workloadchart.py +47 -0
  72. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/utils.py +93 -0
  73. data/lib/subtrac/trac-plugins/estimationtoolsplugin/estimationtools/workloadchart.py +86 -0
  74. data/lib/subtrac/trac-plugins/estimationtoolsplugin/setup.py +20 -0
  75. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/SumRollups.js +23 -0
  76. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/adw_tracdb.py +128 -0
  77. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/git-post-receive +40 -0
  78. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/trac-post-commit.py +285 -0
  79. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/trac_billing.py +173 -0
  80. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/utils/__init__.py +0 -0
  81. data/lib/subtrac/trac-plugins/timingandestimationplugin/scripts/utils/mail.py +164 -0
  82. data/lib/subtrac/trac-plugins/timingandestimationplugin/setup.py +69 -0
  83. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/__init__.py +1 -0
  84. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/api.py +292 -0
  85. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/blackmagic.py +172 -0
  86. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/dbhelper.py +178 -0
  87. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/billingplugin.css +25 -0
  88. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/field_disabler.js +6 -0
  89. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/formatDate.js +356 -0
  90. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/tip_centerwindow.js +100 -0
  91. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/tip_followscroll.js +84 -0
  92. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/js/wz_tooltip.js +1149 -0
  93. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/linkifyer.js +119 -0
  94. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/query.js +73 -0
  95. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/htdocs/ticket.js +165 -0
  96. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/query_webui.py +28 -0
  97. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reportmanager.py +221 -0
  98. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reports.py +675 -0
  99. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/reports_filter.py +150 -0
  100. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/statuses.py +25 -0
  101. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/tande_filters.py +131 -0
  102. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/templates/billing.cs +84 -0
  103. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/templates/billing.html +104 -0
  104. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_daemon.py +194 -0
  105. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_policy.py +62 -0
  106. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/ticket_webui.py +28 -0
  107. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/usermanual.py +127 -0
  108. data/lib/subtrac/trac-plugins/timingandestimationplugin/timingandestimationplugin/webui.py +129 -0
  109. data/lib/subtrac/trac-plugins/worklogplugin/setup.py +29 -0
  110. data/lib/subtrac/trac-plugins/worklogplugin/worklog/__init__.py +1 -0
  111. data/lib/subtrac/trac-plugins/worklogplugin/worklog/api.py +187 -0
  112. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jqModal.css +40 -0
  113. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jqModal.js +67 -0
  114. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jquery.mousewheel.pack.js +12 -0
  115. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/jquery.timeentry.pack.js +7 -0
  116. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/tracWorklog.js +40 -0
  117. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/ui.datepicker.css +208 -0
  118. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/ui.datepicker.js +1439 -0
  119. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/work.png +0 -0
  120. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/work.xcf +0 -0
  121. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/worklogplugin.css +80 -0
  122. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/workstart.png +0 -0
  123. data/lib/subtrac/trac-plugins/worklogplugin/worklog/htdocs/workstop.png +0 -0
  124. data/lib/subtrac/trac-plugins/worklogplugin/worklog/manager.py +336 -0
  125. data/lib/subtrac/trac-plugins/worklogplugin/worklog/reports.py +598 -0
  126. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog.html +45 -0
  127. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_stop.html +70 -0
  128. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_user.html +40 -0
  129. data/lib/subtrac/trac-plugins/worklogplugin/worklog/templates/worklog_webadminui.html +59 -0
  130. data/lib/subtrac/trac-plugins/worklogplugin/worklog/ticket_daemon.py +33 -0
  131. data/lib/subtrac/trac-plugins/worklogplugin/worklog/ticket_filter.py +153 -0
  132. data/lib/subtrac/trac-plugins/worklogplugin/worklog/timeline_hook.py +96 -0
  133. data/lib/subtrac/trac-plugins/worklogplugin/worklog/usermanual.py +29 -0
  134. data/lib/subtrac/trac-plugins/worklogplugin/worklog/util.py +31 -0
  135. data/lib/subtrac/trac-plugins/worklogplugin/worklog/webadminui.py +47 -0
  136. data/lib/subtrac/trac-plugins/worklogplugin/worklog/webui.py +174 -0
  137. data/lib/subtrac/trac-plugins/worklogplugin/worklog/xmlrpc.py +73 -0
  138. data/lib/subtrac/version.rb +4 -0
  139. metadata +191 -0
@@ -0,0 +1,100 @@
1
+ /*
2
+ tip_centerwindow.js v. 1.2
3
+
4
+ The latest version is available at
5
+ http://www.walterzorn.com
6
+ or http://www.devira.com
7
+ or http://www.walterzorn.de
8
+
9
+ Initial author: Walter Zorn
10
+ Last modified: 23.6.2007
11
+
12
+ Extension for the tooltip library wz_tooltip.js.
13
+ Centers a sticky tooltip in the window's visible clientarea,
14
+ optionally even if the window is being scrolled or resized.
15
+ */
16
+
17
+ // Here we define new global configuration variable(s) (as members of the
18
+ // predefined "config." class).
19
+ // From each of these config variables, wz_tooltip.js will automatically derive
20
+ // a command which can be passed to Tip() or TagToTip() in order to customize
21
+ // tooltips individually. These command names are just the config variable
22
+ // name(s) translated to uppercase,
23
+ // e.g. from config. CenterWindow a command CENTERWINDOW will automatically be
24
+ // created.
25
+
26
+ //=================== GLOBAL TOOPTIP CONFIGURATION =========================//
27
+ config. CenterWindow = false // true or false - set to true if you want this to be the default behaviour
28
+ config. CenterAlways = false // true or false - recenter if window is resized or scrolled
29
+ //======= END OF TOOLTIP CONFIG, DO NOT CHANGE ANYTHING BELOW ==============//
30
+
31
+
32
+ // Create a new tt_Extension object (make sure that the name of that object,
33
+ // here ctrwnd, is unique amongst the extensions available for
34
+ // wz_tooltips.js):
35
+ var ctrwnd = new tt_Extension();
36
+
37
+ // Implement extension eventhandlers on which our extension should react
38
+ ctrwnd.OnLoadConfig = function()
39
+ {
40
+ if(tt_aV[CENTERWINDOW])
41
+ {
42
+ // Permit CENTERWINDOW only if the tooltip is sticky
43
+ if(tt_aV[STICKY])
44
+ {
45
+ if(tt_aV[CENTERALWAYS])
46
+ {
47
+ // IE doesn't support style.position "fixed"
48
+ if(tt_ie)
49
+ tt_AddEvtFnc(window, "scroll", Ctrwnd_DoCenter);
50
+ else
51
+ tt_aElt[0].style.position = "fixed";
52
+ tt_AddEvtFnc(window, "resize", Ctrwnd_DoCenter);
53
+ }
54
+ return true;
55
+ }
56
+ tt_aV[CENTERWINDOW] = false;
57
+ }
58
+ return false;
59
+ };
60
+ // We react on the first OnMouseMove event to center the tip on that occasion
61
+ ctrwnd.OnMoveBefore = Ctrwnd_DoCenter;
62
+ ctrwnd.OnKill = function()
63
+ {
64
+ if(tt_aV[CENTERWINDOW] && tt_aV[CENTERALWAYS])
65
+ {
66
+ tt_RemEvtFnc(window, "resize", Ctrwnd_DoCenter);
67
+ if(tt_ie)
68
+ tt_RemEvtFnc(window, "scroll", Ctrwnd_DoCenter);
69
+ else
70
+ tt_aElt[0].style.position = "absolute";
71
+ }
72
+ return false;
73
+ };
74
+ // Helper function
75
+ function Ctrwnd_DoCenter()
76
+ {
77
+ if(tt_aV[CENTERWINDOW])
78
+ {
79
+ var x, y, dx, dy;
80
+
81
+ // Here we use some functions and variables (tt_w, tt_h) which the
82
+ // extension API of wz_tooltip.js provides for us
83
+ if(tt_ie || !tt_aV[CENTERALWAYS])
84
+ {
85
+ dx = tt_GetScrollX();
86
+ dy = tt_GetScrollY();
87
+ }
88
+ else
89
+ {
90
+ dx = 0;
91
+ dy = 0;
92
+ }
93
+ // Position the tip, offset from the center by OFFSETX and OFFSETY
94
+ x = (tt_GetClientW() - tt_w) / 2 + dx + tt_aV[OFFSETX];
95
+ y = (tt_GetClientH() - tt_h) / 2 + dy + tt_aV[OFFSETY];
96
+ tt_SetTipPos(x, y);
97
+ return true;
98
+ }
99
+ return false;
100
+ }
@@ -0,0 +1,84 @@
1
+ /*
2
+ tip_followscroll.js v. 1.1
3
+
4
+ The latest version is available at
5
+ http://www.walterzorn.com
6
+ or http://www.devira.com
7
+ or http://www.walterzorn.de
8
+
9
+ Initial author: Walter Zorn
10
+ Last modified: 21.6.2007
11
+
12
+ Extension for the tooltip library wz_tooltip.js.
13
+ Lets a "sticky" tooltip keep its position inside the clientarea if the window
14
+ is scrolled.
15
+ */
16
+
17
+ // Here we define new global configuration variable(s) (as members of the
18
+ // predefined "config." class).
19
+ // From each of these config variables, wz_tooltip.js will automatically derive
20
+ // a command which can be passed to Tip() or TagToTip() in order to customize
21
+ // tooltips individually. These command names are just the config variable
22
+ // name(s) translated to uppercase,
23
+ // e.g. from config. FollowScroll a command FOLLOWSCROLL will automatically be
24
+ // created.
25
+
26
+ //=================== GLOBAL TOOPTIP CONFIGURATION ======================//
27
+ config. FollowScroll = false // true or false - set to true if you want this to be the default behaviour
28
+ //======= END OF TOOLTIP CONFIG, DO NOT CHANGE ANYTHING BELOW ==============//
29
+
30
+
31
+ // Create a new tt_Extension object (make sure that the name of that object,
32
+ // here fscrl, is unique amongst the extensions available for
33
+ // wz_tooltips.js):
34
+ var fscrl = new tt_Extension();
35
+
36
+ // Implement extension eventhandlers on which our extension should react
37
+ fscrl.OnShow = function()
38
+ {
39
+ if(tt_aV[FOLLOWSCROLL])
40
+ {
41
+ // Permit FOLLOWSCROLL only if the tooltip is sticky
42
+ if(tt_aV[STICKY])
43
+ {
44
+ var x = tt_x - tt_GetScrollX(), y = tt_y - tt_GetScrollY();
45
+
46
+ if(tt_ie)
47
+ {
48
+ fscrl.MoveOnScrl.offX = x;
49
+ fscrl.MoveOnScrl.offY = y;
50
+ fscrl.AddRemEvtFncs(tt_AddEvtFnc);
51
+ }
52
+ else
53
+ {
54
+ tt_SetTipPos(x, y);
55
+ tt_aElt[0].style.position = "fixed";
56
+ }
57
+ return true;
58
+ }
59
+ tt_aV[FOLLOWSCROLL] = false;
60
+ }
61
+ return false;
62
+ };
63
+ fscrl.OnHide = function()
64
+ {
65
+ if(tt_aV[FOLLOWSCROLL])
66
+ {
67
+ if(tt_ie)
68
+ fscrl.AddRemEvtFncs(tt_RemEvtFnc);
69
+ else
70
+ tt_aElt[0].style.position = "absolute";
71
+ }
72
+ };
73
+ // Helper functions (encapsulate in the class to avoid conflicts with other
74
+ // extensions)
75
+ fscrl.MoveOnScrl = function()
76
+ {
77
+ tt_SetTipPos(fscrl.MoveOnScrl.offX + tt_GetScrollX(), fscrl.MoveOnScrl.offY + tt_GetScrollY());
78
+ };
79
+ fscrl.AddRemEvtFncs = function(PAddRem)
80
+ {
81
+ PAddRem(window, "resize", fscrl.MoveOnScrl);
82
+ PAddRem(window, "scroll", fscrl.MoveOnScrl);
83
+ };
84
+
@@ -0,0 +1,1149 @@
1
+ /* This notice must be untouched at all times.
2
+
3
+ wz_tooltip.js v. 4.12
4
+
5
+ The latest version is available at
6
+ http://www.walterzorn.com
7
+ or http://www.devira.com
8
+ or http://www.walterzorn.de
9
+
10
+ Copyright (c) 2002-2007 Walter Zorn. All rights reserved.
11
+ Created 1.12.2002 by Walter Zorn (Web: http://www.walterzorn.com )
12
+ Last modified: 13.7.2007
13
+
14
+ Easy-to-use cross-browser tooltips.
15
+ Just include the script at the beginning of the <body> section, and invoke
16
+ Tip('Tooltip text') from within the desired HTML onmouseover eventhandlers.
17
+ No container DIV, no onmouseouts required.
18
+ By default, width of tooltips is automatically adapted to content.
19
+ Is even capable of dynamically converting arbitrary HTML elements to tooltips
20
+ by calling TagToTip('ID_of_HTML_element_to_be_converted') instead of Tip(),
21
+ which means you can put important, search-engine-relevant stuff into tooltips.
22
+ Appearance of tooltips can be individually configured
23
+ via commands passed to Tip() or TagToTip().
24
+
25
+ Tab Width: 4
26
+ LICENSE: LGPL
27
+
28
+ This library is free software; you can redistribute it and/or
29
+ modify it under the terms of the GNU Lesser General Public
30
+ License (LGPL) as published by the Free Software Foundation; either
31
+ version 2.1 of the License, or (at your option) any later version.
32
+
33
+ This library is distributed in the hope that it will be useful,
34
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
36
+
37
+ For more details on the GNU Lesser General Public License,
38
+ see http://www.gnu.org/copyleft/lesser.html
39
+ */
40
+
41
+ var config = new Object();
42
+
43
+
44
+ //=================== GLOBAL TOOPTIP CONFIGURATION =========================//
45
+ var tt_Debug = true // false or true - recommended: false once you release your page to the public
46
+ var tt_Enabled = true // Allows to (temporarily) suppress tooltips, e.g. by providing the user with a button that sets this global variable to false
47
+ var TagsToTip = true // false or true - if true, the script is capable of converting HTML elements to tooltips
48
+
49
+ // For each of the following config variables there exists a command, which is
50
+ // just the variablename in uppercase, to be passed to Tip() or TagToTip() to
51
+ // configure tooltips individually. Individual commands override global
52
+ // configuration. Order of commands is arbitrary.
53
+ // Example: onmouseover="Tip('Tooltip text', LEFT, true, BGCOLOR, '#FF9900', FADEIN, 400)"
54
+
55
+ config. Above = false // false or true - tooltip above mousepointer?
56
+ config. BgColor = '#E4E7FF' // Background color
57
+ config. BgImg = '' // Path to background image, none if empty string ''
58
+ config. BorderColor = '#002299'
59
+ config. BorderStyle = 'solid' // Any permitted CSS value, but I recommend 'solid', 'dotted' or 'dashed'
60
+ config. BorderWidth = 1
61
+ config. CenterMouse = false // false or true - center the tip horizontally below (or above) the mousepointer
62
+ config. ClickClose = false // false or true - close tooltip if the user clicks somewhere
63
+ config. CloseBtn = false // false or true - closebutton in titlebar
64
+ config. CloseBtnColors = ['#990000', '#FFFFFF', '#DD3333', '#FFFFFF'] // [Background, text, hovered background, hovered text] - use empty strings '' to inherit title colors
65
+ config. CloseBtnText = '&nbsp;X&nbsp;' // Close button text (may also be an image tag)
66
+ config. CopyContent = true // When converting a HTML element to a tooltip, copy only the element's content, rather than converting the element by its own
67
+ config. Delay = 400 // Time span in ms until tooltip shows up
68
+ config. Duration = 0 // Time span in ms after which the tooltip disappears; 0 for infinite duration
69
+ config. FadeIn = 0 // Fade-in duration in ms, e.g. 400; 0 for no animation
70
+ config. FadeOut = 0
71
+ config. FadeInterval = 30 // Duration of each fade step in ms (recommended: 30) - shorter is smoother but causes more CPU-load
72
+ config. Fix = null // Fixated position - x- an y-oordinates in brackets, e.g. [210, 480], or null for no fixation
73
+ config. FollowMouse = true // false or true - tooltip follows the mouse
74
+ config. FontColor = '#000044'
75
+ config. FontFace = 'Verdana,Geneva,sans-serif'
76
+ config. FontSize = '8pt' // E.g. '9pt' or '12px' - unit is mandatory
77
+ config. FontWeight = 'normal' // 'normal' or 'bold';
78
+ config. Left = false // false or true - tooltip on the left of the mouse
79
+ config. OffsetX = 14 // Horizontal offset of left-top corner from mousepointer
80
+ config. OffsetY = 8 // Vertical offset
81
+ config. Opacity = 100 // Integer between 0 and 100 - opacity of tooltip in percent
82
+ config. Padding = 3 // Spacing between border and content
83
+ config. Shadow = false // false or true
84
+ config. ShadowColor = '#C0C0C0'
85
+ config. ShadowWidth = 5
86
+ config. Sticky = false // Do NOT hide tooltip on mouseout? false or true
87
+ config. TextAlign = 'left' // 'left', 'right' or 'justify'
88
+ config. Title = '' // Default title text applied to all tips (no default title: empty string '')
89
+ config. TitleAlign = 'left' // 'left' or 'right' - text alignment inside the title bar
90
+ config. TitleBgColor = '' // If empty string '', BorderColor will be used
91
+ config. TitleFontColor = '#ffffff' // Color of title text - if '', BgColor (of tooltip body) will be used
92
+ config. TitleFontFace = '' // If '' use FontFace (boldified)
93
+ config. TitleFontSize = '' // If '' use FontSize
94
+ config. Width = 0 // Tooltip width; 0 for automatic adaption to tooltip content
95
+ //======= END OF TOOLTIP CONFIG, DO NOT CHANGE ANYTHING BELOW ==============//
96
+
97
+
98
+
99
+
100
+ //====================== PUBLIC ============================================//
101
+ function Tip()
102
+ {
103
+ tt_Tip(arguments, null);
104
+ }
105
+ function TagToTip()
106
+ {
107
+ if(TagsToTip)
108
+ {
109
+ var t2t = tt_GetElt(arguments[0]);
110
+ if(t2t)
111
+ tt_Tip(arguments, t2t);
112
+ }
113
+ }
114
+
115
+ //================== PUBLIC EXTENSION API ==================================//
116
+ // Extension eventhandlers currently supported:
117
+ // OnLoadConfig, OnCreateContentString, OnSubDivsCreated, OnShow, OnMoveBefore,
118
+ // OnMoveAfter, OnHideInit, OnHide, OnKill
119
+
120
+ var tt_aElt = new Array(10), // Container DIV, outer title & body DIVs, inner title & body TDs, closebutton SPAN, shadow DIVs, and IFRAME to cover windowed elements in IE
121
+ tt_aV = new Array(), // Caches and enumerates config data for currently active tooltip
122
+ tt_sContent, // Inner tooltip text or HTML
123
+ tt_scrlX = 0, tt_scrlY = 0,
124
+ tt_musX, tt_musY,
125
+ tt_over,
126
+ tt_x, tt_y, tt_w, tt_h; // Position, width and height of currently displayed tooltip
127
+
128
+ function tt_Extension()
129
+ {
130
+ tt_ExtCmdEnum();
131
+ tt_aExt[tt_aExt.length] = this;
132
+ return this;
133
+ }
134
+ function tt_SetTipPos(x, y)
135
+ {
136
+ var css = tt_aElt[0].style;
137
+
138
+ tt_x = x;
139
+ tt_y = y;
140
+ css.left = x + "px";
141
+ css.top = y + "px";
142
+ if(tt_ie56)
143
+ {
144
+ var ifrm = tt_aElt[tt_aElt.length - 1];
145
+ if(ifrm)
146
+ {
147
+ ifrm.style.left = css.left;
148
+ ifrm.style.top = css.top;
149
+ }
150
+ }
151
+ }
152
+ function tt_Hide()
153
+ {
154
+ if(tt_db && tt_iState)
155
+ {
156
+ if(tt_iState & 0x2)
157
+ {
158
+ tt_aElt[0].style.visibility = "hidden";
159
+ tt_ExtCallFncs(0, "Hide");
160
+ }
161
+ tt_tShow.EndTimer();
162
+ tt_tHide.EndTimer();
163
+ tt_tDurt.EndTimer();
164
+ tt_tFade.EndTimer();
165
+ if(!tt_op && !tt_ie)
166
+ {
167
+ tt_tWaitMov.EndTimer();
168
+ tt_bWait = false;
169
+ }
170
+ if(tt_aV[CLICKCLOSE])
171
+ tt_RemEvtFnc(document, "mouseup", tt_HideInit);
172
+ tt_AddRemOutFnc(false);
173
+ tt_ExtCallFncs(0, "Kill");
174
+ // In case of a TagToTip tooltip, hide converted DOM node and
175
+ // re-insert it into document
176
+ if(tt_t2t && !tt_aV[COPYCONTENT])
177
+ {
178
+ tt_t2t.style.display = "none";
179
+ tt_MovDomNode(tt_t2t, tt_aElt[6], tt_t2tDad);
180
+ }
181
+ tt_iState = 0;
182
+ tt_over = null;
183
+ tt_ResetMainDiv();
184
+ if(tt_aElt[tt_aElt.length - 1])
185
+ tt_aElt[tt_aElt.length - 1].style.display = "none";
186
+ }
187
+ }
188
+ function tt_GetElt(id)
189
+ {
190
+ return(document.getElementById ? document.getElementById(id)
191
+ : document.all ? document.all[id]
192
+ : null);
193
+ }
194
+ function tt_GetDivW(el)
195
+ {
196
+ return(el ? (el.offsetWidth || el.style.pixelWidth || 0) : 0);
197
+ }
198
+ function tt_GetDivH(el)
199
+ {
200
+ return(el ? (el.offsetHeight || el.style.pixelHeight || 0) : 0);
201
+ }
202
+ function tt_GetScrollX()
203
+ {
204
+ return(window.pageXOffset || (tt_db ? (tt_db.scrollLeft || 0) : 0));
205
+ }
206
+ function tt_GetScrollY()
207
+ {
208
+ return(window.pageYOffset || (tt_db ? (tt_db.scrollTop || 0) : 0));
209
+ }
210
+ function tt_GetClientW()
211
+ {
212
+ return(document.body && (typeof(document.body.clientWidth) != tt_u) ? document.body.clientWidth
213
+ : (typeof(window.innerWidth) != tt_u) ? window.innerWidth
214
+ : tt_db ? (tt_db.clientWidth || 0)
215
+ : 0);
216
+ }
217
+ function tt_GetClientH()
218
+ {
219
+ // Exactly this order seems to yield correct values in all major browsers
220
+ return(document.body && (typeof(document.body.clientHeight) != tt_u) ? document.body.clientHeight
221
+ : (typeof(window.innerHeight) != tt_u) ? window.innerHeight
222
+ : tt_db ? (tt_db.clientHeight || 0)
223
+ : 0);
224
+ }
225
+ function tt_GetEvtX(e)
226
+ {
227
+ return (e ? ((typeof(e.pageX) != tt_u) ? e.pageX : (e.clientX + tt_scrlX)) : 0);
228
+ }
229
+ function tt_GetEvtY(e)
230
+ {
231
+ return (e ? ((typeof(e.pageY) != tt_u) ? e.pageY : (e.clientY + tt_scrlY)) : 0);
232
+ }
233
+ function tt_AddEvtFnc(el, sEvt, PFnc)
234
+ {
235
+ if(el)
236
+ {
237
+ if(el.addEventListener)
238
+ el.addEventListener(sEvt, PFnc, false);
239
+ else
240
+ el.attachEvent("on" + sEvt, PFnc);
241
+ }
242
+ }
243
+ function tt_RemEvtFnc(el, sEvt, PFnc)
244
+ {
245
+ if(el)
246
+ {
247
+ if(el.removeEventListener)
248
+ el.removeEventListener(sEvt, PFnc, false);
249
+ else
250
+ el.detachEvent("on" + sEvt, PFnc);
251
+ }
252
+ }
253
+
254
+ //====================== PRIVATE ===========================================//
255
+ var tt_aExt = new Array(), // Array of extension objects
256
+
257
+ tt_db, tt_op, tt_ie, tt_ie56, tt_bBoxOld, // Browser flags
258
+ tt_body,
259
+ tt_flagOpa, // Opacity support: 1=IE, 2=Khtml, 3=KHTML, 4=Moz, 5=W3C
260
+ tt_maxPosX, tt_maxPosY,
261
+ tt_iState = 0, // Tooltip active |= 1, shown |= 2, move with mouse |= 4
262
+ tt_opa, // Currently applied opacity
263
+ tt_bJmpVert, // Tip above mouse (or ABOVE tip below mouse)
264
+ tt_t2t, tt_t2tDad, // Tag converted to tip, and its parent element in the document
265
+ tt_elDeHref, // The tag from which Opera has removed the href attribute
266
+ // Timer
267
+ tt_tShow = new Number(0), tt_tHide = new Number(0), tt_tDurt = new Number(0),
268
+ tt_tFade = new Number(0), tt_tWaitMov = new Number(0),
269
+ tt_bWait = false,
270
+ tt_u = "undefined";
271
+
272
+
273
+ function tt_Init()
274
+ {
275
+ tt_MkCmdEnum();
276
+ // Send old browsers instantly to hell
277
+ if(!tt_Browser() || !tt_MkMainDiv())
278
+ return;
279
+ tt_IsW3cBox();
280
+ tt_OpaSupport();
281
+ tt_AddEvtFnc(document, "mousemove", tt_Move);
282
+ // In Debug mode we search for TagToTip() calls in order to notify
283
+ // the user if they've forgotten to set the TagsToTip config flag
284
+ if(TagsToTip || tt_Debug)
285
+ tt_SetOnloadFnc();
286
+ tt_AddEvtFnc(window, "scroll",
287
+ function()
288
+ {
289
+ tt_scrlX = tt_GetScrollX();
290
+ tt_scrlY = tt_GetScrollY();
291
+ if(tt_iState && !(tt_aV[STICKY] && (tt_iState & 2)))
292
+ tt_HideInit();
293
+ } );
294
+ // Ensure the tip be hidden when the page unloads
295
+ tt_AddEvtFnc(window, "unload", tt_Hide);
296
+ tt_Hide();
297
+ }
298
+ // Creates command names by translating config variable names to upper case
299
+ function tt_MkCmdEnum()
300
+ {
301
+ var n = 0;
302
+ for(var i in config)
303
+ eval("window." + i.toString().toUpperCase() + " = " + n++);
304
+ tt_aV.length = n;
305
+ }
306
+ function tt_Browser()
307
+ {
308
+ var n, nv, n6, w3c;
309
+
310
+ n = navigator.userAgent.toLowerCase(),
311
+ nv = navigator.appVersion;
312
+ tt_op = (document.defaultView && typeof(eval("w" + "indow" + "." + "o" + "p" + "er" + "a")) != tt_u);
313
+ tt_ie = n.indexOf("msie") != -1 && document.all && !tt_op;
314
+ if(tt_ie)
315
+ {
316
+ var ieOld = (!document.compatMode || document.compatMode == "BackCompat");
317
+ tt_db = !ieOld ? document.documentElement : (document.body || null);
318
+ if(tt_db)
319
+ tt_ie56 = parseFloat(nv.substring(nv.indexOf("MSIE") + 5)) >= 5.5
320
+ && typeof document.body.style.maxHeight == tt_u;
321
+ }
322
+ else
323
+ {
324
+ tt_db = document.documentElement || document.body ||
325
+ (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
326
+ : null);
327
+ if(!tt_op)
328
+ {
329
+ n6 = document.defaultView && typeof document.defaultView.getComputedStyle != tt_u;
330
+ w3c = !n6 && document.getElementById;
331
+ }
332
+ }
333
+ tt_body = (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
334
+ : (document.body || null));
335
+ if(tt_ie || n6 || tt_op || w3c)
336
+ {
337
+ if(tt_body && tt_db)
338
+ {
339
+ if(document.attachEvent || document.addEventListener)
340
+ return true;
341
+ }
342
+ else
343
+ tt_Err("wz_tooltip.js must be included INSIDE the body section,"
344
+ + " immediately after the opening <body> tag.");
345
+ }
346
+ tt_db = null;
347
+ return false;
348
+ }
349
+ function tt_MkMainDiv()
350
+ {
351
+ // Create the tooltip DIV
352
+ if(tt_body.insertAdjacentHTML)
353
+ tt_body.insertAdjacentHTML("afterBegin", tt_MkMainDivHtm());
354
+ else if(typeof tt_body.innerHTML != tt_u && document.createElement && tt_body.appendChild)
355
+ tt_body.appendChild(tt_MkMainDivDom());
356
+ // FireFox Alzheimer bug
357
+ if(window.tt_GetMainDivRefs && tt_GetMainDivRefs())
358
+ return true;
359
+ tt_db = null;
360
+ return false;
361
+ }
362
+ function tt_MkMainDivHtm()
363
+ {
364
+ return('<div id="WzTtDiV"></div>' +
365
+ (tt_ie56 ? ('<iframe id="WzTtIfRm" src="javascript:false" scrolling="no" frameborder="0" style="filter:Alpha(opacity=0);position:absolute;top:0px;left:0px;display:none;"></iframe>')
366
+ : ''));
367
+ }
368
+ function tt_MkMainDivDom()
369
+ {
370
+ var el = document.createElement("div");
371
+ if(el)
372
+ el.id = "WzTtDiV";
373
+ return el;
374
+ }
375
+ function tt_GetMainDivRefs()
376
+ {
377
+ tt_aElt[0] = tt_GetElt("WzTtDiV");
378
+ if(tt_ie56 && tt_aElt[0])
379
+ {
380
+ tt_aElt[tt_aElt.length - 1] = tt_GetElt("WzTtIfRm");
381
+ if(!tt_aElt[tt_aElt.length - 1])
382
+ tt_aElt[0] = null;
383
+ }
384
+ if(tt_aElt[0])
385
+ {
386
+ var css = tt_aElt[0].style;
387
+
388
+ css.visibility = "hidden";
389
+ css.position = "absolute";
390
+ css.overflow = "hidden";
391
+ return true;
392
+ }
393
+ return false;
394
+ }
395
+ function tt_ResetMainDiv()
396
+ {
397
+ var w = (window.screen && screen.width) ? screen.width : 10000;
398
+
399
+ tt_SetTipPos(-w, 0);
400
+ tt_aElt[0].innerHTML = "";
401
+ tt_aElt[0].style.width = (w - 1) + "px";
402
+ }
403
+ function tt_IsW3cBox()
404
+ {
405
+ var css = tt_aElt[0].style;
406
+
407
+ css.padding = "10px";
408
+ css.width = "40px";
409
+ tt_bBoxOld = (tt_GetDivW(tt_aElt[0]) == 40);
410
+ css.padding = "0px";
411
+ tt_ResetMainDiv();
412
+ }
413
+ function tt_OpaSupport()
414
+ {
415
+ var css = tt_body.style;
416
+
417
+ tt_flagOpa = (typeof(css.filter) != tt_u) ? 1
418
+ : (typeof(css.KhtmlOpacity) != tt_u) ? 2
419
+ : (typeof(css.KHTMLOpacity) != tt_u) ? 3
420
+ : (typeof(css.MozOpacity) != tt_u) ? 4
421
+ : (typeof(css.opacity) != tt_u) ? 5
422
+ : 0;
423
+ }
424
+ // Ported from http://dean.edwards.name/weblog/2006/06/again/
425
+ // (Dean Edwards et al.)
426
+ function tt_SetOnloadFnc()
427
+ {
428
+ tt_AddEvtFnc(document, "DOMContentLoaded", tt_HideSrcTags);
429
+ tt_AddEvtFnc(window, "load", tt_HideSrcTags);
430
+ if(tt_body.attachEvent)
431
+ tt_body.attachEvent("onreadystatechange",
432
+ function() {
433
+ if(tt_body.readyState == "complete")
434
+ tt_HideSrcTags();
435
+ } );
436
+ if(/WebKit|KHTML/i.test(navigator.userAgent))
437
+ {
438
+ var t = setInterval(function() {
439
+ if(/loaded|complete/.test(document.readyState))
440
+ {
441
+ clearInterval(t);
442
+ tt_HideSrcTags();
443
+ }
444
+ }, 10);
445
+ }
446
+ }
447
+ function tt_HideSrcTags()
448
+ {
449
+ if(!window.tt_HideSrcTags || window.tt_HideSrcTags.done)
450
+ return;
451
+ window.tt_HideSrcTags.done = true;
452
+ if(!tt_HideSrcTagsRecurs(tt_body))
453
+ tt_Err("To enable the capability to convert HTML elements to tooltips,"
454
+ + " you must set TagsToTip in the global tooltip configuration"
455
+ + " to true.");
456
+ }
457
+ function tt_HideSrcTagsRecurs(dad)
458
+ {
459
+ var a, ovr, asT2t;
460
+
461
+ // Walk the DOM tree for tags that have an onmouseover attribute
462
+ // containing a TagToTip('...') call.
463
+ // (.childNodes first since .children is bugous in Safari)
464
+ a = dad.childNodes || dad.children || null;
465
+ for(var i = a ? a.length : 0; i;)
466
+ {--i;
467
+ if(!tt_HideSrcTagsRecurs(a[i]))
468
+ return false;
469
+ ovr = a[i].getAttribute ? a[i].getAttribute("onmouseover")
470
+ : (typeof a[i].onmouseover == "function") ? a[i].onmouseover
471
+ : null;
472
+ if(ovr)
473
+ {
474
+ asT2t = ovr.toString().match(/TagToTip\s*\(\s*'[^'.]+'\s*[\),]/);
475
+ if(asT2t && asT2t.length)
476
+ {
477
+ if(!tt_HideSrcTag(asT2t[0]))
478
+ return false;
479
+ }
480
+ }
481
+ }
482
+ return true;
483
+ }
484
+ function tt_HideSrcTag(sT2t)
485
+ {
486
+ var id, el;
487
+
488
+ // The ID passed to the found TagToTip() call identifies an HTML element
489
+ // to be converted to a tooltip, so hide that element
490
+ id = sT2t.replace(/.+'([^'.]+)'.+/, "$1");
491
+ el = tt_GetElt(id);
492
+ if(el)
493
+ {
494
+ if(tt_Debug && !TagsToTip)
495
+ return false;
496
+ else
497
+ el.style.display = "none";
498
+ }
499
+ else
500
+ tt_Err("Invalid ID\n'" + id + "'\npassed to TagToTip()."
501
+ + " There exists no HTML element with that ID.");
502
+ return true;
503
+ }
504
+ function tt_Tip(arg, t2t)
505
+ {
506
+ if(!tt_db)
507
+ return;
508
+ if(tt_iState)
509
+ tt_Hide();
510
+ if(!tt_Enabled)
511
+ return;
512
+ tt_t2t = t2t;
513
+ if(!tt_ReadCmds(arg))
514
+ return;
515
+ tt_iState = 0x1 | 0x4;
516
+ tt_AdaptConfig1();
517
+ tt_MkTipContent(arg);
518
+ tt_MkTipSubDivs();
519
+ tt_FormatTip();
520
+ tt_bJmpVert = false;
521
+ tt_maxPosX = tt_GetClientW() + tt_scrlX - tt_w - 1;
522
+ tt_maxPosY = tt_GetClientH() + tt_scrlY - tt_h - 1;
523
+ tt_AdaptConfig2();
524
+ // We must fake the first mousemove in order to ensure the tip
525
+ // be immediately shown and positioned
526
+ tt_Move();
527
+ tt_ShowInit();
528
+ }
529
+ function tt_ReadCmds(a)
530
+ {
531
+ var i;
532
+
533
+ // First load the global config values, to initialize also values
534
+ // for which no command has been passed
535
+ i = 0;
536
+ for(var j in config)
537
+ tt_aV[i++] = config[j];
538
+ // Then replace each cached config value for which a command has been
539
+ // passed (ensure the # of command args plus value args be even)
540
+ if(a.length & 1)
541
+ {
542
+ for(i = a.length - 1; i > 0; i -= 2)
543
+ tt_aV[a[i - 1]] = a[i];
544
+ return true;
545
+ }
546
+ tt_Err("Incorrect call of Tip() or TagToTip().\n"
547
+ + "Each command must be followed by a value.");
548
+ return false;
549
+ }
550
+ function tt_AdaptConfig1()
551
+ {
552
+ tt_ExtCallFncs(0, "LoadConfig");
553
+ // Inherit unspecified title formattings from body
554
+ if(!tt_aV[TITLEBGCOLOR].length)
555
+ tt_aV[TITLEBGCOLOR] = tt_aV[BORDERCOLOR];
556
+ if(!tt_aV[TITLEFONTCOLOR].length)
557
+ tt_aV[TITLEFONTCOLOR] = tt_aV[BGCOLOR];
558
+ if(!tt_aV[TITLEFONTFACE].length)
559
+ tt_aV[TITLEFONTFACE] = tt_aV[FONTFACE];
560
+ if(!tt_aV[TITLEFONTSIZE].length)
561
+ tt_aV[TITLEFONTSIZE] = tt_aV[FONTSIZE];
562
+ if(tt_aV[CLOSEBTN])
563
+ {
564
+ // Use title colors for non-specified closebutton colors
565
+ if(!tt_aV[CLOSEBTNCOLORS])
566
+ tt_aV[CLOSEBTNCOLORS] = new Array("", "", "", "");
567
+ for(var i = 4; i;)
568
+ {--i;
569
+ if(!tt_aV[CLOSEBTNCOLORS][i].length)
570
+ tt_aV[CLOSEBTNCOLORS][i] = (i & 1) ? tt_aV[TITLEFONTCOLOR] : tt_aV[TITLEBGCOLOR];
571
+ }
572
+ // Enforce titlebar be shown
573
+ if(!tt_aV[TITLE].length)
574
+ tt_aV[TITLE] = " ";
575
+ }
576
+ // Circumvents broken display of images and fade-in flicker in Geckos < 1.8
577
+ if(tt_aV[OPACITY] == 100 && typeof tt_aElt[0].style.MozOpacity != tt_u && !Array.every)
578
+ tt_aV[OPACITY] = 99;
579
+ // Smartly shorten the delay for fade-in tooltips
580
+ if(tt_aV[FADEIN] && tt_flagOpa && tt_aV[DELAY] > 100)
581
+ tt_aV[DELAY] = Math.max(tt_aV[DELAY] - tt_aV[FADEIN], 100);
582
+ }
583
+ function tt_AdaptConfig2()
584
+ {
585
+ if(tt_aV[CENTERMOUSE])
586
+ tt_aV[OFFSETX] -= ((tt_w - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0)) >> 1);
587
+ }
588
+ // Expose content globally so extensions can modify it
589
+ function tt_MkTipContent(a)
590
+ {
591
+ if(tt_t2t)
592
+ {
593
+ if(tt_aV[COPYCONTENT])
594
+ tt_sContent = tt_t2t.innerHTML;
595
+ else
596
+ tt_sContent = "";
597
+ }
598
+ else
599
+ tt_sContent = a[0];
600
+ tt_ExtCallFncs(0, "CreateContentString");
601
+ }
602
+ function tt_MkTipSubDivs()
603
+ {
604
+ var sCss = 'position:relative;margin:0px;padding:0px;border-width:0px;left:0px;top:0px;line-height:normal;width:auto;',
605
+ sTbTrTd = ' cellspacing=0 cellpadding=0 border=0 style="' + sCss + '"><tbody style="' + sCss + '"><tr><td ';
606
+
607
+ tt_aElt[0].innerHTML =
608
+ (''
609
+ + (tt_aV[TITLE].length ?
610
+ ('<div id="WzTiTl" style="position:relative;z-index:1;">'
611
+ + '<table id="WzTiTlTb"' + sTbTrTd + 'id="WzTiTlI" style="' + sCss + '">'
612
+ + tt_aV[TITLE]
613
+ + '</td>'
614
+ + (tt_aV[CLOSEBTN] ?
615
+ ('<td align="right" style="' + sCss
616
+ + 'text-align:right;">'
617
+ + '<span id="WzClOsE" style="padding-left:2px;padding-right:2px;'
618
+ + 'cursor:' + (tt_ie ? 'hand' : 'pointer')
619
+ + ';" onmouseover="tt_OnCloseBtnOver(1)" onmouseout="tt_OnCloseBtnOver(0)" onclick="tt_HideInit()">'
620
+ + tt_aV[CLOSEBTNTEXT]
621
+ + '</span></td>')
622
+ : '')
623
+ + '</tr></tbody></table></div>')
624
+ : '')
625
+ + '<div id="WzBoDy" style="position:relative;z-index:0;">'
626
+ + '<table' + sTbTrTd + 'id="WzBoDyI" style="' + sCss + '">'
627
+ + tt_sContent
628
+ + '</td></tr></tbody></table></div>'
629
+ + (tt_aV[SHADOW]
630
+ ? ('<div id="WzTtShDwR" style="position:absolute;overflow:hidden;"></div>'
631
+ + '<div id="WzTtShDwB" style="position:relative;overflow:hidden;"></div>')
632
+ : '')
633
+ );
634
+ tt_GetSubDivRefs();
635
+ // Convert DOM node to tip
636
+ if(tt_t2t && !tt_aV[COPYCONTENT])
637
+ {
638
+ // Store the tag's parent element so we can restore that DOM branch
639
+ // once the tooltip is hidden
640
+ tt_t2tDad = tt_t2t.parentNode || tt_t2t.parentElement || tt_t2t.offsetParent || null;
641
+ if(tt_t2tDad)
642
+ {
643
+ tt_MovDomNode(tt_t2t, tt_t2tDad, tt_aElt[6]);
644
+ tt_t2t.style.display = "block";
645
+ }
646
+ }
647
+ tt_ExtCallFncs(0, "SubDivsCreated");
648
+ }
649
+ function tt_GetSubDivRefs()
650
+ {
651
+ var aId = new Array("WzTiTl", "WzTiTlTb", "WzTiTlI", "WzClOsE", "WzBoDy", "WzBoDyI", "WzTtShDwB", "WzTtShDwR");
652
+
653
+ for(var i = aId.length; i; --i)
654
+ tt_aElt[i] = tt_GetElt(aId[i - 1]);
655
+ }
656
+ function tt_FormatTip()
657
+ {
658
+ var css, w, iOffY, iOffSh;
659
+
660
+ //--------- Title DIV ----------
661
+ if(tt_aV[TITLE].length)
662
+ {
663
+ css = tt_aElt[1].style;
664
+ css.background = tt_aV[TITLEBGCOLOR];
665
+ css.paddingTop = (tt_aV[CLOSEBTN] ? 2 : 0) + "px";
666
+ css.paddingBottom = "1px";
667
+ css.paddingLeft = css.paddingRight = tt_aV[PADDING] + "px";
668
+ css = tt_aElt[3].style;
669
+ css.color = tt_aV[TITLEFONTCOLOR];
670
+ css.fontFamily = tt_aV[TITLEFONTFACE];
671
+ css.fontSize = tt_aV[TITLEFONTSIZE];
672
+ css.fontWeight = "bold";
673
+ css.textAlign = tt_aV[TITLEALIGN];
674
+ // Close button DIV
675
+ if(tt_aElt[4])
676
+ {
677
+ css.paddingRight = (tt_aV[PADDING] << 1) + "px";
678
+ css = tt_aElt[4].style;
679
+ css.background = tt_aV[CLOSEBTNCOLORS][0];
680
+ css.color = tt_aV[CLOSEBTNCOLORS][1];
681
+ css.fontFamily = tt_aV[TITLEFONTFACE];
682
+ css.fontSize = tt_aV[TITLEFONTSIZE];
683
+ css.fontWeight = "bold";
684
+ }
685
+ if(tt_aV[WIDTH] > 0)
686
+ tt_w = tt_aV[WIDTH] + ((tt_aV[PADDING] + tt_aV[BORDERWIDTH]) << 1);
687
+ else
688
+ {
689
+ tt_w = tt_GetDivW(tt_aElt[3]) + tt_GetDivW(tt_aElt[4]);
690
+ // Some spacing between title DIV and closebutton
691
+ if(tt_aElt[4])
692
+ tt_w += tt_aV[PADDING];
693
+ }
694
+ // Ensure the top border of the body DIV be covered by the title DIV
695
+ iOffY = -tt_aV[BORDERWIDTH];
696
+ }
697
+ else
698
+ {
699
+ tt_w = 0;
700
+ iOffY = 0;
701
+ }
702
+
703
+ //-------- Body DIV ------------
704
+ css = tt_aElt[5].style;
705
+ css.top = iOffY + "px";
706
+ if(tt_aV[BORDERWIDTH])
707
+ {
708
+ css.borderColor = tt_aV[BORDERCOLOR];
709
+ css.borderStyle = tt_aV[BORDERSTYLE];
710
+ css.borderWidth = tt_aV[BORDERWIDTH] + "px";
711
+ }
712
+ if(tt_aV[BGCOLOR].length)
713
+ css.background = tt_aV[BGCOLOR];
714
+ if(tt_aV[BGIMG].length)
715
+ css.backgroundImage = "url(" + tt_aV[BGIMG] + ")";
716
+ css.padding = tt_aV[PADDING] + "px";
717
+ css.textAlign = tt_aV[TEXTALIGN];
718
+ // TD inside body DIV
719
+ css = tt_aElt[6].style;
720
+ css.color = tt_aV[FONTCOLOR];
721
+ css.fontFamily = tt_aV[FONTFACE];
722
+ css.fontSize = tt_aV[FONTSIZE];
723
+ css.fontWeight = tt_aV[FONTWEIGHT];
724
+ css.background = "";
725
+ css.textAlign = tt_aV[TEXTALIGN];
726
+ if(tt_aV[WIDTH] > 0)
727
+ w = tt_aV[WIDTH] + ((tt_aV[PADDING] + tt_aV[BORDERWIDTH]) << 1);
728
+ else
729
+ // We measure the width of the body's inner TD, because some browsers
730
+ // expand the width of the container and outer body DIV to 100%
731
+ w = tt_GetDivW(tt_aElt[6]) + ((tt_aV[PADDING] + tt_aV[BORDERWIDTH]) << 1);
732
+ if(w > tt_w)
733
+ tt_w = w;
734
+
735
+ //--------- Shadow DIVs ------------
736
+ if(tt_aV[SHADOW])
737
+ {
738
+ tt_w += tt_aV[SHADOWWIDTH];
739
+ iOffSh = Math.floor((tt_aV[SHADOWWIDTH] * 4) / 3);
740
+ // Bottom shadow
741
+ css = tt_aElt[7].style;
742
+ css.top = iOffY + "px";
743
+ css.left = iOffSh + "px";
744
+ css.width = (tt_w - iOffSh - tt_aV[SHADOWWIDTH]) + "px";
745
+ css.height = tt_aV[SHADOWWIDTH] + "px";
746
+ css.background = tt_aV[SHADOWCOLOR];
747
+ // Right shadow
748
+ css = tt_aElt[8].style;
749
+ css.top = iOffSh + "px";
750
+ css.left = (tt_w - tt_aV[SHADOWWIDTH]) + "px";
751
+ css.width = tt_aV[SHADOWWIDTH] + "px";
752
+ css.background = tt_aV[SHADOWCOLOR];
753
+ }
754
+ else
755
+ iOffSh = 0;
756
+
757
+ //-------- Container DIV -------
758
+ tt_SetTipOpa(tt_aV[FADEIN] ? 0 : tt_aV[OPACITY]);
759
+ tt_FixSize(iOffY, iOffSh);
760
+ }
761
+ // Fixate the size so it can't dynamically change while the tooltip is moving.
762
+ function tt_FixSize(iOffY, iOffSh)
763
+ {
764
+ var wIn, wOut, i;
765
+
766
+ tt_aElt[0].style.width = tt_w + "px";
767
+ tt_aElt[0].style.pixelWidth = tt_w;
768
+ wOut = tt_w - ((tt_aV[SHADOW]) ? tt_aV[SHADOWWIDTH] : 0);
769
+ // Body
770
+ wIn = wOut;
771
+ if(!tt_bBoxOld)
772
+ wIn -= ((tt_aV[PADDING] + tt_aV[BORDERWIDTH]) << 1);
773
+ tt_aElt[5].style.width = wIn + "px";
774
+ // Title
775
+ if(tt_aElt[1])
776
+ {
777
+ wIn = wOut - (tt_aV[PADDING] << 1);
778
+ if(!tt_bBoxOld)
779
+ wOut = wIn;
780
+ tt_aElt[1].style.width = wOut + "px";
781
+ tt_aElt[2].style.width = wIn + "px";
782
+ }
783
+ tt_h = tt_GetDivH(tt_aElt[0]) + iOffY;
784
+ // Right shadow
785
+ if(tt_aElt[8])
786
+ tt_aElt[8].style.height = (tt_h - iOffSh) + "px";
787
+ i = tt_aElt.length - 1;
788
+ if(tt_aElt[i])
789
+ {
790
+ tt_aElt[i].style.width = tt_w + "px";
791
+ tt_aElt[i].style.height = tt_h + "px";
792
+ }
793
+ }
794
+ function tt_DeAlt(el)
795
+ {
796
+ var aKid;
797
+
798
+ if(el.alt)
799
+ el.alt = "";
800
+ if(el.title)
801
+ el.title = "";
802
+ aKid = el.childNodes || el.children || null;
803
+ if(aKid)
804
+ {
805
+ for(var i = aKid.length; i;)
806
+ tt_DeAlt(aKid[--i]);
807
+ }
808
+ }
809
+ // This hack removes the annoying native tooltips over links in Opera
810
+ function tt_OpDeHref(el)
811
+ {
812
+ if(!tt_op)
813
+ return;
814
+ if(tt_elDeHref)
815
+ tt_OpReHref();
816
+ while(el)
817
+ {
818
+ if(el.hasAttribute("href"))
819
+ {
820
+ el.t_href = el.getAttribute("href");
821
+ el.t_stats = window.status;
822
+ el.removeAttribute("href");
823
+ el.style.cursor = "hand";
824
+ tt_AddEvtFnc(el, "mousedown", tt_OpReHref);
825
+ window.status = el.t_href;
826
+ tt_elDeHref = el;
827
+ break;
828
+ }
829
+ el = el.parentElement;
830
+ }
831
+ }
832
+ function tt_ShowInit()
833
+ {
834
+ tt_tShow.Timer("tt_Show()", tt_aV[DELAY], true);
835
+ if(tt_aV[CLICKCLOSE])
836
+ tt_AddEvtFnc(document, "mouseup", tt_HideInit);
837
+ }
838
+ function tt_OverInit(e)
839
+ {
840
+ tt_over = e.target || e.srcElement;
841
+ tt_DeAlt(tt_over);
842
+ tt_OpDeHref(tt_over);
843
+ tt_AddRemOutFnc(true);
844
+ }
845
+ function tt_Show()
846
+ {
847
+ var css = tt_aElt[0].style;
848
+
849
+ // Override the z-index of the topmost wz_dragdrop.js D&D item
850
+ css.zIndex = Math.max((window.dd && dd.z) ? (dd.z + 2) : 0, 1010);
851
+ if(tt_aV[STICKY] || !tt_aV[FOLLOWMOUSE])
852
+ tt_iState &= ~0x4;
853
+ if(tt_aV[DURATION] > 0)
854
+ tt_tDurt.Timer("tt_HideInit()", tt_aV[DURATION], true);
855
+ tt_ExtCallFncs(0, "Show")
856
+ css.visibility = "visible";
857
+ tt_iState |= 0x2;
858
+ if(tt_aV[FADEIN])
859
+ tt_Fade(0, 0, tt_aV[OPACITY], Math.round(tt_aV[FADEIN] / tt_aV[FADEINTERVAL]));
860
+ tt_ShowIfrm();
861
+ }
862
+ function tt_ShowIfrm()
863
+ {
864
+ if(tt_ie56)
865
+ {
866
+ var ifrm = tt_aElt[tt_aElt.length - 1];
867
+ if(ifrm)
868
+ {
869
+ var css = ifrm.style;
870
+ css.zIndex = tt_aElt[0].style.zIndex - 1;
871
+ css.display = "block";
872
+ }
873
+ }
874
+ }
875
+ function tt_Move(e)
876
+ {
877
+ e = window.event || e;
878
+ if(e)
879
+ {
880
+ tt_musX = tt_GetEvtX(e);
881
+ tt_musY = tt_GetEvtY(e);
882
+ }
883
+ if(tt_iState)
884
+ {
885
+ if(!tt_over && e)
886
+ tt_OverInit(e);
887
+ if(tt_iState & 0x4)
888
+ {
889
+ // Protect some browsers against jam of mousemove events
890
+ if(!tt_op && !tt_ie)
891
+ {
892
+ if(tt_bWait)
893
+ return;
894
+ tt_bWait = true;
895
+ tt_tWaitMov.Timer("tt_bWait = false;", 1, true);
896
+ }
897
+ if(tt_aV[FIX])
898
+ {
899
+ tt_iState &= ~0x4;
900
+ tt_SetTipPos(tt_aV[FIX][0], tt_aV[FIX][1]);
901
+ }
902
+ else if(!tt_ExtCallFncs(e, "MoveBefore"))
903
+ tt_SetTipPos(tt_PosX(), tt_PosY());
904
+ tt_ExtCallFncs([tt_musX, tt_musY], "MoveAfter")
905
+ }
906
+ }
907
+ }
908
+ function tt_PosX()
909
+ {
910
+ var x;
911
+
912
+ x = tt_musX;
913
+ if(tt_aV[LEFT])
914
+ x -= tt_w + tt_aV[OFFSETX] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0);
915
+ else
916
+ x += tt_aV[OFFSETX];
917
+ // Prevent tip from extending past right/left clientarea boundary
918
+ if(x > tt_maxPosX)
919
+ x = tt_maxPosX;
920
+ return((x < tt_scrlX) ? tt_scrlX : x);
921
+ }
922
+ function tt_PosY()
923
+ {
924
+ var y;
925
+
926
+ // Apply some hysteresis after the tip has snapped to the other side of the
927
+ // mouse. In case of insufficient space above and below the mouse, we place
928
+ // the tip below.
929
+ if(tt_aV[ABOVE] && (!tt_bJmpVert || tt_CalcPosYAbove() >= tt_scrlY + 16))
930
+ y = tt_DoPosYAbove();
931
+ else if(!tt_aV[ABOVE] && tt_bJmpVert && tt_CalcPosYBelow() > tt_maxPosY - 16)
932
+ y = tt_DoPosYAbove();
933
+ else
934
+ y = tt_DoPosYBelow();
935
+ // Snap to other side of mouse if tip would extend past window boundary
936
+ if(y > tt_maxPosY)
937
+ y = tt_DoPosYAbove();
938
+ if(y < tt_scrlY)
939
+ y = tt_DoPosYBelow();
940
+ return y;
941
+ }
942
+ function tt_DoPosYBelow()
943
+ {
944
+ tt_bJmpVert = tt_aV[ABOVE];
945
+ return tt_CalcPosYBelow();
946
+ }
947
+ function tt_DoPosYAbove()
948
+ {
949
+ tt_bJmpVert = !tt_aV[ABOVE];
950
+ return tt_CalcPosYAbove();
951
+ }
952
+ function tt_CalcPosYBelow()
953
+ {
954
+ return(tt_musY + tt_aV[OFFSETY]);
955
+ }
956
+ function tt_CalcPosYAbove()
957
+ {
958
+ var dy = tt_aV[OFFSETY] - (tt_aV[SHADOW] ? tt_aV[SHADOWWIDTH] : 0);
959
+ if(tt_aV[OFFSETY] > 0 && dy <= 0)
960
+ dy = 1;
961
+ return(tt_musY - tt_h - dy);
962
+ }
963
+ function tt_OnOut()
964
+ {
965
+ tt_AddRemOutFnc(false);
966
+ if(!(tt_aV[STICKY] && (tt_iState & 0x2)))
967
+ tt_HideInit();
968
+ }
969
+ function tt_HideInit()
970
+ {
971
+ tt_ExtCallFncs(0, "HideInit");
972
+ tt_iState &= ~0x4;
973
+ if(tt_flagOpa && tt_aV[FADEOUT])
974
+ {
975
+ tt_tFade.EndTimer();
976
+ if(tt_opa)
977
+ {
978
+ var n = Math.round(tt_aV[FADEOUT] / (tt_aV[FADEINTERVAL] * (tt_aV[OPACITY] / tt_opa)));
979
+ tt_Fade(tt_opa, tt_opa, 0, n);
980
+ return;
981
+ }
982
+ }
983
+ tt_tHide.Timer("tt_Hide();", 1, false);
984
+ }
985
+ function tt_OpReHref()
986
+ {
987
+ if(tt_elDeHref)
988
+ {
989
+ tt_elDeHref.setAttribute("href", tt_elDeHref.t_href);
990
+ tt_RemEvtFnc(tt_elDeHref, "mousedown", tt_OpReHref);
991
+ window.status = tt_elDeHref.t_stats;
992
+ tt_elDeHref = null;
993
+ }
994
+ }
995
+ function tt_Fade(a, now, z, n)
996
+ {
997
+ if(n)
998
+ {
999
+ now += Math.round((z - now) / n);
1000
+ if((z > a) ? (now >= z) : (now <= z))
1001
+ now = z;
1002
+ else
1003
+ tt_tFade.Timer("tt_Fade("
1004
+ + a + "," + now + "," + z + "," + (n - 1)
1005
+ + ")",
1006
+ tt_aV[FADEINTERVAL],
1007
+ true);
1008
+ }
1009
+ now ? tt_SetTipOpa(now) : tt_Hide();
1010
+ }
1011
+ // To circumvent the opacity nesting flaws of IE, we set the opacity
1012
+ // for each sub-DIV separately, rather than for the container DIV.
1013
+ function tt_SetTipOpa(opa)
1014
+ {
1015
+ tt_SetOpa(tt_aElt[5].style, opa);
1016
+ if(tt_aElt[1])
1017
+ tt_SetOpa(tt_aElt[1].style, opa);
1018
+ if(tt_aV[SHADOW])
1019
+ {
1020
+ opa = Math.round(opa * 0.8);
1021
+ tt_SetOpa(tt_aElt[7].style, opa);
1022
+ tt_SetOpa(tt_aElt[8].style, opa);
1023
+ }
1024
+ }
1025
+ function tt_OnCloseBtnOver(iOver)
1026
+ {
1027
+ var css = tt_aElt[4].style;
1028
+
1029
+ iOver <<= 1;
1030
+ css.background = tt_aV[CLOSEBTNCOLORS][iOver];
1031
+ css.color = tt_aV[CLOSEBTNCOLORS][iOver + 1];
1032
+ }
1033
+ function tt_Int(x)
1034
+ {
1035
+ var y;
1036
+
1037
+ return(isNaN(y = parseInt(x)) ? 0 : y);
1038
+ }
1039
+ // Adds or removes the document.mousemove or HoveredElem.mouseout handler
1040
+ // conveniently. Keeps track of those handlers to prevent them from being
1041
+ // set or removed redundantly.
1042
+ function tt_AddRemOutFnc(bAdd)
1043
+ {
1044
+ var PSet = bAdd ? tt_AddEvtFnc : tt_RemEvtFnc;
1045
+
1046
+ if(bAdd != tt_AddRemOutFnc.bOn)
1047
+ {
1048
+ PSet(tt_over, "mouseout", tt_OnOut);
1049
+ tt_AddRemOutFnc.bOn = bAdd;
1050
+ if(!bAdd)
1051
+ tt_OpReHref();
1052
+ }
1053
+ }
1054
+ tt_AddRemOutFnc.bOn = false;
1055
+ Number.prototype.Timer = function(s, iT, bUrge)
1056
+ {
1057
+ if(!this.value || bUrge)
1058
+ this.value = window.setTimeout(s, iT);
1059
+ }
1060
+ Number.prototype.EndTimer = function()
1061
+ {
1062
+ if(this.value)
1063
+ {
1064
+ window.clearTimeout(this.value);
1065
+ this.value = 0;
1066
+ }
1067
+ }
1068
+ function tt_SetOpa(css, opa)
1069
+ {
1070
+ tt_opa = opa;
1071
+ if(tt_flagOpa == 1)
1072
+ {
1073
+ // Hack for bugs of IE:
1074
+ // A DIV cannot be made visible in a single step if an opacity < 100
1075
+ // has been applied while the DIV was hidden.
1076
+ // Moreover, in IE6, applying an opacity < 100 has no effect if the
1077
+ // concerned element has no layout (position, size, zoom, ...).
1078
+ if(opa < 100)
1079
+ {
1080
+ var bVis = css.visibility != "hidden";
1081
+ css.zoom = "100%";
1082
+ if(!bVis)
1083
+ css.visibility = "visible";
1084
+ css.filter = "alpha(opacity=" + opa + ")";
1085
+ if(!bVis)
1086
+ css.visibility = "hidden";
1087
+ }
1088
+ else
1089
+ css.filter = "";
1090
+ }
1091
+ else
1092
+ {
1093
+ opa /= 100.0;
1094
+ switch(tt_flagOpa)
1095
+ {
1096
+ case 2:
1097
+ css.KhtmlOpacity = opa; break;
1098
+ case 3:
1099
+ css.KHTMLOpacity = opa; break;
1100
+ case 4:
1101
+ css.MozOpacity = opa; break;
1102
+ case 5:
1103
+ css.opacity = opa; break;
1104
+ }
1105
+ }
1106
+ }
1107
+ function tt_MovDomNode(el, dadFrom, dadTo)
1108
+ {
1109
+ if(dadFrom)
1110
+ dadFrom.removeChild(el);
1111
+ if(dadTo)
1112
+ dadTo.appendChild(el);
1113
+ }
1114
+ function tt_Err(sErr)
1115
+ {
1116
+ if(tt_Debug)
1117
+ alert("Tooltip Script Error Message:\n\n" + sErr);
1118
+ }
1119
+
1120
+ //=========== DEALING WITH EXTENSIONS ==============//
1121
+ function tt_ExtCmdEnum()
1122
+ {
1123
+ var s;
1124
+
1125
+ // Add new command(s) to the commands enum
1126
+ for(var i in config)
1127
+ {
1128
+ s = "window." + i.toString().toUpperCase();
1129
+ if(eval("typeof(" + s + ") == tt_u"))
1130
+ {
1131
+ eval(s + " = " + tt_aV.length);
1132
+ tt_aV[tt_aV.length] = null;
1133
+ }
1134
+ }
1135
+ }
1136
+ function tt_ExtCallFncs(arg, sFnc)
1137
+ {
1138
+ var b = false;
1139
+ for(var i = tt_aExt.length; i;)
1140
+ {--i;
1141
+ var fnc = tt_aExt[i]["On" + sFnc];
1142
+ // Call the method the extension has defined for this event
1143
+ if(fnc && fnc(arg))
1144
+ b = true;
1145
+ }
1146
+ return b;
1147
+ }
1148
+
1149
+ tt_Init();