Indefero

Indefero Commit Details


Date:2008-07-25 03:26:05 (16 years 4 months ago)
Author:Loic d'Anterroches
Branch:dev, develop, feature-issue_links, feature.better-home, feature.content-md5, feature.diff-whitespace, feature.download-md5, feature.issue-links, feature.issue-of-others, feature.issue-summary, feature.search-filter, feature.webrepos, feature.wiki-default-page, master, newdiff, release-1.1, release-1.2, release-1.3, svn
Commit:efbd82fccb20b0b4c9ac82777b8bdf7d83be0e40
Message:Initial commit.

Changes:

File differences

.gitignore
1
2
3
4
tmp
src/IDF/conf/idf.php
src/IDF/conf/idf.test.php
www/test.php
src/IDF/Conf.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Configuration of a project.
*
* It is just storing a list of key/value
* pairs. We can that way store quite a lot of data.
*/
class IDF_Conf extends Pluf_Model
{
public $_model = __CLASS__;
public $datacache = null;
public $f = null;
protected $_project = null;
function init()
{
$this->_a['table'] = 'idf_conf';
$this->_a['model'] = __CLASS__;
$this->_a['cols'] = array(
// It is mandatory to have an "id" column.
'id' =>
array(
'type' => 'Pluf_DB_Field_Sequence',
//It is automatically added.
'blank' => true,
),
'project' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'IDF_Project',
'blank' => false,
'verbose' => __('project'),
),
'vkey' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'size' => 50,
'verbose' => __('key'),
),
'vdesc' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'size' => 250,
'verbose' => __('value'),
),
);
$this->_a['idx'] = array('project_vkey_idx' =>
array(
'col' => 'project, vkey',
'type' => 'unique',
),
);
$this->f = new IDF_Conf_DataProxy($this);
}
function setProject($project)
{
$this->datacache = null;
$this->_project = $project;
}
function initCache()
{
$this->datacache = new ArrayObject();
$sql = new Pluf_SQL('project=%s', $this->_project);
foreach ($this->getList(array('filter' => $sql->gen())) as $val) {
$this->datacache[$val->vkey] = $val->vdesc;
}
}
/**
* FIXME: This is not efficient when setting a large number of
* values in a loop.
*/
function setVal($key, $value)
{
if (!is_null($this->getVal($key, null))
and $value == $this->getVal($key)) {
return;
}
$this->delVal($key, false);
$conf = new IDF_Conf();
$conf->project = $this->_project;
$conf->vkey = $key;
$conf->vdesc = $value;
$conf->create();
$this->initCache();
}
function getVal($key, $default='')
{
if ($this->datacache === null) {
$this->initCache();
}
return (isset($this->datacache[$key])) ? $this->datacache[$key] : $default;
}
function delVal($key, $initcache=true)
{
$gconf = new IDF_Conf();
$sql = new Pluf_SQL('vkey=%s AND project=%s', array($key, $this->_project));
foreach ($gconf->getList(array('filter' => $sql->gen())) as $c) {
$c->delete();
}
if ($initcache) {
$this->initCache();
}
}
}
src/IDF/Conf/DataProxy.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Field proxy to access the configuration data through
* {$conf.f.fieldname} in a template.
*/
class IDF_Conf_DataProxy
{
protected $obj = null;
public function __construct(&$obj)
{
$this->obj = $obj;
}
public function __get($field)
{
return $this->obj->getVal($field);
}
}
src/IDF/Form/IssueCreate.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Create a new issue.
*
* This create the issue entry and the first comment corresponding to
* the description and the attached files.
*
* It is possible to tag the issue following some rules. For example
* you cannot put several "status" or "priority" tags.
*
*/
class IDF_Form_IssueCreate extends Pluf_Form
{
public $user = null;
public $project = null;
public $show_full = false;
public function initFields($extra=array())
{
$this->user = $extra['user'];
$this->project = $extra['project'];
if ($this->user->hasPerm('IDF.project-owner', $this->project)
or $this->user->hasPerm('IDF.project-member', $this->project)) {
$this->show_full = true;
}
$this->fields['summary'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Summary'),
'initial' => '',
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
));
$this->fields['content'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Description'),
'initial' => '',
'widget' => 'Pluf_Form_Widget_TextareaInput',
'widget_attrs' => array(
'cols' => 58,
'rows' => 13,
),
));
if ($this->show_full) {
$this->fields['status'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Status'),
'initial' => 'New',
'widget_attrs' => array(
'maxlength' => 20,
'size' => 15,
),
));
$this->fields['owner'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Owner'),
'initial' => '',
'widget_attrs' => array(
'maxlength' => 20,
'size' => 15,
),
));
for ($i=1;$i<7;$i++) {
$initial = '';
switch ($i) {
case 1:
$initial = 'Type:Defect';
break;
case 2:
$initial = 'Priority:Medium';
break;
}
$this->fields['label'.$i] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Labels'),
'initial' => $initial,
'widget_attrs' => array(
'maxlength' => 50,
'size' => 20,
),
));
}
}
}
/**
* Validate the interconnection in the form.
*/
public function clean()
{
// We need to check that no label with the 'Status' class is
// given.
if (!$this->show_full) {
return $this->cleaned_data;
}
$conf = new IDF_Conf();
$conf->setProject($this->project);
$onemax = array();
foreach (split(',', $conf->getVal('labels_issue_one_max', IDF_Form_IssueTrackingConf::init_one_max)) as $class) {
if (trim($class) != '') {
$onemax[] = mb_strtolower(trim($class));
}
}
$count = array();
for ($i=1;$i<7;$i++) {
$this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(mb_strtolower(trim($class)),
trim($name));
} else {
$class = 'other';
$name = $this->cleaned_data['label'.$i];
}
if ($class == 'status') {
if (!isset($this->errors['label'.$i])) $this->errors['label'.$i] = array();
$this->errors['label'.$i][] = __('You cannot add a label with the "Status" prefix to an issue.');
throw new Pluf_Form_Invalid(__('You provided an invalid label.'));
}
if (!isset($count[$class])) $count[$class] = 1;
else $count[$class] += 1;
if (in_array($class, $onemax) and $count[$class] > 1) {
if (!isset($this->errors['label'.$i])) $this->errors['label'.$i] = array();
$this->errors['label'.$i][] = sprintf(__('You cannot provide more than label from the %s class to an issue.'), $class);
throw new Pluf_Form_Invalid(__('You provided an invalid label.'));
}
}
return $this->cleaned_data;
}
function clean_status()
{
// Check that the status is in the list of official status
$tags = $this->project->getTagsFromConfig('labels_issue_open',
IDF_Form_IssueTrackingConf::init_open,
'Status');
$tags = array_merge($this->project->getTagsFromConfig('labels_issue_closed',
IDF_Form_IssueTrackingConf::init_closed,
'Status')
, $tags);
$found = false;
foreach ($tags as $tag) {
if ($tag->name == trim($this->cleaned_data['status'])) {
$found = true;
break;
}
}
if (!$found) {
throw new Pluf_Form_Invalid(__('You provided an invalid status.'));
}
return $this->cleaned_data['status'];
}
/**
* Save the model in the database.
*
* @param bool Commit in the database or not. If not, the object
* is returned but not saved in the database.
* @return Object Model with data set from the form.
*/
function save($commit=true)
{
if ($this->isValid()) {
// Add a tag for each label
$tags = array();
if ($this->show_full) {
for ($i=1;$i<7;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = trim($this->cleaned_data['label'.$i]);
}
$tags[] = IDF_Tag::add($name, $this->project, $class);
}
}
} else {
$tags[] = IDF_Tag::add('Medium', $this->project, 'Priority');
$tags[] = IDF_Tag::add('Defect', $this->project, 'Type');
}
// Create the issue
$issue = new IDF_Issue();
$issue->project = $this->project;
$issue->submitter = $this->user;
if ($this->show_full) {
$issue->status = IDF_Tag::add(trim($this->cleaned_data['status']), $this->project, 'Status');
$issue->owner = self::findUser($this->cleaned_data['owner']);
} else {
$_t = $this->project->getTagIdsByStatus('open');
$issue->status = new IDF_Tag($_t[0]); // first one is the default
$issue->owner = null;
}
$issue->summary = trim($this->cleaned_data['summary']);
$issue->create();
foreach ($tags as $tag) {
$issue->setAssoc($tag);
}
$issue->setAssoc($this->user); // the user is
// automatically
// interested.
// add the first comment
$comment = new IDF_IssueComment();
$comment->issue = $issue;
$comment->content = $this->cleaned_data['content'];
$comment->submitter = $this->user;
$comment->create();
return $issue;
}
throw new Exception(__('Cannot save the model from an invalid form.'));
}
/**
* Based on the given string, try to find the matching user.
*
* Search order is: email, login, last_name.
*
* If no user found, simply returns null.
*
* @param string User
* @return Pluf_User or null
*/
public static function findUser($string)
{
$string = trim($string);
if (strlen($string) == 0) return null;
$guser = new Pluf_User();
foreach (array('email', 'login', 'last_name') as $what) {
$sql = new Pluf_SQL($what.'=%s', $string);
$users = $guser->getList(array('filter' => $sql->gen()));
if ($users->count() > 0) {
return $users[0];
}
}
return null;
}
}
src/IDF/Form/IssueTrackingConf.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Configuration of the labels etc.
*/
class IDF_Form_IssueTrackingConf extends Pluf_Form
{
/**
* Defined as constants to easily access the value in the
* IssueUpdate/Create form in the case nothing is in the db yet.
*/
const init_open = 'New = Issue has not had initial review yet
Accepted = Problem reproduced / Need acknowledged
Started = Work on this issue has begun';
const init_closed = 'Fixed = Developer made requested changes, QA should verify
Verified = QA has verified that the fix worked
Invalid = This was not a valid issue report
Duplicate = This report duplicates an existing issue
WontFix = We decided to not take action on this issue';
const init_predefined = 'Type:Defect = Report of a software defect
Type:Enhancement = Request for enhancement
Type:Task = Work item that doesn\'t change the code or docs
Type:Patch = Source code patch for review
Type:Other = Some other kind of issue
Priority:Critical = Must resolve in the specified milestone
Priority:High = Strongly want to resolve in the specified milestone
Priority:Medium = Normal priority
Priority:Low = Might slip to later milestone
OpSys:All = Affects all operating systems
OpSys:Windows = Affects Windows users
OpSys:Linux = Affects Linux users
OpSys:OSX = Affects Mac OS X users
Milestone:Release1.0 = All essential functionality working
Component:UI = Issue relates to program UI
Component:Logic = Issue relates to application logic
Component:Persistence = Issue relates to data storage components
Component:Scripts = Utility and installation scripts
Component:Docs = Issue relates to end-user documentation
Security = Security risk to users
Performance = Performance issue
Usability = Affects program usability
Maintainability = Hinders future changes';
const init_one_max = 'Type, Priority, Milestone';
public function initFields($extra=array())
{
$this->fields['labels_issue_open'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Open issue status values'),
'initial' => self::init_open,
'widget' => 'Pluf_Form_Widget_TextareaInput',
'widget_attrs' => array('rows' => 5,
'cols' => 75),
));
$this->fields['labels_issue_closed'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Closed issue status values'),
'initial' => self::init_closed,
'widget_attrs' => array('rows' => 7,
'cols' => 75),
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
$this->fields['labels_issue_predefined'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Predefined issue labels'),
'initial' => self::init_predefined,
'widget_attrs' => array('rows' => 7,
'cols' => 75),
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
$this->fields['labels_issue_one_max'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Each issue may have at most one label with each of these classes'),
'initial' => self::init_one_max,
'widget_attrs' => array('size' => 60),
));
}
}
src/IDF/Form/IssueUpdate.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Update an issue.
*
* We extend IDF_Form_IssueCreate to reuse the validation logic.
*/
class IDF_Form_IssueUpdate extends IDF_Form_IssueCreate
{
public $issue = null;
public function initFields($extra=array())
{
$this->user = $extra['user'];
$this->project = $extra['project'];
$this->issue = $extra['issue'];
if ($this->user->hasPerm('IDF.project-owner', $this->project)
or $this->user->hasPerm('IDF.project-member', $this->project)) {
$this->show_full = true;
}
if ($this->show_full) {
$this->fields['summary'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Summary'),
'initial' => $this->issue->summary,
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
));
}
$this->fields['content'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Comment'),
'initial' => '',
'widget' => 'Pluf_Form_Widget_TextareaInput',
'widget_attrs' => array(
'cols' => 58,
'rows' => 9,
),
));
if ($this->show_full) {
$this->fields['status'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Status'),
'initial' => $this->issue->get_status()->name,
'widget_attrs' => array(
'maxlength' => 20,
'size' => 15,
),
));
$initial = ($this->issue->get_owner() == null) ? '' : $this->issue->get_owner()->login;
$this->fields['owner'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Owner'),
'initial' => $initial,
'widget_attrs' => array(
'maxlength' => 20,
'size' => 15,
),
));
$tags = $this->issue->get_tags_list();
for ($i=1;$i<7;$i++) {
$initial = '';
if (isset($tags[$i-1])) {
if ($tags[$i-1]->class != 'Other') {
$initial = (string) $tags[$i-1];
} else {
$initial = $tags[$i-1]->name;
}
}
$this->fields['label'.$i] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Labels'),
'initial' => $initial,
'widget_attrs' => array(
'maxlength' => 50,
'size' => 20,
),
));
}
}
}
/**
* We check that something is really changed.
*/
public function clean()
{
$this->cleaned_data = parent::clean();
// As soon as we know that at least one change was done, we
// return the cleaned data and do not go further.
if (strlen(trim($this->cleaned_data['content']))) {
return $this->cleaned_data;
}
if ($this->show_full) {
$status = $this->issue->get_status();
if (trim($this->cleaned_data['status']) != $status->name) {
return $this->cleaned_data;
}
if (trim($this->issue->summary) != trim($this->cleaned_data['summary'])) {
return $this->cleaned_data;
}
$owner = self::findUser($this->cleaned_data['owner']);
if ((is_null($owner) and !is_null($this->issue->get_owner()))
or (!is_null($owner) and is_null($this->issue->get_owner()))
or ((!is_null($owner) and !is_null($this->issue->get_owner())) and $owner->id != $this->issue->get_owner()->id)) {
return $this->cleaned_data;
}
$tags = array();
for ($i=1;$i<7;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = trim($this->cleaned_data['label'.$i]);
}
$tags[] = array($class, $name);
}
}
$oldtags = $this->issue->get_tags_list();
foreach ($tags as $tag) {
$found = false;
foreach ($oldtags as $otag) {
if ($otag->class == $tag[0] and $otag->name == $tag[1]) {
$found = true;
break;
}
}
if (!$found) {
// new tag not found in the old tags
return $this->cleaned_data;
}
}
foreach ($oldtags as $otag) {
$found = false;
foreach ($tags as $tag) {
if ($otag->class == $tag[0] and $otag->name == $tag[1]) {
$found = true;
break;
}
}
if (!$found) {
// old tag not found in the new tags
return $this->cleaned_data;
}
}
}
// no changes!
throw new Pluf_Form_Invalid(__('No changes were entered.'));
}
/**
* Save the model in the database.
*
* @param bool Commit in the database or not. If not, the object
* is returned but not saved in the database.
* @return Object Model with data set from the form.
*/
function save($commit=true)
{
if ($this->isValid()) {
if ($this->show_full) {
// Add a tag for each label
$tags = array();
$tagids = array();
for ($i=1;$i<7;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = trim($this->cleaned_data['label'.$i]);
}
$tag = IDF_Tag::add($name, $this->project, $class);
$tags[] = $tag;
$tagids[] = $tag->id;
}
}
// Compare between the old and the new data
$changes = array();
$oldtags = $this->issue->get_tags_list();
foreach ($tags as $tag) {
if (!Pluf_Model_InArray($tag, $oldtags)) {
if (!isset($changes['lb'])) $changes['lb'] = array();
if ($tag->class != 'Other') {
$changes['lb'][] = (string) $tag; //new tag
} else {
$changes['lb'][] = (string) $tag->name;
}
}
}
foreach ($oldtags as $tag) {
if (!Pluf_Model_InArray($tag, $tags)) {
if (!isset($changes['lb'])) $changes['lb'] = array();
if ($tag->class != 'Other') {
$changes['lb'][] = '-'.(string) $tag; //new tag
} else {
$changes['lb'][] = '-'.(string) $tag->name;
}
}
}
// Status, summary and owner
$status = IDF_Tag::add(trim($this->cleaned_data['status']), $this->project, 'Status');
if ($status->id != $this->issue->status) {
$changes['st'] = $status->name;
}
if (trim($this->issue->summary) != trim($this->cleaned_data['summary'])) {
$changes['su'] = trim($this->cleaned_data['summary']);
}
$owner = self::findUser($this->cleaned_data['owner']);
if ((is_null($owner) and !is_null($this->issue->get_owner()))
or (!is_null($owner) and is_null($this->issue->get_owner()))
or ((!is_null($owner) and !is_null($this->issue->get_owner())) and $owner->id != $this->issue->get_owner()->id)) {
$changes['ow'] = (is_null($owner)) ? '---' : $owner->login;
}
// Update the issue
$this->issue->batchAssoc('IDF_Tag', $tagids);
$this->issue->summary = trim($this->cleaned_data['summary']);
$this->issue->status = $status;
$this->issue->owner = $owner;
}
// Create the comment
$comment = new IDF_IssueComment();
$comment->issue = $this->issue;
$comment->content = $this->cleaned_data['content'];
$comment->submitter = $this->user;
if (!$this->show_full) $changes = array();
$comment->changes = $changes;
$comment->create();
$this->issue->update();
return $this->issue;
}
throw new Exception(__('Cannot save the model from an invalid form.'));
}
}
src/IDF/Form/MembersConf.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Configuration of the members.
*
* To simplify the management. Instead of being obliged to go through
* a list of people and then select the rights member/owner, I am
* using the same approach as googlecode, that is, asking for the
* login. This makes the interface simpler and simplicity is king.
*
* In background, the row permission framework is used to give the
* member/owner permission to the given project to the users.
*/
class IDF_Form_MembersConf extends Pluf_Form
{
public $project = null;
public function initFields($extra=array())
{
$this->project = $extra['project'];
$this->fields['owners'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Project owners'),
'initial' => '',
'widget' => 'Pluf_Form_Widget_TextareaInput',
'widget_attrs' => array('rows' => 5,
'cols' => 40),
));
$this->fields['members'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Project members'),
'widget_attrs' => array('rows' => 7,
'cols' => 40),
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
}
public function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
// remove all the permissions
$cm = $this->project->getMembershipData();
$def = array('owners' => Pluf_Permission::getFromString('IDF.project-owner'),
'members' => Pluf_Permission::getFromString('IDF.project-member'));
$guser = new Pluf_User();
foreach ($def as $key=>$perm) {
foreach ($cm[$key] as $user) {
Pluf_RowPermission::remove($user, $this->project, $perm);
}
foreach (preg_split("/\015\012|\015|\012|\,/", $this->cleaned_data[$key], -1, PREG_SPLIT_NO_EMPTY) as $login) {
$sql = new Pluf_SQL('login=%s', array(trim($login)));
$users = $guser->getList(array('filter'=>$sql->gen()));
if ($users->count() == 1) {
Pluf_RowPermission::add($users[0], $this->project, $perm);
}
}
}
}
}
src/IDF/Issue.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Base definition of an issue.
*
* An issue can have labels, comments, can be starred by people.
*/
class IDF_Issue extends Pluf_Model
{
public $_model = __CLASS__;
function init()
{
$this->_a['table'] = 'idf_issues';
$this->_a['model'] = __CLASS__;
$this->_a['cols'] = array(
// It is mandatory to have an "id" column.
'id' =>
array(
'type' => 'Pluf_DB_Field_Sequence',
'blank' => true,
),
'project' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'IDF_Project',
'blank' => false,
'verbose' => __('project'),
'relate_name' => 'issues',
),
'summary' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'size' => 250,
'verbose' => __('summary'),
),
'submitter' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'Pluf_User',
'blank' => false,
'verbose' => __('submitter'),
'relate_name' => 'submitted_issue',
),
'owner' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'Pluf_User',
'blank' => true, // no owner when submitted.
'is_null' => true,
'verbose' => __('owner'),
'relate_name' => 'owned_issue',
),
'interested' =>
array(
'type' => 'Pluf_DB_Field_Manytomany',
'model' => 'Pluf_User',
'blank' => true,
'verbose' => __('interested users'),
'help_text' => __('Interested users will get an email notification when the issue is changed.'),
),
'tags' =>
array(
'type' => 'Pluf_DB_Field_Manytomany',
'blank' => true,
'model' => 'IDF_Tag',
'verbose' => __('labels'),
),
'status' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'blank' => false,
'model' => 'IDF_Tag',
'verbose' => __('status'),
),
'creation_dtime' =>
array(
'type' => 'Pluf_DB_Field_Datetime',
'blank' => true,
'verbose' => __('creation date'),
),
'modif_dtime' =>
array(
'type' => 'Pluf_DB_Field_Datetime',
'blank' => true,
'verbose' => __('modification date'),
),
);
$this->_a['idx'] = array(
'modif_dtime_idx' =>
array(
'col' => 'modif_dtime',
'type' => 'normal',
),
);
$table = $this->_con->pfx.'idf_issue_idf_tag_assoc';
$this->_a['views'] = array(
'join_tags' =>
array(
'join' => 'LEFT JOIN '.$table
.' ON idf_issue_id=id',
),
);
}
function __toString()
{
return $this->id.' - '.$this->summary;
}
function _toIndex()
{
return '';
}
function preSave()
{
if ($this->id == '') {
$this->creation_dtime = gmdate('Y-m-d H:i:s');
}
$this->modif_dtime = gmdate('Y-m-d H:i:s');
}
function postSave()
{
// This will be used to fire the indexing or send a
// notification email to the interested people, etc.
$q = new Pluf_Queue();
$q->model_class = __CLASS__;
$q->model_id = $this->id;
$q->action = 'updated';
$q->lock = 0;
$q->create();
}
}
src/IDF/IssueComment.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* A comment to an issue.
*
* The first description of an issue is also stored as a comment.
*
* A comment is also tracking the changes in the main issue.
*/
class IDF_IssueComment extends Pluf_Model
{
public $_model = __CLASS__;
function init()
{
$this->_a['table'] = 'idf_issuecomments';
$this->_a['model'] = __CLASS__;
$this->_a['cols'] = array(
// It is mandatory to have an "id" column.
'id' =>
array(
'type' => 'Pluf_DB_Field_Sequence',
'blank' => true,
),
'issue' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'IDF_Issue',
'blank' => false,
'verbose' => __('issue'),
'relate_name' => 'comments',
),
'content' =>
array(
'type' => 'Pluf_DB_Field_Text',
'blank' => false,
'verbose' => __('comment'),
),
'submitter' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'Pluf_User',
'blank' => false,
'verbose' => __('submitter'),
'relate_name' => 'commented_issue',
),
'changes' =>
array(
'type' => 'Pluf_DB_Field_Serialized',
'blank' => true,
'verbose' => __('changes'),
'help_text' => __('Serialized array of the changes in the issue.'),
),
'creation_dtime' =>
array(
'type' => 'Pluf_DB_Field_Datetime',
'blank' => true,
'verbose' => __('creation date'),
),
);
$this->_a['idx'] = array(
'creation_dtime_idx' =>
array(
'col' => 'creation_dtime',
'type' => 'normal',
),
);
}
function changedIssue()
{
return count($this->changes) > 0;
}
function _toIndex()
{
return $this->content;
}
function preSave()
{
if ($this->id == '') {
$this->creation_dtime = gmdate('Y-m-d H:i:s');
}
}
function postSave()
{
// This will be used to fire the indexing or send a
// notification email to the interested people, etc.
$q = new Pluf_Queue();
$q->model_class = __CLASS__;
$q->model_id = $this->id;
$q->action = 'updated';
$q->lock = 0;
$q->create();
}
}
src/IDF/Middleware.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Project middleware.
*
*/
class IDF_Middleware
{
/**
* Process the request.
*
* When processing the request, check if matching a project. If
* so, directly set $request->project to the project.
*
* The url to match a project is in the format
* /p/(\w+)/whatever. This means that it will not try to match on
* /login/ or /logout/.
*
* @param Pluf_HTTP_Request The request
* @return bool false or redirect.
*/
function process_request(&$request)
{
$match = array();
if (preg_match('#^/p/(\w+)/#', $request->query, $match)) {
$request->project = IDF_Project::getOr404($match[1]);
}
return false;
}
}
function IDF_Middleware_ContextPreProcessor($request)
{
$c = array();
if (isset($request->project)) {
$c['project'] = $request->project;
$c['isOwner'] = $request->user->hasPerm('IDF.project-owner',
$request->project);
$c['isMember'] = $request->user->hasPerm('IDF.project-member',
$request->project);
}
return $c;
}
src/IDF/Migrations/Install.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Setup of a clean InDefero.
*
* It creates all the tables for the application.
*/
function IDF_Migrations_Install_setup($params=null)
{
$models = array(
'IDF_Project',
'IDF_Tag',
'IDF_Issue',
'IDF_IssueComment',
'IDF_Conf',
);
$db = Pluf::db();
$schema = new Pluf_DB_Schema($db);
foreach ($models as $model) {
$schema->model = new $model();
$schema->createTables();
}
// Install the permissions
$perm = new Pluf_Permission();
$perm->name = 'Project membership';
$perm->code_name = 'project-member';
$perm->description = 'Permission given to project members.';
$perm->application = 'IDF';
$perm->create();
$perm = new Pluf_Permission();
$perm->name = 'Project ownership';
$perm->code_name = 'project-owner';
$perm->description = 'Permission given to project owners.';
$perm->application = 'IDF';
$perm->create();
}
function IDF_Migrations_Install_teardown($params=null)
{
$perm = Pluf_Permission::getFromString('IDF.project-member');
if ($perm) $perm->delete();
$perm = Pluf_Permission::getFromString('IDF.project-owner');
if ($perm) $perm->delete();
$models = array(
'IDF_Conf',
'IDF_IssueComment',
'IDF_Issue',
'IDF_Tag',
'IDF_Project',
);
$db = Pluf::db();
$schema = new Pluf_DB_Schema($db);
foreach ($models as $model) {
$schema->model = new $model();
$schema->dropTables();
}
}
src/IDF/Precondition.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
class IDF_Precondition
{
/**
* Check if the user is project owner.
*
* @param Pluf_HTTP_Request
* @return mixed
*/
static public function projectOwner($request)
{
$res = Pluf_Precondition::loginRequired($request);
if (true !== $res) {
return $res;
}
if ($request->user->hasPerm('IDF.project-owner', $request->project)) {
return true;
}
return new Pluf_HTTP_Response_Forbidden($request);
}
}
src/IDF/Project.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Loic d'Anterroches and contributors.
#
# Plume CMS is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Plume CMS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Base definition of a project.
*
* The issue management system can be used to manage several projects
* at the same time.
*/
class IDF_Project extends Pluf_Model
{
public $_model = __CLASS__;
function init()
{
$this->_a['table'] = 'idf_projects';
$this->_a['model'] = __CLASS__;
$this->_a['cols'] = array(
// It is mandatory to have an "id" column.
'id' =>
array(
'type' => 'Pluf_DB_Field_Sequence',
'blank' => true,
),
'name' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'size' => 250,
'verbose' => __('name'),
),
'shortname' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'size' => 50,
'verbose' => __('short name'),
'help_text' => __('Used in the url to access the project, must be short with only letters and numbers.'),
'unique' => true,
),
'description' =>
array(
'type' => 'Pluf_DB_Field_Text',
'blank' => false,
'size' => 250,
'verbose' => __('description'),
'help_text' => __('The description can be extended using the markdown syntax.'),
),
);
$this->_a['idx'] = array( );
}
/**
* String representation of the abstract.
*/
function __toString()
{
return $this->name;
}
/**
* String ready for indexation.
*/
function _toIndex()
{
return '';
}
function preSave()
{
if ($this->id == '') {
$this->creation_dtime = gmdate('Y-m-d H:i:s');
}
$this->modif_dtime = gmdate('Y-m-d H:i:s');
}
public static function getOr404($shortname)
{
$sql = new Pluf_SQL('shortname=%s', array(trim($shortname)));
$projects = Pluf::factory(__CLASS__)->getList(array('filter' => $sql->gen()));
if ($projects->count() != 1) {
throw new Pluf_HTTP_Error404(sprintf(__('Project "%s" not found.'),
$shortname));
}
return $projects[0];
}
/**
* Returns the number of open/closed issues.
*
* @param string Status ('open'), 'closed'
* @param IDF_Tag Subfilter with a label (null)
* @return int Count
*/
public function getIssueCountByStatus($status='open', $label=null)
{
switch ($status) {
case 'open':
$key = 'labels_issue_open';
$default = IDF_Form_IssueTrackingConf::init_open;
break;
case 'closed':
default:
$key = 'labels_issue_closed';
$default = IDF_Form_IssueTrackingConf::init_closed;
break;
}
$tags = array();
foreach ($this->getTagsFromConfig($key, $default, 'Status') as $tag) {
$tags[] = (int)$tag->id;
}
if (count($tags) == 0) return array();
$sql = new Pluf_SQL(sprintf('project=%%s AND status IN (%s)', implode(', ', $tags)), array($this->id));
if (!is_null($label)) {
$sql2 = new Pluf_SQL('idf_tag_id=%s', array($label->id));
$sql->SAnd($sql2);
}
$params = array('filter' => $sql->gen());
if (!is_null($label)) { $params['view'] = 'join_tags'; }
$gissue = new IDF_Issue();
return $gissue->getCount($params);
}
/**
* Get the open/closed tag ids as they are often used when doing
* listings.
*
* @param string Status ('open') or 'closed'
* @return array Ids of the open/closed tags
*/
public function getTagIdsByStatus($status='open')
{
switch ($status) {
case 'open':
$key = 'labels_issue_open';
$default = IDF_Form_IssueTrackingConf::init_open;
break;
case 'closed':
default:
$key = 'labels_issue_closed';
$default = IDF_Form_IssueTrackingConf::init_closed;
break;
}
$tags = array();
foreach ($this->getTagsFromConfig($key, $default, 'Status') as $tag) {
$tags[] = (int) $tag->id;
}
return $tags;
}
/**
* Convert the definition of tags in the configuration into the
* corresponding list of tags.
*
* @param string Configuration key where the tag is.
* @param string Default config if nothing in the db.
* @param string Default class.
* @return array List of tags
*/
public function getTagsFromConfig($cfg_key, $default, $dclass='Other')
{
$conf = new IDF_Conf();
$conf->setProject($this);
$tags = array();
foreach (preg_split("/\015\012|\015|\012/", $conf->getVal($cfg_key, $default), -1, PREG_SPLIT_NO_EMPTY) as $s) {
$_s = split('=', $s, 2);
$v = trim($_s[0]);
$_v = split(':', $v, 2);
if (count($_v) > 1) {
$class = trim($_v[0]);
$name = trim($_v[1]);
} else {
$name = trim($_s[0]);
$class = $dclass;
}
$tags[] = IDF_Tag::add($name, $this, $class);
}
return $tags;
}
/**
* Return membership data.
*
* The array has 2 keys: 'members' and 'owners'.
*
* The list of users is only taken using the row level permission
* table. That is, if you set a user as administrator, he will
* have the member and owner rights but will not appear in the
* lists.
*
* @param string Format ('objects'), 'string'.
* @return mixed Array of Pluf_User or newline separated list of logins.
*/
public function getMembershipData($fmt='objects')
{
$mperm = Pluf_Permission::getFromString('IDF.project-member');
$operm = Pluf_Permission::getFromString('IDF.project-owner');
$grow = new Pluf_RowPermission();
$db =& Pluf::db();
$false = Pluf_DB_BooleanToDb(false, $db);
$sql = new Pluf_SQL('model_class=%s AND model_id=%s AND owner_class=%s AND permission=%s AND negative='.$false,
array('IDF_Project', $this->id, 'Pluf_User', $operm->id));
$owners = array();
foreach ($grow->getList(array('filter' => $sql->gen())) as $row) {
if ($fmt == 'objects') {
$owners[] = Pluf::factory('Pluf_User', $row->owner_id);
} else {
$owners[] = Pluf::factory('Pluf_User', $row->owner_id)->login;
}
}
$sql = new Pluf_SQL('model_class=%s AND model_id=%s AND owner_class=%s AND permission=%s AND negative=0',
array('IDF_Project', $this->id, 'Pluf_User', $mperm->id));
$members = array();
foreach ($grow->getList(array('filter' => $sql->gen())) as $row) {
if ($fmt == 'objects') {
$members[] = Pluf::factory('Pluf_User', $row->owner_id);
} else {
$members[] = Pluf::factory('Pluf_User', $row->owner_id)->login;
}
}
if ($fmt == 'objects') {
return array('members' => $members, 'owners' => $owners);
} else {
return array('members' => implode("\n", $members),
'owners' => implode("\n", $owners));
}
}
/**
* Generate the tag clouds.
*
* Return an array of tags sorted class, then name. Each tag get
* the extra property 'nb_use' for the number of use in the
* project. Only open issues are used to generate the cloud.
*
* @return ArrayObject of IDF_Tag
*/
public function getTagCloud()
{
$tag_t = Pluf::factory('IDF_Tag')->getSqlTable();
$issue_t = Pluf::factory('IDF_Issue')->getSqlTable();
$asso_t = $this->_con->pfx.'idf_issue_idf_tag_assoc';
$ostatus = $this->getTagIdsByStatus('open');
if (count($ostatus) == 0) $ostatus[] = 0;
$sql = sprintf('SELECT '.$tag_t.'.id AS id, COUNT(*) AS nb_use FROM '.$tag_t.' '."\n".
'LEFT JOIN '.$asso_t.' ON idf_tag_id='.$tag_t.'.id '."\n".
'LEFT JOIN '.$issue_t.' ON idf_issue_id='.$issue_t.'.id '."\n".
'WHERE idf_tag_id NOT NULL AND '.$issue_t.'.status IN (%s) AND '.$issue_t.'.project='.$this->id.' GROUP BY '.$tag_t.'.id ORDER BY '.$tag_t.'.class ASC, '.$tag_t.'.name ASC',
implode(', ', $ostatus));
$tags = array();
foreach ($this->_con->select($sql) as $idc) {
$tag = new IDF_Tag($idc['id']);
$tag->nb_use = $idc['nb_use'];
$tags[] = $tag;
}
return $tags;
}
}
src/IDF/Tag.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Loic d'Anterroches and contributors.
#
# Plume CMS is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Plume CMS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Store a tag definition.
*
* Tags are associated to a project.
*/
define('IDF_TAG_DEFAULT_CLASS', 'other');
class IDF_Tag extends Pluf_Model
{
public $_model = __CLASS__;
function init()
{
$this->_a['table'] = 'idf_tags';
$this->_a['model'] = __CLASS__;
$this->_a['cols'] = array(
// It is mandatory to have an "id" column.
'id' =>
array(
'type' => 'Pluf_DB_Field_Sequence',
//It is automatically added.
'blank' => true,
),
'project' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'IDF_Project',
'blank' => false,
'verbose' => __('project'),
),
'class' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'default' => IDF_TAG_DEFAULT_CLASS,
'verbose' => __('tag class'),
'help_text' => __('The class of the tag.'),
),
'name' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'verbose' => __('name'),
),
'lcname' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'editable' => false,
'verbose' => __('lcname'),
'help_text' => __('Lower case version of the name for fast searching.'),
),
);
$this->_a['idx'] = array(
'lcname_idx' =>
array(
'col' => 'lcname',
'type' => 'normal',
),
'class_idx' =>
array(
'col' => 'class',
'type' => 'normal',
),
);
}
function preSave()
{
$this->lcname = mb_strtolower($this->name);
}
/**
* Add a tag if not already existing.
*
* @param string Name of the tag.
* @param IDF_Project Project of the tag.
* @param string Class of the tag (IDF_TAG_DEFAULT_CLASS)
* @return IDF_Tag The tag.
*/
public static function add($name, $project, $class=IDF_TAG_DEFAULT_CLASS)
{
$class = trim($class);
$name = trim($name);
$gtag = new IDF_Tag();
$sql = new Pluf_SQL('class=%s AND lcname=%s AND project=%s',
array($class, mb_strtolower($name), $project->id));
$tags = $gtag->getList(array('filter' => $sql->gen()));
if ($tags->count() < 1) {
// create a new tag
$tag = new IDF_Tag();
$tag->name = $name;
$tag->class = $class;
$tag->project = $project;
$tag->create();
return $tag;
}
return $tags[0];
}
function __toString()
{
if ($this->class != IDF_TAG_DEFAULT_CLASS) {
return $this->class.':'.$this->name;
}
return $this->name;
}
}
src/IDF/Tests/TestIssue.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
/**
* Test the creation/modification of a project.
*/
class IDF_Tests_TestIssue extends UnitTestCase
{
public $projects = array();
public $users = array();
public function __construct()
{
parent::__construct('Test creation/modification of issues.');
}
/**
* Create 2 projects to work with and 2 users.
*/
public function setUp()
{
$this->projects = array();
$this->users = array();
for ($i=1;$i<3;$i++) {
$project = new IDF_Project();
$project->name = 'Test project '.$i;
$project->shortname = 'test'.$i;
$project->description = sprintf('This is a test project %d.', $i);
$project->create();
$this->projects[] = $project;
$user = new Pluf_User();
$user->last_name = 'user'.$i;
$user->login = 'user'.$i;
$user->email = 'user'.$i.'@example.com';
$user->create();
$this->users[] = $user;
}
}
public function tearDown()
{
// This will drop cascading issues, comments and tags.
foreach ($this->projects as $proj) {
$proj->delete();
}
foreach ($this->users as $u) {
$u->delete();
}
}
public function testCreate()
{
$issue = new IDF_Issue();
$issue->project = $this->projects[0];
$issue->summary = 'This is a test issue';
$issue->submitter = $this->users[0];
$issue->create();
$this->assertEqual(1, $issue->id);
$this->assertIdentical(null, $issue->get_owner());
$this->assertNotIdentical(null, $issue->get_submitter());
}
public function testCreateMultiple()
{
for ($i=1;$i<11;$i++) {
$issue = new IDF_Issue();
$issue->project = $this->projects[0];
$issue->summary = 'This is a test issue '.$i;
$issue->submitter = $this->users[0];
$issue->owner = $this->users[1];
$issue->create();
}
for ($i=11;$i<16;$i++) {
$issue = new IDF_Issue();
$issue->project = $this->projects[1];
$issue->summary = 'This is a test issue '.$i;
$issue->submitter = $this->users[1];
$issue->create();
}
$this->assertEqual(10,
$this->projects[0]->get_issues_list()->count());
$this->assertEqual(5,
$this->projects[1]->get_issues_list()->count());
$this->assertEqual(5,
$this->users[1]->get_submitted_issue_list()->count());
$this->assertEqual(10,
$this->users[0]->get_submitted_issue_list()->count());
$this->assertEqual(10,
$this->users[1]->get_owned_issue_list()->count());
$this->assertEqual(0,
$this->users[1]->get_owned_issue_list(array('filter' => 'project='.(int)$this->projects[1]->id))->count());
$this->assertEqual(10,
$this->users[1]->get_owned_issue_list(array('filter' => 'project='.(int)$this->projects[0]->id))->count());
}
public function testAddIssueComment()
{
$issue = new IDF_Issue();
$issue->project = $this->projects[0];
$issue->summary = 'This is a test issue';
$issue->submitter = $this->users[0];
$issue->create();
$ic = new IDF_IssueComment();
$ic->issue = $issue;
$ic->submitter = $this->users[0];
$ic->content = 'toto';
$changes = array('s' => 'New summary',
'st' => 'Active',
't' => '-OS:Linux OS:Windows');
$ic->changes = $changes;
$ic->create();
$comments = $issue->get_comments_list();
$this->assertEqual($changes, $comments[0]->changes);
}
}
src/IDF/Tests/TestProject.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
/**
* Test the creation/modification of a project.
*/
class IDF_Tests_TestProject extends UnitTestCase
{
public function __construct()
{
parent::__construct('Test creation/modification of a project.');
}
public function tearDown()
{
foreach (Pluf::factory('IDF_Project')->getList() as $proj) {
$proj->delete();
}
}
public function testCreate()
{
$gproj = Pluf::factory('IDF_Project')->getList();
$this->assertEqual(0, $gproj->count());
$project = new IDF_Project();
$project->name = 'Test project';
$project->shortname = 'test';
$project->description = 'This is a test project.';
$project->create();
$id = $project->id;
$p2 = new IDF_Project($id);
$this->assertEqual($p2->shortname, $project->shortname);
}
public function testMultipleCreate()
{
$project = new IDF_Project();
$project->name = 'Test project';
$project->shortname = 'test';
$project->description = 'This is a test project.';
$project->create();
try {
$project = new IDF_Project();
$project->name = 'Test project';
$project->shortname = 'test';
$project->description = 'This is a test project.';
$project->create();
// if here it as failed
$this->fail('It should not be possible to create 2 projects with same shortname');
} catch (Exception $e) {
$this->pass();
}
}
}
src/IDF/Views.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse');
Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404');
Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel');
/**
* Base views of InDefero.
*/
class IDF_Views
{
/**
* List all the projects managed by InDefero.
*/
public function index($request, $match)
{
$projects = Pluf::factory('IDF_Project')->getList();
return Pluf_Shortcuts_RenderToResponse('index.html',
array('page_title' => __('Projects'),
'projects' => $projects),
$request);
}
/**
* Login view.
*/
public function login($request, $match)
{
$v = new Pluf_Views();
return $v->login($request, $match, Pluf::f('login_success_url'));
}
/**
* Logout view.
*/
function logout($request, $match)
{
$views = new Pluf_Views();
return $views->logout($request, $match, Pluf::f('after_logout_page'));
}
}
src/IDF/Views/Issue.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse');
Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404');
Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel');
/**
* Issues' views.
*/
class IDF_Views_Issue
{
/**
* View list of issues for a given project.
*/
public function index($request, $match)
{
$prj = $request->project;
$title = sprintf(__('%s Recent Issues'), (string) $prj);
// Get stats about the issues
$open = $prj->getIssueCountByStatus('open');
$closed = $prj->getIssueCountByStatus('closed');
// Paginator to paginate the issues
$pag = new Pluf_Paginator(new IDF_Issue());
$pag->class = 'recent-issues';
$pag->item_extra_props = array('project_m' => $prj,
'shortname' => $prj->shortname);
$pag->summary = __('This table shows the open recent issues.');
$otags = $prj->getTagIdsByStatus('open');
if (count($otags) == 0) $otags[] = 0;
$pag->forced_where = new Pluf_SQL('project=%s AND status IN ('.implode(', ', $otags).')', array($prj->id));
$pag->action = array('IDF_Views_Issue::index', array($prj->shortname));
$pag->sort_order = array('modif_dtime', 'DESC');
$list_display = array(
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('status', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
return Pluf_Shortcuts_RenderToResponse('issues/index.html',
array('project' => $prj,
'page_title' => $title,
'open' => $open,
'closed' => $closed,
'issues' => $pag,
),
$request);
}
/**
* View the issues of a given user.
*
* Only open issues are shown.
*/
public $myIssues_precond = array('Pluf_Precondition::loginRequired');
public function myIssues($request, $match)
{
$prj = $request->project;
$otags = $prj->getTagIdsByStatus('open');
if (count($otags) == 0) $otags[] = 0;
if ($match[2] == 'submit') {
$title = sprintf(__('My Submitted %s Issues'), (string) $prj);
$f_sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
} else {
$title = sprintf(__('My Working %s Issues'), (string) $prj);
$f_sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
}
// Get stats about the issues
$sql = new Pluf_SQL('project=%s AND submitter=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
$nb_submit = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
$sql = new Pluf_SQL('project=%s AND owner=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $request->user->id));
$nb_owner = Pluf::factory('IDF_Issue')->getCount(array('filter'=>$sql->gen()));
// Paginator to paginate the issues
$pag = new Pluf_Paginator(new IDF_Issue());
$pag->class = 'recent-issues';
$pag->item_extra_props = array('project_m' => $prj,
'shortname' => $prj->shortname);
$pag->summary = __('This table shows the open recent issues.');
$pag->forced_where = $f_sql;
$pag->action = array('IDF_Views_Issue::myIssues', array($prj->shortname, $match[2]));
$pag->sort_order = array('modif_dtime', 'DESC');
$list_display = array(
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('status', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
return Pluf_Shortcuts_RenderToResponse('issues/my-issues.html',
array('project' => $prj,
'page_title' => $title,
'nb_submit' => $nb_submit,
'nb_owner' => $nb_owner,
'issues' => $pag,
),
$request);
}
public $create_precond = array('Pluf_Precondition::loginRequired');
public function create($request, $match)
{
$prj = $request->project;
$title = __('Submit a new issue');
$params = array(
'project' => $prj,
'user' => $request->user);
if ($request->method == 'POST') {
$form = new IDF_Form_IssueCreate($request->POST, $params);
if ($form->isValid()) {
$issue = $form->save();
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index',
array($prj->shortname));
$urlissue = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',
array($prj->shortname, $issue->id));
$request->user->setMessage(sprintf(__('<a href="%s">Issue %d</a> has been created.'), $urlissue, $issue->id));
return new Pluf_HTTP_Response_Redirect($url);
}
} else {
$form = new IDF_Form_IssueCreate(null, $params);
}
$arrays = self::autoCompleteArrays($prj);
return Pluf_Shortcuts_RenderToResponse('issues/create.html',
array_merge(
array('project' => $prj,
'form' => $form,
'page_title' => $title,
),
$arrays),
$request);
}
public function view($request, $match)
{
$prj = $request->project;
$issue = Pluf_Shortcuts_GetObjectOr404('IDF_Issue', $match[2]);
if ($issue->project != $prj->id) {
throw new Pluf_HTTP_Error404();
}
$comments = $issue->get_comments_list(array('order' => 'id ASC'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',
array($prj->shortname, $issue->id));
$title = Pluf_Template::markSafe(sprintf(__('Issue <a href="%s">%d</a>: %s'), $url, $issue->id, $issue->summary));
$form = false; // The form is available only if logged in.
if (!$request->user->isAnonymous()) {
$params = array(
'project' => $prj,
'user' => $request->user,
'issue' => $issue,
);
if ($request->method == 'POST') {
$form = new IDF_Form_IssueUpdate($request->POST, $params);
if ($form->isValid()) {
$issue = $form->save();
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::index',
array($prj->shortname));
$request->user->setMessage(sprintf(__('Issue %d has been updated.'), $issue->id));
return new Pluf_HTTP_Response_Redirect($url);
}
} else {
$form = new IDF_Form_IssueUpdate(null, $params);
}
}
$arrays = self::autoCompleteArrays($prj);
return Pluf_Shortcuts_RenderToResponse('issues/view.html',
array_merge(
array('project' => $prj,
'issue' => $issue,
'comments' => $comments,
'form' => $form,
'page_title' => $title,
),
$arrays),
$request);
}
/**
* View list of issues for a given project with a given status.
*/
public function listStatus($request, $match)
{
$prj = $request->project;
$status = $match[2];
$title = sprintf(__('%s Closed Issues'), (string) $prj);
// Get stats about the issues
$open = $prj->getIssueCountByStatus('open');
$closed = $prj->getIssueCountByStatus('closed');
// Paginator to paginate the issues
$pag = new Pluf_Paginator(new IDF_Issue());
$pag->class = 'recent-issues';
$pag->item_extra_props = array('project_m' => $prj,
'shortname' => $prj->shortname);
$pag->summary = __('This table shows the closed issues.');
$otags = $prj->getTagIdsByStatus('closed');
if (count($otags) == 0) $otags[] = 0;
$pag->forced_where = new Pluf_SQL('project=%s AND status IN ('.implode(', ', $otags).')', array($prj->id));
$pag->action = array('IDF_Views_Issue::index', array($prj->shortname));
$pag->sort_order = array('modif_dtime', 'DESC');
$list_display = array(
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('id', 'status', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
return Pluf_Shortcuts_RenderToResponse('issues/index.html',
array('project' => $prj,
'page_title' => $title,
'open' => $open,
'closed' => $closed,
'issues' => $pag,
),
$request);
}
/**
* View list of issues for a given project with a given label.
*/
public function listLabel($request, $match)
{
$prj = $request->project;
$tag = Pluf_Shortcuts_GetObjectOr404('IDF_Tag', $match[2]);
$status = $match[3];
if ($tag->project != $prj->id or !in_array($status, array('open', 'closed'))) {
throw new Pluf_HTTP_Error404();
}
if ($status == 'open') {
$title = sprintf(__('%1$s Issues with Label %2$s'), (string) $prj,
(string) $tag);
} else {
$title = sprintf(__('%1$s Closed Issues with Label %2$s'),
(string) $prj, (string) $tag);
}
// Get stats about the open/closed issues having this tag.
$open = $prj->getIssueCountByStatus('open', $tag);
$closed = $prj->getIssueCountByStatus('closed', $tag);
// Paginator to paginate the issues
$pag = new Pluf_Paginator(new IDF_Issue());
$pag->model_view = 'join_tags';
$pag->class = 'recent-issues';
$pag->item_extra_props = array('project_m' => $prj,
'shortname' => $prj->shortname);
$pag->summary = sprintf(__('This table shows the issues with label %s.'), (string) $tag);
$otags = $prj->getTagIdsByStatus($status);
if (count($otags) == 0) $otags[] = 0;
$pag->forced_where = new Pluf_SQL('project=%s AND idf_tag_id=%s AND status IN ('.implode(', ', $otags).')', array($prj->id, $tag->id));
$pag->action = array('IDF_Views_Issue::listLabel', array($prj->shortname, $tag->id, $status));
$pag->sort_order = array('modif_dtime', 'DESC');
$list_display = array(
'id' => __('Id'),
array('summary', 'IDF_Views_Issue_SummaryAndLabels', __('Summary')),
array('status', 'IDF_Views_Issue_ShowStatus', __('Status')),
array('modif_dtime', 'Pluf_Paginator_DateAgo', __('Last Updated')),
);
$pag->configure($list_display, array(), array('status', 'modif_dtime'));
$pag->items_per_page = 10;
$pag->no_results_text = __('No issues were found.');
$pag->setFromRequest($request);
if (($open+$closed) > 0) {
$completion = sprintf('%01.0f%%', (100*$closed)/((float) $open+$closed));
} else {
$completion = false;
}
return Pluf_Shortcuts_RenderToResponse('issues/by-label.html',
array('project' => $prj,
'completion' => $completion,
'page_title' => $title,
'open' => $open,
'label' => $tag,
'closed' => $closed,
'issues' => $pag,
),
$request);
}
/**
* Create the autocomplete arrays for the little AJAX stuff.
*/
public static function autoCompleteArrays($project)
{
$conf = new IDF_Conf();
$conf->setProject($project);
$auto = array('auto_status' => '', 'auto_labels' => '');
$auto_raw = array('auto_status' => '', 'auto_labels' => '');
$st = $conf->getVal('labels_issue_open', IDF_Form_IssueTrackingConf::init_open);
$st .= "\n".$conf->getVal('labels_issue_closed', IDF_Form_IssueTrackingConf::init_closed);
$auto_raw['auto_status'] = $st;
$auto_raw['auto_labels'] = $conf->getVal('labels_issue_predefined', IDF_Form_IssueTrackingConf::init_predefined);
foreach ($auto_raw as $key => $st) {
$st = preg_split("/\015\012|\015|\012/", $st, -1, PREG_SPLIT_NO_EMPTY);
foreach ($st as $s) {
$v = '';
$d = '';
$_s = split('=', $s, 2);
if (count($_s) > 1) {
$v = trim($_s[0]);
$d = trim($_s[1]);
} else {
$v = trim($_s[0]);
}
$auto[$key] .= sprintf('{ name: "%s", to: "%s" }, ',
Pluf_esc($d),
Pluf_esc($v));
}
$auto[$key] = substr($auto[$key], 0, -1);
}
return $auto;
}
}
/**
* Display the summary of an issue, then on a new line, display the
* list of labels with a link to a view "by label only".
*
* The summary of the issue is linking to the issue.
*/
function IDF_Views_Issue_SummaryAndLabels($field, $issue, $extra='')
{
$edit = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::view',
array($issue->shortname, $issue->id));
$tags = array();
foreach ($issue->get_tags_list() as $tag) {
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Issue::listLabel',
array($issue->shortname, $tag->id, 'open'));
$tags[] = sprintf('<a class="label" href="%s">%s</a>', $url, Pluf_esc((string) $tag));
}
$out = '';
if (count($tags)) {
$out = '<br /><span class="note">'.implode(', ', $tags).'</span>';
}
return sprintf('<a href="%s">%s</a>', $edit, Pluf_esc($issue->summary)).$out;
}
/**
* Display the status in the issue listings.
*
*/
function IDF_Views_Issue_ShowStatus($field, $issue, $extra='')
{
return Pluf_esc($issue->get_status()->name);
}
src/IDF/Views/Project.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse');
Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404');
Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel');
/**
* Project's views.
*/
class IDF_Views_Project
{
/**
* Administrate the summary of a project.
*/
public $admin_precond = array('IDF_Precondition::projectOwner');
public function admin($request, $match)
{
$prj = $request->project;
$title = sprintf(__('%s Project Summary'), (string) $prj);
$form_fields = array('fields'=> array('name', 'description'));
if ($request->method == 'POST') {
$form = Pluf_Shortcuts_GetFormForModel($prj, $request->POST,
$form_fields);
if ($form->isValid()) {
$prj = $form->save();
$request->user->setMessage(__('The project has been updated.'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::admin',
array($prj->shortname));
return new Pluf_HTTP_Response_Redirect($url);
}
} else {
$form = Pluf_Shortcuts_GetFormForModel($prj, $prj->getData(),
$form_fields);
}
return Pluf_Shortcuts_RenderToResponse('admin/summary.html',
array(
'page_title' => $title,
'form' => $form,
),
$request);
}
/**
* Administrate the issue tracking of a project.
*/
public $adminIssueTracking_precond = array('IDF_Precondition::projectOwner');
public function adminIssues($request, $match)
{
$prj = $request->project;
$title = sprintf(__('%s Issue Tracking Configuration'), (string) $prj);
$conf = new IDF_Conf();
$conf->setProject($prj);
if ($request->method == 'POST') {
$form = new IDF_Form_IssueTrackingConf($request->POST);
if ($form->isValid()) {
foreach ($form->cleaned_data as $key=>$val) {
$conf->setVal($key, $val);
}
$request->user->setMessage(__('The issue tracking configuration has been saved.'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminIssues',
array($prj->shortname));
return new Pluf_HTTP_Response_Redirect($url);
}
} else {
$params = array();
$keys = array('labels_issue_open', 'labels_issue_closed',
'labels_issue_predefined', 'labels_issue_one_max');
foreach ($keys as $key) {
$_val = $conf->getVal($key, false);
if ($_val !== false) {
$params[$key] = $_val;
}
}
if (count($params) == 0) {
$params = null; //Nothing in the db, so new form.
}
$form = new IDF_Form_IssueTrackingConf($params);
}
return Pluf_Shortcuts_RenderToResponse('admin/issue-tracking.html',
array(
'page_title' => $title,
'form' => $form,
),
$request);
}
/**
* Administrate the members of a project.
*/
public $adminMembers_precond = array('IDF_Precondition::projectOwner');
public function adminMembers($request, $match)
{
$prj = $request->project;
$title = sprintf(__('%s Project Members'), (string) $prj);
$params = array(
'project' => $prj,
'user' => $request->user,
);
if ($request->method == 'POST') {
$form = new IDF_Form_MembersConf($request->POST, $params);
if ($form->isValid()) {
$form->save();
$request->user->setMessage(__('The project membership has been saved.'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminMembers',
array($prj->shortname));
return new Pluf_HTTP_Response_Redirect($url);
}
} else {
$form = new IDF_Form_MembersConf($prj->getMembershipData('string'), $params);
}
return Pluf_Shortcuts_RenderToResponse('admin/members.html',
array(
'page_title' => $title,
'form' => $form,
),
$request);
}
}
src/IDF/conf/views.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Loic d'Anterroches and contributors.
#
# Plume CMS is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Plume CMS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
$ctl = array();
$base = Pluf::f('idf_base');
$ctl[] = array('regex' => '#^/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views',
'method' => 'index');
$ctl[] = array('regex' => '#^/login/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views',
'method' => 'login');
$ctl[] = array('regex' => '#^/logout/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views',
'method' => 'logout');
$ctl[] = array('regex' => '#^/help/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views',
'method' => 'faq');
$ctl[] = array('regex' => '#^/p/(\w+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views',
'method' => 'projectHome');
$ctl[] = array('regex' => '#^/p/(\w+)/issues/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Issue',
'method' => 'index');
$ctl[] = array('regex' => '#^/p/(\w+)/issues/(\d+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Issue',
'method' => 'view');
$ctl[] = array('regex' => '#^/p/(\w+)/issues/status/(\w+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Issue',
'method' => 'listStatus');
$ctl[] = array('regex' => '#^/p/(\w+)/issues/label/(\d+)/(\w+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Issue',
'method' => 'listLabel');
$ctl[] = array('regex' => '#^/p/(\w+)/issues/create/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Issue',
'method' => 'create');
$ctl[] = array('regex' => '#^/p/(\w+)/issues/my/(\w+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Issue',
'method' => 'myIssues');
$ctl[] = array('regex' => '#^/p/(\w+)/admin/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Project',
'method' => 'admin');
$ctl[] = array('regex' => '#^/p/(\w+)/admin/issues/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Project',
'method' => 'adminIssues');
$ctl[] = array('regex' => '#^/p/(\w+)/admin/members/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Project',
'method' => 'adminMembers');
return $ctl;
src/IDF/relations.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Loic d'Anterroches and contributors.
#
# Plume CMS is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Plume CMS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
$m = array();
$m['IDF_Tag'] = array('relate_to' => array('IDF_Project'));
$m['IDF_Issue'] = array('relate_to' => array('IDF_Project', 'Pluf_User', 'IDF_Tag'),
'relate_to_many' => array('IDF_Tag', 'Pluf_User'));
$m['IDF_IssueComment'] = array('relate_to' => array('IDF_Issue', 'Pluf_User'));
return $m;
src/IDF/templates/admin/base.html
1
2
3
4
5
6
7
8
9
{extends "base.html"}
{block tabadmin} class="active"{/block}
{block subtabs}
<div id="sub-tabs">
<a {if $inSummary}class="active" {/if}href="{url 'IDF_Views_Project::admin', array($project.shortname)}">{trans 'Project Summary'}</a> |
<a {if $inMembers}class="active" {/if}href="{url 'IDF_Views_Project::adminMembers', array($project.shortname)}">{trans 'Project Members'}</a> |
<a {if $inIssueTracking}class="active" {/if}href="{url 'IDF_Views_Project::adminIssues', array($project.shortname)}">{trans 'Issue Tracking'}</a>
</div>
{/block}
src/IDF/templates/admin/issue-tracking.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{extends "admin/base.html"}
{block docclass}yui-t1{assign $inIssueTracking = true}{/block}
{block body}
<form method="post" action=".">
<table class="form" summary="">
<tr>
<td colspan="2"><strong>{$form.f.labels_issue_open.labelTag}:</strong><br />
{if $form.f.labels_issue_open.errors}{$form.f.labels_issue_open.fieldErrors}{/if}
{$form.f.labels_issue_open|unsafe}
</td>
</tr>
<tr>
<td colspan="2"><strong>{$form.f.labels_issue_closed.labelTag}:</strong><br />
{if $form.f.labels_issue_closed.errors}{$form.f.labels_issue_closed.fieldErrors}{/if}
{$form.f.labels_issue_closed|unsafe}
</td>
</tr>
<tr>
<td colspan="2"><strong>{$form.f.labels_issue_predefined.labelTag}:</strong><br />
{if $form.f.labels_issue_predefined.errors}{$form.f.labels_issue_predefined.fieldErrors}{/if}
{$form.f.labels_issue_predefined|unsafe}
</td>
</tr>
<tr>
<td colspan="2"><strong>{$form.f.labels_issue_one_max.labelTag}:</strong><br />
{if $form.f.labels_issue_one_max.errors}{$form.f.labels_issue_one_max.fieldErrors}{/if}
{$form.f.labels_issue_one_max|unsafe}
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="{trans 'Save Changes'}" name="submit" />
</td>
</tr>
</table>
</form>
{/block}
{block context}
<div class="issue-submit-info">
{blocktrans}
<p><strong>Instructions:</strong></p>
<p>List one status value per line in desired sort-order.</p>
<p>Optionally, use an equals-sign to document the meaning of each status value.</p>
{/blocktrans}
</div>
{/block}
src/IDF/templates/admin/members.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{extends "admin/base.html"}
{block docclass}yui-t3{assign $inMembers = true}{/block}
{block body}
<form method="post" action=".">
<table class="form" summary="">
<tr>
<td colspan="2">{$form.f.owners.labelTag}:<br />
{if $form.f.owners.errors}{$form.f.owners.fieldErrors}{/if}
{$form.f.owners|unsafe}
</td>
</tr>
<tr>
<td colspan="2">{$form.f.members.labelTag}:<br />
{if $form.f.members.errors}{$form.f.members.fieldErrors}{/if}
{$form.f.members|unsafe}
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="{trans 'Save Changes'}" name="submit" />
</td>
</tr>
</table>
</form>
{/block}
{block context}
<div class="issue-submit-info">
{blocktrans}
<p><strong>Instructions:</strong></p>
<p>Specify each person by its login. Each person must have already registered with the given login.</p>
<p>Separate the logins with commas and/or new lines.</p>
{/blocktrans}
</div>
<div class="issue-submit-info">
{blocktrans}
<p><strong>Notes:</strong></p>
<p>A project owner may make any change to this project, including removing other project owners. You need to be carefull when you give owner rights.</p>
<p>A project member will not have access to the administration area but will have more options available in the use of the project.</p>
{/blocktrans}
</div>
{/block}
src/IDF/templates/admin/summary.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{extends "admin/base.html"}
{block docclass}yui-t1{assign $inSummary = true}{/block}
{block body}
{if $form.errors}
<div class="px-message-error">
<p>{trans 'The form contains some errors. Please correct them to update the summary.'}</p>
{if $form.get_top_errors}
{$form.render_top_errors|unsafe}
{/if}
</div>
{/if}
<form method="post" action=".">
<table class="form" summary="">
<tr>
<th><strong>{$form.f.name.labelTag}:</strong></th>
<td>{if $form.f.name.errors}{$form.f.name.fieldErrors}{/if}
{$form.f.name|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.description.labelTag}:</strong></th>
<td>{if $form.f.description.errors}{$form.f.description.fieldErrors}{/if}
{$form.f.description|unsafe}
</td>
</tr>
<tr><td>&nbsp;</td>
<td>
<input type="submit" name="submit" value="{trans 'Save Changes'}" />
</td>
</table>
</form>
{/block}
{block context}
<div class="issue-submit-info">
{assign $url = 'http://daringfireball.net/projects/markdown/syntax'}
{blocktrans}
<p><strong>Instructions:</strong></p>
<p>The description of the project can be improved using the <a href="{$url}">Markdown syntax</a>.</p>
{/blocktrans}
</div>
{/block}
src/IDF/templates/base-simple.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
{*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK *****
*}<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/yui.css'}" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/style.css'}" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="{media '/idf/css/ie6.css'}" />
<![endif]-->
{block extraheader}{/block}
<title>{block pagetitle}{$page_title|strip_tags}{/block}</title>
</head>
<body>
<div id="{block docid}doc3{/block}" class="{block docclass}yui-t3{/block}">
<div id="hd">
<p class="top">
{if !$user.isAnonymous()}{blocktrans}Welcome, <strong>{$user.first_name} {$user.last_name}</strong>.{/blocktrans} <a href="{url 'IDF_Views::logout'}">{trans 'Sign Out'}</a>{else}<a href="{url 'IDF_Views::login'}">{trans 'Sign in or create your account'}</a>{/if}
| <a href="{url 'IDF_Views::faq'}">{trans 'Help'}</a>
</p>
{* <div id="header">
</div> *}
<h1 class="title">{block title}{$page_title}{/block}</h1>
</div>
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<div class="yui-g">
{if $user and $user.id}{getmsgs $user}{/if}
<div class="content">{block body}{/block}</div>
</div>
</div>
</div>
<div class="yui-b context">{block context}{/block}</div>
</div>
<div id="ft">{block foot}{/block}</div>
</div>
<script type="text/javascript" src="{media '/idf/js/jquery-1.2.6.min.js'}"></script>
{block javascript}{/block}
</body>
</html>
src/IDF/templates/base.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
{*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK *****
*}<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/yui.css'}" />
<link rel="stylesheet" type="text/css" href="{media '/idf/css/style.css'}" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="{media '/idf/css/ie6.css'}" />
<![endif]-->
{block extraheader}{/block}
<title>{block pagetitle}{$page_title|strip_tags}{/block}</title>
</head>
<body>
<div id="{block docid}doc3{/block}" class="{block docclass}yui-t3{/block}">
<div id="hd">
{if $project}<h1 class="project-title">{$project}</h1>{/if}
<p class="top">
{if !$user.isAnonymous()}{blocktrans}Welcome, <strong>{$user.first_name} {$user.last_name}</strong>.{/blocktrans} <a href="{url 'IDF_Views::logout'}">{trans 'Sign Out'}</a>{else}<a href="{url 'IDF_Views::login'}">{trans 'Sign in or create your account'}</a>{/if}
| <a href="{url 'IDF_Views::faq'}">{trans 'Help'}</a>
</p>
<div id="header">
<div id="main-tabs">
{if $project}
<a href="{url 'IDF_Views_Issue::index', array($project.shortname)}"{block tabissues}{/block}>{trans 'Issues'}</a>
{if $isOwner}
<a href="{url 'IDF_Views_Project::admin', array($project.shortname)}"{block tabadmin}{/block}>{trans 'Administer'}</a>{/if}{/if}
</div>
{block subtabs}{if $user.isAnonymous()} | {aurl 'url', 'IDF_Views::login'}{blocktrans}<a href="{$url}">Sign in or create your account</a> to create issues or add comments{/blocktrans}{/if}{/block}
</div>
<h1 class="title">{block title}{$page_title}{/block}</h1>
</div>
<div id="bd">
<div id="yui-main">
<div class="yui-b">
<div class="yui-g">
{if $user and $user.id}{getmsgs $user}{/if}
<div class="content">{block body}{/block}</div>
</div>
</div>
</div>
<div class="yui-b context">{block context}{/block}</div>
</div>
<div id="ft">{block foot}{/block}</div>
</div>
<script type="text/javascript" src="{media '/idf/js/jquery-1.2.6.min.js'}"></script>
{include 'js-hotkeys.html'}
{block javascript}{/block}
</body>
</html>
src/IDF/templates/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{extends "base-simple.html"}
{block docclass}yui-t1{/block}
{block body}
{if $projects.count() == 0}
<p>{trans 'No projects managed with InDefero were found.'}</p>
{if $user.administrator}<p>{blocktrans}Create a new project.{/blocktrans}</p>{/if}
{else}
<ul>{foreach $projects as $p}
<li><a href="{url 'IDF_Views::projectHome', array($p.shortname)}">{$p}</a> - {$p.description}</li>
{/foreach}</ul>
{/if}
{/block}
{block context}
<p><strong>{trans 'Managed Projects:'}</strong> {$projects.count()}</p>
{/block}
src/IDF/templates/issues/base.html
1
2
3
4
5
6
7
8
9
{extends "base.html"}
{block tabissues} class="active"{/block}
{block subtabs}
<div id="sub-tabs">
<a href="{url 'IDF_Views_Issue::index', array($project.shortname)}">{trans 'Recent issues'}</a>
{if !$user.isAnonymous()} | <a href="{url 'IDF_Views_Issue::create', array($project.shortname)}">{trans 'New Issue'}</a> | <a href="{url 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}">{trans 'My Issues'}</a>{/if}
{superblock}
</div>
{/block}
src/IDF/templates/issues/by-label.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{extends "issues/base.html"}
{block docclass}yui-t1{/block}
{block body}
{$issues.render}
{if !$user.isAnonymous()}
{aurl 'url', 'IDF_Views_Issue::create', array($project.shortname)}
<p><a href="{$url}">{trans 'New Issue'}</a></p>{/if}
{/block}
{block context}
{aurl 'open_url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}
{aurl 'closed_url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'closed')}
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>
{/blocktrans}{if $completion}
<p><strong>{trans 'Completion:'}</strong> {$completion}</p>
{/if}
<p><strong>{trans 'Label:'}</strong>
{aurl 'url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}
<a href="{$url}" class="label"><strong>{$label.class}:</strong>{$label.name}</a></p>
{/block}
src/IDF/templates/issues/create.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{extends "issues/base.html"}
{block body}
{if $form.errors}
<div class="px-message-error">
<p>{trans 'The form contains some errors. Please correct them to submit the issue.'}</p>
{if $form.get_top_errors}
{$form.render_top_errors|unsafe}
{/if}
</div>
{/if}
<form method="post" enctype="multipart/form-data" action="{url 'IDF_Views_Issue::create', array($project.shortname)}" >
<table class="form" summary="">
<tr>
<th><strong>{$form.f.summary.labelTag}:</strong></th>
<td>{if $form.f.summary.errors}{$form.f.summary.fieldErrors}{/if}
{$form.f.summary|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.content.labelTag}:</strong></th>
<td>{if $form.f.content.errors}{$form.f.content.fieldErrors}{/if}
{$form.f.content|unsafe}
</td>
</tr>{if $isOwner or $isMember}
<tr>
<th><strong>{$form.f.status.labelTag}:</strong></th>
<td>{if $form.f.status.errors}{$form.f.status.fieldErrors}{/if}
{$form.f.status|unsafe}
</td>
</tr>
<tr>
<th>{$form.f.owner.labelTag}:</th>
<td>{if $form.f.owner.errors}{$form.f.owner.fieldErrors}{/if}
{$form.f.owner|unsafe}
</td>
</tr>
<tr>
<th>{$form.f.label1.labelTag}:</th>
<td>
{if $form.f.label1.errors}{$form.f.label1.fieldErrors}{/if}{$form.f.label1|unsafe}
{if $form.f.label2.errors}{$form.f.label2.fieldErrors}{/if}{$form.f.label2|unsafe}
{if $form.f.label3.errors}{$form.f.label3.fieldErrors}{/if}{$form.f.label3|unsafe}<br />
{if $form.f.label4.errors}{$form.f.label4.fieldErrors}{/if}{$form.f.label4|unsafe}
{if $form.f.label5.errors}{$form.f.label5.fieldErrors}{/if}{$form.f.label5|unsafe}
{if $form.f.label6.errors}{$form.f.label6.fieldErrors}{/if}{$form.f.label6|unsafe}
</td>
</tr>{/if}
<tr>
<td>&nbsp;</td>
<td><input type="submit" value="{trans 'Submit Issue'}" name="submit" /> | <a href="{url 'IDF_Views_Issue::index', array($project.shortname)}">{trans 'Cancel'}</a>
</td>
</tr>
</table>
</form>
{/block}
{block context}
<div class="issue-submit-info">
{blocktrans}<p>When you submit the issue do not forget to provide the following information:</p>
<ul>
<li>The steps to reproduce the problem.</li>
<li>The version of the software and your operating system.</li>
<li>Any information that can help the developpers to solve the issue.</li>
<li><strong>Do not provide any password or confidential information!</strong></li>
</ul>{/blocktrans}
</div>
<script type="text/javascript">
document.getElementById('id_summary').focus()
</script>
{/block}
{block javascript}{include 'issues/js-autocomplete.html'}{/block}
src/IDF/templates/issues/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{extends "issues/base.html"}
{block docclass}yui-t2{/block}
{block body}
{$issues.render}
{if !$user.isAnonymous()}
{aurl 'url', 'IDF_Views_Issue::create', array($project.shortname)}
<p><a href="{$url}">{trans 'New Issue'}</a></p>{/if}
{/block}
{block context}
{aurl 'open_url', 'IDF_Views_Issue::index', array($project.shortname)}
{aurl 'closed_url', 'IDF_Views_Issue::listStatus', array($project.shortname, 'closed')}
{blocktrans}<p><strong>Open issues:</strong> <a href="{$open_url}">{$open}</a></p>
<p><strong>Closed issues:</strong> <a href="{$closed_url}">{$closed}</a></p>{/blocktrans}
<p class="smaller">{foreach $project.getTagCloud() as $label}
{aurl 'url', 'IDF_Views_Issue::listLabel', array($project.shortname, $label.id, 'open')}
<a href="{$url}" class="label"><strong>{$label.class}:</strong>{$label.name}</a>{/foreach}</p>
{/block}
src/IDF/templates/issues/js-autocomplete.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<script type="text/javascript" src="{media '/idf/js/jquery.bgiframe.min.js'}"></script>
<script type="text/javascript" src="{media '/idf/js/jquery.autocomplete.min.js'}"></script>
<script type="text/javascript" charset="utf-8">
// <!-- {literal}
$(document).ready(function(){
var auto_labels = [{/literal}{$auto_labels|safe}{literal}];
var auto_status = [{/literal}{$auto_status|safe}{literal}];
var j=0;
for (j=1;j<7;j=j+1) {
$("#id_label"+j).autocomplete(auto_labels, {
minChars: 0,
width: 310,
matchContains: true,
max: 50,
highlightItem: false,
formatItem: function(row, i, max, term) {
return row.to.replace(new RegExp("(" + term + ")", "gi"), "<strong>$1</strong>") + " <span style='font-size: 80%;'>" + row.name + "</span>";
},
formatResult: function(row) {
return row.to;
}
});
}
$("#id_status").autocomplete(auto_status, {
minChars: 0,
width: 310,
matchContains: true,
max: 50,
highlightItem: false,
formatItem: function(row, i, max, term) {
return row.to.replace(new RegExp("(" + term + ")", "gi"), "<strong>$1</strong>") + " <span style='font-size: 80%;'>" + row.name + "</span>";
},
formatResult: function(row) {
return row.to;
}
});
});
{/literal} //-->
</script>
src/IDF/templates/issues/my-issues.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{extends "issues/base.html"}
{block docclass}yui-t2{/block}
{block body}
{$issues.render}
{if !$user.isAnonymous()}
{aurl 'url', 'IDF_Views_Issue::create', array($project.shortname)}
<p><a href="{$url}">{trans 'New Issue'}</a></p>{/if}
{/block}
{block context}
{aurl 'owner_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'owner')}
{aurl 'submit_url', 'IDF_Views_Issue::myIssues', array($project.shortname, 'submit')}
<p><strong>{trans 'Submitted issues:'}</strong> <a href="{$submit_url}">{$nb_submit}</a></p>
{if $nb_owner > 0}
<p><strong>{trans 'Working issues:'}</strong> <a href="{$owner_url}">{$nb_owner}</a></p>{/if}
{/block}
src/IDF/templates/issues/view.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
{extends "issues/base.html"}
{block body}
{assign $i = 0}
{assign $nc = $comments.count()}
{foreach $comments as $c}
<div class="issue-comment{if $i == 0} issue-comment-first{/if}{if $i == ($nc-1)} issue-comment-last{/if}" id="ic{$c.id}">
{if $i == 0}{assign $who = $issue.get_submitter()}
<p>{blocktrans}Reported by {$who}, {$c.creation_dtime|date}{/blocktrans}</p>
{else}{assign $who = $c.get_submitter()}
{aurl 'url', 'IDF_Views_Issue::view', array($project.shortname, $issue.id)}
{assign $id = $c.id}
{assign $url = $url~'#ic'~$c.id}
<p>{blocktrans}Comment <a href="{$url}">{$id}</a> by {$who}, {$c.creation_dtime|date}{/blocktrans}</p>
{/if}
<p class="issue-comment-text">{if strlen($c.content) > 0}{$c.content|nl2br}{else}<i>{trans '(No comments were given for this change.)'}</i>{/if}</p>
{if $i> 0 and $c.changedIssue()}
<div class="issue-changes">
{foreach $c.changes as $w => $v}
<strong>{if $w == 'su'}{trans 'Summary:'}{/if}{if $w == 'st'}{trans 'Status:'}{/if}{if $w == 'ow'}{trans 'Owner:'}{/if}{if $w == 'lb'}{trans 'Labels:'}{/if}</strong> {if $w == 'lb'}{assign $l = implode(', ', $v)}{$l}{else}{$v}{/if}<br />
{/foreach}
</div>
{/if}
</div>{assign $i = $i + 1}{if $i == $nc and false == $form}
<div class="issue-comment-signin">
{aurl 'url', 'IDF_Views::login'}{blocktrans}<a href="{$url}">Sign in</a> to reply to this comment.{/blocktrans}
</div>
{/if}
{/foreach}
{if $form}
<hr />
{if $form.errors}
<div class="px-message-error">
<p>{trans 'The form contains some errors. Please correct them to change the issue.'}</p>
{if $form.get_top_errors}
{$form.render_top_errors|unsafe}
{/if}
</div>
{/if}
<form method="post" enctype="multipart/form-data" action="{url 'IDF_Views_Issue::view', array($project.shortname, $issue.id)}" >
<table class="form" summary="">
<tr>
<th><strong>{$form.f.content.labelTag}:</strong></th>
<td>{if $form.f.content.errors}{$form.f.content.fieldErrors}{/if}
{$form.f.content|unsafe}
</td>
</tr>
{if $isOwner or $isMember}
<tr>
<th><strong>{$form.f.summary.labelTag}:</strong></th>
<td>{if $form.f.summary.errors}{$form.f.summary.fieldErrors}{/if}
{$form.f.summary|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.status.labelTag}:</strong></th>
<td>{if $form.f.status.errors}{$form.f.status.fieldErrors}{/if}
{$form.f.status|unsafe}
</td>
</tr>
<tr>
<th>{$form.f.owner.labelTag}:</th>
<td>{if $form.f.owner.errors}{$form.f.owner.fieldErrors}{/if}
{$form.f.owner|unsafe}
</td>
</tr>
<tr>
<th>{$form.f.label1.labelTag}:</th>
<td>
{if $form.f.label1.errors}{$form.f.label1.fieldErrors}{/if}{$form.f.label1|unsafe}
{if $form.f.label2.errors}{$form.f.label2.fieldErrors}{/if}{$form.f.label2|unsafe}
{if $form.f.label3.errors}{$form.f.label3.fieldErrors}{/if}{$form.f.label3|unsafe}<br />
{if $form.f.label4.errors}{$form.f.label4.fieldErrors}{/if}{$form.f.label4|unsafe}
{if $form.f.label5.errors}{$form.f.label5.fieldErrors}{/if}{$form.f.label5|unsafe}
{if $form.f.label6.errors}{$form.f.label6.fieldErrors}{/if}{$form.f.label6|unsafe}
</td>
</tr>{/if}
<tr>
<td>&nbsp;</td>
<td><input type="submit" value="{trans 'Submit Changes'}" name="submit" /> | <a href="{url 'IDF_Views_Issue::view', array($project.shortname, $issue.id)}">{trans 'Cancel'}</a>
</td>
</tr>
</table>
</form>
{/if}
{/block}
{block context}
<div class="issue-info">
{assign $submitter = $issue.get_submitter()}
<p><strong>{trans 'Created:'}</strong> <span class="nobrk">{$issue.creation_dtime|dateago}</span> <span class="nobrk">{blocktrans}by {$submitter}{/blocktrans}</span></p>
<p>
<strong>{trans 'Updated:'}</strong> <span class="nobrk">{$issue.modif_dtime|dateago}</span></p>
<p>
<strong>{trans 'Status:'}</strong> {$issue.get_status.name}</p>
<p>
<strong>{trans 'Owner:'}</strong> {if $issue.get_owner == null}{trans 'No owner'}{else}{$issue.get_owner}{/if}
</p>{assign $tags = $issue.get_tags_list()}{if $tags.count()}
<p>
<strong>{trans 'Labels:'}</strong><br />
{foreach $issue.get_tags_list() as $tag}{aurl 'url', 'IDF_Views_Issue::listLabel', array($project.shortname, $tag.id, 'open')}
<span class="label"><a href="{$url}" class="label"><strong>{$tag.class}:</strong>{$tag.name}</a></span><br />
{/foreach}
</p>{/if}
</div>
{/block}
{block javascript}{if $form}{include 'issues/js-autocomplete.html'}{/if}{/block}
src/IDF/templates/js-hotkeys.html
1
2
3
4
5
6
7
8
9
10
11
12
13
<script type="text/javascript" src="{media '/idf/js/jquery.hotkeys.js'}"></script>
{if $project}
<script type="text/javascript" charset="utf-8">
// <!--
var hk_submit_issue = '{url 'IDF_Views_Issue::create', array($project.shortname)}';
var hk_recent_issues = '{url 'IDF_Views_Issue::index', array($project.shortname)}';
{literal}
jQuery.hotkeys.add('Shift+a',function (){window.location.href=hk_submit_issue;});
jQuery.hotkeys.add('Shift+r',function (){window.location.href=hk_recent_issues;});
{/literal} //-->
</script>
{/if}
src/IDF/templates/login_form.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{extends "base-simple.html"}
{block docclass}yui-t1{/block}
{block body}
<form method="post" action="{url 'IDF_Views::login'}">
<input type="hidden" name="_redirect_after" value="{$_redirect_after}" />
{if $error}
<p class="px-form-error">{$error}</p>
{/if}
<h3>{trans 'What is your login?'}</h3>
<p><label for="id_login">{trans 'My login is'}</label> <input type="text" name="login" id="id_login" value="{$login}" /></p>
<h3>{trans 'Do you have a password?'}</h3>
<p><input name="action" id="action-new-user" value="new-user" type="radio" /> <label for="action-new-user">{trans 'No, I am a new here.'}</label></p>
<p><input name="action" id="action-login" value="login" type="radio" checked="checked" /> <label for="action-login">{trans 'Yes'}</label>, <label for="id_password">{trans 'my password is'}</label> <input type="password" name="password" id="id_password" /></p>
<p><input type="submit" value="{trans 'Sign in'}" />
</p>
{* <p><a href="{url 'CM_Views::passwordRecovery-1', array(), true}">{trans 'Forgot your password? Click here'}</a>.</p>
*}
</form>
<script type="text/javascript">
document.getElementById('id_login').focus()
</script>
{/block}
www/index.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
// Set the include path to have Pluf and IDF in it.
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).'/../src');
require 'Pluf.php';
Pluf::start(dirname(__FILE__).'/../src/IDF/conf/idf.php');
Pluf_Dispatcher::loadControllers(Pluf::f('idf_views'));
Pluf_Dispatcher::dispatch(Pluf_HTTP_URL::getAction());
www/media/idf/css/ie6.css
1
2
3
img {
behavior: url("/media/idf/css/iepngfix.htc");
}
www/media/idf/css/iepngfix.htc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<public:component>
<public:attach event="onpropertychange" onevent="doFix()" />
<script type="text/javascript">
// IE5.5+ PNG Alpha Fix v1.0RC4
// (c) 2004-2005 Angus Turnbull http://www.twinhelix.com
// This is licensed under the CC-GNU LGPL, version 2.1 or later.
// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
// This must be a path to a blank image. That's all the configuration you need.
if (typeof blankImg == 'undefined') var blankImg = '/media/idf/css/blank.gif';
var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
function filt(s, m)
{
if (filters[f])
{
filters[f].enabled = s ? true : false;
if (s) with (filters[f]) { src = s; sizingMethod = m }
}
else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
}
function doFix()
{
// Assume IE7 is OK.
if (!/MSIE (5\.5|6\.)/.test(navigator.userAgent) ||
(event && !/(background|src)/.test(event.propertyName))) return;
var bgImg = currentStyle.backgroundImage || style.backgroundImage;
if (tagName == 'IMG')
{
if ((/\.png$/i).test(src))
{
if (currentStyle.width == 'auto' && currentStyle.height == 'auto')
style.width = offsetWidth + 'px';
filt(src, 'scale');
src = blankImg;
}
else if (src.indexOf(blankImg) < 0) filt();
}
else if (bgImg && bgImg != 'none')
{
if (bgImg.match(/^url[("']+(.*\.png)[)"']+$/i))
{
var s = RegExp.$1;
if (currentStyle.width == 'auto' && currentStyle.height == 'auto')
style.width = offsetWidth + 'px';
style.backgroundImage = 'none';
filt(s, 'crop');
// IE link fix.
for (var n = 0; n < childNodes.length; n++)
if (childNodes[n].style) childNodes[n].style.position = 'relative';
}
else filt();
}
}
doFix();
</script>
</public:component>
www/media/idf/css/style.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
.yui-g {
padding: 0 1em;
}
div.context {
padding-left: 1em;
}
/**
* Form
*/
table.form th, table.form td {
border: none;
vertical-align: top;
}
table.form th {
text-align: right;
font-weight: normal;
}
.px-message-error {
padding-left: 37px;
background: url("../img/dialog-error.png");
background-repeat: no-repeat;
background-position: 3px 0;
color: #c00;
font-weight: bold;
padding-bottom: 5px;
}
ul.errorlist {
color: #c00;
font-weight: bold;
}
div.user-messages {
border: 1px solid rgb(229, 225, 169);
background-color: #fffde3;
margin-bottom: 1em;
margin-left: -1px;
width: 90%;
}
/**
* Recent issues
*/
table.recent-issues {
width: 90%;
}
table.recent-issues th {
background-color: #e4e8E0;
vertical-align: top;
border-color: #d3d7cf;
}
table.recent-issues tr {
border-left: 1px solid #d3d7cf;
border-right: 1px solid #d3d7cf;
border-bottom: 1px solid #d3d7cf;
}
table.recent-issues td {
border: none;
vertical-align: top;
}
table.recent-issues tfoot th {
text-align: right;
}
table.recent-issues tfoot th a {
color: #000;
font-weight: normal;
}
table.recent-issues th a.px-current-page {
font-weight: bold;
text-decoration: none;
}
span.px-sort {
font-weight: normal;
font-size: 70%;
white-space: nowrap;
padding-left: 1em;
}
span.px-header-title {
white-space: nowrap;
}
/**
* Issue
*/
p.issue-comment-text {
font-family: monospace;
}
div.issue-comment {
border-left: 3px solid #8ae234;
border-bottom: 1px solid #d3d7cf;
border-right: 1px solid #d3d7cf;
padding: 0.5em;
}
div.issue-comment-first {
border-top: 1px solid #d3d7cf;
}
div.issue-comment-signin {
-moz-border-radius: 0 0 3px 3px;
-webkit-border-radius: 0 0 3px 3px;
background-color: #d3d7cf;
padding: 4px;
}
div.issue-comment-signin a {
color: #000;
}
div.issue-changes {
background-color: #d3d7cf;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
padding: 4px;
width: 60%;
}
div.issue-submit-info {
background-color: #d3d7cf;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
padding: 0.5em;
margin-bottom: 1em;
}
span.label {
color: #204a87;
padding-left: 0.5em;
}
a.label {
color: #204a87;
text-decoration: none;
}
span.nobrk {
white-space: nowrap;
}
hr { visibility: hidden; }
textarea {
font-family: monospace;
}
h1.title {
font-weight: normal;
}
h1.project-title {
font-weight: normal;
float: right;
z-index: 100;
text-align: right;
padding-right: 5px;
}
.note {
font-size: 80%;
}
.smaller {
font-size: 90%;
}
.helptext {
font-size: 80%;
color: #555753;
}
div.container {
clear: both;
}
/**
* Tabs
*/
#main-tabs a {
background-color: #d3d7cf;
-moz-border-radius: 3px 3px 0 0;
-webkit-border-radius: 3px 3px 0 0;
padding: 4px 4px 0 4px;
text-decoration: none;
color: #2e3436;
font-weight: 600;
}
#main-tabs a.active {
background-color: #a5e26a;
}
#sub-tabs {
background-color: #a5e26a;
-moz-border-radius: 0 3px 3px 3px;
-webkit-border-radius: 0 3px 3px 3px;
padding: 4px;
}
#sub-tabs a {
color: #2e3436;
}
#sub-tabs a.active {
text-decoration: none;
}
/**
* Autocomplete.
*/
.ac_results {
padding: 0px;
border: 1px solid black;
background-color: white;
overflow: hidden;
z-index: 99999;
text-align: left;
}
.ac_results ul {
width: 100%;
list-style-position: outside;
list-style: none;
padding: 0;
margin: 0;
}
.ac_results li {
margin: 0px;
padding: 2px 5px;
cursor: default;
display: block;
/*
if width will be 100% horizontal scrollbar will apear
when scroll mode will be used
*/
/*width: 100%;*/
font: menu;
font-size: 12px;
/*
it is very important, if line-height not setted or setted
in relative units scroll will be broken in firefox
*/
line-height: 16px;
overflow: hidden;
}
.ac_loading {
background: white url('../img/indicator.gif') right center no-repeat;
}
.ac_odd {
background-color: #eee;
}
.ac_over {
background-color: #4e9a06;
color: white;
}
www/media/idf/css/yui.css
1
2
3
4
5
6
7
8
9
/*
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 2.5.1
*/
html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;font-variant:normal;}sup {vertical-align:text-top;}sub {vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}body {font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
body{text-align:center;}#ft{clear:both;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.25em;min-width:750px;}#doc2{width:73.076em;*width:71.25em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.05em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.30769em;*width:12.00em;}.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}.yui-t2 .yui-b{float:left;width:13.8461em;*width:13.50em;}.yui-t2 #yui-main .yui-b{margin-left:14.8461em;*margin-left:14.55em;}.yui-t3 .yui-b{float:left;width:23.0769em;*width:22.50em;}.yui-t3 #yui-main .yui-b{margin-left:24.0769em;*margin-left:23.62em;}.yui-t4 .yui-b{float:right;width:13.8456em;*width:13.50em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.55em;}.yui-t5 .yui-b{float:right;width:18.4615em;*width:18.00em;}.yui-t5 #yui-main .yui-b{margin-right:19.4615em;*margin-right:19.125em;}.yui-t6 .yui-b{float:right;width:23.0769em;*width:22.50em;}.yui-t6 #yui-main .yui-b{margin-right:24.0769em;*margin-right:23.62em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first,.yui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-gc div.first div.first{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{width:32%;margin-left:1.99%;}.yui-gb .yui-u{*margin-left:1.9%;*width:31.9%;}.yui-gc div.first,.yui-gd .yui-u{width:66%;}.yui-gd div.first{width:32%;}.yui-ge div.first,.yui-gf .yui-u{width:74.2%;}.yui-ge .yui-u,.yui-gf div.first{width:24%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-g .yui-gc div.first,.yui-gd .yui-g{width:66%;}.yui-gb .yui-g div.first{*margin-right:4%;_margin-right:1.3%;}.yui-gb .yui-gc div.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:1.0%;}.yui-gb .yui-gd .yui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-gb .yui-gb .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;}s .yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-g{width:24%;}.yui-gf .yui-g{width:74.2%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first{float:left;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20%;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}.yui-ge div.first .yui-gd .yui-u{width:65%;}.yui-ge div.first .yui-gd div.first{width:32%;}#bd:after,.yui-g:after,.yui-gb:after,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{content:".";display:block;height:0;clear:both;visibility:hidden;}#bd,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;}
h1{font-size:138.5%;}h2{font-size:123.1%;}h3{font-size:108%;}h1,h2,h3{margin:1em 0;}h1,h2,h3,h4,h5,h6,strong{font-weight:bold;}abbr,acronym{border-bottom:1px dotted #000;cursor:help;} em{font-style:italic;}blockquote,ul,ol,dl{margin:1em;}ol,ul,dl{margin-left:2em;}ol li{list-style:decimal outside;}ul li{list-style:disc outside;}dl dd{margin-left:1em;}th,td{border:1px solid #000;padding:.5em;}th{font-weight:bold;text-align:center;}caption{margin-bottom:.5em;text-align:center;}p,fieldset,table,pre{margin-bottom:1em;}
www/media/idf/js/jquery-1.2.6.min.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
* jQuery 1.2.6 - New Wave Javascript
*
* Copyright (c) 2008 John Resig (jquery.com)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
* $Rev: 5685 $
*/
(function(){var _jQuery=window.jQuery,_$=window.$;var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);};var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem){if(elem.id!=match[3])return jQuery().find(selector);return jQuery(elem);}selector=[];}}else
return jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(jQuery.makeArray(selector));},jquery:"1.2.6",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value===undefined)return this[0]&&jQuery[type||"attr"](this[0],name);else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else
return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else
selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=='string'?jQuery(selector):jQuery.makeArray(selector))));},is:function(selector){return!!selector&&jQuery.multiFilter(selector,this).length>0;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i<max;i++){var option=options[i];if(option.selected){value=jQuery.browser.msie&&!option.attributes.value.specified?option.text:option.value;if(one)return value;values.push(value);}}return values;}else
return(this[0].value||"").replace(/\r/g,"");}return undefined;}if(value.constructor==Number)value+='';return this.each(function(){if(this.nodeType!=1)return;if(value.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,value)>=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else
this.value=value;});},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data===undefined&&this.length)data=jQuery.data(this[0],key);return data===undefined&&parts[1]?this.data(parts[0]):data;}else
return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script"))scripts=scripts.add(elem);else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.fn.init.prototype=jQuery.fn;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else
jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}function now(){return+new Date;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==i){target=this;--i;}for(;i<length;i++)if((options=arguments[i])!=null)for(var name in options){var src=target[name],copy=options[name];if(target===copy)continue;if(deep&&copy&&typeof copy=="object"&&!copy.nodeType)target[name]=jQuery.extend(deep,src||(copy.length!=null?[]:{}),copy);else if(copy!==undefined)target[name]=copy;}return target;};var expando="jQuery"+now(),uuid=0,windowData={},exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i,defaultView=document.defaultView||{};jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/^[\s[]?function/.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){var head=document.getElementsByTagName("head")[0]||document.documentElement,script=document.createElement("script");script.type="text/javascript";if(jQuery.browser.msie)script.text=data;else
script.appendChild(document.createTextNode(data));head.insertBefore(script,head.firstChild);head.removeChild(script);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!==undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(object,callback,args){var name,i=0,length=object.length;if(args){if(length==undefined){for(name in object)if(callback.apply(object[name],args)===false)break;}else
for(;i<length;)if(callback.apply(object[i++],args)===false)break;}else{if(length==undefined){for(name in object)if(callback.call(object[name],name,object[name])===false)break;}else
for(var value=object[0];i<length&&callback.call(value,i,value)!==false;value=object[++i]){}}return object;},prop:function(elem,value,type,i,name){if(jQuery.isFunction(value))value=value.call(elem,i);return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(name)?value+"px":value;},className:{add:function(elem,classNames){jQuery.each((classNames||"").split(/\s+/),function(i,className){if(elem.nodeType==1&&!jQuery.className.has(elem.className,className))elem.className+=(elem.className?" ":"")+className;});},remove:function(elem,classNames){if(elem.nodeType==1)elem.className=classNames!=undefined?jQuery.grep(elem.className.split(/\s+/),function(className){return!jQuery.className.has(classNames,className);}).join(" "):"";},has:function(elem,className){return jQuery.inArray(className,(elem.className||elem).toString().split(/\s+/))>-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else
jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret,style=elem.style;function color(elem){if(!jQuery.browser.safari)return false;var ret=defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=style.outline;style.outline="0 solid black";style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&style&&style[name])ret=style[name];else if(defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var computedStyle=defaultView.getComputedStyle(elem,null);if(computedStyle&&!color(elem))ret=computedStyle.getPropertyValue(name);else{var swap=[],stack=[],a=elem,i=0;for(;a&&color(a);a=a.parentNode)stack.unshift(a);for(;i<stack.length;i++)if(color(stack[i])){swap[i]=stack[i].style.display;stack[i].style.display="block";}ret=name=="display"&&swap[stack.length-1]!=null?"none":(computedStyle&&computedStyle.getPropertyValue(name))||"";for(i=0;i<swap.length;i++)if(swap[i]!=null)stack[i].style.display=swap[i];}if(name=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;style.left=ret||0;ret=style.pixelLeft+"px";style.left=left;elem.runtimeStyle.left=rsLeft;}}return ret;},clean:function(elems,context){var ret=[];context=context||document;if(typeof context.createElement=='undefined')context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;jQuery.each(elems,function(i,elem){if(!elem)return;if(elem.constructor==Number)elem+='';if(typeof elem=="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+"></"+tag+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!tags.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!tags.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!tags.indexOf("<td")||!tags.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!tags.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf("<table")&&tags.indexOf("<tbody")<0?div.firstChild&&div.firstChild.childNodes:wrap[1]=="<table>"&&tags.indexOf("<tbody")<0?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else
ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;name=notxml&&jQuery.props[name]||name;if(elem.tagName){var special=/href|src|style/.test(name);if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(name in elem&&notxml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem[name]=value;}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name))return elem.getAttributeNode(name).nodeValue;return elem[name];}if(msie&&notxml&&name=="style")return jQuery.attr(elem.style,"cssText",value);if(set)elem.setAttribute(name,""+value);var attr=msie&&notxml&&special?elem.getAttribute(name,2):elem.getAttribute(name);return attr===null?undefined:attr;}if(msie&&name=="opacity"){if(set){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+''=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+'':"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(set)elem[name]=value;return elem[name];},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(array!=null){var i=array.length;if(i==null||array.split||array.setInterval||array.call)ret[0]=array;else
while(i)ret[--i]=array[i];}return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i<length;i++)if(array[i]===elem)return i;return-1;},merge:function(first,second){var i=0,elem,pos=first.length;if(jQuery.browser.msie){while(elem=second[i++])if(elem.nodeType!=8)first[pos++]=elem;}else
while(elem=second[i++])first[pos++]=elem;return first;},unique:function(array){var ret=[],done={};try{for(var i=0,length=array.length;i<length;i++){var id=jQuery.data(array[i]);if(!done[id]){done[id]=true;ret.push(array[i]);}}}catch(e){ret=array;}return ret;},grep:function(elems,callback,inv){var ret=[];for(var i=0,length=elems.length;i<length;i++)if(!inv!=!callback(elems[i],i))ret.push(elems[i]);return ret;},map:function(elems,callback){var ret=[];for(var i=0,length=elems.length;i<length;i++){var value=callback(elems[i],i);if(value!=null)ret[ret.length]=value;}return ret.concat.apply([],ret);}});var userAgent=navigator.userAgent.toLowerCase();jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing"}});jQuery.each({parent:function(elem){return elem.parentNode;},parents:function(elem){return jQuery.dir(elem,"parentNode");},next:function(elem){return jQuery.nth(elem,2,"nextSibling");},prev:function(elem){return jQuery.nth(elem,2,"previousSibling");},nextAll:function(elem){return jQuery.dir(elem,"nextSibling");},prevAll:function(elem){return jQuery.dir(elem,"previousSibling");},siblings:function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},children:function(elem){return jQuery.sibling(elem.firstChild);},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(selector){var ret=jQuery.map(this,fn);if(selector&&typeof selector=="string")ret=jQuery.multiFilter(selector,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(){var args=arguments;return this.each(function(){for(var i=0,length=args.length;i<length;i++)jQuery(args[i])[original](this);});};});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1)this.removeAttribute(name);},addClass:function(classNames){jQuery.className.add(this,classNames);},removeClass:function(classNames){jQuery.className.remove(this,classNames);},toggleClass:function(classNames){jQuery.className[jQuery.className.has(this,classNames)?"remove":"add"](this,classNames);},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).r.length){jQuery("*",this).add(this).each(function(){jQuery.event.remove(this);jQuery.removeData(this);});if(this.parentNode)this.parentNode.removeChild(this);}},empty:function(){jQuery(">*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return i<m[3]-0;},gt:function(a,i,m){return i>m[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false,re=quickChild,m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j<rl;j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;for(;n;n=n.nextSibling)if(n.nodeType==1){var id=jQuery.data(n);if(m=="~"&&merge[id])break;if(!nodeName||n.nodeName.toUpperCase()==nodeName){if(m=="~")merge[id]=true;r.push(n);}if(m=="+")break;}}ret=r;t=jQuery.trim(t.replace(re,""));foundToken=true;}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0])ret.shift();done=jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length);}else{var re2=quickID;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]];}else{re2=quickClass;m=re2.exec(t);}m[2]=m[2].replace(/\\/g,"");var elem=ret[ret.length-1];if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',elem)[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];}else{for(var i=0;ret[i];i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object")tag="param";r=jQuery.merge(r,ret[i].getElementsByTagName(tag));}if(m[1]==".")r=jQuery.classFilter(r,m[2]);if(m[1]=="#"){var tmp=[];for(var i=0;r[i];i++)if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];break;}r=tmp;}ret=r;}t=t.replace(re2,"");}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t);}}if(t)ret=[];if(ret&&context==ret[0])ret.shift();done=jQuery.merge(done,ret);return done;},classFilter:function(r,m,not){m=" "+m+" ";var tmp=[];for(var i=0;r[i];i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i<rl;i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];if(z==null||/href|src|selected/.test(m[2]))z=jQuery.attr(a,m[2])||'';if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i<rl;i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);if(!merge[id]){var c=1;for(var n=parentNode.firstChild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==0){if(node.nodeIndex==last)add=true;}else if((node.nodeIndex-last)%first==0&&(node.nodeIndex-last)/first>=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[],cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&n!=elem)r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=this.proxy(fn,function(){return fn.apply(this,arguments);});handler.data=data;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered)return jQuery.event.handle.apply(arguments.callee.elem,arguments);});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else
for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});data[0][expando]=true;}data[0].type=type;if(exclusive)data[0].exclusive=true;var handle=jQuery.data(elem,"handle");if(handle)val=handle.apply(elem,data);if((!fn||(jQuery.nodeName(elem,'a')&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val,ret,namespace,all,handlers;event=arguments[0]=jQuery.event.fix(event||window.event);namespace=event.type.split(".");event.type=namespace[0];namespace=namespace[1];all=!namespace&&!event.exclusive;handlers=(jQuery.data(this,"events")||{})[event.type];for(var j in handlers){var handler=handlers[j];if(all||handler.type==namespace){event.handler=handler;event.data=handler.data;ret=handler.apply(this,arguments);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}return val;},fix:function(event){if(event[expando]==true)return event;var originalEvent=event;event={originalEvent:originalEvent};var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");for(var i=props.length;i;i--)event[props[i]]=originalEvent[props[i]];event[expando]=true;event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};event.timeStamp=event.timeStamp||now();if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=event.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;return proxy;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;event.type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);return(fn||data).apply(this,arguments);});return this.each(function(){jQuery.event.add(this,type,one,fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);},toggle:function(fn){var args=arguments,i=1;while(i<args.length)jQuery.event.proxy(fn,args[i++]);return this.click(jQuery.event.proxy(fn,function(event){this.lastToggle=(this.lastToggle||0)%i;event.preventDefault();return args[this.lastToggle++].apply(this,arguments)||false;}));},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else
jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.call(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i<document.styleSheets.length;i++)if(document.styleSheets[i].disabled){setTimeout(arguments.callee,0);return;}jQuery.ready();},false);if(jQuery.browser.safari){var numStyles;(function(){if(jQuery.isReady)return;if(document.readyState!="loaded"&&document.readyState!="complete"){setTimeout(arguments.callee,0);return;}if(numStyles===undefined)numStyles=jQuery("style, link[rel=stylesheet]").length;if(document.styleSheets.length!=numStyles){setTimeout(arguments.callee,0);return;}jQuery.ready();})();}jQuery.event.add(window,"load",jQuery.ready);}jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,name){jQuery.fn[name]=function(fn){return fn?this.bind(name,fn):this.trigger(name);};});var withinElement=function(event,elem){var parent=event.relatedTarget;while(parent&&parent!=elem)try{parent=parent.parentNode;}catch(error){parent=elem;}return parent==elem;};jQuery(window).bind("unload",function(){jQuery("*").add(document).unbind();});jQuery.fn.extend({_load:jQuery.fn.load,load:function(url,params,callback){if(typeof url!='string')return this._load(url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=now();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&type=="GET"){var ts=now();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();if(s.username)xhr.open(type,s.url,s.async,s.username,s.password);else
xhr.open(type,s.url,s.async);try{if(s.data)xhr.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;xhr.abort();return false;}if(s.global)jQuery.event.trigger("ajaxSend",[xhr,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xhr.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else
jQuery.handleError(s,xhr,status);complete();if(s.async)xhr=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xhr){xhr.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xhr.send(s.data);}catch(e){jQuery.handleError(s,xhr,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xhr,s]);}function complete(){if(s.complete)s.complete(xhr,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xhr,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xhr;},handleError:function(s,xhr,status,e){if(s.error)s.error(xhr,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xhr,s,e]);},active:0,httpSuccess:function(xhr){try{return!xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;}catch(e){}return false;},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(filter)data=filter(data,type);if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else
for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else
s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return opt.complete.call(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else
e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.call(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(elem){type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));}return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].call(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.call(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.call(this.elem,this.now,this);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=now();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=now();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done)this.options.complete.call(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}}});jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l,10)||0;top+=parseInt(t,10)||0;}return results;};jQuery.fn.extend({position:function(){var left=0,top=0,results;if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();offset.top-=num(this,'marginTop');offset.left-=num(this,'marginLeft');parentOffset.top+=num(offsetParent,'borderTopWidth');parentOffset.left+=num(offsetParent,'borderLeftWidth');results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};}return results;},offsetParent:function(){var offsetParent=this[0].offsetParent;while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,'position')=='static'))offsetParent=offsetParent.offsetParent;return jQuery(offsetParent);}});jQuery.each(['Left','Top'],function(i,name){var method='scroll'+name;jQuery.fn[method]=function(val){if(!this[0])return;return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;}):this[0]==window||this[0]==document?self[i?'pageYOffset':'pageXOffset']||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];};});jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);};jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);};});})();
www/media/idf/js/jquery.autocomplete.min.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
* Autocomplete - jQuery plugin 1.0.2
*
* Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $
*
*/;(function($){$.fn.extend({autocomplete:function(urlOrData,options){var isUrl=typeof urlOrData=="string";options=$.extend({},$.Autocompleter.defaults,{url:isUrl?urlOrData:null,data:isUrl?null:urlOrData,delay:isUrl?$.Autocompleter.defaults.delay:10,max:options&&!options.scroll?10:150},options);options.highlight=options.highlight||function(value){return value;};options.formatMatch=options.formatMatch||options.formatItem;return this.each(function(){new $.Autocompleter(this,options);});},result:function(handler){return this.bind("result",handler);},search:function(handler){return this.trigger("search",[handler]);},flushCache:function(){return this.trigger("flushCache");},setOptions:function(options){return this.trigger("setOptions",[options]);},unautocomplete:function(){return this.trigger("unautocomplete");}});$.Autocompleter=function(input,options){var KEY={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var $input=$(input).attr("autocomplete","off").addClass(options.inputClass);var timeout;var previousValue="";var cache=$.Autocompleter.Cache(options);var hasFocus=0;var lastKeyPressCode;var config={mouseDownOnSelect:false};var select=$.Autocompleter.Select(options,input,selectCurrent,config);var blockSubmit;$.browser.opera&&$(input.form).bind("submit.autocomplete",function(){if(blockSubmit){blockSubmit=false;return false;}});$input.bind(($.browser.opera?"keypress":"keydown")+".autocomplete",function(event){lastKeyPressCode=event.keyCode;switch(event.keyCode){case KEY.UP:event.preventDefault();if(select.visible()){select.prev();}else{onChange(0,true);}break;case KEY.DOWN:event.preventDefault();if(select.visible()){select.next();}else{onChange(0,true);}break;case KEY.PAGEUP:event.preventDefault();if(select.visible()){select.pageUp();}else{onChange(0,true);}break;case KEY.PAGEDOWN:event.preventDefault();if(select.visible()){select.pageDown();}else{onChange(0,true);}break;case options.multiple&&$.trim(options.multipleSeparator)==","&&KEY.COMMA:case KEY.TAB:case KEY.RETURN:if(selectCurrent()){event.preventDefault();blockSubmit=true;return false;}break;case KEY.ESC:select.hide();break;default:clearTimeout(timeout);timeout=setTimeout(onChange,options.delay);break;}}).focus(function(){hasFocus++;}).blur(function(){hasFocus=0;if(!config.mouseDownOnSelect){hideResults();}}).click(function(){if(hasFocus++>1&&!select.visible()){onChange(0,true);}}).bind("search",function(){var fn=(arguments.length>1)?arguments[1]:null;function findValueCallback(q,data){var result;if(data&&data.length){for(var i=0;i<data.length;i++){if(data[i].result.toLowerCase()==q.toLowerCase()){result=data[i];break;}}}if(typeof fn=="function")fn(result);else $input.trigger("result",result&&[result.data,result.value]);}$.each(trimWords($input.val()),function(i,value){request(value,findValueCallback,findValueCallback);});}).bind("flushCache",function(){cache.flush();}).bind("setOptions",function(){$.extend(options,arguments[1]);if("data"in arguments[1])cache.populate();}).bind("unautocomplete",function(){select.unbind();$input.unbind();$(input.form).unbind(".autocomplete");});function selectCurrent(){var selected=select.selected();if(!selected)return false;var v=selected.result;previousValue=v;if(options.multiple){var words=trimWords($input.val());if(words.length>1){v=words.slice(0,words.length-1).join(options.multipleSeparator)+options.multipleSeparator+v;}v+=options.multipleSeparator;}$input.val(v);hideResultsNow();$input.trigger("result",[selected.data,selected.value]);return true;}function onChange(crap,skipPrevCheck){if(lastKeyPressCode==KEY.DEL){select.hide();return;}var currentValue=$input.val();if(!skipPrevCheck&&currentValue==previousValue)return;previousValue=currentValue;currentValue=lastWord(currentValue);if(currentValue.length>=options.minChars){$input.addClass(options.loadingClass);if(!options.matchCase)currentValue=currentValue.toLowerCase();request(currentValue,receiveData,hideResultsNow);}else{stopLoading();select.hide();}};function trimWords(value){if(!value){return[""];}var words=value.split(options.multipleSeparator);var result=[];$.each(words,function(i,value){if($.trim(value))result[i]=$.trim(value);});return result;}function lastWord(value){if(!options.multiple)return value;var words=trimWords(value);return words[words.length-1];}function autoFill(q,sValue){if(options.autoFill&&(lastWord($input.val()).toLowerCase()==q.toLowerCase())&&lastKeyPressCode!=KEY.BACKSPACE){$input.val($input.val()+sValue.substring(lastWord(previousValue).length));$.Autocompleter.Selection(input,previousValue.length,previousValue.length+sValue.length);}};function hideResults(){clearTimeout(timeout);timeout=setTimeout(hideResultsNow,200);};function hideResultsNow(){var wasVisible=select.visible();select.hide();clearTimeout(timeout);stopLoading();if(options.mustMatch){$input.search(function(result){if(!result){if(options.multiple){var words=trimWords($input.val()).slice(0,-1);$input.val(words.join(options.multipleSeparator)+(words.length?options.multipleSeparator:""));}else
$input.val("");}});}if(wasVisible)$.Autocompleter.Selection(input,input.value.length,input.value.length);};function receiveData(q,data){if(data&&data.length&&hasFocus){stopLoading();select.display(data,q);autoFill(q,data[0].value);select.show();}else{hideResultsNow();}};function request(term,success,failure){if(!options.matchCase)term=term.toLowerCase();var data=cache.load(term);if(data&&data.length){success(term,data);}else if((typeof options.url=="string")&&(options.url.length>0)){var extraParams={timestamp:+new Date()};$.each(options.extraParams,function(key,param){extraParams[key]=typeof param=="function"?param():param;});$.ajax({mode:"abort",port:"autocomplete"+input.name,dataType:options.dataType,url:options.url,data:$.extend({q:lastWord(term),limit:options.max},extraParams),success:function(data){var parsed=options.parse&&options.parse(data)||parse(data);cache.add(term,parsed);success(term,parsed);}});}else{select.emptyList();failure(term);}};function parse(data){var parsed=[];var rows=data.split("\n");for(var i=0;i<rows.length;i++){var row=$.trim(rows[i]);if(row){row=row.split("|");parsed[parsed.length]={data:row,value:row[0],result:options.formatResult&&options.formatResult(row,row[0])||row[0]};}}return parsed;};function stopLoading(){$input.removeClass(options.loadingClass);};};$.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(row){return row[0];},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(value,term){return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>");},scroll:true,scrollHeight:180};$.Autocompleter.Cache=function(options){var data={};var length=0;function matchSubset(s,sub){if(!options.matchCase)s=s.toLowerCase();var i=s.indexOf(sub);if(i==-1)return false;return i==0||options.matchContains;};function add(q,value){if(length>options.cacheLength){flush();}if(!data[q]){length++;}data[q]=value;}function populate(){if(!options.data)return false;var stMatchSets={},nullData=0;if(!options.url)options.cacheLength=1;stMatchSets[""]=[];for(var i=0,ol=options.data.length;i<ol;i++){var rawValue=options.data[i];rawValue=(typeof rawValue=="string")?[rawValue]:rawValue;var value=options.formatMatch(rawValue,i+1,options.data.length);if(value===false)continue;var firstChar=value.charAt(0).toLowerCase();if(!stMatchSets[firstChar])stMatchSets[firstChar]=[];var row={value:value,data:rawValue,result:options.formatResult&&options.formatResult(rawValue)||value};stMatchSets[firstChar].push(row);if(nullData++<options.max){stMatchSets[""].push(row);}};$.each(stMatchSets,function(i,value){options.cacheLength++;add(i,value);});}setTimeout(populate,25);function flush(){data={};length=0;}return{flush:flush,add:add,populate:populate,load:function(q){if(!options.cacheLength||!length)return null;if(!options.url&&options.matchContains){var csub=[];for(var k in data){if(k.length>0){var c=data[k];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub.push(x);}});}}return csub;}else
if(data[q]){return data[q];}else
if(options.matchSubset){for(var i=q.length-1;i>=options.minChars;i--){var c=data[q.substr(0,i)];if(c){var csub=[];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub[csub.length]=x;}});return csub;}}}return null;}};};$.Autocompleter.Select=function(options,input,select,config){var CLASSES={ACTIVE:"ac_over"};var listItems,active=-1,data,term="",needsInit=true,element,list;function init(){if(!needsInit)return;element=$("<div/>").hide().addClass(options.resultsClass).css("position","absolute").appendTo(document.body);list=$("<ul/>").appendTo(element).mouseover(function(event){if(target(event).nodeName&&target(event).nodeName.toUpperCase()=='LI'){active=$("li",list).removeClass(CLASSES.ACTIVE).index(target(event));$(target(event)).addClass(CLASSES.ACTIVE);}}).click(function(event){$(target(event)).addClass(CLASSES.ACTIVE);select();input.focus();return false;}).mousedown(function(){config.mouseDownOnSelect=true;}).mouseup(function(){config.mouseDownOnSelect=false;});if(options.width>0)element.css("width",options.width);needsInit=false;}function target(event){var element=event.target;while(element&&element.tagName!="LI")element=element.parentNode;if(!element)return[];return element;}function moveSelect(step){listItems.slice(active,active+1).removeClass(CLASSES.ACTIVE);movePosition(step);var activeItem=listItems.slice(active,active+1).addClass(CLASSES.ACTIVE);if(options.scroll){var offset=0;listItems.slice(0,active).each(function(){offset+=this.offsetHeight;});if((offset+activeItem[0].offsetHeight-list.scrollTop())>list[0].clientHeight){list.scrollTop(offset+activeItem[0].offsetHeight-list.innerHeight());}else if(offset<list.scrollTop()){list.scrollTop(offset);}}};function movePosition(step){active+=step;if(active<0){active=listItems.size()-1;}else if(active>=listItems.size()){active=0;}}function limitNumberOfItems(available){return options.max&&options.max<available?options.max:available;}function fillList(){list.empty();var max=limitNumberOfItems(data.length);for(var i=0;i<max;i++){if(!data[i])continue;var formatted=options.formatItem(data[i].data,i+1,max,data[i].value,term);if(formatted===false)continue;var li=$("<li/>").html(options.highlight(formatted,term)).addClass(i%2==0?"ac_even":"ac_odd").appendTo(list)[0];$.data(li,"ac_data",data[i]);}listItems=list.find("li");if(options.selectFirst){listItems.slice(0,1).addClass(CLASSES.ACTIVE);active=0;}if($.fn.bgiframe)list.bgiframe();}return{display:function(d,q){init();data=d;term=q;fillList();},next:function(){moveSelect(1);},prev:function(){moveSelect(-1);},pageUp:function(){if(active!=0&&active-8<0){moveSelect(-active);}else{moveSelect(-8);}},pageDown:function(){if(active!=listItems.size()-1&&active+8>listItems.size()){moveSelect(listItems.size()-1-active);}else{moveSelect(8);}},hide:function(){element&&element.hide();listItems&&listItems.removeClass(CLASSES.ACTIVE);active=-1;},visible:function(){return element&&element.is(":visible");},current:function(){return this.visible()&&(listItems.filter("."+CLASSES.ACTIVE)[0]||options.selectFirst&&listItems[0]);},show:function(){var offset=$(input).offset();element.css({width:typeof options.width=="string"||options.width>0?options.width:$(input).width(),top:offset.top+input.offsetHeight,left:offset.left}).show();if(options.scroll){list.scrollTop(0);list.css({maxHeight:options.scrollHeight,overflow:'auto'});if($.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var listHeight=0;listItems.each(function(){listHeight+=this.offsetHeight;});var scrollbarsVisible=listHeight>options.scrollHeight;list.css('height',scrollbarsVisible?options.scrollHeight:listHeight);if(!scrollbarsVisible){listItems.width(list.width()-parseInt(listItems.css("padding-left"))-parseInt(listItems.css("padding-right")));}}}},selected:function(){var selected=listItems&&listItems.filter("."+CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);return selected&&selected.length&&$.data(selected[0],"ac_data");},emptyList:function(){list&&list.empty();},unbind:function(){element&&element.remove();}};};$.Autocompleter.Selection=function(field,start,end){if(field.createTextRange){var selRange=field.createTextRange();selRange.collapse(true);selRange.moveStart("character",start);selRange.moveEnd("character",end);selRange.select();}else if(field.setSelectionRange){field.setSelectionRange(start,end);}else{if(field.selectionStart){field.selectionStart=start;field.selectionEnd=end;}}field.focus();};})(jQuery);
www/media/idf/js/jquery.bgiframe.min.js
1
2
3
4
5
6
7
8
9
10
/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
*
* $LastChangedDate: 2007-07-22 01:45:56 +0200 (Son, 22 Jul 2007) $
* $Rev: 2447 $
*
* Version 2.1.1
*/
(function($){$.fn.bgIframe=$.fn.bgiframe=function(s){if($.browser.msie&&/6.0/.test(navigator.userAgent)){s=$.extend({top:'auto',left:'auto',width:'auto',height:'auto',opacity:true,src:'javascript:false;'},s||{});var prop=function(n){return n&&n.constructor==Number?n+'px':n;},html='<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'+'style="display:block;position:absolute;z-index:-1;'+(s.opacity!==false?'filter:Alpha(Opacity=\'0\');':'')+'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+'"/>';return this.each(function(){if($('> iframe.bgiframe',this).length==0)this.insertBefore(document.createElement(html),this.firstChild);});}return this;};})(jQuery);
www/media/idf/js/jquery.hotkeys.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/******************************************************************************************************************************
* @ Original idea by by Binny V A, Original version: 2.00.A
* @ http://www.openjs.com/scripts/events/keyboard_shortcuts/
* @ Original License : BSD
* @ jQuery Plugin by Tzury Bar Yochay
mail: tzury.by@gmail.com
blog: evalinux.wordpress.com
face: facebook.com/profile.php?id=513676303
(c) Copyrights 2007
* @ jQuery Plugin version Beta (0.0.2)
* @ License: jQuery-License.
TODO:
add queue support (as in gmail) e.g. 'x' then 'y', etc.
add mouse + mouse wheel events.
USAGE:
$.hotkeys.add('Ctrl+c', function(){ alert('copy anyone?');});
$.hotkeys.add('Ctrl+c', {target:'div#editor', type:'keyup', propagate: true},function(){ alert('copy anyone?');});>
$.hotkeys.remove('Ctrl+c');
$.hotkeys.remove('Ctrl+c', {target:'div#editor', type:'keypress'});
******************************************************************************************************************************/
(function (jQuery){
this.version = '(beta)(0.0.3)';
this.all = {};
this.special_keys = {
27: 'esc', 9: 'tab', 32:'space', 13: 'return', 8:'backspace', 145: 'scroll', 20: 'capslock',
144: 'numlock', 19:'pause', 45:'insert', 36:'home', 46:'del',35:'end', 33: 'pageup',
34:'pagedown', 37:'left', 38:'up', 39:'right',40:'down', 112:'f1',113:'f2', 114:'f3',
115:'f4', 116:'f5', 117:'f6', 118:'f7', 119:'f8', 120:'f9', 121:'f10', 122:'f11', 123:'f12'};
this.shift_nums = { "`":"~", "1":"!", "2":"@", "3":"#", "4":"$", "5":"%", "6":"^", "7":"&",
"8":"*", "9":"(", "0":")", "-":"_", "=":"+", ";":":", "'":"\"", ",":"<",
".":">", "/":"?", "\\":"|" };
this.add = function(combi, options, callback) {
if (jQuery.isFunction(options)){
callback = options;
options = {};
}
var opt = {},
defaults = {type: 'keydown', propagate: false, disableInInput: false, target: jQuery('html')[0]},
that = this;
opt = jQuery.extend( opt , defaults, options || {} );
combi = combi.toLowerCase();
// inspect if keystroke matches
var inspector = function(event) {
event = jQuery.event.fix(event); // jQuery event normalization.
var element = event.target;
// @ TextNode -> nodeType == 3
element = (element.nodeType==3) ? element.parentNode : element;
if(opt['disableInInput']) { // Disable shortcut keys in Input, Textarea fields
var target = jQuery(element);
if( target.is("input") || target.is("textarea")){
return;
}
}
var code = event.which,
type = event.type,
character = String.fromCharCode(code).toLowerCase(),
special = that.special_keys[code],
shift = event.shiftKey,
ctrl = event.ctrlKey,
alt= event.altKey,
propagate = true, // default behaivour
mapPoint = null;
// in opera + safari, the event.target is unpredictable.
// for example: 'keydown' might be associated with HtmlBodyElement
// or the element where you last clicked with your mouse.
if (jQuery.browser.opera || jQuery.browser.safari){
while (!that.all[element] && element.parentNode){
element = element.parentNode;
}
}
var cbMap = that.all[element].events[type].callbackMap;
if(!shift && !ctrl && !alt) { // No Modifiers
mapPoint = cbMap[special] || cbMap[character]
}
// deals with combinaitons (alt|ctrl|shift+anything)
else{
var modif = '';
if(alt) modif +='alt+';
if(ctrl) modif+= 'ctrl+';
if(shift) modif += 'shift+';
// modifiers + special keys or modifiers + characters or modifiers + shift characters
mapPoint = cbMap[modif+special] || cbMap[modif+character] || cbMap[modif+that.shift_nums[character]]
}
if (mapPoint){
mapPoint.cb(event);
if(!mapPoint.propagate) {
event.stopPropagation();
event.preventDefault();
return false;
}
}
};
// first hook for this element
if (!this.all[opt.target]){
this.all[opt.target] = {events:{}};
}
if (!this.all[opt.target].events[opt.type]){
this.all[opt.target].events[opt.type] = {callbackMap: {}}
jQuery.event.add(opt.target, opt.type, inspector);
}
this.all[opt.target].events[opt.type].callbackMap[combi] = {cb: callback, propagate:opt.propagate};
return jQuery;
};
this.remove = function(exp, opt) {
opt = opt || {};
target = opt.target || jQuery('html')[0];
type = opt.type || 'keydown';
exp = exp.toLowerCase();
delete this.all[target].events[type].callbackMap[exp]
return jQuery;
};
jQuery.hotkeys = this;
return jQuery;
})(jQuery);

Archive Download the corresponding diff file

Page rendered in 0.29633s using 13 queries.