Revamp the Text library so that there is an explicit Text.Style record

The Style record is needed to allow formatting of text fields!
This commit is contained in:
Evan Czaplicki 2014-03-01 17:26:19 -05:00
parent cc3c8704e2
commit 9723d2d41c
3 changed files with 116 additions and 84 deletions

View file

@ -4,10 +4,9 @@ Elm.Native.Text.make = function(elm) {
elm.Native.Text = elm.Native.Text || {};
if (elm.Native.Text.values) return elm.Native.Text.values;
var JS = Elm.JavaScript.make(elm);
var Utils = Elm.Native.Utils.make(elm);
var Color = Elm.Native.Color.make(elm);
var Element = Elm.Graphics.Element.make(elm);
var List = Elm.Native.List.make(elm);
var Utils = Elm.Native.Utils.make(elm);
var show = Elm.Native.Show.make(elm).show;
function makeSpaces(s) {
@ -51,13 +50,58 @@ Elm.Native.Text.make = function(elm) {
return arr.join('<br/>');
}
function toText(str) { return Utils.txt(properEscape(JS.fromString(str))); }
function toText(str) { return Utils.txt(properEscape(str)); }
// conversions from Elm values to CSS
function toTypefaces(list) {
var typefaces = List.toArray(list);
for (var i = typefaces.length; i--; ) {
var typeface = typefaces[i];
if (typeface.contains(' ')) {
typefaces[i] = "'" + typeface + "'";
}
}
return typefaces.join(',');
}
function toLine(line) {
var ctor = line.ctor;
var decoration = ctor === 'Under' ? 'underline' :
ctor === 'Over' ? 'overline' : 'line-through';
return 'text-decoration:' + decoration + ';';
}
function toColor(c) {
var color = (c._3 === 1)
? ('rgb(' + c._0 + ', ' + c._1 + ', ' + c._2 + ')')
: ('rgba(' + c._0 + ', ' + c._1 + ', ' + c._2 + ', ' + c._3 + ')');
return 'color:' + color + ';';
}
// setting styles of Text
function style(style, text) {
var newText = '<span style="' + toColor(style.color);
if (style.typeface.ctor !== '[]') {
newText += 'font-family:' + toTypefaces(style.typeface) + ';'
}
if (style.height.ctor !== "Nothing") {
newText += 'font-size:' + style.height._0 + 'px;';
}
if (style.bold) {
newText += 'font-weight:bold;';
}
if (style.italic) {
newText += 'font-style:italic;';
}
if (style.line.ctor !== 'Nothing') {
newText += toLine(style.line._0);
}
newText += '">' + Utils.makeText(text) + '</span>'
return Utils.txt(newText);
}
function height(px, text) {
return { style: 'font-size:' + px + 'px;', text:text }
}
function typeface(name, text) {
return { style: 'font-family:' + name + ';', text:text }
function typeface(names, text) {
return { style: 'font-family:' + toTypefaces(names) + ';', text:text }
}
function monospace(text) {
return { style: 'font-family:monospace;', text:text }
@ -71,14 +115,8 @@ Elm.Native.Text.make = function(elm) {
function link(href, text) {
return { href: toText(href), text:text };
}
function underline(text) {
return { line: ' underline', text:text };
}
function overline(text) {
return { line: ' overline', text:text };
}
function strikeThrough(text) {
return { line: ' line-through', text:text };
function line(line, text) {
return { style: toLine(line), text:text };
}
function color(c, text) {
@ -88,8 +126,8 @@ Elm.Native.Text.make = function(elm) {
return { style: 'color:' + color + ';', text:text };
}
function position(align) {
function create(text) {
function block(align) {
return function(text) {
var raw = {
ctor :'RawHtml',
html : Utils.makeText(text),
@ -100,7 +138,6 @@ Elm.Native.Text.make = function(elm) {
var pos = A2(Utils.htmlHeight, 0, raw);
return A3(Element.newElement, pos._0, pos._1, raw);
}
return create;
}
function markdown(text, guid) {
@ -115,36 +152,22 @@ Elm.Native.Text.make = function(elm) {
return A3(Element.newElement, pos._0, pos._1, raw);
}
var text = position('left');
function asText(v) {
return text(monospace(toText(show(v))));
}
function plainText(v) {
return text(toText(v));
}
return elm.Native.Text.values = {
toText: toText,
height : F2(height),
italic : italic,
bold : bold,
underline : underline,
overline : overline,
strikeThrough : strikeThrough,
line : F2(line),
monospace : monospace,
typeface : F2(typeface),
color : F2(color),
link : F2(link),
justified : position('justify'),
centered : position('center'),
righted : position('right'),
text : text,
plainText : plainText,
markdown : markdown,
asText : asText,
leftAligned : block('left'),
rightAligned : block('right'),
centered : block('center'),
justified : block('justify'),
markdown : markdown,
};
};

View file

@ -76,14 +76,8 @@ Elm.Native.Utils.make = function(elm) {
function makeText(text) {
var style = '';
var line = '';
var href = '';
while (true) {
if (text.line) {
line += text.line;
text = text.text;
continue;
}
if (text.style) {
style += text.style;
text = text.text;
@ -95,7 +89,6 @@ Elm.Native.Utils.make = function(elm) {
continue;
}
if (href) text = '<a href="' + href + '">' + text + '</a>';
if (line) style += 'text-decoration:' + line + ';';
if (style) text = '<span style="' + style + '">' + text + '</span>';
return text;
}

View file

@ -6,13 +6,21 @@ module Text where
@docs toText
# Creating Elements
@docs plainText, asText, text, centered, justified, righted
@docs leftAligned, rightAligned, centered, justified
# Formatting
@docs color, typeface, height, link
# Style and Links
@docs Style, style, Line, link
# Simple Formatting
@docs monospace, bold, italic, underline, overline, strikeThrough
# Convenience Functions
There are two convenience functions for creating an `Element` which can be
useful when debugging or prototyping:
@docs plainText, asText
There are also a bunch of functions to set parts of a `Style` individually:
@docs typeface, monospace, height, color, bold, italic, line
-}
@ -25,75 +33,82 @@ import Native.Text
data Text = Text
data Line = Under | Over | Through
{-| Representation of all the ways you can style `Text`.
-}
type Style =
{ typeface : [String]
, height : Maybe Float
, color : Color
, bold : Bool
, italic : Bool
, line : Maybe Line
}
{-| Convert a string into text which can be styled and displayed. -}
toText : String -> Text
toText = Native.Text.toText
{-| Set the typeface of some text. The first argument should be a comma
separated listing of the desired typefaces:
"helvetica, arial, sans-serif"
Works the same as the CSS font-family property.
{-| Set the style of some text.
-}
typeface : String -> Text -> Text
style : Style -> Text -> Text
style = Native.Text.style
{-| Provide a list of prefered typefaces for some text.
["helvetica","arial","sans-serif"]
Not everyone has access to the same typefaces, so rendering will use the first
typeface in the list that is found on the user's computer. If there are no
matches, it will use their default typeface. Works the same as the CSS
font-family property.
-}
typeface : [String] -> Text -> Text
typeface = Native.Text.typeface
{-| Switch to a monospace typeface. Good for code snippets. -}
monospace : Text -> Text
monospace = Native.Text.monospace
{-| Create a link. -}
{-| Create a link.
link "http://elm-lang.org" (toText "Elm Website")
-}
link : String -> Text -> Text
link = Native.Text.link
{-| Set the height of text in pixels. -}
height : Float -> Text -> Text
height = Native.Text.height
{-| Set the color of a string. -}
color : Color -> Text -> Text
color = Native.Text.color
{-| Make a string bold. -}
bold : Text -> Text
bold = Native.Text.bold
{-| Italicize a string. -}
italic : Text -> Text
italic = Native.Text.italic
{-| Draw a line above a string. -}
overline : Text -> Text
overline = Native.Text.overline
line : Line -> Text -> Text
line = Native.Text.line
{-| Underline a string. -}
underline : Text -> Text
underline = Native.Text.underline
leftAligned : Text -> Element
leftAligned = Native.Text.leftAligned
{-| Draw a line through a string. -}
strikeThrough : Text -> Text
strikeThrough = Native.Text.strikeThrough
rightAligned : Text -> Element
rightAligned = Native.Text.rightAligned
{-| Display justified, styled text. -}
justified : Text -> Element
justified = Native.Text.justified
{-| Display centered, styled text. -}
centered : Text -> Element
centered = Native.Text.centered
{-| Display right justified, styled text. -}
righted : Text -> Element
righted = Native.Text.righted
{-| Display styled text. -}
text : Text -> Element
text = Native.Text.text
justified : Text -> Element
justified = Native.Text.justified
{-| Display a plain string. -}
plainText : String -> Element
plainText = Native.Text.plainText
plainText str =
leftAligned (toText str)
{-| for internal use only -}
markdown : Element
@ -107,4 +122,5 @@ the browser:
Excellent for debugging.
-}
asText : a -> Element
asText = Native.Text.asText
asText value =
leftAligned (monospace (toText (show value)))