Skip to content

Commit

Permalink
Issue #12245: Remove extended project browser feature
Browse files Browse the repository at this point in the history
The extended project browser feature consists of two combo boxes (one
for the tier 1 projects and one for the tier 2 projects). Extensive
JavaScript is used to link the two combo boxes together so that changing
the tier 1 project refreshes the tier 2 project list.

This approach suffers from a number of issues:
1) It doesn't escape potentially harmful values before inserting them
within the JavaScript.
2) It uses inline JavaScript which we're avoiding due to #11826.
3) It doesn't scale beyond 2 levels of projects (project and
sub-projects).
4) When enabled there is no fallback mechanism for JavaScript-disabled
browsers.

Therefore this feature should be deprecated, removed and replaced in the
future with a superior and more modern alternative.
  • Loading branch information
davidhicks committed Aug 7, 2010
1 parent 549acf4 commit 919cd8f
Show file tree
Hide file tree
Showing 4 changed files with 5 additions and 128 deletions.
8 changes: 0 additions & 8 deletions config_defaults_inc.php
Expand Up @@ -3752,14 +3752,6 @@
* Sub-projects
*****************
/**
* show extra dropdown for subprojects
* Shows only top projects in the project dropdown and adds an extra dropdown for
* subprojects.
* @global int $g_show_extended_project_browser
*/
$g_show_extended_project_browser = OFF;

/**
* Sub-projects should inherit categories from parent projects.
*/
Expand Down
14 changes: 5 additions & 9 deletions core/html_api.php
Expand Up @@ -561,17 +561,13 @@ function html_login_info() {
# CSRF protection not required here - form does not result in modifications

echo lang_get( 'email_project' ), ': ';
if( ON == config_get( 'show_extended_project_browser' ) ) {
print_extended_project_browser( helper_get_current_project_trace() );
if( ON == config_get( 'use_javascript' ) ) {
echo '<select name="project_id" class="small" onchange="document.forms.form_set_project.submit();">';
} else {
if( ON == config_get( 'use_javascript' ) ) {
echo '<select name="project_id" class="small" onchange="document.forms.form_set_project.submit();">';
} else {
echo '<select name="project_id" class="small">';
}
print_project_option_list( join( ';', helper_get_current_project_trace() ), true, null, true );
echo '</select> ';
echo '<select name="project_id" class="small">';
}
print_project_option_list( join( ';', helper_get_current_project_trace() ), true, null, true );
echo '</select> ';
echo '<input type="submit" class="button-small" value="' . lang_get( 'switch' ) . '" />';
echo '</form>';
}
Expand Down
100 changes: 0 additions & 100 deletions core/print_api.php
Expand Up @@ -536,106 +536,6 @@ function print_subproject_option_list( $p_parent_id, $p_project_id = null, $p_fi
}
}

# --------------------
# Print extended project browser
function print_extended_project_browser( $p_trace = Array(), $p_project_id = null ) {
project_cache_all();
$t_project_ids = current_user_get_accessible_projects();

echo '<script type="text/javascript">' . "\n";
echo "<!--\n";
echo "var subprojects = new Object();\n";

echo 'function unescapeHTML(html) {' . "\n";
echo ' var htmlNode = document.createElement("DIV");' . "\n";
echo ' htmlNode.innerHTML = html;' . "\n";
echo ' if(htmlNode.innerText)' . "\n";
echo ' return htmlNode.innerText; // IE' . "\n";
echo ' return htmlNode.textContent; // FF' . "\n";
echo '} ' . "\n";

$t_projects = Array();

$t_project_count = count( $t_project_ids );
for( $i = 0;$i < $t_project_count;$i++ ) {
$t_id = $t_project_ids[$i];
echo 'subprojects[\'' . $t_id . '\'] = new Object();' . "\n";

$t_name = project_get_field( $t_id, 'name' );
$c_name = addslashes( $t_name );
echo 'subprojects[\'' . $t_id . '\'][\'' . $t_id . '\'] = \'' . $c_name . '\';' . "\n";

$t_projects[$t_id] = $t_name;

print_extended_project_browser_subproject_javascript( $t_id );
}

echo "\n";
echo 'function setProject(projectVal) {' . "\n";
echo "\t" . 'var spInput = document.form_set_project.project_id;' . "\n";
echo "\t" . 'spInput.options.length = 0' . "\n";
echo "\t" . 'if (projectVal == "' . ALL_PROJECTS . '") {' . "\n";
echo "\t\t" . 'spInput.options[0] = new Option(\'--- All Projects ---\', \'' . ALL_PROJECTS . '\');' . "\n";
echo "\t" . '} else {' . "\n";
echo "\t\t" . 'var i = 0;' . "\n";
echo "\t\t" . 'var project = subprojects[ projectVal ];' . "\n";
echo "\t\t" . 'for ( var sp in project ) {' . "\n";
echo "\t\t\t" . 'spInput.options[ i++ ] = new Option( unescapeHTML(project[sp]), sp );' . "\n";
echo "\t\t" . '}' . "\n";
echo "\t" . '}' . "\n";
echo '}' . "\n";

echo '// --></script>' . "\n";
echo '<select name="top_id" onChange="setProject(this.value); document.form_set_project.submit()" class="small">' . "\n";
echo '<option value="' . ALL_PROJECTS . '"';
echo check_selected( $p_project_id, ALL_PROJECTS );
echo '>' . lang_get( 'all_projects' ) . '</option>' . "\n";

foreach( $t_projects as $t_id => $t_name ) {
$c_name = string_attribute( $t_name );
echo '<option value="' . $t_id . '"';
echo check_selected( $p_project_id, $t_id );
echo '>' . $c_name . '</option>' . "\n";
}

echo '</select>' . "\n";

if( 0 === count( $p_trace ) ) {
$t_top_id = ALL_PROJECTS;
} else {
$t_top_id = $p_trace[0];
$t_trace_str = join( ';', $p_trace );
}

echo '<select name="project_id" onChange="document.form_set_project.submit()" class="small-subprojects"></select>' . "\n";
echo '<script type="text/javascript">' . "\n";
echo '<!--' . "\n";
echo 'document.form_set_project.top_id.value = \'' . $t_top_id . '\';' . "\n";
echo 'setProject(' . $t_top_id . ');' . "\n";
echo 'document.form_set_project.project_id.value = \'' . $t_trace_str . '\';' . "\n";
echo '// --></script>' . "\n";
}

# --------------------
# print the subproject javascript for the extended project browser
function print_extended_project_browser_subproject_javascript( $p_trace ) {
$t_trace_projects = explode( ';', $p_trace );
$t_top_id = $t_trace_projects[0];
$t_level = count( $t_trace_projects );
$t_parent_id = $t_trace_projects[$t_level - 1];

$t_project_ids = current_user_get_accessible_subprojects( $t_parent_id );
$t_project_count = count( $t_project_ids );

for( $i = 0;$i < $t_project_count;$i++ ) {
$t_id = $t_project_ids[$i];
$t_name = addslashes( str_repeat(( '&nbsp;' ), $t_level ) . str_repeat(( '&raquo;' ), $t_level ) . ' ' . project_get_field( $t_id, 'name' ) );
echo 'subprojects[\'' . $t_top_id . '\'][\'' . $p_trace . ';' . $t_id . '\'] = \'' . $t_name . '\';' . "\n";

print_extended_project_browser_subproject_javascript( $p_trace . ';' . $t_id );
}
}

# --------------------
# prints the profiles given the user id
function print_profile_option_list( $p_user_id, $p_select_id = '', $p_profiles = null ) {
Expand Down
11 changes: 0 additions & 11 deletions docbook/adminguide/en/configuration.sgml
Expand Up @@ -2811,17 +2811,6 @@
<title>Sub-Projects</title>

<variablelist>
<varlistentry>
<term>$g_show_extended_project_browser</term>
<listitem>
<para>
Whether to use the extended project selector, where top level projects have their
separate selector, and sub-projects have another. If OFF, there will be one combo box
at the top right to select the project/sub-project. If ON, there will be two. The default
is OFF.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>$g_subprojects_inherit_versions</term>
<listitem>
Expand Down

0 comments on commit 919cd8f

Please sign in to comment.