001: /*
002: * Copyright 2000,2005 wingS development team.
003: *
004: * This file is part of wingS (http://wingsframework.org).
005: *
006: * wingS is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * Please see COPYING for the complete licence.
012: */
013: package org.wings.script;
014:
015: import org.wings.SButton;
016: import org.wings.SComponent;
017: import org.wings.util.SStringBuilder;
018:
019: import java.util.Arrays;
020:
021: public class JavaScriptListener implements ScriptListener {
022: private final String event;
023: private final String code;
024: private final String script;
025: private final SComponent[] components;
026: private final int priority;
027:
028: /**
029: * Use this java script implementation to submit forms on button click
030: */
031: // TODO: Implement handling of formless submits
032: // TODO: Avoid triggering of enter key catchers
033: public final static String JS_FORM_SUBMIT_SCRIPT = "wingS.request.sendEvent(event, true, true);";
034:
035: /**
036: * Use i.e. {@link SButton#addScriptListener(org.wings.script.ScriptListener)} to add this scripts.
037: */
038: public final static JavaScriptListener JS_ON_CHANGE_SUBMIT_FORM = new JavaScriptListener(
039: JavaScriptEvent.ON_CHANGE, JS_FORM_SUBMIT_SCRIPT);
040:
041: /**
042: * @param event one of 'onclick', 'onmouseover', ..
043: * @param code the code that is written as a value of the event attribute
044: */
045: public JavaScriptListener(String event, String code) {
046: this .event = event;
047: this .code = code;
048: this .script = null;
049: this .priority = DEFAULT_PRIORITY;
050: this .components = null;
051: }
052:
053: /**
054: * @param event one of 'onclick', 'onmouseover', ..
055: * @param code the code that is written as a value of the event attribute
056: * @param script larger code block (java script functions), that is written
057: * to a combined script file, that is linked in the header
058: */
059: public JavaScriptListener(String event, String code, String script) {
060: this .event = event;
061: this .code = code;
062: this .script = script;
063: this .priority = DEFAULT_PRIORITY;
064: this .components = null;
065: }
066:
067: /**
068: * The code is parsed and all occurrences of '{0..components.length}' are substituted
069: * with that component's id. You can use this to address elements by id.
070: * This mechanism is highly dependant on the code, the plaf generates for a component.
071: *
072: * @param event one of 'onclick', 'onmouseover', ..
073: * @param code the code that is written as a value of the event attribute
074: * @param components the components whose ids are substituted into the code
075: */
076: public JavaScriptListener(String event, String code,
077: SComponent[] components) {
078: this .event = event;
079: this .code = substituteIds(code, components);
080: this .components = components;
081: this .script = null;
082: this .priority = DEFAULT_PRIORITY;
083: }
084:
085: /**
086: * The code is parsed and all occurrences of '{0..components.length}' are substituted
087: * with that component's id. You can use this to address elements by id.
088: * This mechanism is highly dependant on the code, the plaf generates for a component.
089: *
090: * @param event one of 'onclick', 'onmouseover', ..
091: * @param code the code that is written as a value of the event attribute
092: * @param script larger code block (java script functions), that is written
093: * to a separate script file, that is linked in the header
094: * @param components the components whose ids are substituted into the code
095: */
096: public JavaScriptListener(String event, String code, String script,
097: SComponent[] components) {
098: this .event = event;
099: this .code = substituteIds(code, components);
100: this .script = substituteIds(script, components);
101: this .components = components;
102: this .priority = DEFAULT_PRIORITY;
103: }
104:
105: /** @inheritDoc */
106: public String getEvent() {
107: return event;
108: }
109:
110: /** @inheritDoc */
111: public String getCode() {
112: return code;
113: }
114:
115: /** @inheritDoc */
116: public String getScript() {
117: return script;
118: }
119:
120: /** @inheritDoc */
121: public SComponent[] getComponents() {
122: return components;
123: }
124:
125: private String substituteIds(String code, SComponent[] components) {
126: SStringBuilder buffer = new SStringBuilder();
127:
128: int startPos = 0;
129: int endPos = 0;
130: char lastChar = code.charAt(0);
131: for (int i = 1; i < code.length(); ++i) {
132: char c = code.charAt(i);
133: endPos = i;
134: if (lastChar == '{' && Character.isDigit(c)) {
135: int varIndex = (c - '0');
136: while (Character.isDigit(code.charAt(++i))) {
137: varIndex *= 10;
138: varIndex += (code.charAt(i) - '0');
139: }
140: c = code.charAt(i);
141: if (c == '}') {
142: buffer.append(code.substring(startPos, endPos - 1));
143: startPos = i + 1;
144: buffer.append(components[varIndex].getName());
145: } else {
146: throw new IllegalArgumentException(
147: "Expected closing '}' after '{" + varIndex
148: + "'");
149: }
150: }
151: lastChar = c;
152: }
153: buffer.append(code.substring(startPos));
154:
155: return buffer.toString();
156: }
157:
158: /* (non-Javadoc)
159: * @see java.lang.Object#equals(java.lang.Object)
160: */
161: @Override
162: public boolean equals(Object obj) {
163: /* only checking for instanceof, not exact class, so we don't
164: * need to implement this in inherited classes
165: */
166: if (!(obj instanceof JavaScriptListener)) {
167: return false;
168: }
169: JavaScriptListener testObj = (JavaScriptListener) obj;
170:
171: if (testObj.getEvent() == null) {
172: if (getEvent() != null) {
173: return false;
174: }
175: } else {
176: if (!testObj.getEvent().equals(getEvent())) {
177: return false;
178: }
179: }
180:
181: if (testObj.getCode() == null) {
182: if (getCode() != null) {
183: return false;
184: }
185: } else {
186: if (!testObj.getCode().equals(getCode())) {
187: return false;
188: }
189: }
190:
191: if (testObj.getComponents() == null) {
192: if (getComponents() != null) {
193: return false;
194: }
195: } else {
196: if (!Arrays
197: .equals(testObj.getComponents(), getComponents())) {
198: return false;
199: }
200: }
201:
202: if (testObj.getScript() == null) {
203: if (getScript() != null) {
204: return false;
205: }
206: } else {
207: if (!testObj.getScript().equals(getScript())) {
208: return false;
209: }
210: }
211:
212: return true;
213: }
214:
215: @Override
216: public int hashCode() {
217: return code != null ? code.hashCode() : super .hashCode();
218: }
219:
220: /** @inheritDoc */
221: public int getPriority() {
222: return priority;
223: }
224:
225: }
|