Skip to content
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

Support for hyphenated component names #301

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 53 additions & 2 deletions components/event-set/dist/aframe-event-set-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,58 @@ return /******/ (function(modules) { // webpackBootstrap


/* global AFRAME */
var styleParser = AFRAME.utils.styleParser;

// AFRAME styleParse has one issue: it transforms hyphenated keys to camel-case.
// This is a problem when those keys are component names, as A-Frame component
// names often include hyphens, and are not converted internally to camel case.

// To compensate for this, we post-process the data from the parser:
// - analyze the first part of the string, represeting the component
// - if translating this out of camel case to a dashed value gives
// a better match against known A-Frame components, then use the dashed value
// for the component name.

// This solution is not 100% robust, but good enough for most circumstances.
// - Will not handle component names that have a mix of camel case and dashes
// e.g. example-componentOne
// - Could give incorrect results in case where two components have names that
// only differ by their casing.
// e.g. example-component-two & exampleComponentTwo
var styleParse = function styleParse(value) {

function dashLowerCase(str) {
return '-' + str[0].toLowerCase();
}

function fromCamelCase(str) {
return str.replace(/([A-Z])/g, dashLowerCase);
}

var data = AFRAME.utils.styleParser.parse(value);

var key;
var component;
var remainder;
var dashComponent;
var dashKey;

for (key in data) {
component = key.split('.')[0];
remainder = key.split('.').slice(1).join('.');
dashComponent = fromCamelCase(component);
if (component === dashComponent) {
continue;
}

if (AFRAME.components[dashComponent] && !AFRAME.components[component]) {
dashKey = dashComponent.concat('.', remainder);
data[dashKey] = data[key];
delete data[key];
}
}

return data;
};

if (typeof AFRAME === 'undefined') {
throw new Error('Component attempted to register before AFRAME was available.');
Expand All @@ -117,7 +168,7 @@ AFRAME.registerComponent('event-set', {
schema: {
default: '',
parse: function parse(value) {
return styleParser.parse(value);
return styleParse(value);
}
},

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion components/event-set/examples/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<title>Cursor</title>
<meta name="description" content="Changing properties in response to cursor component events"></meta>
<meta property="og:image" content="https://raw.githubusercontent.com/supermedium/superframe/master/components/event-set/examples/basic/preview.gif"></meta>
<script src="https://aframe.io/releases/0.9.0/aframe.min.js"></script>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="../../dist/aframe-event-set-component.min.js"></script>
</head>
<body>
Expand Down
56 changes: 56 additions & 0 deletions components/event-set/examples/hyphenated-component/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!-- This test is virtually identical to the basic test
The only difference is that the component updated with event-set is called "test-material"
rather than "material".
This reproduces the problem seen in https://github.com/supermedium/superframe/issues/296
where event-set component had trouble with hyphenated component names-->

<html>
<head>
<title>Cursor</title>
<meta name="description" content="Changing properties in response to cursor component events, with hyphenated component name"></meta>
<meta property="og:image" content="https://raw.githubusercontent.com/supermedium/superframe/master/components/event-set/examples/basic/preview.gif"></meta>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="../../dist/aframe-event-set-component.min.js"></script>
<script>
AFRAME.registerComponent('test-material', {
update: function() {
this.el.setAttribute("material", this.data)
}
}
);
</script>

</head>
<body>
<a-scene>
<a-entity geometry="primitive: box" material="color: #FCB241"
event-set__click="_target: #eye-1; visible: true"
event-set__click2="_event: click; _target: #eye-2; visible: true"
event-set__mouseenter="test-material.color: #5A67A6"
event-set__mouseleave="test-material.color: #FCB241; _delay: 500"
position="-1 0 -2">
<a-sphere id="eye-1" radius="0.05" position="-0.5 0.7 0.5" visible="false"></a-sphere>
<a-sphere id="eye-2" radius="0.05" position="0.5 0.7 0.5" visible="false"></a-sphere>
</a-entity>

<a-sky color="#D68D08"></a-sky>

<a-entity camera look-controls>
<a-entity cursor
geometry="primitive: ring; radiusInner: 0.01; radiusOuter: 0.016"
test-material="color: #EEE"
position="0 0 -1"></a-entity>
</a-entity>
</a-scene>

<!--githubcorner-->
<a href="https://github.com/supermedium/superframe/tree/master/components/event-set/examples/basic/" class="github-corner">
<svg width="80" height="80" viewBox="0 0 250 250" style="fill: #111; color: #EFEFEF; position: fixed; bottom: 0; border: 0; left: 0; transform: rotate(180deg); opacity: 0.8">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path>
</svg>
</a>
<style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}
</style>
<!--endgithubcorner-->
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 49 additions & 2 deletions components/event-set/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,52 @@
/* global AFRAME */
var styleParser = AFRAME.utils.styleParser;

// AFRAME styleParse has one issue: it transforms hyphenated keys to camel-case.
// This is a problem when those keys are component names, as A-Frame component
// names often include hyphens, and are not converted internally to camel case.

// To compensate for this, we post-process the data from the parser:
// - analyze the first part of the string, represeting the component
// - if translating this out of camel case to a dashed value gives
// a better match against known A-Frame components, then use the dashed value
// for the component name.

// This solution is not 100% robust, but good enough for most circumstances.
// - Will not handle component names that have a mix of camel case and dashes
// e.g. example-componentOne
// - Could give incorrect results in case where two components have names that
// only differ by their casing.
// e.g. example-component-two & exampleComponentTwo
var styleParse = function(value) {

function dashLowerCase (str) { return '-' + str[0].toLowerCase(); }

function fromCamelCase (str) {
return str.replace(/([A-Z])/g, dashLowerCase);
}

const data = AFRAME.utils.styleParser.parse(value);

var key;
var component;
var remainder;
var dashComponent;
var dashKey;

for (key in data) {
component = key.split('.')[0];
remainder = key.split('.').slice(1).join('.');
dashComponent = fromCamelCase(component);
if (component === dashComponent) { continue; }

if (AFRAME.components[dashComponent] && !AFRAME.components[component]) {
dashKey = dashComponent.concat('.', remainder);
data[dashKey] = data[key];
delete data[key];
}
}

return(data);
}

if (typeof AFRAME === 'undefined') {
throw new Error('Component attempted to register before AFRAME was available.');
Expand All @@ -9,7 +56,7 @@ AFRAME.registerComponent('event-set', {
schema: {
default: '',
parse: function (value) {
return styleParser.parse(value);
return styleParse(value);
}
},

Expand Down