Skip to content
This repository has been archived by the owner on Apr 1, 2024. It is now read-only.

Automatically call transferAttributes as needed. #133

Closed
wants to merge 8 commits into from

Conversation

fredemmott
Copy link
Contributor

  • split out XHPBaseHTMLHelpers to just implement the ID and class helpers
    without transferAttributes
  • added tests
  • XHPHelpers should probably be renamed to XHPHTMLHelpers in XHP-Lib 3, and
    the bulk of the transfer/copyattribtues functiontionality split to
    XHPTransferAttributes or something like that. Keeping like this for now to
    reduce BC breakage
  • Allows implementation of non-HTML helpers; until the above modification happens
    this will involve copypasta, but better than the current situation.
  • I /think/ this gets rid of the render()/compose() pattern.

Fixes #130

- split out XHPBaseHTMLHelpers to just implement the ID and class helpers
  without transferAttributes
- added tests
- XHPHelpers should probably be renamed to XHPHTMLHelpers in XHP-Lib 3, and
  the bulk of the transfer/copyattribtues functiontionality split to
  XHPTransferAttributes or something like that. Keeping like this for now to
  reduce BC breakage
- Allows implementation of non-HTML helpers; until the above modification happens
  this will involve copypasta, but better than the current situation.
- I /think/ this gets rid of the render()/compose() pattern.

Fixes facebook/hhvm#130
if (!($root instanceof HasXHPHelpers)) {
throw new XHPClassException(
$this,
'compose() must return an :xhp:html-element or :bootstrap:base '.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll fix this.

@@ -55,6 +58,7 @@
throw new XHPCoreRenderException($this, $that);
}


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: unnecessary extra line.

@TJ09
Copy link
Contributor

TJ09 commented Apr 27, 2015

lgtm beyond the whitespace nits that you already fixed.


// We want to append classes to the root node, instead of replace them,
// so do this attribute manually and then remove it.
if (array_key_exists('class', $attributes) && $attributes['class']) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be something on the class to denote that a set of attributes should be appended instead of replaced. For normal HTML that's just class, but there can be others. For instance, Javelin needs data-sigil. What about putting a function in this trait that is like

protected function getAttributesThatAppendValuesOnTransfer(): ImmSet<string> {
  return ImmSet {'class'};
}

And you can override it in individual classes or create your own trait that extends this to add your special-needs attributes.

In fact, this trait shouldn't even have it, and there should be an XHPHtmlHelpers trait that extends this and adds the class attribute to the set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll split this out to an overridable function.

I think changing when this trait would be too big of a change to do so soon. Agree on that naming being better, but I'd rather keep it as is until a 3.0 seems on the horizon.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

- add test for class attribute behavior
@fredemmott
Copy link
Contributor Author

If this looks good, I'll rebase+squash before merge.

$thisValue = array_key_exists($attr, $attributes)
? (string) $attributes[$attr]
: '';
if ($rootValue !== '' && $thisValue !== '') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to be || since otherwise the root's class could be overwritten by an empty string, right?

A better solution might be to make it null otherwise and check for that instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch - this fails:

  public function testClassesNotOverridenByEmptyString(): void {
    $x = <test:with-class-on-root class="" />;
    $this->assertSame('<div class="rootClass"></div>', $x->toString());
  }

@fredemmott
Copy link
Contributor Author

Fixed, and seems fairly backwards-compatible - xhp-bootstrap still works fine (though it's render() is redundant)

}
$this->removeAttribute($attr);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just

foreach ($this->getAttributesThatAppendValuesOnTransfer() as $attr) {
  if (array_key_exists($attr, $attributes)) {
    $rootValue = (string)$root->getAttribute($attr);
    if ($rootValue !== '') {
      $root->setAttribute($attr, $rootValue.' '.(string)$attributes[$attr]);
      $this->removeAttribute($attr);
    }
  }
}

A little less processing for something that could potentially be called many hundreds of times per request.

@fredemmott
Copy link
Contributor Author

Merging this in tomorrow if there's no further comments.

@Swahvay
Copy link
Contributor

Swahvay commented May 1, 2015

👍🏻

@fredemmott fredemmott closed this in 3923d04 May 1, 2015
@fredemmott fredemmott deleted the call-transfer-attributes branch May 5, 2015 22:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Call transferAttributes() from ❌element on elements that implement HasXHPHelpers
4 participants