Merge lp:~alisonken1/openlp/strings-templates2 into lp:openlp
- strings-templates2
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~alisonken1/openlp/strings-templates2 |
Merge into: | lp:openlp |
Diff against target: |
876 lines (+406/-393) 2 files modified
openlp/core/lib/htmlbuilder.py (+224/-226) tests/functional/openlp_core_lib/test_htmlbuilder.py (+182/-167) |
To merge this branch: | bzr merge lp:~alisonken1/openlp/strings-templates2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tim Bentley | Needs Fixing | ||
Review via email: mp+296567@code.launchpad.net |
This proposal has been superseded by a proposal from 2016-06-07.
Commit message
Convert htmlbuilder.py to use Template() strings for css
Description of the change
Convert htmlbuilder.py to use Template() strings for css
- Changed strings to use Template() instead of format() for css building
- Fix htmlbuilder strings tests
-------
lp:~alisonken1/openlp/strings-templates2 (revision 2675)
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
Ken Roberts (alisonken1) wrote : | # |
Since this is HTML/css source and not just any text variable I followed the
formatting the original HTML SRC. Has something changed since the original
was put in?
On Jun 6, 2016 9:12 AM, "Tim Bentley" <email address hidden> wrote:
> Review: Needs Fixing
>
> Looks good but one comment which is general across all the code.
>
> Diff comments:
>
> > === modified file 'openlp/
> > --- openlp/
> > +++ openlp/
> > @@ -538,15 +538,60 @@
> > </script>
> > </head>
> > <body>
> > -<img id="bgimage" class="size" %s />
> > -<img id="image" class="size" %s />
> > -%s
> > +<img id="bgimage" class="size" ${bg_image} />
> > +<img id="image" class="size" ${image} />
> > +${html_additions}
> > <div class="
> class="lyricscell lyricsmain"
> > <div id="footer" class="
> > <div id="black" class="size"></div>
> > </body>
> > </html>
> > -"""
> > +""")
> > +
> > +LYRICS_SRC = Template("""
> > +.lyricstable {
> > + z-index: 5;
> > + position: absolute;
> > + display: table;
> > + ${stable}
> > +}
> > +.lyricscell {
> > + display: table-cell;
> > + word-wrap: break-word;
> > + -webkit-transition: opacity 0.4s ease;
> > + ${lyrics}
> > +}
> > +.lyricsmain {
> > + ${main}
> > +}
> > +""")
> > +
> > +FOOTER_SRC = Template("""
>
> Indent please.
> No real rule about indentation but Lyrics_src looks better!
>
> > +left: ${left}px;
> > +bottom: ${bottom}px;
> > +width: ${width}px;
> > +font-family: ${family};
> > +font-size: ${size}pt;
> > +color: ${color};
> > +text-align: left;
> > +white-space: ${space};
> > +""")
> > +
> > +LYRICS_FORMAT_SRC = Template("""
> > +${justify}
> > +text-align: ${align};
> > +vertical-align: ${valign};
> > +font-family: ${font};
> > +font-size: ${size}pt;
> > +color: ${color};
> > +line-height: ${line}%;
> > +margin: 0;
> > +padding: 0;
> > +padding-bottom: ${bottom};
> > +padding-left: ${left}px;
> > +width: ${width}px;
> > +height: ${height}
> > +""")
> >
> >
> > def build_html(item, screen, is_live, background, image=None,
> plugins=None):
>
>
> --
>
> https:/
> You are the owner of lp:~alisonken1/openlp/strings-templates2.
>
Tim Bentley (trb143) wrote : | # |
No it just looks a bit cramped and could do with a visit to a beauty spar😁
On 7 Jun 2016 1:42 a.m., "Ken Roberts" <email address hidden> wrote:
> Since this is HTML/css source and not just any text variable I followed the
> formatting the original HTML SRC. Has something changed since the original
> was put in?
> On Jun 6, 2016 9:12 AM, "Tim Bentley" <email address hidden> wrote:
>
> > Review: Needs Fixing
> >
> > Looks good but one comment which is general across all the code.
> >
> > Diff comments:
> >
> > > === modified file 'openlp/
> > > --- openlp/
> > > +++ openlp/
> > > @@ -538,15 +538,60 @@
> > > </script>
> > > </head>
> > > <body>
> > > -<img id="bgimage" class="size" %s />
> > > -<img id="image" class="size" %s />
> > > -%s
> > > +<img id="bgimage" class="size" ${bg_image} />
> > > +<img id="image" class="size" ${image} />
> > > +${html_additions}
> > > <div class="
> > class="lyricscell lyricsmain"
> > > <div id="footer" class="
> > > <div id="black" class="size"></div>
> > > </body>
> > > </html>
> > > -"""
> > > +""")
> > > +
> > > +LYRICS_SRC = Template("""
> > > +.lyricstable {
> > > + z-index: 5;
> > > + position: absolute;
> > > + display: table;
> > > + ${stable}
> > > +}
> > > +.lyricscell {
> > > + display: table-cell;
> > > + word-wrap: break-word;
> > > + -webkit-transition: opacity 0.4s ease;
> > > + ${lyrics}
> > > +}
> > > +.lyricsmain {
> > > + ${main}
> > > +}
> > > +""")
> > > +
> > > +FOOTER_SRC = Template("""
> >
> > Indent please.
> > No real rule about indentation but Lyrics_src looks better!
> >
> > > +left: ${left}px;
> > > +bottom: ${bottom}px;
> > > +width: ${width}px;
> > > +font-family: ${family};
> > > +font-size: ${size}pt;
> > > +color: ${color};
> > > +text-align: left;
> > > +white-space: ${space};
> > > +""")
> > > +
> > > +LYRICS_FORMAT_SRC = Template("""
> > > +${justify}
> > > +text-align: ${align};
> > > +vertical-align: ${valign};
> > > +font-family: ${font};
> > > +font-size: ${size}pt;
> > > +color: ${color};
> > > +line-height: ${line}%;
> > > +margin: 0;
> > > +padding: 0;
> > > +padding-bottom: ${bottom};
> > > +padding-left: ${left}px;
> > > +width: ${width}px;
> > > +height: ${height}
> > > +""")
> > >
> > >
> > > def build_html(item, screen, is_live, background, image=None,
> > plugins=None):
> >
> >
> > --
> >
> >
> https:/
> > You are the owner of lp:~alisonken1/openlp/strings-templates2.
> >
>
> --
>
> https:/
> You are reviewing the proposed merge of
> lp:~alisonken1/openlp/strings-templates2 into lp:openlp.
>
- 2676. By Ken Roberts
-
Beauty spa for the htmlbuilder
- 2677. By Ken Roberts
-
Remove testing verbosity flag
- 2678. By Ken Roberts
-
Oops in string format
- 2679. By Ken Roberts
-
String format oops
- 2680. By Ken Roberts
-
String format oops
Unmerged revisions
Preview Diff
1 | === modified file 'openlp/core/lib/htmlbuilder.py' |
2 | --- openlp/core/lib/htmlbuilder.py 2016-05-17 13:21:29 +0000 |
3 | +++ openlp/core/lib/htmlbuilder.py 2016-06-07 13:12:55 +0000 |
4 | @@ -390,163 +390,207 @@ |
5 | import logging |
6 | |
7 | from PyQt5 import QtWebKit |
8 | +from string import Template |
9 | |
10 | from openlp.core.common import Settings |
11 | from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, VerticalType, HorizontalType |
12 | |
13 | log = logging.getLogger(__name__) |
14 | |
15 | -# TODO: Verify where this is used before converting to python3 |
16 | -HTMLSRC = """ |
17 | -<!DOCTYPE html> |
18 | -<html> |
19 | -<head> |
20 | -<title>OpenLP Display</title> |
21 | -<style> |
22 | -*{ |
23 | +HTML_SRC = Template(""" |
24 | + <!DOCTYPE html> |
25 | + <html> |
26 | + <head> |
27 | + <title>OpenLP Display</title> |
28 | + <style> |
29 | + *{ |
30 | + margin: 0; |
31 | + padding: 0; |
32 | + border: 0; |
33 | + overflow: hidden; |
34 | + -webkit-user-select: none; |
35 | + } |
36 | + body { |
37 | + ${bg_css}; |
38 | + } |
39 | + .size { |
40 | + position: absolute; |
41 | + left: 0px; |
42 | + top: 0px; |
43 | + width: 100%; |
44 | + height: 100%; |
45 | + } |
46 | + #black { |
47 | + z-index: 8; |
48 | + background-color: black; |
49 | + display: none; |
50 | + } |
51 | + #bgimage { |
52 | + z-index: 1; |
53 | + } |
54 | + #image { |
55 | + z-index: 2; |
56 | + } |
57 | + ${css_additions} |
58 | + #footer { |
59 | + position: absolute; |
60 | + z-index: 6; |
61 | + ${footer_css} |
62 | + } |
63 | + /* lyric css */${lyrics_css} |
64 | + sup { |
65 | + font-size: 0.6em; |
66 | + vertical-align: top; |
67 | + position: relative; |
68 | + top: -0.3em; |
69 | + } |
70 | + </style> |
71 | + <script> |
72 | + var timer = null; |
73 | + var transition = ${transitions}; |
74 | + ${js_additions} |
75 | + |
76 | + function show_image(src){ |
77 | + var img = document.getElementById('image'); |
78 | + img.src = src; |
79 | + if(src == '') |
80 | + img.style.display = 'none'; |
81 | + else |
82 | + img.style.display = 'block'; |
83 | + } |
84 | + |
85 | + function show_blank(state){ |
86 | + var black = 'none'; |
87 | + var lyrics = ''; |
88 | + switch(state){ |
89 | + case 'theme': |
90 | + lyrics = 'hidden'; |
91 | + break; |
92 | + case 'black': |
93 | + black = 'block'; |
94 | + break; |
95 | + case 'desktop': |
96 | + break; |
97 | + } |
98 | + document.getElementById('black').style.display = black; |
99 | + document.getElementById('lyricsmain').style.visibility = lyrics; |
100 | + document.getElementById('image').style.visibility = lyrics; |
101 | + document.getElementById('footer').style.visibility = lyrics; |
102 | + } |
103 | + |
104 | + function show_footer(footertext){ |
105 | + document.getElementById('footer').innerHTML = footertext; |
106 | + } |
107 | + |
108 | + function show_text(new_text){ |
109 | + var match = /-webkit-text-fill-color:[^;\"]+/gi; |
110 | + if(timer != null) |
111 | + clearTimeout(timer); |
112 | + /* |
113 | + QtWebkit bug with outlines and justify causing outline alignment |
114 | + problems. (Bug 859950) Surround each word with a <span> to workaround, |
115 | + but only in this scenario. |
116 | + */ |
117 | + var txt = document.getElementById('lyricsmain'); |
118 | + if(window.getComputedStyle(txt).textAlign == 'justify'){ |
119 | + if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){ |
120 | + new_text = new_text.replace(/(\s| )+(?![^<]*>)/g, |
121 | + function(match) { |
122 | + return '</span>' + match + '<span>'; |
123 | + }); |
124 | + new_text = '<span>' + new_text + '</span>'; |
125 | + } |
126 | + } |
127 | + text_fade('lyricsmain', new_text); |
128 | + } |
129 | + |
130 | + function text_fade(id, new_text){ |
131 | + /* |
132 | + Show the text. |
133 | + */ |
134 | + var text = document.getElementById(id); |
135 | + if(text == null) return; |
136 | + if(!transition){ |
137 | + text.innerHTML = new_text; |
138 | + return; |
139 | + } |
140 | + // Fade text out. 0.1 to minimize the time "nothing" is shown on the screen. |
141 | + text.style.opacity = '0.1'; |
142 | + // Fade new text in after the old text has finished fading out. |
143 | + timer = window.setTimeout(function(){_show_text(text, new_text)}, 400); |
144 | + } |
145 | + |
146 | + function _show_text(text, new_text) { |
147 | + /* |
148 | + Helper function to show the new_text delayed. |
149 | + */ |
150 | + text.innerHTML = new_text; |
151 | + text.style.opacity = '1'; |
152 | + // Wait until the text is completely visible. We want to save the timer id, to be able to call |
153 | + // clearTimeout(timer) when the text has changed before finishing fading. |
154 | + timer = window.setTimeout(function(){timer = null;}, 400); |
155 | + } |
156 | + |
157 | + function show_text_completed(){ |
158 | + return (timer == null); |
159 | + } |
160 | + </script> |
161 | + </head> |
162 | + <body> |
163 | + <img id="bgimage" class="size" ${bg_image} /> |
164 | + <img id="image" class="size" ${image} /> |
165 | + ${html_additions} |
166 | + <div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div> |
167 | + <div id="footer" class="footer"></div> |
168 | + <div id="black" class="size"></div> |
169 | + </body> |
170 | + </html> |
171 | + """) |
172 | + |
173 | +LYRICS_SRC = Template(""" |
174 | + .lyricstable { |
175 | + z-index: 5; |
176 | + position: absolute; |
177 | + display: table; |
178 | + ${stable} |
179 | + } |
180 | + .lyricscell { |
181 | + display: table-cell; |
182 | + word-wrap: break-word; |
183 | + -webkit-transition: opacity 0.4s ease; |
184 | + ${lyrics} |
185 | + } |
186 | + .lyricsmain { |
187 | + ${main} |
188 | + } |
189 | + """) |
190 | + |
191 | +FOOTER_SRC = Template(""" |
192 | + left: ${left}px; |
193 | + bottom: ${bottom}px; |
194 | + width: ${width}px; |
195 | + font-family: ${family}; |
196 | + font-size: ${size}pt; |
197 | + color: ${color}; |
198 | + text-align: left; |
199 | + white-space: ${space}; |
200 | + """) |
201 | + |
202 | +LYRICS_FORMAT_SRC = Template(""" |
203 | + ${justify}word-wrap: break-word; |
204 | + text-align: ${align}; |
205 | + vertical-align: ${valign}; |
206 | + font-family: ${font}; |
207 | + font-size: ${size}pt; |
208 | + color: ${color}; |
209 | + line-height: ${line}%; |
210 | margin: 0; |
211 | padding: 0; |
212 | - border: 0; |
213 | - overflow: hidden; |
214 | - -webkit-user-select: none; |
215 | -} |
216 | -body { |
217 | - %s; |
218 | -} |
219 | -.size { |
220 | - position: absolute; |
221 | - left: 0px; |
222 | - top: 0px; |
223 | - width: 100%%; |
224 | - height: 100%%; |
225 | -} |
226 | -#black { |
227 | - z-index: 8; |
228 | - background-color: black; |
229 | - display: none; |
230 | -} |
231 | -#bgimage { |
232 | - z-index: 1; |
233 | -} |
234 | -#image { |
235 | - z-index: 2; |
236 | -} |
237 | -%s |
238 | -#footer { |
239 | - position: absolute; |
240 | - z-index: 6; |
241 | - %s |
242 | -} |
243 | -/* lyric css */ |
244 | -%s |
245 | -sup { |
246 | - font-size: 0.6em; |
247 | - vertical-align: top; |
248 | - position: relative; |
249 | - top: -0.3em; |
250 | -} |
251 | -</style> |
252 | -<script> |
253 | - var timer = null; |
254 | - var transition = %s; |
255 | - %s |
256 | - |
257 | - function show_image(src){ |
258 | - var img = document.getElementById('image'); |
259 | - img.src = src; |
260 | - if(src == '') |
261 | - img.style.display = 'none'; |
262 | - else |
263 | - img.style.display = 'block'; |
264 | - } |
265 | - |
266 | - function show_blank(state){ |
267 | - var black = 'none'; |
268 | - var lyrics = ''; |
269 | - switch(state){ |
270 | - case 'theme': |
271 | - lyrics = 'hidden'; |
272 | - break; |
273 | - case 'black': |
274 | - black = 'block'; |
275 | - break; |
276 | - case 'desktop': |
277 | - break; |
278 | - } |
279 | - document.getElementById('black').style.display = black; |
280 | - document.getElementById('lyricsmain').style.visibility = lyrics; |
281 | - document.getElementById('image').style.visibility = lyrics; |
282 | - document.getElementById('footer').style.visibility = lyrics; |
283 | - } |
284 | - |
285 | - function show_footer(footertext){ |
286 | - document.getElementById('footer').innerHTML = footertext; |
287 | - } |
288 | - |
289 | - function show_text(new_text){ |
290 | - var match = /-webkit-text-fill-color:[^;\"]+/gi; |
291 | - if(timer != null) |
292 | - clearTimeout(timer); |
293 | - /* |
294 | - QtWebkit bug with outlines and justify causing outline alignment |
295 | - problems. (Bug 859950) Surround each word with a <span> to workaround, |
296 | - but only in this scenario. |
297 | - */ |
298 | - var txt = document.getElementById('lyricsmain'); |
299 | - if(window.getComputedStyle(txt).textAlign == 'justify'){ |
300 | - if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){ |
301 | - new_text = new_text.replace(/(\s| )+(?![^<]*>)/g, |
302 | - function(match) { |
303 | - return '</span>' + match + '<span>'; |
304 | - }); |
305 | - new_text = '<span>' + new_text + '</span>'; |
306 | - } |
307 | - } |
308 | - text_fade('lyricsmain', new_text); |
309 | - } |
310 | - |
311 | - function text_fade(id, new_text){ |
312 | - /* |
313 | - Show the text. |
314 | - */ |
315 | - var text = document.getElementById(id); |
316 | - if(text == null) return; |
317 | - if(!transition){ |
318 | - text.innerHTML = new_text; |
319 | - return; |
320 | - } |
321 | - // Fade text out. 0.1 to minimize the time "nothing" is shown on the screen. |
322 | - text.style.opacity = '0.1'; |
323 | - // Fade new text in after the old text has finished fading out. |
324 | - timer = window.setTimeout(function(){_show_text(text, new_text)}, 400); |
325 | - } |
326 | - |
327 | - function _show_text(text, new_text) { |
328 | - /* |
329 | - Helper function to show the new_text delayed. |
330 | - */ |
331 | - text.innerHTML = new_text; |
332 | - text.style.opacity = '1'; |
333 | - // Wait until the text is completely visible. We want to save the timer id, to be able to call |
334 | - // clearTimeout(timer) when the text has changed before finishing fading. |
335 | - timer = window.setTimeout(function(){timer = null;}, 400); |
336 | - } |
337 | - |
338 | - function show_text_completed(){ |
339 | - return (timer == null); |
340 | - } |
341 | -</script> |
342 | -</head> |
343 | -<body> |
344 | -<img id="bgimage" class="size" %s /> |
345 | -<img id="image" class="size" %s /> |
346 | -%s |
347 | -<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div> |
348 | -<div id="footer" class="footer"></div> |
349 | -<div id="black" class="size"></div> |
350 | -</body> |
351 | -</html> |
352 | -""" |
353 | + padding-bottom: ${bottom}; |
354 | + padding-left: ${left}px; |
355 | + width: ${width}px; |
356 | + height: ${height}px;${font_style}${font_weight} |
357 | + """) |
358 | |
359 | |
360 | def build_html(item, screen, is_live, background, image=None, plugins=None): |
361 | @@ -582,18 +626,17 @@ |
362 | css_additions += plugin.get_display_css() |
363 | js_additions += plugin.get_display_javascript() |
364 | html_additions += plugin.get_display_html() |
365 | - html = HTMLSRC % ( |
366 | - build_background_css(item, width), |
367 | - css_additions, |
368 | - build_footer_css(item, height), |
369 | - build_lyrics_css(item), |
370 | - 'true' if theme_data and theme_data.display_slide_transition and is_live else 'false', |
371 | - js_additions, |
372 | - bgimage_src, |
373 | - image_src, |
374 | - html_additions |
375 | - ) |
376 | - return html |
377 | + return HTML_SRC.substitute(bg_css=build_background_css(item, width), |
378 | + css_additions=css_additions, |
379 | + footer_css=build_footer_css(item, height), |
380 | + lyrics_css=build_lyrics_css(item), |
381 | + transitions='true' if (theme_data and |
382 | + theme_data.display_slide_transition and |
383 | + is_live) else 'false', |
384 | + js_additions=js_additions, |
385 | + bg_image=bgimage_src, |
386 | + image=image_src, |
387 | + html_additions=html_additions) |
388 | |
389 | |
390 | def webkit_version(): |
391 | @@ -650,24 +693,6 @@ |
392 | |
393 | :param item: Service Item containing theme and location information |
394 | """ |
395 | - # TODO: Verify this before converting to python3 |
396 | - style = """ |
397 | -.lyricstable { |
398 | - z-index: 5; |
399 | - position: absolute; |
400 | - display: table; |
401 | - %s |
402 | -} |
403 | -.lyricscell { |
404 | - display: table-cell; |
405 | - word-wrap: break-word; |
406 | - -webkit-transition: opacity 0.4s ease; |
407 | - %s |
408 | -} |
409 | -.lyricsmain { |
410 | - %s |
411 | -} |
412 | -""" |
413 | theme_data = item.theme_data |
414 | lyricstable = '' |
415 | lyrics = '' |
416 | @@ -680,8 +705,7 @@ |
417 | lyricsmain += ' text-shadow: {theme} {shadow}px ' \ |
418 | '{shadow}px;'.format(theme=theme_data.font_main_shadow_color, |
419 | shadow=theme_data.font_main_shadow_size) |
420 | - lyrics_css = style % (lyricstable, lyrics, lyricsmain) |
421 | - return lyrics_css |
422 | + return LYRICS_SRC.substitute(stable=lyricstable, lyrics=lyrics, main=lyricsmain) |
423 | |
424 | |
425 | def build_lyrics_outline_css(theme_data): |
426 | @@ -710,38 +734,23 @@ |
427 | """ |
428 | align = HorizontalType.Names[theme_data.display_horizontal_align] |
429 | valign = VerticalType.Names[theme_data.display_vertical_align] |
430 | - if theme_data.font_main_outline: |
431 | - left_margin = int(theme_data.font_main_outline_size) * 2 |
432 | - else: |
433 | - left_margin = 0 |
434 | - justify = 'white-space:pre-wrap;' |
435 | + left_margin = (int(theme_data.font_main_outline_size) * 2) if theme_data.font_main_outline else 0 |
436 | # fix tag incompatibilities |
437 | - if theme_data.display_horizontal_align == HorizontalType.Justify: |
438 | - justify = '' |
439 | - if theme_data.display_vertical_align == VerticalType.Bottom: |
440 | - padding_bottom = '0.5em' |
441 | - else: |
442 | - padding_bottom = '0' |
443 | - lyrics = '{justify} word-wrap: break-word; ' \ |
444 | - 'text-align: {align}; vertical-align: {valign}; font-family: {font}; ' \ |
445 | - 'font-size: {size}pt; color: {color}; line-height: {line:d}%; margin: 0;' \ |
446 | - 'padding: 0; padding-bottom: {bottom}; padding-left: {left}px; width: {width}px; ' \ |
447 | - 'height: {height}px; '.format(justify=justify, |
448 | - align=align, |
449 | - valign=valign, |
450 | - font=theme_data.font_main_name, |
451 | - size=theme_data.font_main_size, |
452 | - color=theme_data.font_main_color, |
453 | - line=100 + int(theme_data.font_main_line_adjustment), |
454 | - bottom=padding_bottom, |
455 | - left=left_margin, |
456 | - width=width, |
457 | - height=height) |
458 | - if theme_data.font_main_italics: |
459 | - lyrics += 'font-style:italic; ' |
460 | - if theme_data.font_main_bold: |
461 | - lyrics += 'font-weight:bold; ' |
462 | - return lyrics |
463 | + justify = '' if (theme_data.display_horizontal_align == HorizontalType.Justify) else ' white-space: pre-wrap;\n' |
464 | + padding_bottom = '0.5em' if (theme_data.display_vertical_align == VerticalType.Bottom) else '0' |
465 | + return LYRICS_FORMAT_SRC.substitute(justify=justify, |
466 | + align=align, |
467 | + valign=valign, |
468 | + font=theme_data.font_main_name, |
469 | + size=theme_data.font_main_size, |
470 | + color=theme_data.font_main_color, |
471 | + line='{line:d}'.format(line=100 + int(theme_data.font_main_line_adjustment)), |
472 | + bottom=padding_bottom, |
473 | + left=left_margin, |
474 | + width=width, |
475 | + height=height, |
476 | + font_style='\n font-style: italic;' if theme_data.font_main_italics else '', |
477 | + font_weight='\n font-weight: bold;' if theme_data.font_main_bold else '') |
478 | |
479 | |
480 | def build_footer_css(item, height): |
481 | @@ -751,22 +760,11 @@ |
482 | :param item: Service Item to be processed. |
483 | :param height: |
484 | """ |
485 | - style = """ |
486 | - left: {left}px; |
487 | - bottom: {bottom}px; |
488 | - width: {width}px; |
489 | - font-family: {family}; |
490 | - font-size: {size}pt; |
491 | - color: {color}; |
492 | - text-align: left; |
493 | - white-space: {space}; |
494 | - """ |
495 | theme = item.theme_data |
496 | if not theme or not item.footer: |
497 | return '' |
498 | bottom = height - int(item.footer.y()) - int(item.footer.height()) |
499 | whitespace = 'normal' if Settings().value('themes/wrap footer') else 'nowrap' |
500 | - lyrics_html = style.format(left=item.footer.x(), bottom=bottom, width=item.footer.width(), |
501 | - family=theme.font_footer_name, size=theme.font_footer_size, |
502 | - color=theme.font_footer_color, space=whitespace) |
503 | - return lyrics_html |
504 | + return FOOTER_SRC.substitute(left=item.footer.x(), bottom=bottom, width=item.footer.width(), |
505 | + family=theme.font_footer_name, size=theme.font_footer_size, |
506 | + color=theme.font_footer_color, space=whitespace) |
507 | |
508 | === modified file 'tests/functional/openlp_core_lib/test_htmlbuilder.py' |
509 | --- tests/functional/openlp_core_lib/test_htmlbuilder.py 2016-05-31 21:40:13 +0000 |
510 | +++ tests/functional/openlp_core_lib/test_htmlbuilder.py 2016-06-07 13:12:55 +0000 |
511 | @@ -14,177 +14,190 @@ |
512 | from tests.helpers.testmixin import TestMixin |
513 | |
514 | HTML = """ |
515 | -<!DOCTYPE html> |
516 | -<html> |
517 | -<head> |
518 | -<title>OpenLP Display</title> |
519 | -<style> |
520 | -*{ |
521 | - margin: 0; |
522 | - padding: 0; |
523 | - border: 0; |
524 | - overflow: hidden; |
525 | - -webkit-user-select: none; |
526 | -} |
527 | -body { |
528 | - ; |
529 | -} |
530 | -.size { |
531 | - position: absolute; |
532 | - left: 0px; |
533 | - top: 0px; |
534 | - width: 100%; |
535 | - height: 100%; |
536 | -} |
537 | -#black { |
538 | - z-index: 8; |
539 | - background-color: black; |
540 | - display: none; |
541 | -} |
542 | -#bgimage { |
543 | - z-index: 1; |
544 | -} |
545 | -#image { |
546 | - z-index: 2; |
547 | -} |
548 | -plugin CSS |
549 | -#footer { |
550 | - position: absolute; |
551 | - z-index: 6; |
552 | - dummy: dummy; |
553 | -} |
554 | -/* lyric css */ |
555 | - |
556 | -sup { |
557 | - font-size: 0.6em; |
558 | - vertical-align: top; |
559 | - position: relative; |
560 | - top: -0.3em; |
561 | -} |
562 | -</style> |
563 | -<script> |
564 | - var timer = null; |
565 | - var transition = false; |
566 | - plugin JS |
567 | - |
568 | - function show_image(src){ |
569 | - var img = document.getElementById('image'); |
570 | - img.src = src; |
571 | - if(src == '') |
572 | - img.style.display = 'none'; |
573 | - else |
574 | - img.style.display = 'block'; |
575 | - } |
576 | - |
577 | - function show_blank(state){ |
578 | - var black = 'none'; |
579 | - var lyrics = ''; |
580 | - switch(state){ |
581 | - case 'theme': |
582 | - lyrics = 'hidden'; |
583 | - break; |
584 | - case 'black': |
585 | - black = 'block'; |
586 | - break; |
587 | - case 'desktop': |
588 | - break; |
589 | - } |
590 | - document.getElementById('black').style.display = black; |
591 | - document.getElementById('lyricsmain').style.visibility = lyrics; |
592 | - document.getElementById('image').style.visibility = lyrics; |
593 | - document.getElementById('footer').style.visibility = lyrics; |
594 | - } |
595 | - |
596 | - function show_footer(footertext){ |
597 | - document.getElementById('footer').innerHTML = footertext; |
598 | - } |
599 | - |
600 | - function show_text(new_text){ |
601 | - var match = /-webkit-text-fill-color:[^;"]+/gi; |
602 | - if(timer != null) |
603 | - clearTimeout(timer); |
604 | - /* |
605 | - QtWebkit bug with outlines and justify causing outline alignment |
606 | - problems. (Bug 859950) Surround each word with a <span> to workaround, |
607 | - but only in this scenario. |
608 | - */ |
609 | - var txt = document.getElementById('lyricsmain'); |
610 | - if(window.getComputedStyle(txt).textAlign == 'justify'){ |
611 | - if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){ |
612 | - new_text = new_text.replace(/(\s| )+(?![^<]*>)/g, |
613 | - function(match) { |
614 | - return '</span>' + match + '<span>'; |
615 | - }); |
616 | - new_text = '<span>' + new_text + '</span>'; |
617 | - } |
618 | - } |
619 | - text_fade('lyricsmain', new_text); |
620 | - } |
621 | - |
622 | - function text_fade(id, new_text){ |
623 | - /* |
624 | - Show the text. |
625 | - */ |
626 | - var text = document.getElementById(id); |
627 | - if(text == null) return; |
628 | - if(!transition){ |
629 | + <!DOCTYPE html> |
630 | + <html> |
631 | + <head> |
632 | + <title>OpenLP Display</title> |
633 | + <style> |
634 | + *{ |
635 | + margin: 0; |
636 | + padding: 0; |
637 | + border: 0; |
638 | + overflow: hidden; |
639 | + -webkit-user-select: none; |
640 | + } |
641 | + body { |
642 | + ; |
643 | + } |
644 | + .size { |
645 | + position: absolute; |
646 | + left: 0px; |
647 | + top: 0px; |
648 | + width: 100%; |
649 | + height: 100%; |
650 | + } |
651 | + #black { |
652 | + z-index: 8; |
653 | + background-color: black; |
654 | + display: none; |
655 | + } |
656 | + #bgimage { |
657 | + z-index: 1; |
658 | + } |
659 | + #image { |
660 | + z-index: 2; |
661 | + } |
662 | + plugin CSS |
663 | + #footer { |
664 | + position: absolute; |
665 | + z-index: 6; |
666 | + dummy: dummy; |
667 | + } |
668 | + /* lyric css */ |
669 | + sup { |
670 | + font-size: 0.6em; |
671 | + vertical-align: top; |
672 | + position: relative; |
673 | + top: -0.3em; |
674 | + } |
675 | + </style> |
676 | + <script> |
677 | + var timer = null; |
678 | + var transition = false; |
679 | + plugin JS |
680 | + |
681 | + function show_image(src){ |
682 | + var img = document.getElementById('image'); |
683 | + img.src = src; |
684 | + if(src == '') |
685 | + img.style.display = 'none'; |
686 | + else |
687 | + img.style.display = 'block'; |
688 | + } |
689 | + |
690 | + function show_blank(state){ |
691 | + var black = 'none'; |
692 | + var lyrics = ''; |
693 | + switch(state){ |
694 | + case 'theme': |
695 | + lyrics = 'hidden'; |
696 | + break; |
697 | + case 'black': |
698 | + black = 'block'; |
699 | + break; |
700 | + case 'desktop': |
701 | + break; |
702 | + } |
703 | + document.getElementById('black').style.display = black; |
704 | + document.getElementById('lyricsmain').style.visibility = lyrics; |
705 | + document.getElementById('image').style.visibility = lyrics; |
706 | + document.getElementById('footer').style.visibility = lyrics; |
707 | + } |
708 | + |
709 | + function show_footer(footertext){ |
710 | + document.getElementById('footer').innerHTML = footertext; |
711 | + } |
712 | + |
713 | + function show_text(new_text){ |
714 | + var match = /-webkit-text-fill-color:[^;"]+/gi; |
715 | + if(timer != null) |
716 | + clearTimeout(timer); |
717 | + /* |
718 | + QtWebkit bug with outlines and justify causing outline alignment |
719 | + problems. (Bug 859950) Surround each word with a <span> to workaround, |
720 | + but only in this scenario. |
721 | + */ |
722 | + var txt = document.getElementById('lyricsmain'); |
723 | + if(window.getComputedStyle(txt).textAlign == 'justify'){ |
724 | + if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){ |
725 | + new_text = new_text.replace(/(\s| )+(?![^<]*>)/g, |
726 | + function(match) { |
727 | + return '</span>' + match + '<span>'; |
728 | + }); |
729 | + new_text = '<span>' + new_text + '</span>'; |
730 | + } |
731 | + } |
732 | + text_fade('lyricsmain', new_text); |
733 | + } |
734 | + |
735 | + function text_fade(id, new_text){ |
736 | + /* |
737 | + Show the text. |
738 | + */ |
739 | + var text = document.getElementById(id); |
740 | + if(text == null) return; |
741 | + if(!transition){ |
742 | + text.innerHTML = new_text; |
743 | + return; |
744 | + } |
745 | + // Fade text out. 0.1 to minimize the time "nothing" is shown on the screen. |
746 | + text.style.opacity = '0.1'; |
747 | + // Fade new text in after the old text has finished fading out. |
748 | + timer = window.setTimeout(function(){_show_text(text, new_text)}, 400); |
749 | + } |
750 | + |
751 | + function _show_text(text, new_text) { |
752 | + /* |
753 | + Helper function to show the new_text delayed. |
754 | + */ |
755 | text.innerHTML = new_text; |
756 | - return; |
757 | - } |
758 | - // Fade text out. 0.1 to minimize the time "nothing" is shown on the screen. |
759 | - text.style.opacity = '0.1'; |
760 | - // Fade new text in after the old text has finished fading out. |
761 | - timer = window.setTimeout(function(){_show_text(text, new_text)}, 400); |
762 | - } |
763 | - |
764 | - function _show_text(text, new_text) { |
765 | - /* |
766 | - Helper function to show the new_text delayed. |
767 | - */ |
768 | - text.innerHTML = new_text; |
769 | - text.style.opacity = '1'; |
770 | - // Wait until the text is completely visible. We want to save the timer id, to be able to call |
771 | - // clearTimeout(timer) when the text has changed before finishing fading. |
772 | - timer = window.setTimeout(function(){timer = null;}, 400); |
773 | - } |
774 | - |
775 | - function show_text_completed(){ |
776 | - return (timer == null); |
777 | - } |
778 | -</script> |
779 | -</head> |
780 | -<body> |
781 | -<img id="bgimage" class="size" style="display:none;" /> |
782 | -<img id="image" class="size" style="display:none;" /> |
783 | -plugin HTML |
784 | -<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div> |
785 | -<div id="footer" class="footer"></div> |
786 | -<div id="black" class="size"></div> |
787 | -</body> |
788 | -</html> |
789 | -""" |
790 | + text.style.opacity = '1'; |
791 | + // Wait until the text is completely visible. We want to save the timer id, to be able to call |
792 | + // clearTimeout(timer) when the text has changed before finishing fading. |
793 | + timer = window.setTimeout(function(){timer = null;}, 400); |
794 | + } |
795 | + |
796 | + function show_text_completed(){ |
797 | + return (timer == null); |
798 | + } |
799 | + </script> |
800 | + </head> |
801 | + <body> |
802 | + <img id="bgimage" class="size" style="display:none;" /> |
803 | + <img id="image" class="size" style="display:none;" /> |
804 | + plugin HTML |
805 | + <div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div> |
806 | + <div id="footer" class="footer"></div> |
807 | + <div id="black" class="size"></div> |
808 | + </body> |
809 | + </html> |
810 | + """ |
811 | BACKGROUND_CSS_RADIAL = 'background: -webkit-gradient(radial, 5 50%, 100, 5 50%, 5, from(#000000), to(#FFFFFF)) fixed' |
812 | LYRICS_CSS = """ |
813 | -.lyricstable { |
814 | - z-index: 5; |
815 | - position: absolute; |
816 | - display: table; |
817 | - left: 10px; top: 20px; |
818 | -} |
819 | -.lyricscell { |
820 | - display: table-cell; |
821 | + .lyricstable { |
822 | + z-index: 5; |
823 | + position: absolute; |
824 | + display: table; |
825 | + left: 10px; top: 20px; |
826 | + } |
827 | + .lyricscell { |
828 | + display: table-cell; |
829 | + word-wrap: break-word; |
830 | + -webkit-transition: opacity 0.4s ease; |
831 | + lyrics_format_css |
832 | + } |
833 | + .lyricsmain { |
834 | + text-shadow: #000000 5px 5px; |
835 | + } |
836 | + """ |
837 | +LYRICS_OUTLINE_CSS = ' -webkit-text-stroke: 0.125em #000000; -webkit-text-fill-color: #FFFFFF; ' |
838 | +LYRICS_FORMAT_CSS = """ |
839 | word-wrap: break-word; |
840 | - -webkit-transition: opacity 0.4s ease; |
841 | - lyrics_format_css |
842 | -} |
843 | -.lyricsmain { |
844 | - text-shadow: #000000 5px 5px; |
845 | -} |
846 | -""" |
847 | -LYRICS_OUTLINE_CSS = ' -webkit-text-stroke: 0.125em #000000; -webkit-text-fill-color: #FFFFFF; ' |
848 | -LYRICS_FORMAT_CSS = ' word-wrap: break-word; text-align: justify; vertical-align: bottom; ' + \ |
849 | - 'font-family: Arial; font-size: 40pt; color: #FFFFFF; line-height: 108%; margin: 0;padding: 0; ' + \ |
850 | - 'padding-bottom: 0.5em; padding-left: 2px; width: 1580px; height: 810px; font-style:italic; font-weight:bold; ' |
851 | + text-align: justify; |
852 | + vertical-align: bottom; |
853 | + font-family: Arial; |
854 | + font-size: 40pt; |
855 | + color: #FFFFFF; |
856 | + line-height: 108%; |
857 | + margin: 0; |
858 | + padding: 0; |
859 | + padding-bottom: 0.5em; |
860 | + padding-left: 2px; |
861 | + width: 1580px; |
862 | + height: 810px; |
863 | + font-style: italic; |
864 | + font-weight: bold; |
865 | + """ |
866 | FOOTER_CSS_BASE = """ |
867 | left: 10px; |
868 | bottom: 0px; |
869 | @@ -243,6 +256,8 @@ |
870 | # WHEN: Create the html. |
871 | html = build_html(item, screen, is_live, background, plugins=plugins) |
872 | |
873 | + self.maxDiff = None |
874 | + |
875 | # THEN: The returned html should match. |
876 | self.assertEqual(html, HTML, 'The returned html should match') |
877 |
Looks good but one comment which is general across all the code.