package jj.engine;
import java.util.Collections;
import java.util.Map;
import jj.document.CurrentDocumentRequestProcessor;
import jj.http.server.websocket.WebSocketConnectionHost;
import jj.jjmessage.EventNameHelper;
import jj.jjmessage.JJMessage;
import jj.script.CurrentScriptEnvironment;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.mozilla.javascript.Callable;
import org.mozilla.javascript.Context;
/**
* The Selection object when the document is being processed.
* @author jason
*
*/
public class DocumentSelection implements Selection {
private final Elements elements;
private final String selector;
private final CurrentDocumentRequestProcessor document;
private final CurrentScriptEnvironment env;
public DocumentSelection(final String selector, final Element element, final CurrentDocumentRequestProcessor document, final CurrentScriptEnvironment env) {
this(selector, new Elements(element), document, env);
}
public DocumentSelection(final String selector, final Elements elements, final CurrentDocumentRequestProcessor document, final CurrentScriptEnvironment env) {
this.selector = selector;
this.elements = elements;
this.document = document;
this.env = env;
}
public String selector() {
return selector;
}
@Override
public Selection hide() {
document.current().addStartupJJMessage(JJMessage.makeSet(this.selector, "hide", null));
return this;
}
@Override
public Selection hide(final String duration) {
document.current().addStartupJJMessage(JJMessage.makeSet(this.selector, "hide", duration));
return this;
}
@Override
public Selection show() {
document.current().addStartupJJMessage(JJMessage.makeSet(this.selector, "show", null));
return this;
}
@Override
public Selection show(final String duration) {
document.current().addStartupJJMessage(JJMessage.makeSet(this.selector, "show", duration));
return this;
}
// -- Events
@Override
public Selection on(final String type, final Callable function) {
return on(type, "", function);
}
@Override
public Selection on(final String type, final String selector, final Callable function) {
document.current().addStartupJJMessage(JJMessage.makeBind(this.selector, selector, type));
// this is wrong! we need a way to associate the clients!
// also UGLY UGLY UGLY. but this class is going away. maybe today!
((WebSocketConnectionHost)env.current()).addFunction(EventNameHelper.makeEventName(this.selector, selector, type), function);
return this;
}
@Override
public Selection bind(final String type, final Callable function) {
return on(type, function);
}
@Override
public Selection bind(final String type, final Object data, final Callable function) {
return on(type, function);
}
@Override
public Selection bind(String type, boolean cancel) {
// TODO!
return this;
}
@Override
public Selection bind(String type, Object data, boolean cancel) {
// TODO make this work
return this;
}
@Override
public Selection click(Callable function) {
return bind("click", null, function);
}
@Override
public Selection enter(Callable function) {
return bind("enter", null, function);
};
public Selection append(final Selection selection) {
// it will always be
DocumentSelection in = (DocumentSelection)selection;
Elements clone = null;
for (final Element dst : elements) {
clone = clone == null ? in.elements : in.elements.clone();
for (final Element src : clone) {
dst.appendChild(src);
}
}
return this;
}
public Selection text(String text) {
for (final Element element : elements) {
element.text(text);
}
return this;
}
public String data(final String key) {
for (final Element element : elements) {
if (element.dataset().containsKey(key)) {
return element.dataset().get(key);
}
}
return null;
}
public Selection data(final String key, final String value) {
for (final Element element : elements) {
element.dataset().put(key, value);
}
return this;
}
public Map<String, String> dataset() {
Element first = first();
return first == null ? Collections.<String, String>emptyMap() : first.dataset();
}
@Override
public String attr(String attributeKey) {
return elements.attr(attributeKey);
}
@Override
public boolean hasAttr(String attributeKey) {
return elements.hasAttr(attributeKey);
}
@Override
public Selection attr(String attributeKey, String attributeValue) {
elements.attr(attributeKey, attributeValue);
return this;
}
@Override
public Selection removeAttr(String attributeKey) {
elements.removeAttr(attributeKey);
return this;
}
@Override
public Selection addClass(String className) {
elements.addClass(className);
return this;
}
@Override
public Selection removeClass(String className) {
elements.removeClass(className);
return this;
}
@Override
public Selection toggleClass(String className) {
elements.toggleClass(className);
return this;
}
@Override
public boolean hasClass(String className) {
return elements.hasClass(className);
}
@Override
public String val() {
return elements.val();
}
@Override
public Selection val(String value) {
elements.val(value);
return this;
}
@Override
public String text() {
return elements.text();
}
public boolean hasText() {
return elements.hasText();
}
@Override
public Object html() {
return Context.javaToJS(elements.html(), env.current().scope());
}
public String outerHtml() {
return elements.outerHtml();
}
public Selection tagName(String tagName) {
elements.tagName(tagName);
return this;
}
@Override
public Selection html(String html) {
elements.html(html);
return this;
}
@Override
public Selection prepend(String html) {
elements.prepend(html);
return this;
}
@Override
public Selection append(String html) {
elements.append(html);
return this;
}
@Override
public Selection before(String html) {
elements.before(html);
return this;
}
@Override
public Selection after(String html) {
elements.after(html);
return this;
}
@Override
public Selection wrap(String html) {
elements.wrap(html);
return this;
}
@Override
public Selection unwrap() {
elements.unwrap();
return this;
}
@Override
public Selection empty() {
elements.empty();
return this;
}
@Override
public Selection remove() {
elements.remove();
return this;
}
@Override
public Selection select(String query) {
// FIXME this selector is not correct at all
return new DocumentSelection(selector, elements.select(query), document, env);
}
@Override
public Selection not(String query) {
// FIXME this selector is not correct at all
return new DocumentSelection(selector, elements.not(query), document, env);
}
@Override
public Selection eq(int index) {
// FIXME this selector is not correct at all
return new DocumentSelection(selector, elements.eq(index), document, env);
}
@Override
public boolean is(String query) {
return elements.is(query);
}
@Override
public Selection parents() {
// FIXME this selector is not correct at all
return new DocumentSelection(selector, elements.parents(), document, env);
}
@Override
public Element first() {
return elements.first();
}
@Override
public Element last() {
return elements.last();
}
@Override
public Selection clone() {
return new DocumentSelection(selector, elements.clone(), document, env);
}
@Override
public String toString() {
return DocumentSelection.class.getSimpleName() + ": " + selector + "\n" + elements;
}
}