mirror of
https://github.com/Mibew/mibew.git
synced 2024-11-15 08:34:11 +03:00
connection error handling, add build scripts
git-svn-id: https://webim.svn.sourceforge.net/svnroot/webim/trunk@122 c66351dc-e62f-0410-b875-e3a5c0b9693f
This commit is contained in:
parent
99c36bf687
commit
2fcc7ca242
735
src/messenger/js/JSO.java
Normal file
735
src/messenger/js/JSO.java
Normal file
@ -0,0 +1,735 @@
|
||||
/*
|
||||
* JavaScript Obfucator is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* JavaScript Obfucator is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Obfuscate the JavaScript code.
|
||||
* updated by Evgeny Gryaznov, March 2006
|
||||
* @author Shane Ng <gnenahs at poboxes dot com>
|
||||
*/
|
||||
public class JSO {
|
||||
|
||||
private Random randomizer = new Random(321);
|
||||
|
||||
public static final String[] reserved = {
|
||||
"abstract", "else", "instanceof", "switch", "boolean", "enum", "int",
|
||||
"synchronized", "break", "export", "interface", "this", "byte", "extends",
|
||||
"long", "throw", "case", "false", "native", "throws", "catch", "final",
|
||||
"new", "transient", "char", "finally", "null", "true", "class", "float",
|
||||
"package", "try", "const", "for", "private", "typeof", "continue", "function",
|
||||
"protected", "var", "debugger", "goto", "public", "void", "default", "if",
|
||||
"return", "volatile", "delete", "implements", "short", "while", "do", "import",
|
||||
"static", "with", "double", "in", "super", "undefined", "arguments"
|
||||
};
|
||||
|
||||
public static final String[] builtIn = {
|
||||
"history", "packages", "pageXOffset", "pageYOffset", "isNaN", "array", "java",
|
||||
"plugin", "clientInformation", "prototype", "layer", "layers", "crypto", "date", "secure",
|
||||
"embed", "navigator", "product", "netscape", "escape", "eval", "sun",
|
||||
"taint", "fileUpload", "toString", "unescape", "untaint", "frameRate",
|
||||
"valueOf", "getClass", "encodeURIComponent", "overrideMimeType",
|
||||
|
||||
// Types
|
||||
"Math", "Date", "Array", "RegExp", "Image", "Function", "ActiveXObject",
|
||||
"Number", "String", "Object", "JavaClass", "JavaObject", "JavaPackage", "JavaArray",
|
||||
|
||||
// DOM
|
||||
"anchor", "image", "area", "checkbox", "password", "radio", "textarea",
|
||||
"contentDocument", "contentWindow", "document",
|
||||
"window", "element", "location", "option", "style", "body",
|
||||
|
||||
// Properties
|
||||
"accessKey", "action", "activeElement", "align", "aLink", "aLinkColor", "alt",
|
||||
"altHTML", "altKey", "appCodeName", "appMinorVersion", "appName", "appVersion",
|
||||
"autocomplete", "availHeight", "availWidth", "background", "backgroundAttachment",
|
||||
"backgroundColor", "backgroundImage", "backgroundPosition", "backgroundPositionX",
|
||||
"backgroundPositionY", "backgroundRepeat", "balance", "behavior", "bgColor",
|
||||
"bgProperties", "border", "borderBottom", "borderBottomColor", "borderBottomStyle",
|
||||
"borderBottomWidth", "borderCollapse", "borderColor", "borderColorDark",
|
||||
"borderColorLight", "borderLeft", "borderLeftColor", "borderLeftStyle",
|
||||
"borderLeftWidth", "borderRight", "borderRightColor", "borderRightStyle",
|
||||
"borderRightWidth", "borderStyle", "borderTop", "borderTopColor", "borderTopStyle",
|
||||
"borderTopWidth", "borderWidth", "bottom", "bottomMargin", "boundingHeight", "boundingLeft",
|
||||
"boundingTop", "boundingWidth", "browserLanguage", "bufferDepth", "button",
|
||||
"cancelBubble", "canHaveChildren", "caption", "cellIndex", "cellPadding", "cellSpacing",
|
||||
"checked", "classid", "className", "clear", "clientHeight", "clientLeft", "clientTop",
|
||||
"clientWidth", "clientX", "clientY", "clip", "clipBottom", "clipLeft", "clipRight",
|
||||
"clipTop", "closed", "code", "codeBase", "codeType", "color", "colorDepth", "cols",
|
||||
"colSpan", "compact", "complete", "content", "cookie", "cookieEnabled", "coords",
|
||||
"cpuClass", "cssText", "ctrlKey", "cursor", "data", "dataFld", "dataFormatAs",
|
||||
"dataPageSize", "dataSrc", "defaultCharset", "defaultChecked", "defaultSelected",
|
||||
"defaultStatus", "defaultValue", "defer", "designMode", "dialogArguments", "dialogHeight",
|
||||
"dialogLeft", "dialogTop", "dialogWidth", "dir", "direction", "disabled", "display",
|
||||
"documentElement", "domain", "dropEffect", "dynsrc", "effectAllowed", "encoding", "event",
|
||||
"expando", "face", "fgColor", "fileCreatedDate", "fileModifiedDate", "fileSize",
|
||||
"fileUpdatedDate", "filter", "firstChild", "font", "fontFamily", "fontSize",
|
||||
"fontSmoothingEnabled", "fontStyle", "fontVariant", "fontWeight", "form", "frame",
|
||||
"frameBorder", "frameSpacing", "fromElement", "hash", "height", "hidden", "host",
|
||||
"hostname", "href", "hspace", "htmlFor", "htmlText", "httpEquiv", "id", "imeMode",
|
||||
"indeterminate", "index", "innerHTML", "innerText", "isMap", "isTextEdit", "keyCode",
|
||||
"lang", "language", "lastChild", "lastModified", "layoutGrid", "layoutGridChar",
|
||||
"layoutGridCharSpacing", "layoutGridLine", "layoutGridMode", "layoutGridType", "left",
|
||||
"leftMargin", "length", "letterSpacing", "lineBreak", "lineHeight", "link", "linkColor",
|
||||
"listStyle", "listStyleImage", "listStylePosition", "listStyleType", "loop", "lowsrc",
|
||||
"margin", "marginBottom", "marginHeight", "marginLeft", "marginRight", "marginTop",
|
||||
"marginWidth", "maxLength", "media", "menuArguments", "method", "Methods", "multiple",
|
||||
"name", "nameProp", "nextSibling", "nodeName", "nodeType", "nodeValue", "noHref",
|
||||
"noResize", "noShade", "noWrap", "object", "offscreenBuffering", "offsetHeight",
|
||||
"offsetLeft", "offsetParent", "offsetTop", "offsetWidth", "offsetX", "offsetY",
|
||||
"onLine", "opener", "outerHTML", "outerText", "overflow", "overflowX", "overflowY",
|
||||
"owningElement", "padding", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop",
|
||||
"pageBreakAfter", "pageBreakBefore", "palette", "parent", "parentElement", "parentNode",
|
||||
"parentStyleSheet", "parentTextEdit", "parentWindow", "pathname", "pixelBottom",
|
||||
"pixelHeight", "pixelLeft", "pixelRight", "pixelTop", "pixelWidth", "platform",
|
||||
"pluginspage", "port", "posBottom", "posHeight", "position", "posLeft", "posRight",
|
||||
"posTop", "posWidth", "previousSibling", "propertyName", "protocol", "qualifier",
|
||||
"readOnly", "reason", "recordNumber", "recordset", "referrer", "rel",
|
||||
"repeat", "returnValue", "rev", "right", "rightMargin", "rowIndex", "rowSpan",
|
||||
"rubyAlign", "rubyOverhang", "rubyPosition", "scopeName", "screenLeft",
|
||||
"screenTop", "screenX", "screenY", "scrollAmount", "scrollDelay",
|
||||
"scrollHeight", "scrolling", "scrollLeft", "scrollTop", "scrollWidth", "search",
|
||||
"sectionRowIndex", "selected", "selectedIndex", "selectorText", "self", "shape",
|
||||
"shiftKey", "size", "sourceIndex", "span", "specified", "src", "srcElement", "srcFilter",
|
||||
"srcUrn", "start", "status", "styleFloat", "systemLanguage", "tabIndex", "tableLayout",
|
||||
"tagName", "tagUrn", "target", "text", "textAlign", "textAutospace", "textDecoration",
|
||||
"textDecorationLineThrough", "textDecorationNone", "textDecorationOverline",
|
||||
"textDecorationUnderline", "textIndent", "textJustify", "textTransform", "tFoot", "tHead",
|
||||
"title", "toElement", "top", "topMargin", "trueSpeed", "type", "unicodeBidi", "uniqueID",
|
||||
"units", "updateInterval", "URL", "urn", "useMap", "userAgent", "userLanguage", "vAlign",
|
||||
"value", "vcard_name", "verticalAlign", "visibility", "vLink", "vlinkColor", "volume",
|
||||
"vspace", "whiteSpace", "width", "wordBreak", "wordSpacing", "wrap", "x",
|
||||
"XMLDocument", "y", "zIndex",
|
||||
// non-IE
|
||||
"outerHeight", "innerHeight", "outerWidth", "innerWidth",
|
||||
"which",
|
||||
|
||||
// collections
|
||||
"all", "anchors", "applets", "areas", "attributes", "behaviorUrns",
|
||||
"bookmarks", "boundElements", "cells", "childNodes", "children",
|
||||
"controlRange", "elements", "embeds", "filters", "forms", "frames",
|
||||
"images", "imports", "links", "mimeTypes", "options", "plugins", "rows",
|
||||
"rules", "scripts", "styleSheets", "tBodies", "TextRectangle",
|
||||
|
||||
// Methods
|
||||
"add", "addBehavior", "AddFavorite", "addImport", "addRule", "alert",
|
||||
"appendChild", "applyElement", "assign", "attachEvent", "back", "blur",
|
||||
"clearAttributes", "clearData", "clearInterval", "clearRequest",
|
||||
"clearTimeout", "click", "cloneNode", "close", "collapse", "compareEndPoints",
|
||||
"componentFromPoint", "confirm", "contains", "createCaption", "createControlRange",
|
||||
"createElement", "createRange", "createStyleSheet", "createTextNode", "createTextRange",
|
||||
"createTFoot", "createTHead", "deleteCaption", "deleteCell", "deleteRow", "deleteTFoot",
|
||||
"deleteTHead", "detachEvent", "doScroll", "duplicate", "elementFromPoint",
|
||||
"empty", "execCommand", "execScript", "expand", "findText", "firstPage", "focus",
|
||||
"forward", "getAdjacentText", "getAttribute", "getBookmark", "getBoundingClientRect",
|
||||
"getClientRects", "getData", "getElementById", "getElementsByName", "getElementsByTagName",
|
||||
"getExpression", "go", "hasChildNodes", "inRange",
|
||||
"insertAdjacentElement", "insertAdjacentHTML", "insertAdjacentText", "insertBefore",
|
||||
"insertCell", "insertRow", "isEqual", "IsSubscribed", "item", "javaEnabled", "lastPage",
|
||||
"mergeAttributes", "move", "moveBy", "moveEnd", "moveRow", "moveStart", "moveTo",
|
||||
"moveToBookmark", "moveToElementText", "moveToPoint", "namedRecordset", "navigate",
|
||||
"NavigateAndFind", "nextPage", "open", "pasteHTML",
|
||||
"previousPage", "print", "prompt", "queryCommandEnabled", "queryCommandIndeterm",
|
||||
"queryCommandState", "queryCommandSupported", "queryCommandValue", "recalc", "refresh",
|
||||
"releaseCapture", "reload", "remove", "removeAttribute", "removeBehavior",
|
||||
"removeChild", "removeExpression", "removeNode", "removeRule", "replace",
|
||||
"replaceAdjacentText", "replaceChild", "replaceNode", "reset", "resizeBy",
|
||||
"resizeTo", "scroll", "scrollBy", "scrollIntoView", "scrollTo", "select",
|
||||
"setAttribute", "setCapture", "setData", "setEndPoint", "setExpression", "setInterval",
|
||||
"setTimeout", "ShowBrowserUI", "showHelp", "showModalDialog", "showModelessDialog",
|
||||
"splitText", "stop", "submit", "swapNode", "tags", "taintEnabled",
|
||||
"urns", "write", "writeln",
|
||||
// builtIn
|
||||
"toUpperCase", "toLowerCase", "match", "substring", "split", "indexOf",
|
||||
"parseFloat", "parseInt",
|
||||
"getYear", "getTime", "getMonth", "getFullYear", "getDay", "getDate",
|
||||
"exec", "join", "call", "floor", "toUTCString",
|
||||
|
||||
// events
|
||||
"onabort", "onafterprint", "onafterupdate", "onbeforecopy", "onbeforecut",
|
||||
"onbeforeeditfocus", "onbeforepaste", "onbeforeprint", "onbeforeunload",
|
||||
"onbeforeupdate", "onblur", "onbounce", "oncellchange", "onchange", "onclick",
|
||||
"oncontextmenu", "oncopy", "oncut", "ondataavailable", "ondatasetchanged", "ondatasetcomplete",
|
||||
"ondblclick", "ondrag", "ondragend", "ondragenter", "ondragleave", "ondragover",
|
||||
"ondragstart", "ondrop", "onerror", "onerrorupdate", "onfilterchange", "onfinish",
|
||||
"onfocus", "onhelp", "onkeydown", "onkeypress", "onkeyup", "onload",
|
||||
"onlosecapture", "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup",
|
||||
"onpaste", "onpropertychange", "onreset", "onresize", "onrowenter",
|
||||
"onrowexit", "onrowsdelete", "onrowsinserted", "onscroll", "onselect", "onselectstart",
|
||||
"onstart", "onstop", "onsubmit", "onunload",
|
||||
|
||||
// Ajax
|
||||
"XMLHttpRequest", "readyState", "onreadystatechange", "responseXML",
|
||||
"responseText", "responseBody", "statusText",
|
||||
"send", "abort", "setRequestHeader", "getResponseHeader", "getAllResponseHeaders",
|
||||
"timeout"
|
||||
};
|
||||
|
||||
public static final char[] DELIMITER = {'?', ':', '!', '=', '(', ')', '[', ']',
|
||||
'{', '}', '\r', '\n', '\t', ' ', '\"', '\'', '<', '>', ',', '.', '/',
|
||||
'\\', '+', '-', '*', '&', '|', '^', '%', ';'
|
||||
};
|
||||
|
||||
|
||||
public static final String[] alpha = {
|
||||
"m", "n", "q", "r", "s", "t", "u",
|
||||
"h", "i", "j", "k", "l", "o", "p",
|
||||
"d", "e", "f", "g", "a", "b", "c",
|
||||
"v", "w", "x", "y", "z", "$", "_"
|
||||
};
|
||||
|
||||
public static final HashSet exclusionTokenSet = new HashSet();
|
||||
public static final HashSet forceReplace = new HashSet();
|
||||
public static final HashSet forceReplaceInStrings = new HashSet();
|
||||
|
||||
public static final HashMap forceTextualReplace = new HashMap();
|
||||
|
||||
public static int ref = alpha.length;
|
||||
public static HashMap map = new HashMap();
|
||||
|
||||
public static final String ARG_EXCLUDE_TOKENS = "e=";
|
||||
public static final String ARG_DESTINATION_DIR = "d=";
|
||||
public static final String ARG_OBFUSCATE_STRING = "o=";
|
||||
public static final String ARG_DEBUG = "debug";
|
||||
public static final String ARG_DEBUGEXCLUDE = "debugnames";
|
||||
public static final String ARG_REPLACE = "textrepl=";
|
||||
|
||||
private double[] stringObfuscationParameter = {0, 0, 0.5};
|
||||
private String[] file = null;
|
||||
public static boolean isDebug = false;
|
||||
public static boolean isExcludeAll = false;
|
||||
private String destinationDir = null;
|
||||
private JSOState state = new JSOState();
|
||||
private String delimiter = new String(DELIMITER);
|
||||
private HashSet encounteredInStrings = new HashSet();
|
||||
private HashMap encounteredInStringsFiles = new HashMap();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ArrayList fileList = new ArrayList(args.length);
|
||||
String[] file = null;
|
||||
String destinationDir = null;
|
||||
double[] stringObfuscationParameter = {1, .59, 0.5};
|
||||
|
||||
if (args.length == 0) {
|
||||
printUsage();
|
||||
return;
|
||||
} else if (args.length > 1) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if( args[i].equals(ARG_DEBUG)) {
|
||||
isDebug = true;
|
||||
} else if( args[i].equals(ARG_DEBUGEXCLUDE) ) {
|
||||
isExcludeAll = true;
|
||||
} else if (args[i].startsWith(ARG_EXCLUDE_TOKENS)) {
|
||||
readexclusionTokenSet(args[i].substring(ARG_EXCLUDE_TOKENS.length()));
|
||||
} else if (args[i].startsWith(ARG_DESTINATION_DIR) && destinationDir == null) {
|
||||
File dir = new File(args[i].substring(ARG_DESTINATION_DIR.length()));
|
||||
if (!dir.exists() && !dir.mkdirs()) {
|
||||
System.err.println("Cannot create the output directory \"" + dir.getName() + "\"");
|
||||
return;
|
||||
} else if (dir.exists() && dir.isFile()) {
|
||||
System.err.println("The output parameter \"" + args[i] + "\" is not a directory");
|
||||
return;
|
||||
}
|
||||
destinationDir = dir.getAbsolutePath();
|
||||
} else if (args[i].startsWith(ARG_OBFUSCATE_STRING)) {
|
||||
String[] param = args[i].substring(ARG_OBFUSCATE_STRING.length()).split(",", 3);
|
||||
if (param.length >= 2) {
|
||||
try {
|
||||
stringObfuscationParameter[0] = Double.parseDouble(param[0]);
|
||||
stringObfuscationParameter[1] = Double.parseDouble(param[1]);
|
||||
if (param.length == 3) {
|
||||
stringObfuscationParameter[2] = Double.parseDouble(param[2]);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
System.err.println("The obfuscation parameters are not numbers.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
System.err.println("At least 2 obfuscation parameters are required, e.g. o=0.4,0.7.");
|
||||
return;
|
||||
}
|
||||
} else if( args[i].startsWith(ARG_REPLACE) ) {
|
||||
String[] param = args[i].substring(ARG_REPLACE.length()).split(",", 3);
|
||||
if (param.length == 2) {
|
||||
forceTextualReplace.put(param[0], param[1]);
|
||||
} else {
|
||||
System.err.println("2 parameters are required, e.g. textrepl=a,b");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
fileList.add(args[i]);
|
||||
}
|
||||
}
|
||||
file = new String[fileList.size()];
|
||||
fileList.toArray(file);
|
||||
} else {
|
||||
file = new String[]{args[0]};
|
||||
}
|
||||
addexclusionTokenSet(reserved);
|
||||
addexclusionTokenSet(builtIn);
|
||||
|
||||
JSO obfuscator = new JSO(file, destinationDir, stringObfuscationParameter);
|
||||
obfuscator.run();
|
||||
}
|
||||
|
||||
private static void printUsage() {
|
||||
System.err.println("Usage: java JSO <list of javascript file> [options]");
|
||||
System.err.println("");
|
||||
System.err.println("where the options are:");
|
||||
System.err.println("\te=<exception list file>");
|
||||
System.err.println("\t\t- filename of the exception list");
|
||||
System.err.println("\t\t- exception tokens are delimited by tab, space, dot, comma, ");
|
||||
System.err.println("\t\t single quote and double quote");
|
||||
System.err.println("\td=<destination directory>");
|
||||
System.err.println("\t\t- the output directory");
|
||||
System.err.println("\t\t- print to the STDOUT if not specified");
|
||||
System.err.println("\to=<obfuscation parameters of string literals>");
|
||||
System.err.println("\t\t- If it is specified, the characters in string literals will be ");
|
||||
System.err.println("\t\t encoded to either \\uXXXX (hexidemcial) or \\XXX (octal) format");
|
||||
System.err.println("\t\t- The parameters are a 2 or 3 floating point values delimited ");
|
||||
System.err.println(" by commas. e.g. 0.5,0.3 or 0.5,0.3,0.9");
|
||||
System.err.println("\t\t- The values are ");
|
||||
System.err.println("\t\t * probability to encode a string");
|
||||
System.err.println("\t\t * probability to encode a character in a candidate string");
|
||||
System.err.println("\t\t * probability to encode a character into \\uXXXX format");
|
||||
System.err.println("\t\t- The last parameter is set to 0.5 if not specified");
|
||||
System.err.println("");
|
||||
System.err.println("Press Enter to read the examples...");
|
||||
try{
|
||||
System.in.read();
|
||||
} catch (Exception e){}
|
||||
System.err.println("Examples:");
|
||||
System.err.println("");
|
||||
System.err.println(" Obfuscate all scripts in the current directory and output to ./out directory:");
|
||||
System.err.println("\tjava JSO *.js d=out");
|
||||
System.err.println("");
|
||||
System.err.println(" Pipe the STDOUT output to x.o.js:");
|
||||
System.err.println("\tjava JSO x.js > x.o.js ");
|
||||
System.err.println("");
|
||||
System.err.println(" Merge a.js and b.js and pipe the merged output to script.js. Tokens in ");
|
||||
System.err.println(" exception list, noReplace.txt will not be replaced:");
|
||||
System.err.println("\tjava JSO a.js b.js e=noReplace.txt > script.js");
|
||||
System.err.println("");
|
||||
System.err.println(" Obfuscate the 100% of string literals, 68% of the characters will be encoded. ");
|
||||
System.err.println(" 50% of the characters will be encoded as \\uXXXX format (default):");
|
||||
System.err.println("\tjava JSO x.js o=1,0.68");
|
||||
}
|
||||
|
||||
public JSO(String[] file, String destinationDir, double[] stringObfuscationParameter){
|
||||
this.file = file;
|
||||
this.destinationDir = destinationDir;
|
||||
if (stringObfuscationParameter != null && stringObfuscationParameter.length >= 2) {
|
||||
this.stringObfuscationParameter = stringObfuscationParameter;
|
||||
}
|
||||
}
|
||||
|
||||
public void run() throws IOException {
|
||||
for (int i = 0; i < file.length; i++) {
|
||||
BufferedReader in = new BufferedReader(new FileReader(file[i]));
|
||||
PrintWriter out = null;
|
||||
File f = new File(file[i]);
|
||||
|
||||
if (destinationDir == null) {
|
||||
out = new PrintWriter(System.out, true);
|
||||
} else {
|
||||
out = new PrintWriter(new FileWriter(new File(destinationDir + File.separator + f.getName())));
|
||||
}
|
||||
|
||||
this.obfuscate(in, out, f.getName());
|
||||
System.out.println("obfuscated " + f.getName());
|
||||
|
||||
in.close();
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
|
||||
|
||||
System.err.println( "Obfuscated" );
|
||||
System.err.println(map.toString().replace(',', '\n'));
|
||||
|
||||
encounteredInStrings.retainAll(map.keySet());
|
||||
System.err.println( "Not Obfuscated in strings:" );
|
||||
for( Iterator it = encounteredInStrings.iterator(); it.hasNext(); ) {
|
||||
String s = (String)it.next();
|
||||
System.err.println( "\t"+s+": " + (String)encounteredInStringsFiles.get(s) );
|
||||
}
|
||||
}
|
||||
|
||||
private void obfuscate(BufferedReader in, PrintWriter out, String fname) throws IOException {
|
||||
state.reset();
|
||||
|
||||
int line_counter = 0;
|
||||
for (String line = in.readLine(); line != null; line = in.readLine()) {
|
||||
line_counter++;
|
||||
if( !isDebug )
|
||||
line = line.trim();
|
||||
if (line.length() == 0) {
|
||||
if( isDebug )
|
||||
out.println();
|
||||
continue;
|
||||
}
|
||||
if( line.startsWith( "//-" ) ) {
|
||||
String[] toAdd = line.substring(3).split(",");
|
||||
for( int i = 0; i < toAdd.length; i++ )
|
||||
exclusionTokenSet.add(toAdd[i].trim());
|
||||
continue;
|
||||
} else if( line.startsWith("//+")) {
|
||||
String[] toAdd = line.substring(3).split(",");
|
||||
for( int i = 0; i < toAdd.length; i++ )
|
||||
forceReplace.add(toAdd[i].trim());
|
||||
continue;
|
||||
} else if( line.startsWith("//'")) {
|
||||
String[] toAdd = line.substring(3).split(",");
|
||||
for( int i = 0; i < toAdd.length; i++ ) {
|
||||
forceReplace.add(toAdd[i].trim());
|
||||
forceReplaceInStrings.add(toAdd[i].trim());
|
||||
}
|
||||
}
|
||||
|
||||
for( Iterator it = forceTextualReplace.keySet().iterator(); it.hasNext(); ) {
|
||||
String key = (String)it.next();
|
||||
line = line.replaceAll(key, (String)forceTextualReplace.get(key));
|
||||
}
|
||||
|
||||
StringTokenizer st = new StringTokenizer(line, delimiter, true);
|
||||
|
||||
if (st.hasMoreTokens()) {
|
||||
state.setToken(st.nextToken());
|
||||
}
|
||||
|
||||
for (; state.token != null; state.skipToken()) {
|
||||
if (st.hasMoreTokens()) {
|
||||
state.setNextToken(st.nextToken());
|
||||
} else {
|
||||
state.noToken();
|
||||
}
|
||||
|
||||
boolean doubleSlashed = state.flipFlags();
|
||||
if (doubleSlashed) {
|
||||
break;
|
||||
}
|
||||
|
||||
handleToken(out, fname, line_counter);
|
||||
}
|
||||
|
||||
if( isDebug )
|
||||
out.println();
|
||||
else if (!state.delimiter && !state.commented )
|
||||
out.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleToken(PrintWriter out, String fname, int line ) {
|
||||
if (state.token.length() > 0) {
|
||||
if (state.delimiter) {
|
||||
if (state.inString() && !state.backslashed && state.c != '\\' &&
|
||||
state.c != '\"' && state.c != '\'') {
|
||||
state.token = obfuscateQuotedString(state.token);
|
||||
}
|
||||
} else {
|
||||
if (state.inString()) {
|
||||
if( forceReplaceInStrings.contains(state.token) && canReplace(state.token) ) {
|
||||
state.token = generateToken(state.token);
|
||||
} else if( Character.isJavaIdentifierStart(state.token.charAt(0))) {
|
||||
encounteredInStrings.add(state.token);
|
||||
String s = (String)encounteredInStringsFiles.get(state.token);
|
||||
s = ( s == null ) ? "" : s + ", ";
|
||||
s += fname +"[" + line + "]";
|
||||
encounteredInStringsFiles.put(state.token, s);
|
||||
}
|
||||
if (!state.backslashed) {
|
||||
state.token = obfuscateQuotedString(state.token);
|
||||
}
|
||||
} else if( !state.commented ) {
|
||||
if(canReplace(state.token)){
|
||||
state.token = generateToken(state.token);
|
||||
} else if( state.token.length() > 0 && Character.isDigit( state.token.charAt(0) ) ) {
|
||||
try {
|
||||
int i = Integer.parseInt( state.token );
|
||||
double res = randomizer.nextDouble();
|
||||
int e = (int)(i * res);
|
||||
|
||||
if( i > 3 ) {
|
||||
if( res < 0.2 && i >= 16 )
|
||||
state.token = "0x"+Integer.toHexString(i);
|
||||
else if( res < 0.6 && i >= 8 )
|
||||
state.token = "0" + Integer.toOctalString(i);
|
||||
else
|
||||
state.token = "(" + e + "+" + (i-e) + ")";
|
||||
}
|
||||
|
||||
} catch( NumberFormatException ex ) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!state.commented && (state.printToken || state.inString())) {
|
||||
out.print(state.token);
|
||||
}
|
||||
|
||||
if (state.c == '}' && !state.commented && !isDebug) {
|
||||
out.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private static void readexclusionTokenSet(String file) throws IOException {
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
in = new BufferedReader(new FileReader(file));
|
||||
for (String line = in.readLine(); line != null; line = in.readLine()) {
|
||||
StringTokenizer st = new StringTokenizer(line, "\t ,.\"\'");
|
||||
for (; st.hasMoreTokens();) {
|
||||
exclusionTokenSet.add(st.nextToken());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String obfuscateQuotedString(String token) {
|
||||
if (randomizer.nextDouble() < stringObfuscationParameter[0]) {
|
||||
StringBuffer buffer = new StringBuffer(token.length());
|
||||
int n = token.length();
|
||||
int pos = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (randomizer.nextDouble() < stringObfuscationParameter[1]) {
|
||||
buffer.append(token.substring(pos, i));
|
||||
encode(token.charAt(i), buffer);
|
||||
pos = i + 1;
|
||||
}
|
||||
}
|
||||
if (pos < n) {
|
||||
buffer.append(token.substring(pos));
|
||||
}
|
||||
return buffer.toString();
|
||||
} else {
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
private void encode(char c, StringBuffer buffer) {
|
||||
if (randomizer.nextDouble() < stringObfuscationParameter[2] || c > 0777) {
|
||||
buffer.append("\\u");
|
||||
encode(c, 16, 4, buffer);
|
||||
} else {
|
||||
buffer.append("\\");
|
||||
encode(c, 8, 3, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private void encode(char c, int radix, int length, StringBuffer buffer) {
|
||||
String value = Integer.toString(c, radix);
|
||||
int n = length - value.length();
|
||||
|
||||
if (n > 0) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
buffer.append('0');
|
||||
}
|
||||
buffer.append(value);
|
||||
} else {
|
||||
buffer.append(value.substring(-n));
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateToken(String token) {
|
||||
if (map.containsKey(token)) {
|
||||
return (String) map.get(token);
|
||||
} else {
|
||||
String result = null;
|
||||
do {
|
||||
StringBuffer buffer = new StringBuffer(token.length());
|
||||
for (int i = ref; i > 0; i = i / alpha.length) {
|
||||
buffer.append(alpha[i % alpha.length]);
|
||||
}
|
||||
|
||||
ref++;
|
||||
result = buffer.toString();
|
||||
} while (exclusionTokenSet.contains(result) || map.containsValue(result));
|
||||
|
||||
map.put(token, result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean canReplace(String token) {
|
||||
if (token.length() <= 1 || token.charAt(0) == '$' )
|
||||
return false;
|
||||
if (map.containsKey(token))
|
||||
return true;
|
||||
if( isExcludeAll )
|
||||
return false;
|
||||
if( forceReplace.contains(token) )
|
||||
return true;
|
||||
if (exclusionTokenSet.contains(token) )
|
||||
return false;
|
||||
if (Character.isDigit(token.charAt(0)))
|
||||
return false;
|
||||
if( token.charAt(0) == '_' )
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void addexclusionTokenSet(String[] array) {
|
||||
if (array != null) {
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if( exclusionTokenSet.contains(array[i]) )
|
||||
System.err.println( "warn, already excluded: " + array[i] );
|
||||
exclusionTokenSet.add(array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isDelimiter(String token) {
|
||||
if (token != null && token.length() > 0) {
|
||||
for (int i = 0; i < DELIMITER.length; i++) {
|
||||
if (token.charAt(0) == DELIMITER[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class JSOState {
|
||||
boolean dotted = false;
|
||||
boolean doubleQuoted = false;
|
||||
boolean singleQuoted = false;
|
||||
boolean backslashed = false;
|
||||
boolean commented = false;
|
||||
boolean printToken = true;
|
||||
boolean delimiter = false;
|
||||
|
||||
String token;
|
||||
String lastToken;
|
||||
String nextToken;
|
||||
|
||||
char c0 = 0;
|
||||
char c = 0;
|
||||
char c2 = 0;
|
||||
|
||||
void reset() {
|
||||
dotted = false;
|
||||
doubleQuoted = false;
|
||||
singleQuoted = false;
|
||||
backslashed = false;
|
||||
commented = false;
|
||||
printToken = true;
|
||||
delimiter = false;
|
||||
|
||||
token = null;
|
||||
lastToken = null;
|
||||
nextToken = null;
|
||||
|
||||
c0 = 0;
|
||||
c = 0;
|
||||
c2 = 0;
|
||||
}
|
||||
|
||||
boolean printable() {
|
||||
return !commented && (printToken || inString());
|
||||
}
|
||||
|
||||
boolean inString() {
|
||||
return doubleQuoted || singleQuoted;
|
||||
}
|
||||
|
||||
boolean delimiterSurrounded() {
|
||||
return !JSO.isDelimiter(nextToken) && !JSO.isDelimiter(lastToken);
|
||||
}
|
||||
|
||||
boolean isWhitespace(){
|
||||
return Character.isWhitespace(c);
|
||||
}
|
||||
|
||||
String setToken(String value) {
|
||||
String oldToken = lastToken;
|
||||
lastToken = token;
|
||||
token = value;
|
||||
nextToken = null;
|
||||
|
||||
if (value != null) {
|
||||
c0 = c;
|
||||
c = token == null ? 0 : token.charAt(0);
|
||||
c2 = 0;
|
||||
|
||||
backslashed = c0 == '\\';
|
||||
dotted = c0 == '.';
|
||||
delimiter = JSO.isDelimiter(token);
|
||||
printToken = true;
|
||||
}
|
||||
|
||||
return oldToken;
|
||||
}
|
||||
|
||||
String tokenBackslashed() {
|
||||
String result = null;
|
||||
int index = 0;
|
||||
if (c == 'u') {
|
||||
index = 4;
|
||||
} else if (Character.isDigit(c)) {
|
||||
index = 3;
|
||||
} else {
|
||||
throw new IllegalStateException("Token not backslashed or invalid JavaScript syntax.");
|
||||
}
|
||||
result = token.substring(0, index);
|
||||
token = token.substring(index);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void setNextToken(String value) {
|
||||
nextToken = value;
|
||||
c2 = value.charAt(0);
|
||||
}
|
||||
|
||||
void skipToken() {
|
||||
this.setToken(nextToken);
|
||||
}
|
||||
|
||||
void noToken() {
|
||||
nextToken = null;
|
||||
c2 = 0;
|
||||
}
|
||||
|
||||
boolean flipFlags() {
|
||||
if (isWhitespace()) {
|
||||
printToken = delimiterSurrounded() || JSO.isDebug;
|
||||
} else if (c == '/') {
|
||||
if (!commented && c2 == '/') {
|
||||
return true;
|
||||
} else if (!commented && c2 == '*' &&
|
||||
!inString()) {
|
||||
commented = true;
|
||||
} else if (commented && c0 == '*') {
|
||||
commented = false;
|
||||
printToken = false;
|
||||
}
|
||||
} else if (c == '\"' && !singleQuoted && !backslashed && !commented) {
|
||||
doubleQuoted = !doubleQuoted;
|
||||
} else if (c == '\'' && !doubleQuoted && !backslashed && !commented) {
|
||||
singleQuoted = !singleQuoted;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
34
src/messenger/js/build.xml
Normal file
34
src/messenger/js/build.xml
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE project [<!ENTITY buildfile SYSTEM "file:./build-user.xml">]>
|
||||
|
||||
<project basedir="." default="update" name="Obfuscator">
|
||||
<property name="obfuscator.location" value="." />
|
||||
<property name="webim.location" value="../webim" />
|
||||
|
||||
<target name="update" depends="build">
|
||||
<java classname="JSO" fork="true" error="${obfuscator.location}/bin/obfuscation.log">
|
||||
<arg value="${obfuscator.location}/common.js" />
|
||||
<arg value="${obfuscator.location}/chat.js" />
|
||||
<arg value="${obfuscator.location}/users.js" />
|
||||
<arg value="${obfuscator.location}/brws.js" />
|
||||
<arg value="d=${webim.location}/js/" />
|
||||
<!-- <arg value="debug"/> -->
|
||||
<!-- <arg value="debugnames"/> -->
|
||||
<!-- <arg value="o=0,0"/> -->
|
||||
<classpath>
|
||||
<pathelement location="${obfuscator.location}/bin/" />
|
||||
</classpath>
|
||||
</java>
|
||||
</target>
|
||||
|
||||
<target name="build" depends="init">
|
||||
<javac destdir="${obfuscator.location}/bin" fork="false">
|
||||
<src path="${obfuscator.location}" />
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${obfuscator.location}/bin"/>
|
||||
</target>
|
||||
|
||||
</project>
|
@ -1,19 +1,16 @@
|
||||
var FrameUtils = {
|
||||
getDocument: function(frm) {
|
||||
if (frm.contentDocument) {
|
||||
return frm.contentDocument;
|
||||
return frm.contentDocument;
|
||||
} else if (frm.contentWindow) {
|
||||
return frm.contentWindow.document;
|
||||
} else if (frm.document) {
|
||||
return frm.document;
|
||||
} else {
|
||||
alert( myRealAgent + ": cannot find document in frame " + frm);
|
||||
//for( var a in frm )
|
||||
// alert( a );
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
initFrame: function(frm) {
|
||||
var doc = this.getDocument(frm);
|
||||
doc.open();
|
||||
@ -57,8 +54,11 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
this.setOptions(_options);
|
||||
this._options.onComplete = this.requestComplete.bind(this);
|
||||
this._options.onException = this.handleException.bind(this);
|
||||
this._options.onTimeout = this.handleTimeout.bind(this);
|
||||
this._options.timeout = 5000;
|
||||
this.updater = {};
|
||||
this.frequency = (this._options.frequency || 2);
|
||||
this.lastupdate = 0;
|
||||
this.cansend = true;
|
||||
FrameUtils.initFrame(this._options.container);
|
||||
if( this._options.message ) {
|
||||
@ -70,9 +70,15 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
},
|
||||
|
||||
handleException: function(_request, ex) {
|
||||
this.setStatus(ex.name + " occured: " + ex.message);
|
||||
this.setStatus("offline, reconnecting");
|
||||
this.stopUpdate();
|
||||
this.timer = setTimeout(this.update.bind(this), this.frequency * 1000);
|
||||
this.timer = setTimeout(this.update.bind(this), 1000);
|
||||
},
|
||||
|
||||
handleTimeout: function(_request) {
|
||||
this.setStatus("timeout, reconnecting");
|
||||
this.stopUpdate();
|
||||
this.timer = setTimeout(this.update.bind(this), 1000);
|
||||
},
|
||||
|
||||
updateOptions: function(act) {
|
||||
@ -82,9 +88,9 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
if( this._options.user )
|
||||
this._options.parameters += "&user=true";
|
||||
if( act == 'refresh' && this._options.message && this._options.message.value != '' )
|
||||
this._options.parameters += "&typed=1";
|
||||
this._options.parameters += "&typed=1";
|
||||
},
|
||||
|
||||
|
||||
enableInput: function(val) {
|
||||
if( this._options.message )
|
||||
this._options.message.disabled = !val;
|
||||
@ -103,24 +109,26 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
},
|
||||
|
||||
requestComplete: function(_response) {
|
||||
this.enableInput(true);
|
||||
this.cansend = true;
|
||||
var xmlRoot = Ajax.getXml(_response);
|
||||
if( xmlRoot && xmlRoot.tagName == 'thread' ) {
|
||||
this.updateContent( xmlRoot );
|
||||
} else {
|
||||
this.handleError(_response, xmlRoot, 'refresh messages failed');
|
||||
}
|
||||
|
||||
try {
|
||||
this.enableInput(true);
|
||||
this.cansend = true;
|
||||
var xmlRoot = Ajax.getXml(_response);
|
||||
if( xmlRoot && xmlRoot.tagName == 'thread' ) {
|
||||
this.updateContent( xmlRoot );
|
||||
} else {
|
||||
this.handleError(_response, xmlRoot, 'refresh messages failed');
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
this.timer = setTimeout(this.update.bind(this), this.frequency * 1000);
|
||||
},
|
||||
|
||||
postMessage: function(msg) {
|
||||
if( msg == "" || !this.cansend) {
|
||||
return;
|
||||
}
|
||||
this.cansend = false;
|
||||
this.stopUpdate();
|
||||
if( msg == "" || !this.cansend) {
|
||||
return;
|
||||
}
|
||||
this.cansend = false;
|
||||
this.stopUpdate();
|
||||
this.updateOptions("post");
|
||||
var postOptions = {}.extend(this._options);
|
||||
postOptions.parameters += "&message=" + encodeURIComponent(msg);
|
||||
@ -137,10 +145,10 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
},
|
||||
|
||||
changeName: function(newname) {
|
||||
new Ajax.Request(this._options.servl, {parameters:'act=rename&thread=' + (this._options.threadid || -1) +
|
||||
new Ajax.Request(this._options.servl, {parameters:'act=rename&thread=' + (this._options.threadid || -1) +
|
||||
'&token=' + (this._options.token || 0) + '&name=' + encodeURIComponent(newname)});
|
||||
},
|
||||
|
||||
|
||||
onThreadClosed: function(_response) {
|
||||
var xmlRoot = Ajax.getXml(_response);
|
||||
if( xmlRoot && xmlRoot.tagName == 'closed' ) {
|
||||
@ -165,14 +173,14 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
showTyping: function(istyping) {
|
||||
if( $("typingdiv") ) {
|
||||
$("typingdiv").style.display=istyping ? 'inline' : 'none';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setupAvatar: function(avatar) {
|
||||
var imageLink = NodeUtils.getNodeText(avatar);
|
||||
if( this._options.avatar && this._options.user ) {
|
||||
this._options.avatar.innerHTML = imageLink != ""
|
||||
? "<img src=\""+Chat.webimRoot+"/images/free.gif\" width=\"7\" height=\"1\" border=\"0\" alt=\"\" /><img src=\""
|
||||
this._options.avatar.innerHTML = imageLink != ""
|
||||
? "<img src=\""+Chat.webimRoot+"/images/free.gif\" width=\"7\" height=\"1\" border=\"0\" alt=\"\" /><img src=\""
|
||||
+imageLink+ "\" border=\"0\" alt=\"\"/>"
|
||||
: "";
|
||||
}
|
||||
@ -186,7 +194,7 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
if( _lastid ) {
|
||||
this._options.lastid = _lastid;
|
||||
}
|
||||
|
||||
|
||||
var typing = NodeUtils.getAttrValue(xmlRoot, "typing");
|
||||
if( typing ) {
|
||||
this.showTyping(typing == '1');
|
||||
@ -195,20 +203,34 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
for( var i = 0; i < xmlRoot.childNodes.length; i++ ) {
|
||||
var node = xmlRoot.childNodes[i];
|
||||
if( node.tagName == 'message' ) {
|
||||
haveMessage = true;
|
||||
haveMessage = true;
|
||||
this.processMessage(result_div, node);
|
||||
} else if( node.tagName == 'avatar' ) {
|
||||
this.setupAvatar(node);
|
||||
}
|
||||
// TODO thread events
|
||||
}
|
||||
}
|
||||
if( haveMessage ) {
|
||||
if(window.location.search.indexOf('trace=on')>=0) {
|
||||
var val = "updated";
|
||||
if(this.lastupdate > 0) {
|
||||
var seconds = ((new Date()).getTime() - this.lastupdate)/1000;
|
||||
val = val + ", " + seconds + " secs";
|
||||
if(seconds > 10) {
|
||||
alert(val);
|
||||
}
|
||||
}
|
||||
this.lastupdate = (new Date()).getTime();
|
||||
this.setStatus(val);
|
||||
} else {
|
||||
this.clearStatus();
|
||||
}
|
||||
if( haveMessage ) {
|
||||
FrameUtils.scrollDown(this._options.container);
|
||||
if( !this.focused )
|
||||
if( !this.focused ) {
|
||||
window.focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
handleKeyDown: function(k) {
|
||||
if( k ){ ctrl=k.ctrlKey;k=k.which; } else { k=event.keyCode;ctrl=event.ctrlKey; }
|
||||
if( this._options.message && ((k==13 && (ctrl || myRealAgent == 'opera')) || (k==10)) ) {
|
||||
@ -226,19 +248,26 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
if( xmlRoot && xmlRoot.tagName == 'error' ) {
|
||||
this.setStatus(NodeUtils.getNodeValue(xmlRoot,"descr"));
|
||||
} else {
|
||||
this.setStatus(_action+', ' + Ajax.getError(_response));
|
||||
}
|
||||
this.setStatus("reconnecting");
|
||||
}
|
||||
},
|
||||
|
||||
showStatusDiv: function(k) {
|
||||
if( $("engineinfo") ) {
|
||||
$("engineinfo").style.display='inline';
|
||||
$("engineinfo").innerHTML = k;
|
||||
}
|
||||
},
|
||||
|
||||
setStatus: function(k) {
|
||||
if( this.statusTimeout )
|
||||
clearTimeout(this.statusTimeout);
|
||||
window.status = k;
|
||||
this.showStatusDiv(k);
|
||||
this.statusTimeout = setTimeout(this.clearStatus.bind(this), 4000);
|
||||
},
|
||||
|
||||
clearStatus: function() {
|
||||
window.status = "";
|
||||
$("engineinfo").style.display='none';
|
||||
}
|
||||
});
|
||||
|
||||
@ -246,7 +275,7 @@ Class.inherit( Ajax.ChatThreadUpdater, Ajax.Base, {
|
||||
HSplitter = Class.create();
|
||||
HSplitter.prototype = {
|
||||
initialize: function(_options) {
|
||||
this._options = _options;
|
||||
this._options = _options;
|
||||
this.captured = 0;
|
||||
if( this._options.first && this._options.second && this._options.control ) {
|
||||
this._options.control.onmousedown = this.onmousedownEvent.bind(this);
|
||||
@ -255,7 +284,7 @@ HSplitter.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
onmousedownEvent: function(e) {
|
||||
onmousedownEvent: function(e) {
|
||||
var ev = e || event;
|
||||
|
||||
if( this._options.control.setCapture )
|
||||
@ -294,13 +323,14 @@ HSplitter.prototype = {
|
||||
var Chat = {
|
||||
threadUpdater : {},
|
||||
hSplitter : {},
|
||||
|
||||
|
||||
applyName: function() {
|
||||
Chat.threadUpdater.changeName($('uname').value);
|
||||
$('changename1').style.display='none';
|
||||
$('changename2').style.display='inline';
|
||||
$('unamelink').innerHTML=$('uname').value;
|
||||
},
|
||||
|
||||
|
||||
showNameField: function() {
|
||||
$('changename1').style.display='inline';
|
||||
$('changename2').style.display='none';
|
||||
@ -323,7 +353,7 @@ Behaviour.register({
|
||||
'select#predefined' : function(el) {
|
||||
el.onchange = function() {
|
||||
var message = $('msgwnd');
|
||||
message.value = this.options[this.selectedIndex].innerText || this.options[this.selectedIndex].innerHTML;
|
||||
message.value = this.options[this.selectedIndex].innerText || this.options[this.selectedIndex].innerHTML;
|
||||
this.selectedIndex = 0;
|
||||
message.focus();
|
||||
};
|
||||
@ -350,7 +380,7 @@ Behaviour.register({
|
||||
},
|
||||
'a#refresh' : function(el) {
|
||||
el.onclick = function() {
|
||||
Chat.threadUpdater.stopUpdate();
|
||||
Chat.threadUpdater.stopUpdate();
|
||||
Chat.threadUpdater.update();
|
||||
};
|
||||
},
|
||||
@ -365,4 +395,4 @@ EventHelper.register(window, 'onload', function(){
|
||||
Chat.webimRoot = threadParams.wroot;
|
||||
Chat.hSplitter = new HSplitter({control:$("spl1"), first:$("msgwndtd"), second:$("chatwndtd"), minfirst:30, minsec:30});
|
||||
Chat.threadUpdater = new Ajax.ChatThreadUpdater(({container:myRealAgent=='safari'?self.frames[0]:$("chatwnd"),avatar:$("avatarwnd"),message:$("msgwnd")}).extend( threadParams || {} ));
|
||||
});
|
||||
});
|
@ -17,7 +17,7 @@
|
||||
|
||||
var Class = {
|
||||
create: function() {
|
||||
return function() {
|
||||
return function() {
|
||||
this./**/initialize./**/apply(this, arguments);
|
||||
};
|
||||
},
|
||||
@ -92,10 +92,10 @@ PeriodicalExecuter.prototype = {
|
||||
|
||||
onTimerEvent: function() {
|
||||
if (!this.currentlyExecuting) {
|
||||
try {
|
||||
try {
|
||||
this.currentlyExecuting = true;
|
||||
this.callback();
|
||||
} finally {
|
||||
this.callback();
|
||||
} finally {
|
||||
this.currentlyExecuting = false;
|
||||
}
|
||||
}
|
||||
@ -115,7 +115,7 @@ function findObj( id )
|
||||
if( x.length == 0 ) return null;
|
||||
if( x.length == 1 ) return x[ 0 ];
|
||||
}
|
||||
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ function $() {
|
||||
if (typeof elem == 'string')
|
||||
elem = findObj(elem);
|
||||
|
||||
if (arguments.length == 1)
|
||||
if (arguments.length == 1)
|
||||
return elem;
|
||||
|
||||
elems.push(elem);
|
||||
@ -150,15 +150,15 @@ if (!Function.prototype.apply) {
|
||||
var parameterStrings = new Array();
|
||||
if (!obj) obj = window;
|
||||
if (!params) params = new Array();
|
||||
|
||||
|
||||
for (var i = 0; i < params.length; i++)
|
||||
parameterStrings[i] = 'params[' + i + ']';
|
||||
|
||||
|
||||
obj.$apply$ = this;
|
||||
var result = eval('obj.$apply$(' +
|
||||
var result = eval('obj.$apply$(' +
|
||||
parameterStrings.join(', ') + ')');
|
||||
obj.$apply$ = null;
|
||||
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
@ -174,7 +174,7 @@ var Ajax = {
|
||||
|
||||
getXml: function(_response) {
|
||||
if( _response &&
|
||||
_response.status >= 200 &&
|
||||
_response.status >= 200 &&
|
||||
_response.status < 300 ) {
|
||||
var xmlDoc = _response.responseXML;
|
||||
if( xmlDoc && xmlDoc.documentElement )
|
||||
@ -182,7 +182,7 @@ var Ajax = {
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
getError: function(_response) {
|
||||
return _response.statusText || "connection error N" + _response.status;
|
||||
},
|
||||
@ -200,10 +200,15 @@ Ajax.Base.prototype = {
|
||||
}.extend(_options || {});
|
||||
},
|
||||
|
||||
getStatus: function() {
|
||||
try {
|
||||
return this.transport.status || 0;
|
||||
} catch (e) { return 0 }
|
||||
},
|
||||
|
||||
responseIsSuccess: function() {
|
||||
return this./**/transport.status == undefined
|
||||
|| this.transport.status == 0
|
||||
|| (this.transport.status >= 200 && this.transport.status < 300);
|
||||
var status = this.getStatus();
|
||||
return !status || (status >= 200 && status < 300);
|
||||
},
|
||||
|
||||
responseIsFailure: function() {
|
||||
@ -212,13 +217,15 @@ Ajax.Base.prototype = {
|
||||
};
|
||||
|
||||
Ajax./**/Request = Class.create();
|
||||
Ajax.Request./**/Events =
|
||||
Ajax.Request./**/Events =
|
||||
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
|
||||
|
||||
Class.inherit( Ajax.Request, Ajax.Base, {
|
||||
initialize: function(url, _options) {
|
||||
this.transport = Ajax.getTransport();
|
||||
this.setOptions(_options);
|
||||
this.transportTimer = {};
|
||||
this.finished = false;
|
||||
this.request(url);
|
||||
},
|
||||
|
||||
@ -230,11 +237,13 @@ Class.inherit( Ajax.Request, Ajax.Base, {
|
||||
if (this._options._method == 'get' && parameters.length > 0)
|
||||
url += '?' + parameters;
|
||||
|
||||
this.transport.open(this._options._method, url, this._options.asynchronous);
|
||||
this.transport.open(this._options._method.toUpperCase(), url, this._options.asynchronous);
|
||||
|
||||
if (this._options.asynchronous) {
|
||||
this.transport.onreadystatechange = this.onStateChange.bind(this);
|
||||
setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
|
||||
if(this._options.timeout) {
|
||||
this.transportTimer = setTimeout(this.handleTimeout.bind(this), this._options.timeout);
|
||||
}
|
||||
}
|
||||
|
||||
this.setRequestHeaders();
|
||||
@ -248,18 +257,19 @@ Class.inherit( Ajax.Request, Ajax.Base, {
|
||||
},
|
||||
|
||||
setRequestHeaders: function() {
|
||||
var requestHeaders =
|
||||
var requestHeaders =
|
||||
['X-Requested-With', 'XMLHttpRequest'];
|
||||
|
||||
if (this._options._method == 'post') {
|
||||
requestHeaders.push('Content-type',
|
||||
requestHeaders.push('Content-type',
|
||||
'application/x-www-form-urlencoded');
|
||||
|
||||
/* Force "Connection: close" for Mozilla browsers to work around
|
||||
* a bug where XMLHttpReqeuest sends an incorrect Content-length
|
||||
* header. See Mozilla Bugzilla #246651.
|
||||
/* Force "Connection: close" for older Mozilla browsers to work
|
||||
* around a bug where XMLHttpRequest sends an incorrect
|
||||
* Content-length header. See Mozilla Bugzilla #246651.
|
||||
*/
|
||||
if (this.transport.overrideMimeType)
|
||||
if (this.transport.overrideMimeType &&
|
||||
(navigator.userAgent.match("/Gecko\/(\d{4})/") || [0,2005])[1] < 2005)
|
||||
requestHeaders.push('Connection', 'close');
|
||||
}
|
||||
|
||||
@ -276,18 +286,10 @@ Class.inherit( Ajax.Request, Ajax.Base, {
|
||||
this.respondToReadyState(this.transport.readyState);
|
||||
},
|
||||
|
||||
header: function(name) {
|
||||
try {
|
||||
return this.transport.getResponseHeader(name);
|
||||
} catch (e) {}
|
||||
},
|
||||
|
||||
evalResponse: function() {
|
||||
try {
|
||||
return eval(this.transport.responseText);
|
||||
} catch (e) {
|
||||
this.dispatchException(e);
|
||||
}
|
||||
handleTimeout: function() {
|
||||
if(this.finished) { return; }
|
||||
this.finished = true;
|
||||
(this._options.onTimeout || Ajax.emptyFunction)(this);
|
||||
},
|
||||
|
||||
respondToReadyState: function(readystate) {
|
||||
@ -295,26 +297,18 @@ Class.inherit( Ajax.Request, Ajax.Base, {
|
||||
|
||||
if (event == 'Complete') {
|
||||
try {
|
||||
(this._options['on' + this.transport.status]
|
||||
|| this._options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
|
||||
|| Ajax.emptyFunction)(this.transport);
|
||||
if(!this.finished) {
|
||||
this.finished = true;
|
||||
if(this._options.timeout) { clearTimeout(this.transportTimer); }
|
||||
(this._options.onComplete || Ajax.emptyFunction)(this.transport);
|
||||
}
|
||||
} catch (e) {
|
||||
this.dispatchException(e);
|
||||
}
|
||||
|
||||
if ((this.header('Content-type') || '').match("text\\/javascript"))
|
||||
this.evalResponse();
|
||||
}
|
||||
|
||||
try {
|
||||
(this._options['on' + event] || Ajax.emptyFunction)(this.transport);
|
||||
} catch (e) {
|
||||
this.dispatchException(e);
|
||||
}
|
||||
|
||||
/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
|
||||
if (event == 'Complete')
|
||||
/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
|
||||
this.transport.onreadystatechange = Ajax.emptyFunction;
|
||||
}
|
||||
},
|
||||
|
||||
dispatchException: function(exception) {
|
||||
@ -325,7 +319,7 @@ Class.inherit( Ajax.Request, Ajax.Base, {
|
||||
var EventHelper = {
|
||||
register : function(obj, ev,func){
|
||||
var oldev = obj[ev];
|
||||
|
||||
|
||||
if (typeof oldev != 'function') {
|
||||
obj[ev] = func;
|
||||
} else {
|
||||
@ -341,7 +335,7 @@ var EventHelper = {
|
||||
Behaviour v1.1 by Ben Nolan, June 2005. Based largely on the work
|
||||
of Simon Willison (see comments by Simon below).
|
||||
http://ripcord.co.nz/behaviour/
|
||||
*/
|
||||
*/
|
||||
|
||||
var Behaviour = {
|
||||
list : new Array,
|
||||
@ -436,11 +430,11 @@ document.getElementsBySelector = function(selector) {
|
||||
}
|
||||
|
||||
// [evgeny] code for attribute selection is removed...
|
||||
|
||||
|
||||
if (!currentContext[0]){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// If we get here, token is JUST an element (not a class or ID selector)
|
||||
tag_name = token;
|
||||
var found = new Array;
|
||||
@ -492,14 +486,14 @@ var CommonUtils = {
|
||||
return _row;
|
||||
if( _table.rows['head'] != null )
|
||||
return null;
|
||||
|
||||
|
||||
for( k=0; k < _table.rows.length; k++ ) {
|
||||
if( _table.rows[k].id == _id )
|
||||
return _table.rows[k];
|
||||
}
|
||||
return null;
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
getCell: function(_id,_row,_table) {
|
||||
var _cell = _row.cells[_id];
|
||||
if( _cell != null )
|
||||
@ -510,9 +504,9 @@ var CommonUtils = {
|
||||
if( _row.cells[k].id == _id )
|
||||
return _row.cells[k];
|
||||
}
|
||||
return null;
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
insertCell: function(_row,_id,_className,_align,_height, _inner) {
|
||||
var cell = _row.insertCell(-1);
|
||||
cell.id = _id;
|
||||
@ -524,3 +518,4 @@ var CommonUtils = {
|
||||
cell.innerHTML = _inner;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,16 +5,25 @@ Class.inherit( Ajax.PeriodicalUpdater, Ajax.Base, {
|
||||
this.setOptions(_options);
|
||||
this._options.onComplete = this.requestComplete.bind(this);
|
||||
this._options.onException = this.handleException.bind(this);
|
||||
this._options.onTimeout = this.handleTimeout.bind(this);
|
||||
this._options.timeout = 5000;
|
||||
this.frequency = (this._options.frequency || 2);
|
||||
this.updater = {};
|
||||
this.update();
|
||||
},
|
||||
|
||||
|
||||
handleException: function(_request, ex) {
|
||||
if( this._options.handleError )
|
||||
this._options.handleError( ex.name + " occured: " + ex.message );
|
||||
this._options.handleError("offline, reconnecting");
|
||||
this.stopUpdate();
|
||||
this.timer = setTimeout(this.update.bind(this), this.frequency * 1000);
|
||||
this.timer = setTimeout(this.update.bind(this), 1000);
|
||||
},
|
||||
|
||||
handleTimeout: function(_request) {
|
||||
if( this._options.handleError )
|
||||
this._options.handleError("timeout, reconnecting");
|
||||
this.stopUpdate();
|
||||
this.timer = setTimeout(this.update.bind(this), 1000);
|
||||
},
|
||||
|
||||
stopUpdate: function() {
|
||||
@ -30,14 +39,16 @@ Class.inherit( Ajax.PeriodicalUpdater, Ajax.Base, {
|
||||
},
|
||||
|
||||
requestComplete: function(presponse) {
|
||||
if (presponse != null && presponse.status == 200 ) {
|
||||
var xmlDoc = presponse.responseXML;
|
||||
(this._options.updateContent || Ajax.emptyFunction)( xmlDoc );
|
||||
} else {
|
||||
if( this._options.handleError )
|
||||
this._options.handleError(Ajax.getError(_response));
|
||||
try {
|
||||
var xmlRoot = Ajax.getXml(presponse);
|
||||
if( xmlRoot ) {
|
||||
(this._options.updateContent || Ajax.emptyFunction)( xmlRoot );
|
||||
} else {
|
||||
if( this._options.handleError )
|
||||
this._options.handleError("reconnecting");
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
this.timer = setTimeout(this.update.bind(this), this.frequency * 1000);
|
||||
}
|
||||
});
|
||||
@ -49,13 +60,13 @@ var HtmlGenerationUtils = {
|
||||
cell.style.backgroundImage = 'url('+webimRoot+'/images/tablediv3.gif)';
|
||||
cell.innerHTML = '<img src="'+webimRoot+'/images/free.gif" width="3" height="1" border="0" alt="">';
|
||||
},
|
||||
|
||||
|
||||
removeHr: function(_table, _index ) {
|
||||
_table.deleteRow(_index+2);
|
||||
_table.deleteRow(_index+1);
|
||||
_table.deleteRow(_index);
|
||||
},
|
||||
|
||||
|
||||
insertHr: function(_table, _index) {
|
||||
var row = _table.insertRow(_index);
|
||||
var cell = row.insertCell(-1);
|
||||
@ -74,12 +85,12 @@ var HtmlGenerationUtils = {
|
||||
cell.height = 2;
|
||||
},
|
||||
|
||||
popupLink: function(link, title, wndid, inner, width, height) {
|
||||
return '<a href="'+link+'" target="_blank" title="'+title+'" onclick="this.newWindow = window.open(\''+link+'\', \''+
|
||||
popupLink: function(link, title, wndid, inner, width, height,linkclass) {
|
||||
return '<a href="'+link+'"'+(linkclass != null ? ' class="'+linkclass+'"' : '')+' target="_blank" title="'+title+'" onclick="this.newWindow = window.open(\''+link+'\', \''+
|
||||
wndid+'\', \'toolbar=0,scrollbars=0,location=0,status=1,menubar=0,width='+width+',height='+height+',resizable=1\');this.newWindow.focus();this.newWindow.opener=window;return false;">'+
|
||||
inner+'</a>';
|
||||
},
|
||||
|
||||
|
||||
generateOneRowTable: function(content) {
|
||||
return '<table width="100%" cellspacing="0" cellpadding="0" border="0"><tr>' + content + '</tr></table>';
|
||||
},
|
||||
@ -87,21 +98,18 @@ var HtmlGenerationUtils = {
|
||||
viewOpenCell: function(username,servlet,id,canview,canopen,ban,message) {
|
||||
var cellsCount = 2;
|
||||
var link = servlet+"?thread="+id;
|
||||
var innerContent = ( ban == "full" ) ? "<i style='color:#aaaaaa;'>"+username+"</i>" : ( ( ban == "other" ) ? "<i>"+username+"</i>" : username );
|
||||
var gen = '<td class="table" style="padding-left:0px; padding-right:0px;">';
|
||||
gen += HtmlGenerationUtils.popupLink( canopen ? link : link+"&viewonly=true", localized[canopen ? 0 : 1], "ImCenter"+id, innerContent, 600, 420);
|
||||
gen += HtmlGenerationUtils.popupLink( link, localized[canopen ? 0 : 1], "ImCenter"+id, username, 600, 420, ban);
|
||||
gen += '</td><td><img src="'+webimRoot+'/images/free.gif" width="5" height="1" border="0" alt=""></td>';
|
||||
if( canopen ) {
|
||||
gen += '<td width="30" align="center">';
|
||||
gen += HtmlGenerationUtils.popupLink( link, localized[0], "ImCenter"+id, '<img src="'+webimRoot+'/images/tbliclspeak.gif" width="15" height="15" border="0" alt="'+localized[0]+'">', 600, 420);
|
||||
gen += HtmlGenerationUtils.popupLink( link, localized[0], "ImCenter"+id, '<img src="'+webimRoot+'/images/tbliclspeak.gif" width="15" height="15" border="0" alt="'+localized[0]+'">', 600, 420, null);
|
||||
gen += '</td>';
|
||||
cellsCount++;
|
||||
}
|
||||
|
||||
|
||||
return HtmlGenerationUtils.generateOneRowTable(gen);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
Ajax.ThreadListUpdater = Class.create();
|
||||
@ -118,22 +126,22 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
this.t = this._options.table;
|
||||
this.periodicalUpdater = new Ajax.PeriodicalUpdater(this._options);
|
||||
},
|
||||
|
||||
|
||||
updateParams: function() {
|
||||
return "company=" + this._options.company + "&since=" + this._options.lastrevision;
|
||||
},
|
||||
|
||||
|
||||
setStatus: function(msg) {
|
||||
this._options.status.innerHTML = msg;
|
||||
},
|
||||
|
||||
|
||||
handleError: function(s) {
|
||||
this.setStatus( s );
|
||||
},
|
||||
|
||||
|
||||
updateThread: function(node) {
|
||||
var id, stateid, vstate, canview = false, canopen = false, ban = null;
|
||||
|
||||
|
||||
for( var i = 0; i < node.attributes.length; i++ ) {
|
||||
var attr = node.attributes[i];
|
||||
if( attr.nodeName == "id" )
|
||||
@ -144,15 +152,15 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
vstate = attr.nodeValue;
|
||||
else if( attr.nodeName == "canopen" )
|
||||
canopen = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function setcell(_table, row,id,pcontent) {
|
||||
var cell = CommonUtils.getCell( id, row, _table );
|
||||
if( cell )
|
||||
cell.innerHTML = pcontent;
|
||||
}
|
||||
|
||||
|
||||
var row = CommonUtils.getRow("thr"+id, this.t);
|
||||
if( stateid == "closed" ) {
|
||||
if( row ) {
|
||||
@ -169,13 +177,12 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
var agent = NodeUtils.getNodeValue(node,"agent");
|
||||
var modified = NodeUtils.getNodeValue(node,"modified");
|
||||
var message = NodeUtils.getNodeValue(node,"message");
|
||||
var etc = "";
|
||||
|
||||
|
||||
var etc = '<td class="table">'+NodeUtils.getNodeValue(node,"useragent")+'</td>';
|
||||
etc = HtmlGenerationUtils.generateOneRowTable(etc);
|
||||
|
||||
var startRow = CommonUtils.getRow(stateid, this.t);
|
||||
var endRow = CommonUtils.getRow(stateid+"end", this.t);
|
||||
|
||||
|
||||
if( row != null && (row.rowIndex <= startRow.rowIndex || row.rowIndex >= endRow.rowIndex ) ) {
|
||||
HtmlGenerationUtils.removeHr(this.t, row.rowIndex+1);
|
||||
this.t.deleteRow(row.rowIndex);
|
||||
@ -187,7 +194,7 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
HtmlGenerationUtils.insertHr(this.t, startRow.rowIndex+2);
|
||||
row.id = "thr"+id;
|
||||
this.threadTimers[id] = new Array(vtime,modified,stateid);
|
||||
CommonUtils.insertCell(row, "name", "table", null, 30, HtmlGenerationUtils.viewOpenCell(vname,this._options.agentservl,id,canview,canopen,ban,message) );
|
||||
CommonUtils.insertCell(row, "name", "table", null, 30, HtmlGenerationUtils.viewOpenCell(vname,this._options.agentservl,id,canview,canopen,ban,message));
|
||||
HtmlGenerationUtils.insertSplitter(row);
|
||||
CommonUtils.insertCell(row, "contid", "table", "center", null, vaddr );
|
||||
HtmlGenerationUtils.insertSplitter(row);
|
||||
@ -200,7 +207,7 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
CommonUtils.insertCell(row, "wait", "table", "center", null, (stateid!='chat' ? this.getTimeSince(modified) : '-') );
|
||||
HtmlGenerationUtils.insertSplitter(row);
|
||||
CommonUtils.insertCell(row, "etc", "table", "center", null, etc );
|
||||
|
||||
|
||||
if( stateid == 'wait' || stateid == 'prio' )
|
||||
return true;
|
||||
} else {
|
||||
@ -215,7 +222,7 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
|
||||
updateQueueMessages: function() {
|
||||
function updateQueue(t,id,nclients) {
|
||||
var startRow = t.rows[id];
|
||||
@ -228,12 +235,12 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
_status.innerHTML = (startRow.rowIndex + 1 == endRow.rowIndex) ? nclients : "";
|
||||
_status.height = (startRow.rowIndex + 1 == endRow.rowIndex) ? 30 : 10;
|
||||
}
|
||||
|
||||
|
||||
updateQueue(this.t, "wait", this._options.noclients);
|
||||
updateQueue(this.t, "prio", this._options.noclients);
|
||||
updateQueue(this.t, "chat", this._options.noclients);
|
||||
},
|
||||
|
||||
|
||||
getTimeSince: function(srvtime) {
|
||||
var secs = Math.floor(((new Date()).getTime()-srvtime-this.delta)/1000);
|
||||
var minutes = Math.floor(secs/60);
|
||||
@ -251,7 +258,7 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
|
||||
return prefix + minutes+":"+secs;
|
||||
},
|
||||
|
||||
|
||||
updateTimers: function() {
|
||||
for (var i in this.threadTimers) {
|
||||
if (this.threadTimers[i] != null) {
|
||||
@ -269,19 +276,18 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateContent: function(xmldoc) {
|
||||
var root = xmldoc.documentElement;
|
||||
|
||||
updateContent: function(root) {
|
||||
var newAdded = false;
|
||||
if( root.tagName == 'threads' ) {
|
||||
var _time = NodeUtils.getAttrValue(root, "time");
|
||||
var _revision = NodeUtils.getAttrValue(root, "revision" );
|
||||
|
||||
|
||||
if( _time )
|
||||
this.delta = (new Date()).getTime() - _time;
|
||||
if( _revision )
|
||||
this._options.lastrevision = _revision;
|
||||
|
||||
|
||||
for( var i = 0; i < root.childNodes.length; i++ ) {
|
||||
var node = root.childNodes[i];
|
||||
if( node.tagName == 'thread' )
|
||||
@ -291,12 +297,13 @@ Class.inherit( Ajax.ThreadListUpdater, Ajax.Base, {
|
||||
this.updateQueueMessages();
|
||||
this.updateTimers();
|
||||
this.setStatus( "Up to date" );
|
||||
if( newAdded )
|
||||
if( newAdded ) {
|
||||
window.focus();
|
||||
}
|
||||
} else if( root.tagName == 'error' ) {
|
||||
this.setStatus( "error: " + NodeUtils.getNodeValue(root,"descr") );
|
||||
this.setStatus(NodeUtils.getNodeValue(root,"descr") );
|
||||
} else {
|
||||
this.setStatus( "wrong response" );
|
||||
this.setStatus( "reconnecting" );
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -305,6 +312,5 @@ var webimRoot = "";
|
||||
|
||||
EventHelper.register(window, 'onload', function(){
|
||||
webimRoot = updaterOptions.wroot;
|
||||
new Ajax.ThreadListUpdater(({table:$("threadlist"),status:$("connstatus")}).extend(updaterOptions || {}));
|
||||
new Ajax.ThreadListUpdater(({table:$("threadlist"),status:$("connstatus")}).extend(updaterOptions || {}));
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user