New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text module Refactoring *WIP* #161

Closed
wants to merge 3 commits into
base: master
from

Conversation

Projects
None yet
2 participants
@jazmit
Contributor

jazmit commented Feb 6, 2015

WIP on Text refactoring. Anyone interested is welcome to comment and advise.
The idea is to normalize the internal representation of Text objects to {Array.<{text: string, style: Object.<string, string}>}. The keys and values of the style object will still be valid CSS keys and values, but this will make it easier to manipalate text objects without resorting to using the DOM API.
I've put a TODO by every function I think needs to change.

TODO

  • Add tests for Text module
  • Change Text representation
  • Move text-related functions from Util to Text
  • Add comments for Text module
@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Feb 6, 2015

Member

I'm not sure what you have proposed as the data structure, but I think it'd be best to model it like any other union type in elm:

type Text = Literal String | Styled String String Text | Append Text Text

You can do all that in JS and mess with it to make it more efficient, but I'd think of like a union type.

Another thing to think about is how to get toString to still work.

Member

evancz commented Feb 6, 2015

I'm not sure what you have proposed as the data structure, but I think it'd be best to model it like any other union type in elm:

type Text = Literal String | Styled String String Text | Append Text Text

You can do all that in JS and mess with it to make it more efficient, but I'd think of like a union type.

Another thing to think about is how to get toString to still work.

@jazmit

This comment has been minimized.

Show comment
Hide comment
@jazmit

jazmit Feb 7, 2015

Contributor

Ah.. lightbulb.. I was wondering why everything was implemented as linked lists.. so maybe we should keep the current representation but just replace the current CSS string with [key, value] pairs?

Contributor

jazmit commented Feb 7, 2015

Ah.. lightbulb.. I was wondering why everything was implemented as linked lists.. so maybe we should keep the current representation but just replace the current CSS string with [key, value] pairs?

@jazmit

This comment has been minimized.

Show comment
Hide comment
@jazmit

jazmit Feb 7, 2015

Owner

Is this the way to go for testing otherwise 'opaque' modules such as Text?

Owner

jazmit commented on tests/Native/Test/Text.js in 4625757 Feb 7, 2015

Is this the way to go for testing otherwise 'opaque' modules such as Text?

@jazmit

This comment has been minimized.

Show comment
Hide comment
@jazmit

jazmit Feb 7, 2015

Contributor

toString on a Text object returns "" for me.. is this intended behaviour?

Contributor

jazmit commented Feb 7, 2015

toString on a Text object returns "" for me.. is this intended behaviour?

Show outdated Hide outdated tests/Native/Test/Text.js
Elm.Native.Test.Text.make = function(localRuntime) {
localRuntime.Native = localRuntime.Native || {};
localRuntime.Native.Test = localRuntime.Native.Test || {};
localRuntime.Native.Test.Text = localRuntime.Native.Test.Text || {};

This comment has been minimized.

@evancz

evancz Feb 8, 2015

Member

Don't do this aligning stuff. It's really frail. When any line changes, lots of things need to change. Not worth it in the long run!

@evancz

evancz Feb 8, 2015

Member

Don't do this aligning stuff. It's really frail. When any line changes, lots of things need to change. Not worth it in the long run!

Show outdated Hide outdated tests/Native/Test/Text.js
localRuntime.Native.Test.Text = localRuntime.Native.Test.Text || {};
if (localRuntime.Native.Test.Text.values)
return localRuntime.Native.Test.Text.values;

This comment has been minimized.

@evancz

evancz Feb 8, 2015

Member

Always use curly braces!

@evancz

evancz Feb 8, 2015

Member

Always use curly braces!

Show outdated Hide outdated tests/Test/Text.elm
tests : Test
tests = suite "Text Tests"

This comment has been minimized.

@evancz

evancz Feb 8, 2015

Member

Always bring the definition down a line:

tests =
  suite "Text Tests"
    [ ...
    ]
@evancz

evancz Feb 8, 2015

Member

Always bring the definition down a line:

tests =
  suite "Text Tests"
    [ ...
    ]
Show outdated Hide outdated tests/Test/Text.elm
]
toHtmlString : Text -> String
toHtmlString = Native.Test.Text.textToHtmlString

This comment has been minimized.

@evancz

evancz Feb 8, 2015

Member

Same here, always bring it down.

@evancz

evancz Feb 8, 2015

Member

Same here, always bring it down.

Show outdated Hide outdated tests/Test/Text.elm
testFromString : Test
testFromString =
let result = toHtmlString (fromString "Hello")
in test "simple" <| assertEqual "Hello" result

This comment has been minimized.

@evancz

evancz Feb 8, 2015

Member
testFromString =
  let result = toHtmlString (fromString "Hello")
  in
      test "simple" <| assertEqual "Hello" result 
@evancz

evancz Feb 8, 2015

Member
testFromString =
  let result = toHtmlString (fromString "Hello")
  in
      test "simple" <| assertEqual "Hello" result 
@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Feb 8, 2015

Member

I am unsure about how to ideally test this. If it is represented directly as a Union Type in Elm, we can run tests by making sure it's the value we expect. Perhaps we can do it this way and add a "secret" tag that only toString looks for. That'd mean making a special Union Type in JS:

function append(text1, text2) {
    return {
        ctor: 'Append',
        _0: text1,
        _1: text2,
        isText: true
    };
}

So it'll look like a union type to all of Elm, but when toString looks at it, it can check for isText.

And yes, I made it <internal structure> on purpose. It was not clear to me what the "right" way to visualize it given that it really is not a string and that Text.fromString "hello" is not the same as Text.bold (Text.fromString "hello"). I don't really know the right answer here, but I don't feel that we should expose the internal structure. What do you think?

Also, we were talking about moving some Text functions around. Might be something to consider here.

Member

evancz commented Feb 8, 2015

I am unsure about how to ideally test this. If it is represented directly as a Union Type in Elm, we can run tests by making sure it's the value we expect. Perhaps we can do it this way and add a "secret" tag that only toString looks for. That'd mean making a special Union Type in JS:

function append(text1, text2) {
    return {
        ctor: 'Append',
        _0: text1,
        _1: text2,
        isText: true
    };
}

So it'll look like a union type to all of Elm, but when toString looks at it, it can check for isText.

And yes, I made it <internal structure> on purpose. It was not clear to me what the "right" way to visualize it given that it really is not a string and that Text.fromString "hello" is not the same as Text.bold (Text.fromString "hello"). I don't really know the right answer here, but I don't feel that we should expose the internal structure. What do you think?

Also, we were talking about moving some Text functions around. Might be something to consider here.

@jazmit

This comment has been minimized.

Show comment
Hide comment
@jazmit

jazmit Feb 8, 2015

Contributor

I think exposing type Text = Literal String | Styled String String Text | Append Text Text is probably not such a frightening idea.. after all I would think we'd want it to be possible to manipulate and process Text values from client code without depending on Native modules. However, this can be left for another pull request, as it won't necessarily make for great tests - they'd turn out kinda tautological:

assertEqual (Text.append text1 text2) (Append text1 text2)

If we're testing conversion to and from another format I'd be more confident that code changes aren't breaking anything. Since it's not outrageous that we might one day provide a toHtmlString : Text -> String function, I think that continuing with the current approach is probably OK. If one day this function does exist it just requires changing one line of the test.

Contributor

jazmit commented Feb 8, 2015

I think exposing type Text = Literal String | Styled String String Text | Append Text Text is probably not such a frightening idea.. after all I would think we'd want it to be possible to manipulate and process Text values from client code without depending on Native modules. However, this can be left for another pull request, as it won't necessarily make for great tests - they'd turn out kinda tautological:

assertEqual (Text.append text1 text2) (Append text1 text2)

If we're testing conversion to and from another format I'd be more confident that code changes aren't breaking anything. Since it's not outrageous that we might one day provide a toHtmlString : Text -> String function, I think that continuing with the current approach is probably OK. If one day this function does exist it just requires changing one line of the test.

@jazmit

This comment has been minimized.

Show comment
Hide comment
@jazmit

jazmit Feb 8, 2015

Contributor

I'll have a think about moving the asText function to the Element module.

Contributor

jazmit commented Feb 8, 2015

I'll have a think about moving the asText function to the Element module.

@jazmit

This comment has been minimized.

Show comment
Hide comment
@jazmit

jazmit Feb 8, 2015

Contributor

Any objections to pulling in the Elm QuickCheck library to help with the testing here?

Contributor

jazmit commented Feb 8, 2015

Any objections to pulling in the Elm QuickCheck library to help with the testing here?

evancz pushed a commit that referenced this pull request Feb 22, 2015

Do Text representation refactor described in #161
@jazmit, please take a look and see if everything looks okay! I’m
getting this branch ready to demo and want everything to be working, so
I took a swing at this.
@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Feb 22, 2015

Member

Okay, things should be refactored now. Not sure about speed, but at least we are no longer going through HTML in the Collage code!

I think we need to look into how \n behaves in Text rendered to the collage? My guess is badly.

I don't mind about elm-check, but I think do that kind of thing separate from the Text stuff.

Member

evancz commented Feb 22, 2015

Okay, things should be refactored now. Not sure about speed, but at least we are no longer going through HTML in the Collage code!

I think we need to look into how \n behaves in Text rendered to the collage? My guess is badly.

I don't mind about elm-check, but I think do that kind of thing separate from the Text stuff.

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz Feb 22, 2015

Member

As an aside, this whole addition is really cool :) I was testing it out to make sure everything was in order, and it was very fun!

Member

evancz commented Feb 22, 2015

As an aside, this whole addition is really cool :) I was testing it out to make sure everything was in order, and it was very fun!

@evancz

This comment has been minimized.

Show comment
Hide comment
@evancz

evancz May 11, 2016

Member

All the Graphics.* modules have moved to evancz/elm-graphics so it makes sense to retarget stuff like this. That module also did get refactored for this change and I think it's a lot nicer.

Member

evancz commented May 11, 2016

All the Graphics.* modules have moved to evancz/elm-graphics so it makes sense to retarget stuff like this. That module also did get refactored for this change and I think it's a lot nicer.

@evancz evancz closed this May 11, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment