diff --git a/composition/content_merge.go b/composition/content_merge.go index f3c1fee..e06dd7a 100644 --- a/composition/content_merge.go +++ b/composition/content_merge.go @@ -5,7 +5,6 @@ import ( "errors" "io" "strings" - "fmt" ) const ( @@ -34,9 +33,6 @@ type ContentMerge struct { // merge priorities for the content objects // no entry means priority == 0 priorities map[Content]int - - // all stylesheets contained in used fragments - stylesheets []string } // NewContentMerge creates a new buffered ContentMerge @@ -53,87 +49,59 @@ func NewContentMerge(metaJSON map[string]interface{}) *ContentMerge { return cntx } -func (cntx *ContentMerge) collectStylesheets(f Fragment) { - cntx.stylesheets = append(cntx.stylesheets, f.Stylesheets()...) -} - -func (cntx *ContentMerge) writeStylesheets(w io.Writer) { - for _, href := range cntx.stylesheets { - stylesheet := fmt.Sprintf("\n ", href) - io.WriteString(w, stylesheet) +func (cntx *ContentMerge) GetHtml() ([]byte, error) { + if len(cntx.priorities) > 0 { + cntx.processMetaPriorityParsing() } -} + w := bytes.NewBuffer(make([]byte, 0, DefaultBufferSize)) -func generateExecutionFunction(cntx *ContentMerge, w io.Writer) (executeFragment func(fragmentName string) error) { + var executeFragment func(fragmentName string) error executeFragment = func(fragmentName string) error { f, exist := cntx.GetBodyFragmentByName(fragmentName) if !exist { missingFragmentString := generateMissingFragmentString(cntx.Body, fragmentName) return errors.New(missingFragmentString) } - cntx.collectStylesheets(f) return f.Execute(w, cntx.MetaJSON, executeFragment) } - return executeFragment -} -func (cntx *ContentMerge) GetHtml() ([]byte, error) { - - if len(cntx.priorities) > 0 { - cntx.processMetaPriorityParsing() - } - - // start header, but don't close it. We will add stylsheets later on - header := bytes.NewBuffer(make([]byte, 0, DefaultBufferSize)) - io.WriteString(header, "\n\n \n ") + io.WriteString(w, "\n\n \n ") for _, f := range cntx.Head { - cntx.collectStylesheets(f) - executeFragment := generateExecutionFunction(cntx, header) - if err := f.Execute(header, cntx.MetaJSON, executeFragment); err != nil { + if err := f.Execute(w, cntx.MetaJSON, executeFragment); err != nil { return nil, err } } + io.WriteString(w, "\n \n \n ") + io.WriteString(w, ">\n ") startFragmentName := "" if _, exist := cntx.GetBodyFragmentByName(LayoutFragmentName); exist { startFragmentName = LayoutFragmentName } - // recursively process body fragments - executeFragment := generateExecutionFunction(cntx, body) if err := executeFragment(startFragmentName); err != nil { return nil, err } for _, f := range cntx.Tail { - cntx.collectStylesheets(f) - if err := f.Execute(body, cntx.MetaJSON, executeFragment); err != nil { + if err := f.Execute(w, cntx.MetaJSON, executeFragment); err != nil { return nil, err } } - io.WriteString(body, "\n \n\n") - // write the collected stylesheets to the header and close it - cntx.writeStylesheets(header) - io.WriteString(header, "\n ") + io.WriteString(w, "\n \n\n") - // return concatenated header and body - html := append(header.Bytes(), body.Bytes()...) - return html, nil + return w.Bytes(), nil } // GetBodyFragmentByName returns a fragment by ists name. diff --git a/composition/content_merge_test.go b/composition/content_merge_test.go index 06e732b..76fa923 100644 --- a/composition/content_merge_test.go +++ b/composition/content_merge_test.go @@ -15,8 +15,6 @@ func Test_ContentMerge_PositiveCase(t *testing.T) { - - @@ -38,7 +36,6 @@ func Test_ContentMerge_PositiveCase(t *testing.T) { `) - body.AddStylesheets([]string{"/abc/def", "/üst/das/möglich"}) cm := NewContentMerge(nil) cm.AddContent(&MemoryContent{ @@ -78,14 +75,6 @@ func Test_ContentMerge_BodyCompositionWithExplicitNames(t *testing.T) { - - - - - - - - @@ -99,48 +88,32 @@ func Test_ContentMerge_BodyCompositionWithExplicitNames(t *testing.T) { cm := NewContentMerge(nil) - body := NewStringFragment( + cm.AddContent(&MemoryContent{ + name: LayoutFragmentName, + body: map[string]Fragment{ + "": NewStringFragment( ` §[> page2-a]§ §[> example1.com#page2-b]§ §[> page3-a]§ - `) - body.AddStylesheets([]string{"/body/first", "/body/second"}) - cm.AddContent(&MemoryContent{ - name: LayoutFragmentName, - body: map[string]Fragment{ - "": body}}, 0) - - page2A := NewStringFragment("") - page2A.AddStylesheets([]string{"/page/2A/first", "/page/2A/second"}) - page2B := NewStringFragment("") - page2B.AddStylesheets([]string{"/page/2B/first", "/page/2B/second"}) - - // this fragment is not rendered, so it's stylesheets should not appear in page header - pageUnreferenced := NewStringFragment("") - pageUnreferenced.AddStylesheets([]string{"/unreferenced/first", "/unreferenced/second"}) + `)}}, 0) cm.AddContent(&MemoryContent{ name: "example1.com", body: map[string]Fragment{ - "page2-a": page2A, - "page2-b": page2B, - "unreferenced": pageUnreferenced, + "page2-a": NewStringFragment(""), + "page2-b": NewStringFragment(""), }}, 0) - page3A := NewStringFragment("") - page3A.AddStylesheets([]string{"/page/3A/first", "/page/3A/second"}) cm.AddContent(&MemoryContent{ name: "example2.com", body: map[string]Fragment{ - "page3-a": page3A, + "page3-a": NewStringFragment(""), }}, 0) html, err := cm.GetHtml() a.NoError(err) - expected = removeTabsAndNewLines(expected) - result := removeTabsAndNewLines(string(html)) - a.Equal(expected, result) + a.Equal(expected, string(html)) } func Test_ContentMerge_LookupByDifferentFragmentNames(t *testing.T) { diff --git a/composition/discovered_fetch_definition_test.go b/composition/discovered_fetch_definition_test.go index 0b2cf71..e7409d8 100644 --- a/composition/discovered_fetch_definition_test.go +++ b/composition/discovered_fetch_definition_test.go @@ -24,4 +24,4 @@ func Test_FetchDefinition_DiscoveredByError(t *testing.T) { a.Panics(func() { testSubject.DiscoveredBy("a") }) -} +} \ No newline at end of file diff --git a/composition/html_content_parser.go b/composition/html_content_parser.go index adb8536..917b108 100644 --- a/composition/html_content_parser.go +++ b/composition/html_content_parser.go @@ -51,7 +51,6 @@ func (parser *HtmlContentParser) Parse(c *MemoryContent, in io.Reader) error { } func (parser *HtmlContentParser) parseHead(z *html.Tokenizer, c *MemoryContent) error { - var stylesheets []string attrs := make([]html.Attribute, 0, 10) headBuff := bytes.NewBuffer(nil) @@ -78,10 +77,6 @@ forloop: } continue } - if href, isStylesheed := getStylesheet(tag, attrs); isStylesheed { - stylesheets = append(stylesheets, href) - continue - } case tt == html.EndTagToken: if string(tag) == "head" { break forloop @@ -92,24 +87,13 @@ forloop: s := headBuff.String() st := strings.Trim(s, " \n") - if len(st) > 0 || len(stylesheets) > 0 { - frg := NewStringFragment(st) - frg.AddStylesheets(stylesheets) - c.head = frg + if len(st) > 0 { + c.head = NewStringFragment(st) } return nil } -func getStylesheet(tag []byte, attrs []html.Attribute) (href string, isStylesheet bool) { - if string(tag) == "link" && attrHasValue(attrs, "rel", "stylesheet") { - href, _ := getAttr(attrs, "href") - return href.Val, true - } - return "", false -} - func (parser *HtmlContentParser) parseBody(z *html.Tokenizer, c *MemoryContent) error { - var stylesheets []string attrs := make([]html.Attribute, 0, 10) bodyBuff := bytes.NewBuffer(nil) @@ -177,10 +161,6 @@ forloop: continue } } - if href, isStylesheed := getStylesheet(tag, attrs); isStylesheed { - stylesheets = append(stylesheets, href) - continue - } case tt == html.EndTagToken: if string(tag) == "body" { @@ -192,10 +172,8 @@ forloop: s := bodyBuff.String() if _, defaultFragmentExists := c.body[""]; !defaultFragmentExists { - if st := strings.Trim(s, " \n"); len(st) > 0 || len(stylesheets) > 0 { - frg := NewStringFragment(st) - frg.AddStylesheets(stylesheets) - c.body[""] = frg + if st := strings.Trim(s, " \n"); len(st) > 0 { + c.body[""] = NewStringFragment(st) } } @@ -203,7 +181,6 @@ forloop: } func parseFragment(z *html.Tokenizer) (f Fragment, dependencies map[string]Params, err error) { - var stylesheets []string attrs := make([]html.Attribute, 0, 10) dependencies = make(map[string]Params) @@ -239,11 +216,6 @@ forloop: continue } - if href, isStylesheed := getStylesheet(tag, attrs); isStylesheed { - stylesheets = append(stylesheets, href) - continue - } - case tt == html.EndTagToken: if string(tag) == UicFragment || string(tag) == UicTail { break forloop @@ -252,9 +224,7 @@ forloop: buff.Write(raw) } - frg := NewStringFragment(buff.String()) - frg.AddStylesheets(stylesheets) - return frg, dependencies, nil + return NewStringFragment(buff.String()), dependencies, nil } func getInclude(z *html.Tokenizer, attrs []html.Attribute) (startMarker, endMarker, dependencyName string, dependencyParams Params, error error) { diff --git a/composition/html_content_parser_test.go b/composition/html_content_parser_test.go index c6e01cc..94be43a 100644 --- a/composition/html_content_parser_test.go +++ b/composition/html_content_parser_test.go @@ -356,73 +356,6 @@ func Test_HtmlContentParser_parseHead(t *testing.T) { a.Equal("bar", c.Meta()["foo"]) } - -func Test_HtmlContentParser_collectStylesheets_bodyAsDefaultFragment(t *testing.T) { - a := assert.New(t) - - parser := &HtmlContentParser{} - z := bytes.NewBufferString(` - - - - - - -
- - - - Bli Bla blub - - -
- -`) - - c := NewMemoryContent() - err := parser.Parse(c, z) - a.NoError(err) - a.Equal([]string{"/basketservice/stylesheets/main-93174ed18d.css"}, - c.Body()["content"].Stylesheets()) - a.Equal([]string{"/productservice/stylesheets/main-93174ed18d.css"}, - c.Body()[""].Stylesheets()) -} - -func Test_HtmlContentParser_collectStylesheets_OverrideDefault(t *testing.T) { - a := assert.New(t) - - parser := &HtmlContentParser{} - z := bytes.NewBufferString(` - - - - - - -
- - - - Bli Bla blub - - - - Bli Bla blub - - -
- -`) - - c := NewMemoryContent() - err := parser.Parse(c, z) - a.NoError(err) - a.Equal([]string{"/basketservice/stylesheets/main-93174ed18d.css"}, - c.Body()["content"].Stylesheets()) - a.Equal([]string{"/override/stylesheets/main-93174ed18d.css"}, - c.Body()[""].Stylesheets()) -} - func Test_HtmlContentParser_parseBody(t *testing.T) { a := assert.New(t) @@ -558,9 +491,6 @@ func Test_HtmlContentParser_parseBody_DefaultFragmentOverwritten(t *testing.T) {

Default Fragment Content


Overwritten - - - Unused `)) @@ -569,9 +499,8 @@ func Test_HtmlContentParser_parseBody_DefaultFragmentOverwritten(t *testing.T) { err := parser.parseBody(z, c) a.NoError(err) - a.Equal(2, len(c.Body())) + a.Equal(1, len(c.Body())) eqFragment(t, "Overwritten", c.Body()[""]) - eqFragment(t, "Unused", c.Body()["content"]) } func Test_HtmlContentParser_parseHead_JsonError(t *testing.T) { @@ -596,8 +525,7 @@ func Test_HtmlContentParser_parseFragment(t *testing.T) { z := html.NewTokenizer(bytes.NewBufferString(` Bli Bla blub - -
+
@@ -613,7 +541,6 @@ func Test_HtmlContentParser_parseFragment(t *testing.T) { a.NoError(err) expected := `Bli Bla blub -
§[> example.com/foo#content]§ §[#> example.com/optional#content]§§[/example.com/optional#content]§ @@ -624,8 +551,6 @@ func Test_HtmlContentParser_parseFragment(t *testing.T) { z.Next() endTag, _ := z.TagName() a.Equal("testend", string(endTag)) - a.Equal("/navigationservice/stylesheets/main-93174ed18d.css", f.Stylesheets()[0]) - a.Equal(1, len(f.Stylesheets())) } // Regression test: to ensure, that escaped entities in attributes do not lead to a problem. @@ -663,7 +588,6 @@ func Test_HtmlContentParser_parseMetaJson(t *testing.T) { a.NoError(err) a.Equal("bar", c.Meta()["foo"]) - a.Equal("bazz", c.Meta()["boo"]) } func Test_HtmlContentParser_parseMetaJson_Errors(t *testing.T) { @@ -742,7 +666,7 @@ func eqFragment(t *testing.T, expected string, f Fragment) { expectedStripped = strings.Replace(expectedStripped, "\n", "", -1) if expectedStripped != sfStripped { - t.Error("Fragment is not equal: \nexpected: ", expected, "\nactual: ", sf) + t.Error("Fragment is not equal: \nexpected: ", expected, "\nactual: ", sf) } } diff --git a/composition/interfaces.go b/composition/interfaces.go index 4c9c478..ea8eb11 100644 --- a/composition/interfaces.go +++ b/composition/interfaces.go @@ -15,9 +15,6 @@ type Fragment interface { // MemorySize return the estimated size in bytes, for this object in memory MemorySize() int - - // Return the list of stylesheets used in this fragment - Stylesheets() []string } type ContentLoader interface { diff --git a/composition/string_fragment.go b/composition/string_fragment.go index d844ab9..640321c 100644 --- a/composition/string_fragment.go +++ b/composition/string_fragment.go @@ -6,34 +6,24 @@ import ( // StringFragment is a simple template based representation of a fragment. type StringFragment struct { - content string - stylesheets []string + content string } func NewStringFragment(c string) *StringFragment { - return &StringFragment{ - content: c, - stylesheets: nil, + return &StringFragment { + content: c, } } -func (f *StringFragment) Content() string { +func (f StringFragment) Content() string { return f.content } -func (f *StringFragment) Stylesheets() []string { - return f.stylesheets -} - -func (f *StringFragment) AddStylesheets(stylesheets []string) { - f.stylesheets = append(f.stylesheets, stylesheets...) -} - -func (f *StringFragment) Execute(w io.Writer, data map[string]interface{}, executeNestedFragment func(nestedFragmentName string) error) error { +func (f StringFragment) Execute(w io.Writer, data map[string]interface{}, executeNestedFragment func(nestedFragmentName string) error) error { return executeTemplate(w, f.Content(), data, executeNestedFragment) } // MemorySize return the estimated size in bytes, for this object in memory -func (f *StringFragment) MemorySize() int { +func (f StringFragment) MemorySize() int { return len(f.content) } diff --git a/composition/string_fragment_test.go b/composition/string_fragment_test.go index 6d195a3..d159790 100644 --- a/composition/string_fragment_test.go +++ b/composition/string_fragment_test.go @@ -10,8 +10,6 @@ func Test_StringFragment(t *testing.T) { a := assert.New(t) f := NewStringFragment("§[foo]§") - f.AddStylesheets([]string{"/abc/def", "ghi/xyz"}) - a.Equal([]string{"/abc/def", "ghi/xyz"}, f.Stylesheets()) buf := bytes.NewBufferString("") err := f.Execute(buf, map[string]interface{}{"foo": "bar"}, nil) a.NoError(err) diff --git a/composition_example/expected_test_result.html b/composition_example/expected_test_result.html index a637680..fb29f4e 100644 --- a/composition_example/expected_test_result.html +++ b/composition_example/expected_test_result.html @@ -1,18 +1,7 @@ - - - - - - - - - - - - + @@ -22,11 +11,10 @@
- The Subheader
- -
This is a dynamic teaser for id t001
+ +
This is a dynamic teaser for id t001

    diff --git a/composition_example/static/basic.html b/composition_example/static/basic.html index 809beeb..f3cbcf5 100644 --- a/composition_example/static/basic.html +++ b/composition_example/static/basic.html @@ -1,15 +1,12 @@ - +

    Basic Web Elements

    The Header

    - - -
    The Header: §[header_text]§
    @@ -18,7 +15,6 @@

    The Header

    The Subheader

    - The Subheader
    @@ -27,7 +23,6 @@

    The Footer


    The footer -
    diff --git a/composition_example/static/layout.html b/composition_example/static/layout.html index 6d466b8..06ff77b 100644 --- a/composition_example/static/layout.html +++ b/composition_example/static/layout.html @@ -1,10 +1,8 @@ -

    This is the basic layout

    - @@ -12,6 +10,5 @@

    This is the basic layout

    - diff --git a/composition_example/static/styles.html b/composition_example/static/styles.html index 9a28d6a..553e776 100644 --- a/composition_example/static/styles.html +++ b/composition_example/static/styles.html @@ -1,6 +1,6 @@ - +

    This file only defines some styles and generic javascript for the head.

    @@ -11,7 +11,6 @@

    This file only defines some styles and generic javascript for the head.

    $('
    some dynamic text at the end
    ').appendTo('body'); }) -