зеркало из https://github.com/mozilla/pjs.git
Bug 322693: Create a mechanism to manage multiple custom skins.
Patch by Marc Schumann <wurblzap@gmail.com>; r=myk,mkanat; a=myk
This commit is contained in:
Родитель
aef28cebd5
Коммит
e0c494d2e3
|
@ -368,6 +368,7 @@ sub bz_locations {
|
|||
'localconfig' => "$libpath/$localconfig",
|
||||
'datadir' => "$libpath/$datadir",
|
||||
'attachdir' => "$libpath/$datadir/attachments",
|
||||
'skinsdir' => "$libpath/skins/contrib",
|
||||
# $webdotdir must be in the webtree somewhere. Even if you use a
|
||||
# local dot, we output images to there. Also, if $webdotdir is
|
||||
# not relative to the bugzilla root directory, you'll need to
|
||||
|
|
|
@ -1047,6 +1047,7 @@ use constant ABSTRACT_SCHEMA => {
|
|||
default_value => {TYPE => 'varchar(32)', NOTNULL => 1},
|
||||
is_enabled => {TYPE => 'BOOLEAN', NOTNULL => 1,
|
||||
DEFAULT => 'TRUE'},
|
||||
subclass => {TYPE => 'varchar(32)'},
|
||||
],
|
||||
},
|
||||
|
||||
|
|
|
@ -50,6 +50,8 @@ use constant SETTINGS => {
|
|||
# 2006-05-01 olav@bkor.dhs.org -- Bug 7710
|
||||
state_addselfcc => { options => ['always', 'never', 'cc_unless_role'],
|
||||
default => 'cc_unless_role' },
|
||||
# 2006-08-04 wurblzap@gmail.com -- Bug 322693
|
||||
skin => { subclass => 'Skin', default => 'standard' },
|
||||
|
||||
};
|
||||
|
||||
|
@ -75,8 +77,10 @@ use constant DEFAULT_COMPONENT => {
|
|||
sub update_settings {
|
||||
my %settings = %{SETTINGS()};
|
||||
foreach my $setting (keys %settings) {
|
||||
add_setting($setting, $settings{$setting}->{options},
|
||||
$settings{$setting}->{default});
|
||||
add_setting($setting,
|
||||
$settings{$setting}->{options},
|
||||
$settings{$setting}->{default},
|
||||
$settings{$setting}->{subclass});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -485,6 +485,8 @@ sub update_table_definitions {
|
|||
|
||||
_update_longdescs_who_index();
|
||||
|
||||
$dbh->bz_add_column('setting', 'subclass', {TYPE => 'varchar(32)'});
|
||||
|
||||
################################################################
|
||||
# New --TABLE-- changes should go *** A B O V E *** this point #
|
||||
################################################################
|
||||
|
|
|
@ -184,6 +184,7 @@ sub FILESYSTEM {
|
|||
graphs => $ws_dir_writeable,
|
||||
$webdotdir => $ws_dir_writeable,
|
||||
'skins/custom' => $ws_dir_readable,
|
||||
'skins/contrib' => $ws_dir_readable,
|
||||
);
|
||||
|
||||
# The name of each file, pointing at its default permissions and
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#
|
||||
# Contributor(s): Shane H. W. Travis <travis@sedsystems.ca>
|
||||
# Max Kanat-Alexander <mkanat@bugzilla.org>
|
||||
# Marc Schumann <wurblzap@gmail.com>
|
||||
#
|
||||
|
||||
|
||||
|
@ -39,10 +40,10 @@ sub new {
|
|||
my $user_id = shift;
|
||||
|
||||
my $class = ref($invocant) || $invocant;
|
||||
my $subclass = '';
|
||||
|
||||
# Create a ref to an empty hash and bless it
|
||||
my $self = {};
|
||||
bless($self, $class);
|
||||
|
||||
my $dbh = Bugzilla->dbh;
|
||||
|
||||
|
@ -60,9 +61,10 @@ sub new {
|
|||
# to retrieve the information for this setting ourselves.
|
||||
if (scalar @_ == 0) {
|
||||
|
||||
my ($default, $is_enabled, $value) =
|
||||
my ($default, $is_enabled, $value);
|
||||
($default, $is_enabled, $value, $subclass) =
|
||||
$dbh->selectrow_array(
|
||||
q{SELECT default_value, is_enabled, setting_value
|
||||
q{SELECT default_value, is_enabled, setting_value, subclass
|
||||
FROM setting
|
||||
LEFT JOIN profile_setting
|
||||
ON setting.name = profile_setting.setting_name
|
||||
|
@ -73,9 +75,9 @@ sub new {
|
|||
|
||||
# if not defined, then grab the default value
|
||||
if (! defined $value) {
|
||||
($default, $is_enabled) =
|
||||
($default, $is_enabled, $subclass) =
|
||||
$dbh->selectrow_array(
|
||||
q{SELECT default_value, is_enabled
|
||||
q{SELECT default_value, is_enabled, subclass
|
||||
FROM setting
|
||||
WHERE name = ?},
|
||||
undef,
|
||||
|
@ -96,12 +98,23 @@ sub new {
|
|||
}
|
||||
}
|
||||
else {
|
||||
# If the values were passed in, simply assign them and return.
|
||||
$self->{'is_enabled'} = shift;
|
||||
$self->{'default_value'} = shift;
|
||||
$self->{'value'} = shift;
|
||||
$self->{'is_default'} = shift;
|
||||
($subclass) = $dbh->selectrow_array(
|
||||
q{SELECT subclass FROM setting WHERE name = ?},
|
||||
undef,
|
||||
$setting_name);
|
||||
# If the values were passed in, simply assign them and return.
|
||||
$self->{'is_enabled'} = shift;
|
||||
$self->{'default_value'} = shift;
|
||||
$self->{'value'} = shift;
|
||||
$self->{'is_default'} = shift;
|
||||
}
|
||||
if ($subclass) {
|
||||
eval('require ' . $class . '::' . $subclass);
|
||||
$@ && ThrowCodeError('setting_subclass_invalid',
|
||||
{'subclass' => $subclass});
|
||||
$class = $class . '::' . $subclass;
|
||||
}
|
||||
bless($self, $class);
|
||||
|
||||
$self->{'_setting_name'} = $setting_name;
|
||||
$self->{'_user_id'} = $user_id;
|
||||
|
@ -114,18 +127,18 @@ sub new {
|
|||
###############################
|
||||
|
||||
sub add_setting {
|
||||
my ($name, $values, $default_value) = @_;
|
||||
my ($name, $values, $default_value, $subclass) = @_;
|
||||
my $dbh = Bugzilla->dbh;
|
||||
|
||||
return if _setting_exists($name);
|
||||
|
||||
($name && $values && $default_value)
|
||||
($name && $default_value)
|
||||
|| ThrowCodeError("setting_info_invalid");
|
||||
|
||||
print "Adding a new user setting called '$name'\n";
|
||||
$dbh->do(q{INSERT INTO setting (name, default_value, is_enabled)
|
||||
VALUES (?, ?, 1)},
|
||||
undef, ($name, $default_value));
|
||||
$dbh->do(q{INSERT INTO setting (name, default_value, is_enabled, subclass)
|
||||
VALUES (?, ?, 1, ?)},
|
||||
undef, ($name, $default_value, $subclass));
|
||||
|
||||
my $sth = $dbh->prepare(q{INSERT INTO setting_value (name, value, sortindex)
|
||||
VALUES (?, ?, ?)});
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Bugzilla Bug Tracking System.
|
||||
#
|
||||
# Contributor(s): Marc Schumann <wurblzap@gmail.com>
|
||||
#
|
||||
|
||||
|
||||
package Bugzilla::User::Setting::Skin;
|
||||
|
||||
use strict;
|
||||
|
||||
use base qw(Bugzilla::User::Setting);
|
||||
|
||||
use Bugzilla::Constants;
|
||||
use File::Spec::Functions;
|
||||
use File::Basename;
|
||||
|
||||
use constant BUILTIN_SKIN_NAMES => ['standard'];
|
||||
|
||||
sub legal_values {
|
||||
my ($self) = @_;
|
||||
|
||||
return $self->{'legal_values'} if defined $self->{'legal_values'};
|
||||
|
||||
my $dirbase = bz_locations()->{'skinsdir'};
|
||||
# Avoid modification of the list BUILTIN_SKIN_NAMES points to by copying the
|
||||
# list over instead of simply writing $legal_values = BUILTIN_SKIN_NAMES.
|
||||
my @legal_values = @{(BUILTIN_SKIN_NAMES)};
|
||||
|
||||
foreach my $direntry (glob(catdir($dirbase, '*'))) {
|
||||
if (-d $direntry) {
|
||||
# Stylesheet set
|
||||
push(@legal_values, basename($direntry));
|
||||
}
|
||||
elsif ($direntry =~ /\.css$/) {
|
||||
# Single-file stylesheet
|
||||
push(@legal_values, basename($direntry));
|
||||
}
|
||||
}
|
||||
|
||||
return $self->{'legal_values'} = \@legal_values;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Bugzilla::User::Setting::Skin - Object for a user preference setting for skins
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Skin.pm extends Bugzilla::User::Setting and implements a class specialized for
|
||||
skins settings.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=over
|
||||
|
||||
=item C<legal_values()>
|
||||
|
||||
Description: Returns all legal skins
|
||||
Params: none
|
||||
Returns: A reference to an array containing the names of all legal skins
|
||||
|
||||
=back
|
|
@ -330,6 +330,10 @@
|
|||
option. Setting names must begin with a letter, and contain only
|
||||
letters, digits, or the symbols '_', '-', '.', or ':'.
|
||||
|
||||
[% ELSIF error == "setting_subclass_invalid" %]
|
||||
There is no such Setting subclass as
|
||||
<code>[% subclass FILTER html %]</code>.
|
||||
|
||||
[% ELSIF error == "setting_value_invalid" %]
|
||||
The value "<code>[% value FILTER html %]</code>" is not in the list of
|
||||
legal values for the <em>[% name FILTER html %]</em> setting.
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
h2 = ""
|
||||
h3 = ""
|
||||
onload = ""
|
||||
style_urls = []
|
||||
%]
|
||||
|
||||
[%# We should be able to set the default value of the h1 variable
|
||||
|
@ -67,6 +68,8 @@
|
|||
|
||||
[% PROCESS "global/site-navigation.html.tmpl" %]
|
||||
|
||||
[% PROCESS 'global/setting-descs.none.tmpl' %]
|
||||
|
||||
[% IF javascript %]
|
||||
<script type="text/javascript">
|
||||
[% javascript %]
|
||||
|
@ -81,22 +84,86 @@
|
|||
|
||||
[%+ INCLUDE "global/help-header.html.tmpl" %]
|
||||
|
||||
<link href="skins/standard/global.css" rel="stylesheet" type="text/css">
|
||||
<link href="skins/custom/global.css" rel="stylesheet" type="text/css">
|
||||
[%# Set up the skin CSS cascade:
|
||||
# 1. Standard Bugzilla stylesheet set (persistent)
|
||||
# 2. Standard Bugzilla stylesheet set (selectable)
|
||||
# 3. All third-party "skin" stylesheet sets (selectable)
|
||||
# 4. Page-specific styles
|
||||
# 5. Custom Bugzilla stylesheet set (persistent)
|
||||
# "Selectable" skin file sets may be either preferred or alternate.
|
||||
# Exactly one is preferred, determined by the "skin" user preference.
|
||||
#%]
|
||||
[% IF user.settings.skin.value != 'standard' %]
|
||||
[% user_skin = user.settings.skin.value %]
|
||||
[% END %]
|
||||
[% style_urls.unshift('skins/standard/global.css') %]
|
||||
|
||||
[%# CSS cascade, part 1: Standard Bugzilla stylesheet set (persistent).
|
||||
# Always present.
|
||||
#%]
|
||||
[% FOREACH style_url = style_urls %]
|
||||
<link href="[% style_url FILTER html %]"
|
||||
rel="stylesheet"
|
||||
type="text/css">
|
||||
[% END %]
|
||||
|
||||
[%# CSS cascade, part 2: Standard Bugzilla stylesheet set (selectable)
|
||||
# Present if skin selection is enabled.
|
||||
#%]
|
||||
[% IF user.settings.skin.is_enabled %]
|
||||
[% FOREACH style_url = style_urls %]
|
||||
<link href="[% style_url FILTER html %]"
|
||||
rel="[% 'alternate ' IF user_skin %]stylesheet"
|
||||
title="[% setting_descs.standard FILTER html %]"
|
||||
type="text/css">
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
[%# CSS cascade, part 3: Third-party stylesheet set (selectable).
|
||||
# All third-party skins are present if skin selection is enabled.
|
||||
# The admin-selected skin is always present.
|
||||
#%]
|
||||
[% FOREACH contrib_skin = user.settings.skin.legal_values %]
|
||||
[% NEXT IF contrib_skin == 'standard' %]
|
||||
[% NEXT UNLESS contrib_skin == user_skin
|
||||
OR user.settings.skin.is_enabled %]
|
||||
[% contrib_skin = contrib_skin FILTER url_quote %]
|
||||
[% IF contrib_skin.match('\.css$') %]
|
||||
[%# 1st skin variant: single-file stylesheet %]
|
||||
<link href="[% "skins/contrib/$contrib_skin" %]"
|
||||
rel="[% 'alternate ' UNLESS contrib_skin == user_skin %]stylesheet"
|
||||
title="[% contrib_skin FILTER html %]"
|
||||
type="text/css">
|
||||
[% ELSE %]
|
||||
[%# 2nd skin variant: stylesheet set %]
|
||||
[% FOREACH style_url = style_urls %]
|
||||
[% IF style_url.match('^skins/standard/') %]
|
||||
<link href="[% style_url.replace('^skins/standard/',
|
||||
"skins/contrib/$contrib_skin/") %]"
|
||||
rel="[% 'alternate ' UNLESS contrib_skin == user_skin %]stylesheet"
|
||||
title="[% contrib_skin FILTER html %]"
|
||||
type="text/css">
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
[%# CSS cascade, part 4: page-specific styles.
|
||||
#%]
|
||||
[% IF style %]
|
||||
<style type="text/css">
|
||||
[% style %]
|
||||
</style>
|
||||
[% END %]
|
||||
|
||||
[% IF style_urls %]
|
||||
[% FOREACH style_url = style_urls %]
|
||||
<link href="[% style_url FILTER html %]" rel="stylesheet" type="text/css">
|
||||
[% IF style_url.match('^skins/standard/') %]
|
||||
<link href="[% style_url.replace('^skins/standard/', 'skins/custom/')
|
||||
FILTER html %]" rel="stylesheet" type="text/css">
|
||||
[% END %]
|
||||
[%# CSS cascade, part 5: Custom Bugzilla stylesheet set (persistent).
|
||||
# Always present. Site administrators may override all other style
|
||||
# definitions, including skins, using custom stylesheets.
|
||||
#%]
|
||||
[% FOREACH style_url = style_urls %]
|
||||
[% IF style_url.match('^skins/standard/') %]
|
||||
<link href="[% style_url.replace('^skins/standard/', "skins/custom/")
|
||||
FILTER html %]" rel="stylesheet" type="text/css">
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
"post_bug_submit_action" => "After changing $terms.abug",
|
||||
"next_bug" => "Show next $terms.bug in my list",
|
||||
"same_bug" => "Show the updated $terms.bug",
|
||||
"standard" => "Classic",
|
||||
"skin" => "$terms.Bugzilla's general appearance (skin)",
|
||||
"nothing" => "Do Nothing",
|
||||
"state_addselfcc" => "Automatically add me to the CC list of bugs I change",
|
||||
"always" => "Always",
|
||||
|
|
Загрузка…
Ссылка в новой задаче