2
* Copyright 2009 Canonical Ltd. This software is licensed under the
3
* GNU Affero General Public License version 3 (see the file LICENSE).
5
* This script defines functions for popping up a 'Help' dialog for an
6
* external site. All links that have a 'target="help"' attribute will
7
* be turned into pop-up help links. A single popup is present on the
8
* screen at a time - opening another help link will open a new dialog,
9
* and clicking on the same link again closes the dialog.
11
* This library depends on the MochiKit JavaScript library v1.4+.
21
function initInlineHelp() {
23
Activate the popup help system by connecting all of the actionable
26
// The button is inserted in the page dynamically:
27
// Changed from an <input type=button> to a <button> since
28
// IE8 doesn't handle style.css's input{visibility:inherit} correctly.
29
$('help-close').innerHTML =
30
'<button id="help-close-btn">Close</button>';
31
forEach(findHelpLinks(), setupHelpTrigger);
35
function findHelpLinks() {
37
Return all of the links in the document that have a target="help"
40
has_help_target = function (elem) {
41
return getNodeAttribute(elem, 'target') == 'help';
43
return filter(has_help_target,
44
currentDocument().getElementsByTagName('a'));
47
function setupHelpTrigger(elem) {
49
Turn the specified element into a proper help link: add the
50
'class="help"' attribute if it is missing, and connect the
51
necessary event handlers.
53
// We want this to be idempotent, so we treat the 'help' class as a
55
if (!hasElementClass(elem, 'help')) {
56
addElementClass(elem, 'help');
57
connect(elem, 'onclick', handleClickOnHelp);
63
* Functions for using the help window.
67
// We need to keep track of last element that triggered a help window.
68
var last_help_trigger = null;
71
function initHelpPane() {
73
Link the popup help pane to its events, set its visibility, etc.
75
connect('help-close-btn', 'onclick', handleClickOnClose);
79
function showHelpFor(trigger) {
81
Show the help popup for a particular trigger element.
84
// Assume we are using an <iframe> for the help.
85
// Also assume an <a> tag is the source, and we want to target the
86
// <iframe> at its href.
88
// Let our "Loading..." background gif show through.
89
makeInvisible('help-pane-content');
91
// Set our 'onload' event handler *outside* of the MochiKit.Signal
92
// framework. Normally we should not do this, but we need
93
// to work around a bug where the 'onload' signal falls silent
94
// for all events after the first.
95
$('help-pane-content').onload = handleHelpLoaded;
97
setNodeAttribute('help-pane-content', 'src', trigger.href);
99
var help_pane = $('help-pane');
101
/* The help pane is positioned in the center of the screen: */
102
var viewport_dim = getViewportDimensions();
103
var help_pane_dim = elementDimensions('help-pane');
104
var pos_x = Math.round(viewport_dim.w / 2) - (help_pane_dim.w / 2);
105
var pos_y = Math.round(viewport_dim.h / 2) - (help_pane_dim.h / 2);
106
var viewport_pos = getViewportPosition();
107
pos_y += viewport_pos.y;
108
setElementPosition(help_pane, new Coordinates(pos_x, pos_y));
109
makeVisible(help_pane);
111
// XXX mars 2008-05-19
112
// Work-around for MochiKit bug #274. The previous call to
113
// setElementPosition() sets "style=none;" as a side-effect!!!
114
setStyle(help_pane, {'display': ''});
117
function dismissHelp() {
118
makeInvisible('help-pane');
121
function handleClickOnHelp(event) {
122
// We don't want <a> tags to navigate.
124
var trigger = event.src();
126
if (!isVisible('help-pane')) {
127
showHelpFor(trigger);
128
} else if (trigger == last_help_trigger) {
129
// Clicking on the same link that opened a help window closes it
133
// The user clicked on a different help link, so open it instead.
135
showHelpFor(trigger);
137
last_help_trigger = trigger;
140
function handleClickOnClose(event) {
141
// Prevent the <a> tag from navigating.
146
function handleHelpLoaded(event) {
148
Show the help contents after the help <iframe> has finished
151
makeVisible('help-pane-content');
154
function handleClickOnPage(event) {
156
Check to see if a click was inside a help window. If it wasn't,
157
and the window is open, then dismiss it.
159
var help = $('help-pane');
160
if (isVisible(help) &&
161
!isInside(event.mouse().page, help)) {
168
* Helpers and utility functions.
172
function toggleVisible(elem) {
173
toggleElementClass("invisible", elem);
176
function makeVisible(elem) {
177
removeElementClass(elem, "invisible");
180
function makeInvisible(elem) {
181
addElementClass(elem, "invisible");
184
function isVisible(elem) {
185
// You may also want to check for:
186
// getElement(elem).style.display == "none"
187
return !hasElementClass(elem, "invisible");
190
function isInside(point, element) {
192
Is 'point' inside the supplied 'element'?
194
return intersect(point,
195
getElementPosition(element),
196
getElementDimensions(element));
199
function intersect(point, dim_point, dimensions) {
201
Is 'point' inside the box draw by 'dimensions' at point 'dim_point'?
203
return ((point.x > dim_point.x) &&
204
(point.x < dim_point.x + dimensions.w) &&
205
(point.y > dim_point.y) &&
206
(point.y < dim_point.y + dimensions.h));