Git Product home page Git Product logo

detox's Introduction

Detox

Build Status

This is a library for haxeJS that makes it easier to work with the DOM or XML. It is mostly inspired by JQuery but aims to give a more haxe-like way of coding.

It makes heavy use of haxe's "using" mixin, which allows you to write some really easy code.

Here's some code so you can get an idea of what I mean:

// You include this at the top of your file

using Detox;

// Now you can write code like this:

"h1".find();                // Find all <h1> elements on the page
"#myID .myclass".find();    // Find elements using CSS selectors
"div".create();             // Create <div>
"table".create();           // Create <table>
"Hello <i>you</i>".parse()  // Turn this into DOM/XML objects

// And traverse it like this:

var listItems = "#menu li".find();
for (listItem in listItems)
{
    trace (listItem.text());
    trace (listItem.find('a').attr('href'));
}

// Or like this

var myParent = "#parent".find();
for (thisChild in myParent.children())
{
    var thisText = thisChild.text()
    var prevChild = thisChild.prev().text();
    var nextChild = thisChild.next().text();
    Std.format("$thisText comes after $prevText and before $nextText");
}

// Or manipulate it like this:

var mylink = "a".create();              // Create <a></a>
mylink.setText("My Link");              // <a>My Link</a>
mylink.setAttr("href", "#");            // <a href="#">My Link</a>
myLink.setInnerHTML("Hi <i>There</i>"); // <a href="#">Hi <i>There</i></a>

// And then you can move things around like this
var icon = "<img src='create.png' alt='create' />".parse();
myLink.append(icon); 
icon.appendTo(myLink); // or the other way around


// And then you can add events like this:

myLink.click(function (e) {
    trace ("You clicked " + e.currentTarget.text());
})
"form#myform".find().submit(function (e) {
    e.preventDefault();
    for (input in e.currentTarget.find("input"))
    {
        trace (input.attr('name') + ": " + input.val());
    }
});

Basic Aims

  • Have jQuery-like functionality
  • Be very haxe-like and easy to use.
  • Provide a base for building HTML/JS widgets using haxe classes.
  • Be null-safe, that is, if something is missing fail silently, don't throw errors.
  • Provide a cross-platform friendly way of working with XML / DOM trees. This is implemented using Haxe's Xml class and SelectHXML for the selection engine. Obviously style, animation and events won't make much sense on the server side, but certainly the general DOM manipulation and traversing can work.

Demos

Here are some very basic demos to show how it works. Currently they are working in both Firefox and Webkit, though our EventManagement code is not IE-friendly yet. But none of you would be using IE, would you?

Todo List

Growl-Like Notifications

Full Usage

General helpers

  • "myselector".find();
  • "div".create();
  • "
    Some HTML code.
    ".parse();

Node / Element Manipulation

  • isElement()
  • isComment()
  • isTextNode()
  • isDocument()
  • toCollection() - Element Only
  • get() - Get first Node out of query
  • get(1) - Get second Node out of query
  • attr("src")
  • setAttr("src", "image.jpg")
  • removeAttr("src")
  • hasClass("myClass")
  • hasClass("myfirstclass mysecondclass")
  • addClass("myClass")
  • addClass("myfirstclass mysecondclass")
  • removeClass("myClass")
  • removeClass("myfirstclass mysecondclass")
  • toggleClass("myClass")
  • toggleClass("myfirstclass mysecondclass")
  • tagName()
  • val()
  • setVal("newValue")
  • text()
  • setText()
  • innerHTML()
  • setInnerHTML()
  • html() - get the full XML/HTML of this node and it's children
  • clone()

Traversing

  • children()
  • firstChildren() - open to changing name
  • lastChildren() - open to changing name
  • parent()
  • parents() - on Xml targets, "parent" is already taken. Use parents() for a null-safe option.
  • ancestors()
  • next()
  • prev()
  • find()

DOM Manipulation

  • append(newChild)
  • prepend(newChild)
  • appendTo(newParent)
  • prependTo(newParent)
  • insertThisBefore(sibling)
  • insertThisAfter(sibling)
  • beforeThisInsert(newSibling)
  • afterThisInsert(newSibling)
  • remove() - remove the current element
  • removeChildren(childElement)
  • removeChildren(childElements)
  • empty()

Event Management

For each of these, eventType is a String, for example "click", "move", "keyup". Listener should be function (e) { trace("Do something..."); }

  • trigger(eventType) - not implemented yet
  • triggerHandler(eventType)
  • on(eventType, listener)
  • off(eventType, listener)
  • one(eventType, listener)
  • mousedown(listener)
  • mouseenter(listener)
  • mouseleave(listener)
  • mousemove(listener)
  • mouseout(listener)
  • mouseover(listener)
  • mouseup(listener)
  • keydown(listener)
  • keypress(listener)
  • keyup(listener)
  • hover(listener)
  • submit(listener)
  • toggleClick(listener)
  • blur(listener)
  • change(listener)
  • click(listener)
  • dblclick(listener)
  • focus(listener)
  • focusIn(listener)
  • focusOut(listener)
  • resize(listener)
  • scroll(listener)
  • select(listener)
  • load(listener)
  • unload(listener)
  • error(listener)
  • ready(listener)

Style

  • Mostly not implemented yet.

Animation

  • Mostly not implemented yet.

Status

  • NA: this feature does not apply to this platform
  • NotYet: this feature has not been written yet
  • NoTests: implemented, but no tests written - no guarantee it works
  • NotRun: implemented, and tests written, but not run yet on this platform.
  • TestFails: implemented, tested, some tests failing
  • Okay: implemented, tests passing, could do with a few more tests.
  • Good: implemented, tests passing, good coverage, good to go.
Feature Browser JS Other Platforms
Firefox WebKit Opera IE7 IE8 IE9 Flash 9+ Neko PHP NodeJS CPP
Element Manipulation Good NotRun Good Good NotRun NotYet Good
Query (Collection) Good NotRun Good Good NotRun NotYet Good
DOM Manipulation Good NotRun Good Good NotRun NotYet Good
Traversing Good NotRun Good Good NotRun NotYet Good
Event Management NoTests (should work) NA
Style NotYet NA
Animation NotYet NA

Platform Inconsistencies

  • On XML based targets (non JS), parent is an Node, not a function that returns a Node. It is not null-safe. Use parents() instead to be safe and consistent across platforms.
  • On XML based targets (non JS), remove() is a method to remove attributes. Because it already exists, our "remove()" mixin does not work. Use removeFromDOM() instead.

Future

Small things to add:

  • node.index() - index in parent
  • node.hasAttr('style'):Bool

detox's People

Contributors

andyli avatar derekhinchliffe avatar fponticelli avatar ibilon avatar jasononeil avatar skial avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

detox's Issues

Investigate use of SelectHX and SelectHXML (Preparation for cross-platform)

These two libraries (one for JS/DOM and one for Haxe/XML) are selector engines that utilise macros - meaning they can be type safe: they can return the right type of object depending on the selector you can use.

This is interesting to us because:

  • We can get more accurate types to work with, rather than always just getting "node". Type-safe is always good!
  • It will give us a selector engine to use on non-js platforms.
  • It may work as a fallback on old browsers which don't have querySelectorAll(). This may be preferable to using sizzle etc.

Easier manipulation using selectors

"#menu".addClass("big");
".complete".hide();

etc

Do this by creating a class

class DtxStringHelper {
    static function getCollection(string) {
        // return a DOMCollection, either a selector, executed on the Document.  Or parse it as XML... not sure how to tell the difference?
    }

    public static function addClass(string, className)
    {
        var collection = getCollection(string);
    }
}

Concerns:

  • pollute the String namespace
    • alternatively use "#menu".dtx().addClass();
  • ... anything else?

Option for embedding Sizzle for older browsers

If we do this we might be able to get closer to browser support on older platforms.

I suppose you could make it optional with a compiler switch?

Code could be copied from Franco's DHX library.

parse() can't accept a "<html>" element

var myDoc = "<html>
    <head><title>My Title</title></head>
    <body>My Body</body>
</html>".parse();

trace (myDoc.length);

This shows 5. TextNode, head, TextNode, body, TextNode.

I would expect it to show 1: html

If we change <html></html> to <myxml></myxml>, it works as expected.

Tested in Firefox

Bean dependency

Hi Jason,

Trying your lib, I ran into this issue :

/dtx/collection/EventManagement.hx:15: characters 7-11 : Class not found : Bean

Is it a regression or a missing extern ? Thanks

Methods that can duplicate a node ought to return a query containing all the clones

This happens in both DOMManipulation classes.

It causes weirdness when you do something like this:

li.setText('first");
lists.prepend(li);
li.setText("second");

If there are multiple "lists", then "li" will be cloned so it can be appended to each one. Because we only return the original though, li.setText('second') is going to have no effect on the second, third etc cloned nodes.

Replace use of 'Node' with a typedef (preparation for cross-platform)

To prepare for porting this to haxe Xml so it can be used across platforms, create a typedef that implements ONLY the properties of Node that are essential for:

  • ElementManipulation
  • Traversing
  • DOMManipulation

I suspect the typedef will look something like

typedef StrippedDownNode = {
    var nodeName:String;
    var nodeType:Int;
    var nodeValue:String;
    var attributes:Iterable<String>;
    var getAttribute:String->String;
    var setAttribute:String->String;
    var removeAttribute:String->String;
    var hasAttribute:String->Bool;
    var innerHTML:String
    var textContent:Void->String;
}

Try to figure out a way to create an interface between the XML implementation and the JS/DOM implementation. Probably a good question for those on the mailing list who are a lot smarter than me.

Error whilst in macro time

/home/dayz/i/src/haxe/haxe/std/neko/_std/EReg.hx:33: characters 11-61 : Non capturing groups '(?:' are not supported in macros
<builtin>:1: character 0 : Called from
/home/dayz/i/src/haxe/haxe/std/neko/_std/EReg.hx:22: lines 22-33 : Called from
/media/i/src/haxe/lib/selecthxml/0,5,2/src/selecthxml/engine/RegexLexer.hx:14: characters 22-135 : Called from

Just needed to define an empty macro for this error to trigger. Reported here because selecthxml is deprecated.

Implement Animation

Once Style is working.

Presumably use an existing tween library for haxe/js?

Look at D3 and see if their syntax is preferable to jquery. Maybe ask Franco...

Type name Node is redefined

I can't run Detox in my Project since compilation ends up with the error message below.
I guess der are incompatibilites of beanhx and xirsys_stdjs.

detox/0,8,0,0/dtx/single/EventManagement.hx:15: characters 0-12 : Type name Node is redefined from module UserAgentContext

My Detox 0.8.0 is running together with beanhx 0.9.1.0 and xirsys_stdjs 5.0.5
And in both of those libraries a definition for "Node" exists:
Bean.hx - line 10:

typedef Node = js.Dom.HtmlDom;

UserAgentContext.hx - line 87:

typedef Node = js.w3c.level3.Core.Node;

Create html() method

  • For DOMNode
  • For DOMCollection
  • Write tests for DOMNode
  • Write tests for DOMCollection
  • Add to README

Package for haxelib

Once I am satisfied with the status of the library, package an update for haxelib. Bump the minor version number. Possibly update the haxelib description too...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.