Skip to content

Commit

Permalink
Merge pull request #28 from refractproject/smizell/convenience-methods
Browse files Browse the repository at this point in the history
Add Convenience Methods
Make meta into Minim instance
Bump version to v0.4.0

Resolves #25
  • Loading branch information
smizell committed May 27, 2015
2 parents ad09737 + b1fde3b commit ae470d7
Show file tree
Hide file tree
Showing 6 changed files with 338 additions and 24 deletions.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ var stringType = minim.convertToType("foobar");
var compact = stringType.toCompactRefract(); // ['string', {}, {}, 'foobar']
```

#### equals

Allows for testing equality with the content of the element.

```javascript
var stringType = minim.convertToType("foobar");
stringType.equals('abcd'); // returns false
```

### Element Types

Minim supports the following primitive types and the
Expand Down Expand Up @@ -310,6 +319,50 @@ var numbers = arrayType.children(function(el) {

Because only children are tested with the condition function, the values `[1, 2]` are seen as an `array` type whose content is never tested. Thus, the only direct child which is a number type is `3`.

##### getById

Search the entire tree to find a matching ID.

```javascript
elTree.getById('some-id');
```

##### contains

Test to see if a collection contains the value given. Does a deep equality check.

```javascript
var arrayType = new minim.ArrayType(['a', [1, 2], 'b', 3]);
arrayType.contains('a'); // returns true
```

##### first

Returns the first element in the collection.

```javascript
var arrayType = new minim.ArrayType(['a', [1, 2], 'b', 3]);
arrayType.first(); // returns the element for "a"
```

##### second

Returns the second element in the collection.

```javascript
var arrayType = new minim.ArrayType(['a', [1, 2], 'b', 3]);
arrayType.second(); // returns the element for "[1, 2]"
```

##### last

Returns the last element in the collection.

```javascript
var arrayType = new minim.ArrayType(['a', [1, 2], 'b', 3]);
arrayType.last(); // returns the element for "3"
```

#### ObjectType

This is a type for representing objects. Objects store their items as an ordered array, so they inherit most of the methods above from the `ArrayType`.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "minim",
"version": "0.3.1",
"version": "0.4.0",
"description": "A library for interacting with JSON through Refract elements",
"main": "lib/minim.js",
"scripts": {
Expand Down
161 changes: 148 additions & 13 deletions src/primitives.es6
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,86 @@ import registry from './registry';
export const attributeElementKeys = Symbol('attributeElementKeys');
export const storedElement = Symbol('storedElement');

export class Meta {
constructor(meta = {}) {
this.meta = {};

for (let key of Object.keys(meta)) {
this.meta[key] = registry.toType(meta[key]);
}
}

toObject() {
let meta = {};

for (let key of Object.keys(this.meta)) {
meta[key] = this.meta[key].toValue();
}

return meta;
}

getProperty(name, value) {
if (!this.meta[name]) {
this.meta[name] = registry.toType(value);
}

return this.meta[name];
}

setProperty(name, value) {
this.meta[name] = registry.toType(value);
}

get id() {
return this.getProperty('id', '');
}

set id(value) {
this.setProperty('id', value);
}

get class() {
return this.getProperty('class', []);
}

set class(value) {
this.setProperty('class', value);
}

get name() {
return this.getProperty('name', '');
}

set name(value) {
this.setProperty('name', value);
}

get title() {
return this.getProperty('title', '');
}

set title(value) {
this.setProperty('title', value);
}

get description() {
return this.getProperty('description', '');
}

set description(value) {
this.setProperty('description', value);
}
}

/*
* ElementType is the base element from which all other elements are built.
* It has no specific information about how to handle the content, but is
* able to convert to and from Refract/Javascript.
*/
export class ElementType {
constructor(content = null, meta = {}, attributes = {}) {
this.meta = meta;
this.meta = new Meta(meta);
this.attributes = attributes;
this.content = content;
this[attributeElementKeys] = [];
Expand All @@ -46,7 +118,7 @@ export class ElementType {
const attributes = this.convertAttributesToRefract('toRefract');
const initial = {
element: this.element,
meta: this.meta,
meta: this.meta.toObject(),
attributes,
content: this.content
};
Expand All @@ -55,7 +127,7 @@ export class ElementType {

toCompactRefract() {
const attributes = this.convertAttributesToRefract('toCompactRefract');
return [this.element, this.meta, attributes, this.content];
return [this.element, this.meta.toObject(), attributes, this.content];
}

/*
Expand Down Expand Up @@ -91,7 +163,7 @@ export class ElementType {
}

fromRefract(dom) {
this.meta = dom.meta;
this.meta = new Meta(dom.meta);
this.attributes = dom.attributes;
this.content = dom.content;

Expand All @@ -106,7 +178,7 @@ export class ElementType {
}

fromCompactRefract(tuple) {
this.meta = tuple[1];
this.meta = new Meta(tuple[1]);
this.attributes = tuple[2];
this.content = tuple[3];

Expand All @@ -128,6 +200,10 @@ export class ElementType {
this.content = content;
return this;
}

equals(value) {
return _.isEqual(this.toValue(), value);
}
}

export class NullType extends ElementType {
Expand Down Expand Up @@ -209,30 +285,38 @@ class Collection extends ElementType {
const attributes = this.convertAttributesToRefract('toCompactRefract');
const compactDoms = this.content.map((el) =>
el.toCompactRefract());
return [this.element, this.meta, attributes, compactDoms];
return [this.element, this.meta.toObject(), attributes, compactDoms];
}

fromRefract(dom) {
this.meta = dom.meta;
this.meta = new Meta(dom.meta);
this.attributes = dom.attributes;
this.content = (dom.content || []).map((content) =>
registry.fromRefract(content));

this.convertAttributesToElements((attribute) =>
registry.fromRefract(attribute));

if (this.element !== dom.element) {
this.element = dom.element;
}

return this;
}

fromCompactRefract(tuple) {
this.meta = tuple[1];
this.meta = new Meta(tuple[1]);
this.attributes = tuple[2];
this.content = (tuple[3] || []).map((content) =>
registry.fromCompactRefract(content));

this.convertAttributesToElements((attribute) =>
registry.fromCompactRefract(attribute));

if (this.element !== tuple[0]) {
this.element = tuple[0];
}

return this;
}

Expand Down Expand Up @@ -302,6 +386,47 @@ class Collection extends ElementType {
newArray.content = this.findElements(condition, {recursive: false});
return newArray;
}

/*
* Search the tree recursively and find the element with the matching ID
*/
getById(id) {
return this.find(item => item.meta.id.toValue() === id).first();
}

/*
* Return the first item in the collection
*/
first() {
return this.get(0);
}

/*
* Return the second item in the collection
*/
second() {
return this.get(1);
}

/*
* Return the last item in the collection
*/
last() {
return this.get(this.length - 1);
}

/*
* Looks for matching children using deep equality
*/
contains(value) {
for (let item of this.content) {
if (_.isEqual(item.toValue(), value)) {
return true;
}
}

return false;
}
}

export class ArrayType extends Collection {
Expand Down Expand Up @@ -337,19 +462,19 @@ export class ObjectType extends Collection {

toValue() {
return this.content.reduce((results, el) => {
results[el.meta.name] = el.toValue();
results[el.meta.name.toValue()] = el.toValue();
return results;
}, {});
}

get(name) {
return name === undefined ? this : _.first(
this.content.filter((value) => value.meta.name === name)
this.content.filter((value) => value.meta.name.toValue() === name)
);
}

set(name, value) {
const location = this.content.map(item => item.meta.name).indexOf(name);
const location = this.content.map(item => item.meta.name.toValue()).indexOf(name);

let refractedContent = registry.toType(value);
// TODO: Should we mutate or copy here? Of course it doesn't matter
Expand All @@ -369,14 +494,24 @@ export class ObjectType extends Collection {
}

keys() {
return this.content.map((value) => value.meta.name);
return this.content.map((value) => value.meta.name.toValue());
}

values() {
return this.content.map((value) => value.get());
}

hasKey(value) {
for (let item of this.content) {
if (item.meta.name.equals(value)) {
return true;
}
}

return false;
}

items() {
return this.content.map((value) => [value.meta.name, value.get()]);
return this.content.map((value) => [value.meta.name.toValue(), value.get()]);
}
}
8 changes: 0 additions & 8 deletions test.js

This file was deleted.

Loading

0 comments on commit ae470d7

Please sign in to comment.