/*
* Helma License Notice
*
* The contents of this file are subject to the Helma License
* Version 2.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://adele.helma.org/download/helma/license.txt
*
* Copyright 1998-2006 Helma Software. All Rights Reserved.
*
* $RCSfile: String.js,v $
* $Author$
* $Revision$
* $Date$
*/
String.ANUMPATTERN = /[^a-zA-Z0-9]/;
String.APATTERN = /[^a-zA-Z]/;
String.NUMPATTERN = /[^0-9]/;
String.FILEPATTERN = /[^a-zA-Z0-9-_\. ]/;
String.HEXPATTERN = /[^a-fA-F0-9]/;
String.EMAILPATTERN = /^.+@.+\.[a-zA-Z]+$/;
String.URLPATTERN = /^([^:]*):\/\/+(?:([^\/]*):)?(?:([^\/]*)@)?([\w\-_.]*[^.])(\/[^?]*)?(?:\?(.*))?$/;
String.LEFT = -1
String.BALANCE = 0
String.RIGHT = 1
String.ISOFORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
String.SPACE = " ";
String.EMPTY = "";
String.NULL = String.EMPTY; // to be deprecated?
/**
* @fileoverview Adds useful methods to the JavaScript String type.
*
* To use this optional module, its repository needs to be added to the
* application, for example by calling app.addRepository('modules/core/String.js')
*/
/**
* checks if a date format pattern is correct
* @return Boolean true if the pattern is correct
*/
String.prototype.isDateFormat = function() {
try {
new java.text.SimpleDateFormat(this);
return true;
} catch (err) {
return false;
}
};
/**
* parse a timestamp into a date object. This is used when users
* want to set createtime explicitly when creating/editing stories.
* @param String date format to be applied
* @param Object Java TimeZone Object (optional)
* @return Object contains the resulting date
*/
String.prototype.toDate = function(format, timezone) {
var sdf = res.data._dateformat;
if (!sdf) {
sdf = new java.text.SimpleDateFormat(format);
res.data._dateformat = sdf;
} else if (format != sdf.toPattern())
sdf.applyPattern(format);
if (timezone && timezone != sdf.getTimeZone())
sdf.setTimeZone(timezone);
try {
return new Date(sdf.parse(this).getTime());
} catch (err) {
return null;
}
};
/**
* function checks if the string passed contains any characters that
* are forbidden in URLs and tries to create a java.net.URL from it
* FIXME: probably deprecated -> helma.Url
* @return Boolean
* @see helma.Url.PATTERN
*/
String.prototype.isUrl = function() {
if (String.URLPATTERN.test(this))
return true;
try {
return new java.net.URL(this);
} catch (err) {
return false;
}
return true;
};
/**
* function checks if the string passed contains any characters
* that are forbidden in image- or filenames
* @return Boolean
*/
String.prototype.isFileName = function() {
return !String.FILEPATTERN.test(this);
};
/**
* function cleans the string passed as argument from any characters
* that are forbidden or shouldn't be used in filenames
* @return Boolean
*/
String.prototype.toFileName = function() {
return this.replace(new RegExp(String.FILEPATTERN.source, "g"), String.NULL);
};
/**
* function checks a string for a valid color value in hexadecimal format.
* it may also contain # as first character
* @returns Boolean false, if string length (without #) > 6 or < 6 or
* contains any character which is not a valid hex value
*/
String.prototype.isHexColor = function() {
var str = this;
if (this.indexOf("#") == 0)
str = this.substring(1);
if (str.length != 6)
return false;
return !String.HEXPATTERN.test(str);
};
/**
* converts a string into a hexadecimal color
* representation (e.g. "ffcc33"). also knows how to
* convert a color string like "rgb (255, 204, 51)".
* @return String the resulting hex color (w/o "#")
*/
String.prototype.toHexColor = function() {
if (this.startsWith("rgb")) {
res.push();
var col = this.replace(/[^0-9,]/g, String.NULL);
var parts = col.split(",");
for (var i in parts) {
var num = parseInt(parts[i], 10);
var hex = num.toString(16);
res.write(hex.pad("0", 2, String.LEFT));
}
return res.pop();
}
var col = this.replace(new RegExp(String.HEXPATTERN.source), String.NULL);
return col.toLowerCase().pad("0", 6, String.LEFT);
};
/**
* function returns true if the string contains
* only a-z and 0-9 (case insensitive!)
* @return Boolean true in case string is alpha, false otherwise
*/
String.prototype.isAlphanumeric = function() {
if (!this.length)
return false;
return !String.ANUMPATTERN.test(this);
};
/**
* function cleans a string by throwing away all
* non-alphanumeric characters
* @return cleaned string
*/
String.prototype.toAlphanumeric = function() {
return this.replace(new RegExp(String.ANUMPATTERN.source, "g"), String.NULL);
};
/**
* function returns true if the string contains
* only characters a-z
* @return Boolean true in case string is alpha, false otherwise
*/
String.prototype.isAlpha = function() {
if (!this.length)
return false;
return !String.APATTERN.test(this);
};
/**
* function returns true if the string contains
* only 0-9
* @return Boolean true in case string is numeric, false otherwise
*/
String.prototype.isNumeric = function() {
if (!this.length)
return false;
return !String.NUMPATTERN.test(this);
};
/**
* transforms the first n characters of a string to uppercase
* @param Number amount of characters to transform
* @return String the resulting string
*/
String.prototype.capitalize = function(limit) {
if (limit == null)
limit = 1;
var head = this.substring(0, limit);
var tail = this.substring(limit, this.length);
return head.toUpperCase() + tail.toLowerCase();
};
/**
* transforms the first n characters of each
* word in a string to uppercase
* @return String the resulting string
*/
String.prototype.titleize = function() {
var parts = this.split(" ");
res.push();
for (var i in parts) {
res.write(parts[i].capitalize());
if (i < parts.length-1)
res.write(" ");
}
return res.pop();
};
/**
* translates all characters of a string into HTML entities
* @return String translated result
*/
String.prototype.entitize = function() {
res.push();
for (var i=0; i/g, replacement);
return str;
};
/**
* function calculates the md5 hash of a string
* @return String md5 hash of the string
*/
String.prototype.md5 = function() {
return Packages.helma.util.MD5Encoder.encode(this);
};
/**
* function repeats a string passed as argument
* @param Int amount of repetitions
* @return String resulting string
*/
String.prototype.repeat = function(multiplier) {
res.push();
for (var i=0; i -1)
return true;
return false;
};
/**
* function compares a string with the one passed as argument
* using diff
* @param String String to compare against String object value
* @param String Optional regular expression string to use for
* splitting. If not defined, newlines will be used.
* @return Object Array containing one JS object for each line
* with the following properties:
* .num Line number
* .value String line if unchanged
* .deleted Obj Array containing deleted lines
* .inserted Obj Array containing added lines
*/
String.prototype.diff = function(mod, separator) {
// if no separator use line separator
var regexp = (typeof(separator) == "undefined") ?
new RegExp("\r\n|\r|\n") :
new RegExp(separator);
// split both strings into arrays
var orig = this.split(regexp);
var mod = mod.split(regexp);
// create the Diff object
var diff = new Packages.helma.util.Diff(orig, mod);
// get the diff.
var d = diff.diff();
if (!d)
return null;
var max = Math.max(orig.length, mod.length);
var result = new Array();
for (var i=0;i -1) {
count += 1;
offset += 1;
}
return count;
};
/**
* returns the string encoded using the base64 algorithm
*/
String.prototype.enbase64 = function() {
var bytes = new java.lang.String(this) . getBytes();
return new Packages.sun.misc.BASE64Encoder().encode(bytes);
};
/**
* returns the decoded string using the base64 algorithm
*/
String.prototype.debase64 = function() {
var bytes = new Packages.sun.misc.BASE64Decoder().decodeBuffer(this);
return String(new java.lang.String(bytes));
};
// wrapper methods for string-related
// global helma functions
String.prototype.encode = function() {
return encode(this);
};
String.prototype.encodeXml = function() {
return encodeXml(this);
};
String.prototype.encodeForm = function() {
return encodeForm(this);
};
String.prototype.format = function() {
return format(this);
};
String.prototype.stripTags = function() {
return stripTags(this);
};
/**
* factory to create functions for sorting objects in an array
* @param String name of the field each object is compared with
* @param Number order (ascending or descending)
* @return Function ready for use in Array.prototype.sort
*/
String.Sorter = function(field, order) {
if (!order)
order = 1;
var key = field + ":" + order;
if (!String.Sorter.cache[key]) {
String.Sorter.cache[key] = function(a, b) {
var str1 = String(a[field] || String.NULL).toLowerCase();
var str2 = String(b[field] || String.NULL).toLowerCase();
if (str1 > str2)
return order * 1;
if (str1 < str2)
return order * -1;
return 0;
};
}
return String.Sorter.cache[key];
};
String.Sorter.ASC = 1;
String.Sorter.DESC = -1;
String.Sorter.cache = {};
/**
* create a string from a bunch of substrings
* @param String one or more strings as arguments
* @return String the resulting string
*/
String.compose = function() {
res.push();
for (var i=0; i