pmdtester 1.0.0.pre.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +10 -0
- data/.rubocop_todo.yml +27 -0
- data/.travis.yml +22 -0
- data/Gemfile +20 -0
- data/History.md +36 -0
- data/LICENSE +25 -0
- data/README.rdoc +33 -0
- data/Rakefile +54 -0
- data/bin/pmdtester +7 -0
- data/config/all-java.xml +18 -0
- data/config/design.xml +78 -0
- data/config/project-list.xml +29 -0
- data/config/projectlist_1_0_0.xsd +28 -0
- data/lib/pmdtester/builders/diff_builder.rb +35 -0
- data/lib/pmdtester/builders/diff_report_builder.rb +226 -0
- data/lib/pmdtester/builders/html_report_builder.rb +34 -0
- data/lib/pmdtester/builders/pmd_report_builder.rb +128 -0
- data/lib/pmdtester/builders/rule_set_builder.rb +114 -0
- data/lib/pmdtester/builders/summary_report_builder.rb +149 -0
- data/lib/pmdtester/cmd.rb +40 -0
- data/lib/pmdtester/parsers/options.rb +147 -0
- data/lib/pmdtester/parsers/pmd_report_document.rb +82 -0
- data/lib/pmdtester/parsers/projects_parser.rb +41 -0
- data/lib/pmdtester/pmd_branch_detail.rb +67 -0
- data/lib/pmdtester/pmd_error.rb +67 -0
- data/lib/pmdtester/pmd_report_detail.rb +47 -0
- data/lib/pmdtester/pmd_violation.rb +66 -0
- data/lib/pmdtester/pmdtester.rb +17 -0
- data/lib/pmdtester/project.rb +112 -0
- data/lib/pmdtester/report_diff.rb +111 -0
- data/lib/pmdtester/resource_locator.rb +10 -0
- data/lib/pmdtester/runner.rb +130 -0
- data/resources/css/maven-base.css +155 -0
- data/resources/css/maven-theme.css +171 -0
- metadata +249 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PmdTester
|
4
|
+
# This class represents all the diff report information,
|
5
|
+
# including the summary information of the original pmd reports,
|
6
|
+
# as well as the specific information of the diff report.
|
7
|
+
class ReportDiff
|
8
|
+
attr_accessor :base_violations_size
|
9
|
+
attr_accessor :patch_violations_size
|
10
|
+
attr_accessor :violation_diffs_size
|
11
|
+
|
12
|
+
attr_accessor :base_errors_size
|
13
|
+
attr_accessor :patch_errors_size
|
14
|
+
attr_accessor :error_diffs_size
|
15
|
+
|
16
|
+
attr_accessor :base_execution_time
|
17
|
+
attr_accessor :patch_execution_time
|
18
|
+
attr_accessor :diff_execution_time
|
19
|
+
|
20
|
+
attr_accessor :base_timestamp
|
21
|
+
attr_accessor :patch_timestamp
|
22
|
+
|
23
|
+
attr_accessor :violation_diffs
|
24
|
+
attr_accessor :error_diffs
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
@base_violations_size = 0
|
28
|
+
@patch_violations_size = 0
|
29
|
+
@violation_diffs_size = 0
|
30
|
+
|
31
|
+
@base_errors_size = 0
|
32
|
+
@patch_errors_size = 0
|
33
|
+
@error_diffs_size = 0
|
34
|
+
|
35
|
+
@base_execution_time = 0
|
36
|
+
@patch_execution_time = 0
|
37
|
+
@diff_execution_time = 0
|
38
|
+
|
39
|
+
@base_timestamp = ''
|
40
|
+
@patch_timestamp = ''
|
41
|
+
|
42
|
+
@violation_diffs = {}
|
43
|
+
@error_diffs = {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def diffs_exist?
|
47
|
+
!error_diffs_size.zero? || !violation_diffs_size.zero?
|
48
|
+
end
|
49
|
+
|
50
|
+
def calculate_violations(base_violations, patch_violations)
|
51
|
+
@base_violations_size = base_violations.violations_size
|
52
|
+
@patch_violations_size = patch_violations.violations_size
|
53
|
+
violation_diffs = build_diffs(base_violations.violations, patch_violations.violations)
|
54
|
+
@violation_diffs = violation_diffs
|
55
|
+
@violation_diffs_size = get_diffs_size(violation_diffs)
|
56
|
+
end
|
57
|
+
|
58
|
+
def calculate_errors(base_errors, patch_errors)
|
59
|
+
@base_errors_size = base_errors.errors_size
|
60
|
+
@patch_errors_size = patch_errors.errors_size
|
61
|
+
error_diffs = build_diffs(base_errors.errors, patch_errors.errors)
|
62
|
+
@error_diffs = error_diffs
|
63
|
+
@error_diffs_size = get_diffs_size(error_diffs)
|
64
|
+
end
|
65
|
+
|
66
|
+
def calculate_details(base_info, patch_info)
|
67
|
+
base_details = PmdReportDetail.new
|
68
|
+
base_details.load(base_info) unless base_info.nil?
|
69
|
+
patch_details = PmdReportDetail.new
|
70
|
+
patch_details.load(patch_info) unless patch_info.nil?
|
71
|
+
|
72
|
+
@base_execution_time = base_details.format_execution_time
|
73
|
+
@patch_execution_time = patch_details.format_execution_time
|
74
|
+
@diff_execution_time =
|
75
|
+
PmdReportDetail.convert_seconds(base_details.execution_time -
|
76
|
+
patch_details.execution_time)
|
77
|
+
|
78
|
+
@base_timestamp = base_details.timestamp
|
79
|
+
@patch_timestamp = patch_details.timestamp
|
80
|
+
[base_details, patch_details]
|
81
|
+
end
|
82
|
+
|
83
|
+
def build_diffs(base_hash, patch_hash)
|
84
|
+
diffs = base_hash.merge(patch_hash) do |_key, base_value, patch_value|
|
85
|
+
(base_value | patch_value) - (base_value & patch_value)
|
86
|
+
end
|
87
|
+
|
88
|
+
diffs.delete_if do |_key, value|
|
89
|
+
value.empty?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_diffs_size(diffs_hash)
|
94
|
+
size = 0
|
95
|
+
diffs_hash.keys.each do |key|
|
96
|
+
size += diffs_hash[key].size
|
97
|
+
end
|
98
|
+
size
|
99
|
+
end
|
100
|
+
|
101
|
+
def introduce_new_errors?
|
102
|
+
@error_diffs.values.each do |pmd_errors|
|
103
|
+
pmd_errors.each do |pmd_error|
|
104
|
+
return true if pmd_error.branch.eql?('patch')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PmdTester
|
4
|
+
# This class is responsible for locating the static resources of PmdTester.
|
5
|
+
class ResourceLocator
|
6
|
+
def self.locate(resource_path)
|
7
|
+
File.expand_path(File.dirname(__FILE__) + "/../../#{resource_path}")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './builders/diff_builder.rb'
|
4
|
+
require_relative './builders/diff_report_builder.rb'
|
5
|
+
require_relative './builders/rule_set_builder'
|
6
|
+
require_relative './builders/summary_report_builder.rb'
|
7
|
+
require_relative './builders/pmd_report_builder.rb'
|
8
|
+
require_relative './parsers/options'
|
9
|
+
require_relative './parsers/projects_parser'
|
10
|
+
require_relative './pmdtester'
|
11
|
+
require_relative './pmd_branch_detail'
|
12
|
+
|
13
|
+
module PmdTester
|
14
|
+
# The Runner is a class responsible of organizing all PmdTester modules
|
15
|
+
# and running the PmdTester
|
16
|
+
class Runner
|
17
|
+
include PmdTester
|
18
|
+
def initialize(argv)
|
19
|
+
@options = Options.new(argv)
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
case @options.mode
|
24
|
+
when Options::LOCAL
|
25
|
+
run_local_mode
|
26
|
+
when Options::ONLINE
|
27
|
+
run_online_mode
|
28
|
+
when Options::SINGLE
|
29
|
+
run_single_mode
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def run_local_mode
|
34
|
+
logger.info "Mode: #{@options.mode}"
|
35
|
+
RuleSetBuilder.new(@options).build if @options.auto_config_flag
|
36
|
+
|
37
|
+
get_projects(@options.project_list) unless @options.nil?
|
38
|
+
PmdReportBuilder
|
39
|
+
.new(@options.base_config, @projects, @options.local_git_repo, @options.base_branch)
|
40
|
+
.build
|
41
|
+
PmdReportBuilder
|
42
|
+
.new(@options.patch_config, @projects, @options.local_git_repo, @options.patch_branch)
|
43
|
+
.build
|
44
|
+
|
45
|
+
build_html_reports
|
46
|
+
end
|
47
|
+
|
48
|
+
def run_online_mode
|
49
|
+
logger.info "Mode: #{@options.mode}"
|
50
|
+
|
51
|
+
baseline_path = download_baseline(@options.base_branch)
|
52
|
+
|
53
|
+
if @options.auto_config_flag
|
54
|
+
RuleSetBuilder.new(@options).build
|
55
|
+
else
|
56
|
+
# patch branch build pmd reports with same configuration as base branch
|
57
|
+
@options.patch_config = "#{baseline_path}/config.xml"
|
58
|
+
end
|
59
|
+
|
60
|
+
# patch branch build pmd report with same list of projects as base branch
|
61
|
+
project_list = "#{baseline_path}/project-list.xml"
|
62
|
+
get_projects(project_list)
|
63
|
+
|
64
|
+
PmdReportBuilder
|
65
|
+
.new(@options.patch_config, @projects, @options.local_git_repo, @options.patch_branch)
|
66
|
+
.build
|
67
|
+
|
68
|
+
build_html_reports
|
69
|
+
end
|
70
|
+
|
71
|
+
def download_baseline(branch_name)
|
72
|
+
branch_filename = PmdBranchDetail.branch_filename(branch_name)
|
73
|
+
zip_filename = "#{branch_filename}-baseline.zip"
|
74
|
+
target_path = 'target/reports'
|
75
|
+
FileUtils.mkdir_p(target_path) unless File.directory?(target_path)
|
76
|
+
|
77
|
+
url = get_baseline_url(zip_filename)
|
78
|
+
wget_cmd = "wget #{url}"
|
79
|
+
unzip_cmd = "unzip -qo #{zip_filename}"
|
80
|
+
|
81
|
+
Dir.chdir(target_path) do
|
82
|
+
Cmd.execute(wget_cmd) unless File.exist?(zip_filename)
|
83
|
+
Cmd.execute(unzip_cmd)
|
84
|
+
end
|
85
|
+
|
86
|
+
"#{target_path}/#{branch_filename}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def get_baseline_url(zip_filename)
|
90
|
+
"https://sourceforge.net/projects/pmd/files/pmd-regression-tester/#{zip_filename}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def run_single_mode
|
94
|
+
logger.info "Mode: #{@options.mode}"
|
95
|
+
|
96
|
+
get_projects(@options.project_list) unless @options.nil?
|
97
|
+
branch_details = PmdReportBuilder
|
98
|
+
.new(@options.patch_config, @projects,
|
99
|
+
@options.local_git_repo, @options.patch_branch)
|
100
|
+
.build
|
101
|
+
# copy list of projects file to the patch baseline
|
102
|
+
FileUtils.cp(@options.project_list, branch_details.target_branch_project_list_path)
|
103
|
+
|
104
|
+
build_html_reports unless @options.html_flag
|
105
|
+
end
|
106
|
+
|
107
|
+
def build_html_reports
|
108
|
+
build_diff_html_reports
|
109
|
+
SummaryReportBuilder.new.build(@projects, @options.base_branch, @options.patch_branch)
|
110
|
+
end
|
111
|
+
|
112
|
+
def build_diff_html_reports
|
113
|
+
@projects.each do |project|
|
114
|
+
logger.info "Preparing report for #{project.name}"
|
115
|
+
report_diffs = DiffBuilder.new.build(project.get_pmd_report_path(@options.base_branch),
|
116
|
+
project.get_pmd_report_path(@options.patch_branch),
|
117
|
+
project.get_report_info_path(@options.base_branch),
|
118
|
+
project.get_report_info_path(@options.patch_branch),
|
119
|
+
@options.filter_set)
|
120
|
+
project.report_diff = report_diffs
|
121
|
+
DiffReportBuilder.new.build(project)
|
122
|
+
end
|
123
|
+
logger.info 'Built all difference reports successfully!'
|
124
|
+
end
|
125
|
+
|
126
|
+
def get_projects(file_path)
|
127
|
+
@projects = ProjectsParser.new.parse(file_path)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
body {
|
2
|
+
margin: 0px;
|
3
|
+
padding: 0px;
|
4
|
+
}
|
5
|
+
img {
|
6
|
+
border:none;
|
7
|
+
}
|
8
|
+
table {
|
9
|
+
padding:0px;
|
10
|
+
width: 100%;
|
11
|
+
margin-left: -2px;
|
12
|
+
margin-right: -2px;
|
13
|
+
}
|
14
|
+
acronym {
|
15
|
+
cursor: help;
|
16
|
+
border-bottom: 1px dotted #feb;
|
17
|
+
}
|
18
|
+
table.bodyTable th, table.bodyTable td {
|
19
|
+
padding: 2px 4px 2px 4px;
|
20
|
+
vertical-align: top;
|
21
|
+
}
|
22
|
+
div.clear{
|
23
|
+
clear:both;
|
24
|
+
visibility: hidden;
|
25
|
+
}
|
26
|
+
div.clear hr{
|
27
|
+
display: none;
|
28
|
+
}
|
29
|
+
#bannerLeft, #bannerRight {
|
30
|
+
font-size: xx-large;
|
31
|
+
font-weight: bold;
|
32
|
+
}
|
33
|
+
#bannerLeft img, #bannerRight img {
|
34
|
+
margin: 0px;
|
35
|
+
}
|
36
|
+
.xleft, #bannerLeft img {
|
37
|
+
float:left;
|
38
|
+
}
|
39
|
+
.xright, #bannerRight {
|
40
|
+
float:right;
|
41
|
+
}
|
42
|
+
#banner {
|
43
|
+
padding: 0px;
|
44
|
+
}
|
45
|
+
#banner img {
|
46
|
+
border: none;
|
47
|
+
}
|
48
|
+
#breadcrumbs {
|
49
|
+
padding: 3px 10px 3px 10px;
|
50
|
+
}
|
51
|
+
#leftColumn {
|
52
|
+
width: 170px;
|
53
|
+
float:left;
|
54
|
+
overflow: auto;
|
55
|
+
}
|
56
|
+
#bodyColumn {
|
57
|
+
margin-right: 1.5em;
|
58
|
+
margin-left: 197px;
|
59
|
+
}
|
60
|
+
#legend {
|
61
|
+
padding: 8px 0 8px 0;
|
62
|
+
}
|
63
|
+
#navcolumn {
|
64
|
+
padding: 8px 4px 0 8px;
|
65
|
+
}
|
66
|
+
#navcolumn h5 {
|
67
|
+
margin: 0;
|
68
|
+
padding: 0;
|
69
|
+
font-size: small;
|
70
|
+
}
|
71
|
+
#navcolumn ul {
|
72
|
+
margin: 0;
|
73
|
+
padding: 0;
|
74
|
+
font-size: small;
|
75
|
+
}
|
76
|
+
#navcolumn li {
|
77
|
+
list-style-type: none;
|
78
|
+
background-image: none;
|
79
|
+
background-repeat: no-repeat;
|
80
|
+
background-position: 0 0.4em;
|
81
|
+
padding-left: 16px;
|
82
|
+
list-style-position: outside;
|
83
|
+
line-height: 1.2em;
|
84
|
+
font-size: smaller;
|
85
|
+
}
|
86
|
+
#navcolumn li.expanded {
|
87
|
+
background-image: url(../images/expanded.gif);
|
88
|
+
}
|
89
|
+
#navcolumn li.collapsed {
|
90
|
+
background-image: url(../images/collapsed.gif);
|
91
|
+
}
|
92
|
+
#navcolumn li.none {
|
93
|
+
text-indent: -1em;
|
94
|
+
margin-left: 1em;
|
95
|
+
}
|
96
|
+
#poweredBy {
|
97
|
+
text-align: center;
|
98
|
+
}
|
99
|
+
#navcolumn img {
|
100
|
+
margin-top: 10px;
|
101
|
+
margin-bottom: 3px;
|
102
|
+
}
|
103
|
+
#poweredBy img {
|
104
|
+
display:block;
|
105
|
+
margin: 20px 0 20px 17px;
|
106
|
+
}
|
107
|
+
#search img {
|
108
|
+
margin: 0px;
|
109
|
+
display: block;
|
110
|
+
}
|
111
|
+
#search #q, #search #btnG {
|
112
|
+
border: 1px solid #999;
|
113
|
+
margin-bottom:10px;
|
114
|
+
}
|
115
|
+
#search form {
|
116
|
+
margin: 0px;
|
117
|
+
}
|
118
|
+
#lastPublished {
|
119
|
+
font-size: x-small;
|
120
|
+
}
|
121
|
+
.navSection {
|
122
|
+
margin-bottom: 2px;
|
123
|
+
padding: 8px;
|
124
|
+
}
|
125
|
+
.navSectionHead {
|
126
|
+
font-weight: bold;
|
127
|
+
font-size: x-small;
|
128
|
+
}
|
129
|
+
.section {
|
130
|
+
padding: 4px;
|
131
|
+
}
|
132
|
+
#footer {
|
133
|
+
padding: 3px 10px 3px 10px;
|
134
|
+
font-size: x-small;
|
135
|
+
}
|
136
|
+
#breadcrumbs {
|
137
|
+
font-size: x-small;
|
138
|
+
margin: 0pt;
|
139
|
+
}
|
140
|
+
.source {
|
141
|
+
padding: 12px;
|
142
|
+
margin: 1em 7px 1em 7px;
|
143
|
+
}
|
144
|
+
.source pre {
|
145
|
+
margin: 0px;
|
146
|
+
padding: 0px;
|
147
|
+
}
|
148
|
+
#navcolumn img.imageLink, .imageLink {
|
149
|
+
padding-left: 0px;
|
150
|
+
padding-bottom: 0px;
|
151
|
+
padding-top: 0px;
|
152
|
+
padding-right: 2px;
|
153
|
+
border: 0px;
|
154
|
+
margin: 0px;
|
155
|
+
}
|
@@ -0,0 +1,171 @@
|
|
1
|
+
body {
|
2
|
+
padding: 0px 0px 10px 0px;
|
3
|
+
}
|
4
|
+
body, td, select, input, li{
|
5
|
+
font-family: Verdana, Helvetica, Arial, sans-serif;
|
6
|
+
font-size: 13px;
|
7
|
+
}
|
8
|
+
code{
|
9
|
+
font-family: Courier, monospace;
|
10
|
+
font-size: 13px;
|
11
|
+
}
|
12
|
+
a {
|
13
|
+
text-decoration: none;
|
14
|
+
}
|
15
|
+
a:link {
|
16
|
+
color:#36a;
|
17
|
+
}
|
18
|
+
a:visited {
|
19
|
+
color:#47a;
|
20
|
+
}
|
21
|
+
a:active, a:hover {
|
22
|
+
color:#69c;
|
23
|
+
}
|
24
|
+
#legend li.externalLink {
|
25
|
+
background: url(../images/external.png) left top no-repeat;
|
26
|
+
padding-left: 18px;
|
27
|
+
}
|
28
|
+
a.externalLink, a.externalLink:link, a.externalLink:visited, a.externalLink:active, a.externalLink:hover {
|
29
|
+
background: url(../images/external.png) right center no-repeat;
|
30
|
+
padding-right: 18px;
|
31
|
+
}
|
32
|
+
#legend li.newWindow {
|
33
|
+
background: url(../images/newwindow.png) left top no-repeat;
|
34
|
+
padding-left: 18px;
|
35
|
+
}
|
36
|
+
a.newWindow, a.newWindow:link, a.newWindow:visited, a.newWindow:active, a.newWindow:hover {
|
37
|
+
background: url(../images/newwindow.png) right center no-repeat;
|
38
|
+
padding-right: 18px;
|
39
|
+
}
|
40
|
+
h2 {
|
41
|
+
padding: 4px 4px 4px 6px;
|
42
|
+
border: 1px solid #999;
|
43
|
+
color: #900;
|
44
|
+
background-color: #ddd;
|
45
|
+
font-weight:900;
|
46
|
+
font-size: x-large;
|
47
|
+
}
|
48
|
+
h3 {
|
49
|
+
padding: 4px 4px 4px 6px;
|
50
|
+
border: 1px solid #aaa;
|
51
|
+
color: #900;
|
52
|
+
background-color: #eee;
|
53
|
+
font-weight: normal;
|
54
|
+
font-size: large;
|
55
|
+
}
|
56
|
+
h4 {
|
57
|
+
font-weight: normal;
|
58
|
+
font-size: large;
|
59
|
+
}
|
60
|
+
h5 {
|
61
|
+
padding: 4px 4px 4px 6px;
|
62
|
+
color: #900;
|
63
|
+
font-size: normal;
|
64
|
+
}
|
65
|
+
p {
|
66
|
+
line-height: 1.3em;
|
67
|
+
font-size: small;
|
68
|
+
}
|
69
|
+
#breadcrumbs {
|
70
|
+
border-top: 1px solid #aaa;
|
71
|
+
border-bottom: 1px solid #aaa;
|
72
|
+
background-color: #ccc;
|
73
|
+
}
|
74
|
+
#leftColumn {
|
75
|
+
margin: 10px 0 0 5px;
|
76
|
+
border: 1px solid #999;
|
77
|
+
background-color: #eee;
|
78
|
+
}
|
79
|
+
#navcolumn h5 {
|
80
|
+
font-size: smaller;
|
81
|
+
border-bottom: 1px solid #aaaaaa;
|
82
|
+
padding-top: 2px;
|
83
|
+
color: #000;
|
84
|
+
}
|
85
|
+
|
86
|
+
table.bodyTable th {
|
87
|
+
color: white;
|
88
|
+
background-color: #bbb;
|
89
|
+
text-align: left;
|
90
|
+
font-weight: bold;
|
91
|
+
}
|
92
|
+
|
93
|
+
table.bodyTable th, table.bodyTable td {
|
94
|
+
font-size: 1em;
|
95
|
+
}
|
96
|
+
|
97
|
+
table.bodyTable tr.a {
|
98
|
+
background-color: #af8;
|
99
|
+
}
|
100
|
+
|
101
|
+
table.bodyTable tr.b {
|
102
|
+
background-color: #fca;
|
103
|
+
}
|
104
|
+
|
105
|
+
table.bodyTable tr.c {
|
106
|
+
background-color: #eee;
|
107
|
+
}
|
108
|
+
|
109
|
+
table.bodyTable tr.d {
|
110
|
+
background-color: #fef7bc;
|
111
|
+
}
|
112
|
+
|
113
|
+
table.bodyTable td.a {
|
114
|
+
background-color: #af8;
|
115
|
+
}
|
116
|
+
|
117
|
+
table.bodyTable td.b {
|
118
|
+
background-color: #fca;
|
119
|
+
}
|
120
|
+
|
121
|
+
table.bodyTable td.c {
|
122
|
+
background-color: #eee;
|
123
|
+
}
|
124
|
+
|
125
|
+
.source {
|
126
|
+
border: 1px solid #999;
|
127
|
+
}
|
128
|
+
dl {
|
129
|
+
padding: 4px 4px 4px 6px;
|
130
|
+
border: 1px solid #aaa;
|
131
|
+
background-color: #ffc;
|
132
|
+
}
|
133
|
+
dt {
|
134
|
+
color: #900;
|
135
|
+
}
|
136
|
+
|
137
|
+
#banner {
|
138
|
+
border-bottom: 1px solid #fff;
|
139
|
+
}
|
140
|
+
|
141
|
+
button {
|
142
|
+
background-color: #ddd;
|
143
|
+
border: none;
|
144
|
+
color: #900;
|
145
|
+
padding: 6px 12px;
|
146
|
+
text-align: center;
|
147
|
+
text-decoration: none;
|
148
|
+
display: inline-block;
|
149
|
+
font-size: 25px;
|
150
|
+
margin: 4px 2px;
|
151
|
+
cursor: pointer;
|
152
|
+
}
|
153
|
+
|
154
|
+
#example {
|
155
|
+
position: relative;
|
156
|
+
}
|
157
|
+
|
158
|
+
#example-checkbox {
|
159
|
+
display: none;
|
160
|
+
}
|
161
|
+
|
162
|
+
#example-checkbox:checked + #example:after {
|
163
|
+
content: attr(data-text);
|
164
|
+
position: absolute;
|
165
|
+
top: 0;
|
166
|
+
left: 0;
|
167
|
+
right: 0;
|
168
|
+
bottom: 0;
|
169
|
+
background: white;
|
170
|
+
}
|
171
|
+
|