Beauty spa for the htmlbuilder

This commit is contained in:
Ken Roberts 2016-06-07 06:12:22 -07:00
parent 2443b94eda
commit 5fe54b5907
2 changed files with 361 additions and 361 deletions

View File

@ -398,200 +398,199 @@ from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, Vertic
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
HTML_SRC = Template(""" HTML_SRC = Template("""
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>OpenLP Display</title> <title>OpenLP Display</title>
<style> <style>
*{ *{
margin: 0; margin: 0;
padding: 0; padding: 0;
border: 0; border: 0;
overflow: hidden; overflow: hidden;
-webkit-user-select: none; -webkit-user-select: none;
}
body {
${bg_css};
}
.size {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
#black {
z-index: 8;
background-color: black;
display: none;
}
#bgimage {
z-index: 1;
}
#image {
z-index: 2;
}
${css_additions}
#footer {
position: absolute;
z-index: 6;
${footer_css}
}
/* lyric css */
${lyrics_css}
sup {
font-size: 0.6em;
vertical-align: top;
position: relative;
top: -0.3em;
}
</style>
<script>
var timer = null;
var transition = ${transitions};
${js_additions}
function show_image(src){
var img = document.getElementById('image');
img.src = src;
if(src == '')
img.style.display = 'none';
else
img.style.display = 'block';
} }
body {
${bg_css};
}
.size {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
#black {
z-index: 8;
background-color: black;
display: none;
}
#bgimage {
z-index: 1;
}
#image {
z-index: 2;
}
${css_additions}
#footer {
position: absolute;
z-index: 6;
${footer_css}
}
/* lyric css */${lyrics_css}
sup {
font-size: 0.6em;
vertical-align: top;
position: relative;
top: -0.3em;
}
</style>
<script>
var timer = null;
var transition = ${transitions};
${js_additions}
function show_blank(state){ function show_image(src){
var black = 'none'; var img = document.getElementById('image');
var lyrics = ''; img.src = src;
switch(state){ if(src == '')
case 'theme': img.style.display = 'none';
lyrics = 'hidden'; else
break; img.style.display = 'block';
case 'black':
black = 'block';
break;
case 'desktop':
break;
} }
document.getElementById('black').style.display = black;
document.getElementById('lyricsmain').style.visibility = lyrics;
document.getElementById('image').style.visibility = lyrics;
document.getElementById('footer').style.visibility = lyrics;
}
function show_footer(footertext){ function show_blank(state){
document.getElementById('footer').innerHTML = footertext; var black = 'none';
} var lyrics = '';
switch(state){
function show_text(new_text){ case 'theme':
var match = /-webkit-text-fill-color:[^;\"]+/gi; lyrics = 'hidden';
if(timer != null) break;
clearTimeout(timer); case 'black':
/* black = 'block';
QtWebkit bug with outlines and justify causing outline alignment break;
problems. (Bug 859950) Surround each word with a <span> to workaround, case 'desktop':
but only in this scenario. break;
*/
var txt = document.getElementById('lyricsmain');
if(window.getComputedStyle(txt).textAlign == 'justify'){
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
new_text = new_text.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
function(match) {
return '</span>' + match + '<span>';
});
new_text = '<span>' + new_text + '</span>';
} }
document.getElementById('black').style.display = black;
document.getElementById('lyricsmain').style.visibility = lyrics;
document.getElementById('image').style.visibility = lyrics;
document.getElementById('footer').style.visibility = lyrics;
} }
text_fade('lyricsmain', new_text);
}
function text_fade(id, new_text){ function show_footer(footertext){
/* document.getElementById('footer').innerHTML = footertext;
Show the text. }
*/
var text = document.getElementById(id); function show_text(new_text){
if(text == null) return; var match = /-webkit-text-fill-color:[^;\"]+/gi;
if(!transition){ if(timer != null)
clearTimeout(timer);
/*
QtWebkit bug with outlines and justify causing outline alignment
problems. (Bug 859950) Surround each word with a <span> to workaround,
but only in this scenario.
*/
var txt = document.getElementById('lyricsmain');
if(window.getComputedStyle(txt).textAlign == 'justify'){
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
new_text = new_text.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
function(match) {
return '</span>' + match + '<span>';
});
new_text = '<span>' + new_text + '</span>';
}
}
text_fade('lyricsmain', new_text);
}
function text_fade(id, new_text){
/*
Show the text.
*/
var text = document.getElementById(id);
if(text == null) return;
if(!transition){
text.innerHTML = new_text;
return;
}
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
text.style.opacity = '0.1';
// Fade new text in after the old text has finished fading out.
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
}
function _show_text(text, new_text) {
/*
Helper function to show the new_text delayed.
*/
text.innerHTML = new_text; text.innerHTML = new_text;
return; text.style.opacity = '1';
// Wait until the text is completely visible. We want to save the timer id, to be able to call
// clearTimeout(timer) when the text has changed before finishing fading.
timer = window.setTimeout(function(){timer = null;}, 400);
} }
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
text.style.opacity = '0.1';
// Fade new text in after the old text has finished fading out.
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
}
function _show_text(text, new_text) { function show_text_completed(){
/* return (timer == null);
Helper function to show the new_text delayed. }
*/ </script>
text.innerHTML = new_text; </head>
text.style.opacity = '1'; <body>
// Wait until the text is completely visible. We want to save the timer id, to be able to call <img id="bgimage" class="size" ${bg_image} />
// clearTimeout(timer) when the text has changed before finishing fading. <img id="image" class="size" ${image} />
timer = window.setTimeout(function(){timer = null;}, 400); ${html_additions}
} <div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
<div id="footer" class="footer"></div>
function show_text_completed(){ <div id="black" class="size"></div>
return (timer == null); </body>
} </html>
</script> """)
</head>
<body>
<img id="bgimage" class="size" ${bg_image} />
<img id="image" class="size" ${image} />
${html_additions}
<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
<div id="footer" class="footer"></div>
<div id="black" class="size"></div>
</body>
</html>
""")
LYRICS_SRC = Template(""" LYRICS_SRC = Template("""
.lyricstable { .lyricstable {
z-index: 5; z-index: 5;
position: absolute; position: absolute;
display: table; display: table;
${stable} ${stable}
} }
.lyricscell { .lyricscell {
display: table-cell; display: table-cell;
word-wrap: break-word; word-wrap: break-word;
-webkit-transition: opacity 0.4s ease; -webkit-transition: opacity 0.4s ease;
${lyrics} ${lyrics}
} }
.lyricsmain { .lyricsmain {
${main} ${main}
} }
""") """)
FOOTER_SRC = Template(""" FOOTER_SRC = Template("""
left: ${left}px; left: ${left}px;
bottom: ${bottom}px; bottom: ${bottom}px;
width: ${width}px; width: ${width}px;
font-family: ${family}; font-family: ${family};
font-size: ${size}pt; font-size: ${size}pt;
color: ${color}; color: ${color};
text-align: left; text-align: left;
white-space: ${space}; white-space: ${space};
""") """)
LYRICS_FORMAT_SRC = Template(""" LYRICS_FORMAT_SRC = Template("""
${justify}word-wrap: break-word; ${justify}word-wrap: break-word;
text-align: ${align}; text-align: ${align};
vertical-align: ${valign}; vertical-align: ${valign};
font-family: ${font}; font-family: ${font};
font-size: ${size}pt; font-size: ${size}pt;
color: ${color}; color: ${color};
line-height: ${line}%; line-height: ${line}%;
margin: 0; margin: 0;
padding: 0; padding: 0;
padding-bottom: ${bottom}; padding-bottom: ${bottom};
padding-left: ${left}px; padding-left: ${left}px;
width: ${width}px; width: ${width}px;
height: ${height}px;${font_style}${font_weight} height: ${height}px;${font_style}${font_weight}
""") """)
def build_html(item, screen, is_live, background, image=None, plugins=None): def build_html(item, screen, is_live, background, image=None, plugins=None):
@ -737,7 +736,7 @@ def build_lyrics_format_css(theme_data, width, height):
valign = VerticalType.Names[theme_data.display_vertical_align] valign = VerticalType.Names[theme_data.display_vertical_align]
left_margin = (int(theme_data.font_main_outline_size) * 2) if theme_data.font_main_outline else 0 left_margin = (int(theme_data.font_main_outline_size) * 2) if theme_data.font_main_outline else 0
# fix tag incompatibilities # fix tag incompatibilities
justify = '' if (theme_data.display_horizontal_align == HorizontalType.Justify) else 'white-space:pre-wrap;\n' justify = '' if (theme_data.display_horizontal_align == HorizontalType.Justify) else ' white-space: pre-wrap;\n'
padding_bottom = '0.5em' if (theme_data.display_vertical_align == VerticalType.Bottom) else '0' padding_bottom = '0.5em' if (theme_data.display_vertical_align == VerticalType.Bottom) else '0'
return LYRICS_FORMAT_SRC.substitute(justify=justify, return LYRICS_FORMAT_SRC.substitute(justify=justify,
align=align, align=align,
@ -750,8 +749,8 @@ def build_lyrics_format_css(theme_data, width, height):
left=left_margin, left=left_margin,
width=width, width=width,
height=height, height=height,
font_style='\nfont-style:italic;' if theme_data.font_main_italics else '', font_style='\n font-style: italic;' if theme_data.font_main_italics else '',
font_weight='\nfont-weight:bold;' if theme_data.font_main_bold else '') font_weight='\n font-weight: bold;' if theme_data.font_main_bold else '')
def build_footer_css(item, height): def build_footer_css(item, height):

View File

@ -14,201 +14,200 @@ from tests.functional import MagicMock, patch
from tests.helpers.testmixin import TestMixin from tests.helpers.testmixin import TestMixin
HTML = """ HTML = """
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>OpenLP Display</title> <title>OpenLP Display</title>
<style> <style>
*{ *{
margin: 0; margin: 0;
padding: 0; padding: 0;
border: 0; border: 0;
overflow: hidden; overflow: hidden;
-webkit-user-select: none; -webkit-user-select: none;
}
body {
;
}
.size {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
#black {
z-index: 8;
background-color: black;
display: none;
}
#bgimage {
z-index: 1;
}
#image {
z-index: 2;
}
plugin CSS
#footer {
position: absolute;
z-index: 6;
dummy: dummy;
}
/* lyric css */
sup {
font-size: 0.6em;
vertical-align: top;
position: relative;
top: -0.3em;
}
</style>
<script>
var timer = null;
var transition = false;
plugin JS
function show_image(src){
var img = document.getElementById('image');
img.src = src;
if(src == '')
img.style.display = 'none';
else
img.style.display = 'block';
} }
body {
;
}
.size {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
#black {
z-index: 8;
background-color: black;
display: none;
}
#bgimage {
z-index: 1;
}
#image {
z-index: 2;
}
plugin CSS
#footer {
position: absolute;
z-index: 6;
dummy: dummy;
}
/* lyric css */
sup {
font-size: 0.6em;
vertical-align: top;
position: relative;
top: -0.3em;
}
</style>
<script>
var timer = null;
var transition = false;
plugin JS
function show_blank(state){ function show_image(src){
var black = 'none'; var img = document.getElementById('image');
var lyrics = ''; img.src = src;
switch(state){ if(src == '')
case 'theme': img.style.display = 'none';
lyrics = 'hidden'; else
break; img.style.display = 'block';
case 'black':
black = 'block';
break;
case 'desktop':
break;
} }
document.getElementById('black').style.display = black;
document.getElementById('lyricsmain').style.visibility = lyrics;
document.getElementById('image').style.visibility = lyrics;
document.getElementById('footer').style.visibility = lyrics;
}
function show_footer(footertext){ function show_blank(state){
document.getElementById('footer').innerHTML = footertext; var black = 'none';
} var lyrics = '';
switch(state){
function show_text(new_text){ case 'theme':
var match = /-webkit-text-fill-color:[^;"]+/gi; lyrics = 'hidden';
if(timer != null) break;
clearTimeout(timer); case 'black':
/* black = 'block';
QtWebkit bug with outlines and justify causing outline alignment break;
problems. (Bug 859950) Surround each word with a <span> to workaround, case 'desktop':
but only in this scenario. break;
*/
var txt = document.getElementById('lyricsmain');
if(window.getComputedStyle(txt).textAlign == 'justify'){
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
new_text = new_text.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
function(match) {
return '</span>' + match + '<span>';
});
new_text = '<span>' + new_text + '</span>';
} }
document.getElementById('black').style.display = black;
document.getElementById('lyricsmain').style.visibility = lyrics;
document.getElementById('image').style.visibility = lyrics;
document.getElementById('footer').style.visibility = lyrics;
} }
text_fade('lyricsmain', new_text);
}
function text_fade(id, new_text){ function show_footer(footertext){
/* document.getElementById('footer').innerHTML = footertext;
Show the text. }
*/
var text = document.getElementById(id); function show_text(new_text){
if(text == null) return; var match = /-webkit-text-fill-color:[^;"]+/gi;
if(!transition){ if(timer != null)
clearTimeout(timer);
/*
QtWebkit bug with outlines and justify causing outline alignment
problems. (Bug 859950) Surround each word with a <span> to workaround,
but only in this scenario.
*/
var txt = document.getElementById('lyricsmain');
if(window.getComputedStyle(txt).textAlign == 'justify'){
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
new_text = new_text.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
function(match) {
return '</span>' + match + '<span>';
});
new_text = '<span>' + new_text + '</span>';
}
}
text_fade('lyricsmain', new_text);
}
function text_fade(id, new_text){
/*
Show the text.
*/
var text = document.getElementById(id);
if(text == null) return;
if(!transition){
text.innerHTML = new_text;
return;
}
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
text.style.opacity = '0.1';
// Fade new text in after the old text has finished fading out.
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
}
function _show_text(text, new_text) {
/*
Helper function to show the new_text delayed.
*/
text.innerHTML = new_text; text.innerHTML = new_text;
return; text.style.opacity = '1';
// Wait until the text is completely visible. We want to save the timer id, to be able to call
// clearTimeout(timer) when the text has changed before finishing fading.
timer = window.setTimeout(function(){timer = null;}, 400);
} }
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
text.style.opacity = '0.1';
// Fade new text in after the old text has finished fading out.
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
}
function _show_text(text, new_text) { function show_text_completed(){
/* return (timer == null);
Helper function to show the new_text delayed. }
*/ </script>
text.innerHTML = new_text; </head>
text.style.opacity = '1'; <body>
// Wait until the text is completely visible. We want to save the timer id, to be able to call <img id="bgimage" class="size" style="display:none;" />
// clearTimeout(timer) when the text has changed before finishing fading. <img id="image" class="size" style="display:none;" />
timer = window.setTimeout(function(){timer = null;}, 400); plugin HTML
} <div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
<div id="footer" class="footer"></div>
function show_text_completed(){ <div id="black" class="size"></div>
return (timer == null); </body>
} </html>
</script> """
</head>
<body>
<img id="bgimage" class="size" style="display:none;" />
<img id="image" class="size" style="display:none;" />
plugin HTML
<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
<div id="footer" class="footer"></div>
<div id="black" class="size"></div>
</body>
</html>
"""
BACKGROUND_CSS_RADIAL = 'background: -webkit-gradient(radial, 5 50%, 100, 5 50%, 5, from(#000000), to(#FFFFFF)) fixed' BACKGROUND_CSS_RADIAL = 'background: -webkit-gradient(radial, 5 50%, 100, 5 50%, 5, from(#000000), to(#FFFFFF)) fixed'
LYRICS_CSS = """ LYRICS_CSS = """
.lyricstable { .lyricstable {
z-index: 5; z-index: 5;
position: absolute; position: absolute;
display: table; display: table;
left: 10px; top: 20px; left: 10px; top: 20px;
} }
.lyricscell { .lyricscell {
display: table-cell; display: table-cell;
word-wrap: break-word; word-wrap: break-word;
-webkit-transition: opacity 0.4s ease; -webkit-transition: opacity 0.4s ease;
lyrics_format_css lyrics_format_css
} }
.lyricsmain { .lyricsmain {
text-shadow: #000000 5px 5px; text-shadow: #000000 5px 5px;
} }
""" """
LYRICS_OUTLINE_CSS = ' -webkit-text-stroke: 0.125em #000000; -webkit-text-fill-color: #FFFFFF; ' LYRICS_OUTLINE_CSS = ' -webkit-text-stroke: 0.125em #000000; -webkit-text-fill-color: #FFFFFF; '
LYRICS_FORMAT_CSS = """ LYRICS_FORMAT_CSS = """
word-wrap: break-word; word-wrap: break-word;
text-align: justify; text-align: justify;
vertical-align: bottom; vertical-align: bottom;
font-family: Arial; font-family: Arial;
font-size: 40pt; font-size: 40pt;
color: #FFFFFF; color: #FFFFFF;
line-height: 108%; line-height: 108%;
margin: 0; margin: 0;
padding: 0; padding: 0;
padding-bottom: 0.5em; padding-bottom: 0.5em;
padding-left: 2px; padding-left: 2px;
width: 1580px; width: 1580px;
height: 810px; height: 810px;
font-style:italic; font-style: italic;
font-weight:bold; font-weight: bold;
""" """
FOOTER_CSS_BASE = """ FOOTER_CSS_BASE = """
left: 10px; left: 10px;
bottom: 0px; bottom: 0px;
width: 1260px; width: 1260px;
font-family: Arial; font-family: Arial;
font-size: 12pt; font-size: 12pt;
color: #FFFFFF; color: #FFFFFF;
text-align: left; text-align: left;
white-space: %s; white-space: %s;
""" """
FOOTER_CSS = FOOTER_CSS_BASE % ('nowrap') FOOTER_CSS = FOOTER_CSS_BASE % ('nowrap')
FOOTER_CSS_WRAP = FOOTER_CSS_BASE % ('normal') FOOTER_CSS_WRAP = FOOTER_CSS_BASE % ('normal')
FOOTER_CSS_INVALID = '' FOOTER_CSS_INVALID = ''
@ -257,6 +256,8 @@ class Htmbuilder(TestCase, TestMixin):
# WHEN: Create the html. # WHEN: Create the html.
html = build_html(item, screen, is_live, background, plugins=plugins) html = build_html(item, screen, is_live, background, plugins=plugins)
self.maxDiff = None
# THEN: The returned html should match. # THEN: The returned html should match.
self.assertEqual(html, HTML, 'The returned html should match') self.assertEqual(html, HTML, 'The returned html should match')