Technical issues

The auto-update to 2.9 didn’t went that well, seems like WordPress is choking on my wp-content folder. At least I managed to restore it to the default theme. That’ll have to do until I manage to reproduce and fix the error locally.

Regex search-and-replace to add script elements to a lot of html files

I needed to add a script tag in every file that included jquery.ui.core.js, directly after that that existing element, with the same indentation. This is what worked quite nicely for me:

Search for: (\s+)<script type=”text/javascript” src=”(.+)/ui/jquery.ui.core.js”></script>

Replace with: $1<script type=”text/javascript” src=”$2/ui/jquery.ui.core.js”></script>$1<script type=”text/javascript” src=”$2/ui/jquery.ui.widget.js”></script>

It groups the whitespace in front of the script element as well as the “../../”-part, and then just duplicates it, inserting the matched groups.

Release: Validation Plugin 1.6

Update update: Files are now availble via Microsoft’s AJAX CDN.

An update for the jQuery validation plugin is available. There are five new localizations (now at 26 in total), including Arabic and Farsi (both right-to-left). Validation of selects is now more interactive, click events are properly handled to provide quicker feedback (also a bug related to selects in IE8 is fixed). The equalTo-method is now aware of changes to the target field, so a change to a password field will be reflected in a confirm-password field. And more…

Download this release.

The only not fully backwards-compatible change (if you spot anything else, please report it as a bug): The dateDE and numberDE methods were replaced with a localization/methods_de.js file, with localized versions of both the date and number methods. There are also localized methods for the NL and PT locales. The goal is to gather more localized versions of these, similar to the localized messages.

The full changelog:

As usual, support is available via:

  • Please post questions to the jQuery discussion list, putting “(validate)” into the subject of your post, making it easier to spot it and respond quickly. Keep your question short and succinct and provide code when possible; a testpage makes it much more likely that you get an useful answer in no time.
  • Please post bug reports and other contributions (enhancements, features, eg. new validation methods) to the plugins.jQuery.com bug tracker (requires registration).

Enjoy!

Undo/redo command stack in Java

Another fragment that turned out to be useless for the project, but may come handy in the future. A port to JavaScript should be easy enough, too:

import java.util.ArrayList;
import java.util.List;

public class CommandStack {

	/**
	 * Implement for each individual change that can occur in an editor.
	 * 

* Both {@link #execute()} and {@link #undo()} should fire property change * events for notifying the editor of an update. */ public static abstract class Command { private String name; public Command(String name) { this.name = name; } @Override public String toString() { return name; } /** * Implements the actual change. *

* Any state-saving for {@link #undo()} * has to occur elsewhere, eg. in the constructor. */ public abstract void execute(); /** * Reverts any changes applied by {@link #execute()}. */ public abstract void undo(); } private final List commands = new ArrayList(); private int currentLocation = -1; private int saveLocation = currentLocation; public void add(Command command) { clearInFrontOfCurrent(); command.execute(); commands.add(command); currentLocation++; } public void undo() { commands.get(currentLocation).undo(); currentLocation--; } public boolean undoEnabled() { return currentLocation >= 0; } public void redo() { currentLocation++; commands.get(currentLocation).execute(); } public boolean redoEnabled() { return currentLocation < commands.size() - 1; } public boolean dirty() { return currentLocation != saveLocation; } private void clearInFrontOfCurrent() { while (currentLocation < commands.size() - 1) { commands.remove(currentLocation + 1); } } public void markSaveLocation() { saveLocation = currentLocation; } @Override public String toString() { return commands.toString(); } }

And to illustrate the usage, the JUnit test:

import junit.framework.TestCase;

public class CommandStackTest extends TestCase {

	CommandStack stack = new CommandStack();

	private String name;
	private int age;

	class EditName extends Command {

		private String oldName = name;
		private String newName;

		public EditName(String newName) {
			super("Update name to " + newName);
			this.newName = newName;
		}

		public void execute() {
			name = newName;
		}

		public void undo() {
			name = oldName;
		}
	};
	
	class EditAge extends Command {

		private int oldAge = age;
		private int newAge;

		public EditAge(int newAge) {
			super("Update age to " + newAge);
			this.newAge = newAge;
		}

		public void execute() {
			age = newAge;
		}

		public void undo() {
			age = oldAge;
		}
	};

	public void test_basics() {
		assertNull(name);
		assertEquals(0, age);
		assertFalse(stack.dirty());
		assertFalse(stack.undoEnabled());
		assertFalse(stack.redoEnabled());
		
		stack.add(new EditName("Peter"));
		
		assertTrue(stack.dirty());
		assertEquals("Peter", name);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());
		
		stack.undo();
		
		assertNull(name);
		assertFalse(stack.undoEnabled());
		assertTrue(stack.redoEnabled());
		assertFalse(stack.dirty());
		
		stack.redo();
		
		assertTrue(stack.dirty());
		assertEquals("Peter", name);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());
		
		stack.markSaveLocation();
		
		assertFalse(stack.dirty());
		assertEquals("Peter", name);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());
		
		stack.add(new EditAge(10));
		
		assertTrue(stack.dirty());
		assertEquals(10, age);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());
		
		stack.undo();
		
		assertFalse(stack.dirty());
		assertEquals(0, age);
		assertTrue(stack.undoEnabled());
		assertTrue(stack.redoEnabled());
		
		stack.add(new EditName("Pan"));
		
		assertTrue(stack.dirty());
		assertEquals("Pan", name);
		assertEquals(0, age);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());
		
		stack.undo();
		stack.undo();
		
		assertTrue(stack.dirty());
		assertNull(name);
		assertEquals(0, age);
		assertFalse(stack.undoEnabled());
		assertTrue(stack.redoEnabled());
		
		stack.redo();
		stack.redo();
		
		assertTrue(stack.dirty());
		assertEquals("Pan", name);
		assertEquals(0, age);
		assertTrue(stack.undoEnabled());
		assertFalse(stack.redoEnabled());
	}

}