You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Bård Magnus Kvalheim <ma...@kvalheim.eu> on 2013/10/01 10:11:57 UTC

Re: [5.4.22] Possible issue with Element#attribute for css class. -> Class is replaced and not added

Okay, so just a short update this morning.

Stepping through I can see while writing the attribute value that:

before writing the 'state' is:
<div class="tab-pane" id="choose">

After writing attribute, it makes it a 'duplicate' class attribute
cnt.attribute("class", "active") -> <div *class="active" class="tab-pane*"
id="choose">

then final markup is (somewhere the class attribute with empty namespace
got removed):
<div *class="active"* id="choose">


Come to think about it I think I've seen cases of duplicate class
attributes prior to 5.4 (5.2/3) as well which also ended up in final markup.

The class attribute to add have a *null namespace* - while the existing
class attribute have a *empty namespace*.
As expected - if I step through and change the attribute namespace (of
existing class attribute) to null, then all 'checks pass' and the class
value is added correctly
<div class="tab-pane active" id="choose">


I'm still not sure if it's a bug, or I'm just using it wrong (perhaps with
namespaces).
Does anyone have some more insight or have come across similar issues with
duplicate class attributes or missing class attribute values?

cheers
Magnus

On Mon, Sep 30, 2013 at 10:45 PM, Bård Magnus Kvalheim
<ma...@kvalheim.eu>wrote:

> Hi again.
>
> So have still not been able to figure out how to resolve, but have the
> following observations in mixins and components.
>
> *Mixins:*
> Seems to work fine and work correctly by adding a css classname. I have
> several mixins that contribute css.
>
> *Component:*
> Still replaces the classname.
>
> Components have a template so that could be there's a namespace difference
> or a behaviour I've missed..
>
>
> *Example:*
> In this case what I'm trying to do is to make a component around bootstrap
> tabs.
> http://getbootstrap.com/javascript/#tabs
>
> <div id="choose" class="tab-pane">
> is rendered
> <div class="active" id="choose"> (missing tab-pane)
>
>  Planned to optimize the markup/code and add ajax loading of tab content,
> but want to make this work first. Any ideas to what I could be doing wrong?
>
> thanks in advance
> Magnus
>
> *Tabs.tml*
> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "
> http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
> <t:container
> xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
>  xmlns:p="tapestry:parameter">
> <div id="${ClientId}" class="tabsContainer">
>  <ul class="nav nav-tabs">
> <t:body />
> </ul>
>  <div class="tab-content">
> <t:delegate to="tabContent" />
> </div>
>  </div>
> </t:container>
>
> *Tabs.java (snip)*
> @AfterRenderTemplate
> void handleActive(MarkupWriter writer) {
>  Element e = writer.getElement();
> Element thisEl = e.getElementById(getClientId());
>  Element activeLi = null;
> String contentId = show;
>  //get first
> if(show==null) {
> activeLi = thisEl.find("ul/li");
>  } else {
> Element a = thisEl.getElementByAttributeValue("href", "#"+show);
> if(a!=null) {
>  activeLi = a.getContainer();
> }
> }
>  if(activeLi!=null) {
> activeLi.attribute("class", "active");
> if(contentId==null && activeLi.find("a")!=null) {
>  contentId = activeLi.find("a").getAttribute("href");
> }
>  }
>  if(contentId!=null) {
> if(contentId.startsWith("#")) contentId = contentId.substring(1);
>  Element cnt = thisEl.getElementById(contentId);
> if(cnt!=null) {
> cnt.attribute("class", "active");
>  }
> }
> }
>
> *Usage:*
> <ul t:type="tabs" t:show="literal:choose">
>  <li><a href="#choose" data-toggle="tab">${message:image.choose}</a></li>
> <li><a href="#upload" data-toggle="tab">${message:image.upload}</a></li>
>  <p:tabContent>
> <div id="choose" class="tab-pane">
> <div t:id="as3GalleryBundle"/>
>  </div>
> <div id="upload" class="tab-pane">
> <t:ui.pickimage t:id="imgPick2" t:enableH5="true" class="imgPick"/>
>  </div>
> </p:tabContent>
> </ul>
>
>
>
> On Fri, Sep 27, 2013 at 11:19 AM, Bård Magnus Kvalheim <magnus@kvalheim.eu
> > wrote:
>
>> Hi guys.
>>
>> So I've might have come across a bug in 5.4.22 when trying to add a css
>> class to an element.
>>
>> The Element#addClassName is deprecated and delegate to Element#attribute
>> where attributes named "class" now gets special treatment.
>>
>> The problem I'm seeing is that Element#attribute overrides the class
>> attribute.
>>
>> In Element#updateAttribute there is a namespace test and looks like it's
>> failing as given namespace is null and attribute namespace is empty string.
>> [1]
>>
>> If I instead provide empty string as namespace in the Element#attribute
>> then the isClass test fails as the namespace is not null. [2]
>>
>> Can anyone confirm the issue - and should I open a JIRA?
>>
>> ----
>> Element.class#updateAttribute
>> [1] if (cursor.matches(namespace, name))
>> {
>> [2] boolean isClass = namespace == null && name.equals("class");
>>
>> if (!(force || isClass))
>> {
>> return;
>>  }
>>
>> cheers
>> Magnus
>>
>
>