Vettig Maven JSLint-plugin

Äntligen en ordentlig maven-plugin som kör jslint på javascript-koden. Version 2.0.2 har bättre dokumentation än 2.0.1. Här är en snippet från en pom:

<project ...>
	<build>
		<plugins>
			<plugin>
				<groupid>com.googlecode.jslint4java</groupid>
				<artifactid>jslint4java-maven-plugin</artifactid>
				<version>2.0.2</version>
				<executions>
					<execution>
						<id>lint</id>
						<phase>compile</phase>
						<goals>
							<goal>lint</goal>
						</goals>
						<configuration>
							<sourcefolders>
								<sourcefolder>${basedir}/src/main/webapp/js</sourcefolder>
							</sourcefolders>
							<failonerror>true</failonerror>
							<options>
								<browser>true</browser>
								<forin>true</forin>
								<fragment>true</fragment>
								<undef>true</undef>
								<nomen>true</nomen>
								<plusplus>true</plusplus>
								<predef>Ext,jQuery</predef>
								<sloppy>true</sloppy>
								<vars>true</vars>
								<white>true</white>
							</options>
						</configuration>
					</execution>
				</executions>
			</plugin>
</plugins></build></project>

Fantastisk utvecklarvår i Göteborg 2012!

Aldrig förr har utvecklarcommunityn i Göteborg varit så sprudlande som den är nu, iaf om du frågar mig! Till att börja med har vi minst tre rejäla konferenser, tyvärr inte fyra då Nordic Ruby går av stapeln i Stockholm i år. Hur som helst – ovanpå det har vi ju javaforum, nforum och alla user groups på Meetup, liksom SweNug, Alt.net, OWASP och en mängd andra aktiviteter som t ex Göteborgs Agilister och allt som anordnas av DataFöreningen Sverige (DFS).

Att vi har detta utbud i Göteborg tycker jag är kanon! Det ger varje utvecklare en möjlighet att välja själv, att inte bara vara tvingad till att stirra blint på en leverantörs erbjudanden, bara en teknik, bara en grupp – dvs inte bara smalna av och ramla in i “samma gamla hjulspår”, utan verkligen har en möjlighet att bredda sin insikt, kompetens och sitt nätverk.

Det som är än mer glädjande är att i all denna “konkurrens” så har verkligen de flesta user grupper jag varit i kontakt med satt just utvecklarna i första rummet. Det finns ett litet undantag som sätter sina egna ekonomiska intressen före utvecklarna i user groupen och försöker kontrollera informationen som når utvecklarna, istället för att låta medlemmarna själva bestämma vad de tycker. Jag gissar att detta blir uppenbart så småningom och att en ny grupp bildas spontant – som är till primärt för utvecklare, inte ett bolags ekonomiska intressen.
(Min uppfattning är att utvecklare är intelligenta, självständiga individer som är helt kompetenta nog att ta egna informerade beslut, inte få “så här skall du tycka och göra” nedtryckt i halsen. Nåväl, det lär som sagt självregleras inom tid.)

Så, without further ado: här är min lista på vårens toppar i Göteborg 2012!

Konferenser

WebCoast, 16-18 mars, Lindholmen Science Park (en unconference)
Software Passion Summit, 19-20 mars, Clarion Hotel Post (Centralstationen)
Scandinavian Developer Conference, 16-17 april, Svenska mässan (Korsvägen)
dev:mobile, 12 juni, Folkets hus (Järntorget)

User Groups etc

(Dessa har ju återkommande möten och byter emellanåt plats – därav blir datum/adress inte så intressant.)

vilket_är_lättast_AttLäsaTyckerDu

Jag har skaffat mig en åsikt: det_är_lättare_att_läsa_vanlig_text_så_här, änAttLäsaDetNärDetStårSammanSkrivetUtanNågonWhiteSpace. De flesta känner till att vi mnäskionr kan lsäa ord unta srröte poerblm bara start- och slutbokstaven står på rätt plats. FrsöökGröaSmmaaSakMedDtetaTxbtelcok. Så, jag har skaffat mig åsikten att underscore är en bra idé att använda i t ex namn på test(metoder). I JavaScript brukar de flesta testramverk erbjuda följande mönster:

TestCase("Nu testar vi logiken i UserManager", {
    "lägga till en användare": function() {
        var before = this.userManger.getUserCount();
        this.userManager.addUser("Fredrik", "Wendt");
        var after = this.userManger.getUserCount();
        assertThat(after, equals(before + 1));
    }
});

Det är då ganska lätt att se vad som gått fel när en rapport säger:

In Suite "Nu testar vi logiken i UserManager", the test "lägga till en användare" failed.

I Java kan vi inte använda blanktecken som del av identifierare. I Java 7 kan man iaf använda 1_000_000 för att skriva ut en miljon, yay! Men det löser inte problemet med att få läsbara namn på test(metoderna). Understreck till räddning!

Ett problem som följer med understreck är att Eclipse rätt ur lådan inte stödjer att hoppa inom identifierare som innehåller just understreck: ctrl+höger hoppar alltså till slutet av hela identifieraren. Med AnyEditTools (finns på Eclipse Marketplace) blir detta problem ett minne blott, och man får också hjälp att konvertera mellan Camel Case och Underscores. Perfekt julklapp! :)

Presentation om testdriven JavaScript-utveckling

Igår talade jag på JavaForum om tre verktyg (JsTestDriver, JsHamcrest, JsMockito) som möjliggör en godkänt komfortabel miljö för testdriven utveckling av JavaScript-kod. Jag har slangat upp presentationen på SlideShare och koden som det refereras till finns på GitHub.

Jag skulle kanske tryckt lite mer på att det i min mening inte lämpar sig för end-to-end-tester, typ ATDD eller BDD – där är fortfarande något som har Selenium i botten kung (om man gör det rätt).

JsTestDriver

Most of my code writing time last week writing was spent in JavaScript land (or ECMAScript, wonder it the most commonly used name will ever change). I was to write a small templating package and had to write some new stuff and set out to use JsTestDriver and after a few minutes I was up and running in Eclipse.

The idea is OK I guess – run tests and production code in the same environment it will run in when deployed. There are a couple of cons to JsTestDriver (used through Eclipse) though:

  1. if you’re configuration file doesn’t include the test file you’re trying to execute, there’s no clue to what you’ve done wrong – the panel in Eclipse will just show the green bar and 0/0 tests run.
  2. if you have syntax (or construct like) errors in your unit under test, you’ll get the same behavior as above
  3. sometimes you’re served a cached version of (some of) the JS source files – hence there’s a button to “refresh browsers” and it’s sad that it has to be there and that you actually have to use it
  4. sometimes the engine gets into some strange state where it dryRuns the tests instead of actually executing them

Apart from that, its behavior is quite predictable. Minor issues:

  1. running a test complete locks Eclipse’s UI thread
  2. a Rerun quick command option would be great (Ctrl+3)

JsHamcrest

Another minor issue is that the “index” of JsHamcrest matchers is really hard to get an overview of. Whenever I wanted to use a certain type of matcher, it was really hard to quickly tell from the documentation if it was there or not. Go see for yourself and look for a matcher that mathes any object for instance.

JsHamcrest.Integration.JsTestDriver();
# get a list of matchers:
curl "http://jshamcrest.destaquenet.com/modules/matchers.html" | grep "dt id" |cut -d '"' -f 2 |cut -d '.' -f 3

JsMockito

JsMockito works really nice. The only thing that could’ve been better is the integration with JsTestDriver: when a verify step fails, you’ll get a good error message but you don’t get the typical feedback as from which line the verify/assert that failed was on. Not a big deal since you see which test that failed.

JsMockito.Integration.JsTestDriver();

Optimera Stockholm

Det är lite lockande att som Göteborgare passa på att skämta om bästkust och hur man har behov av optimering i Stockholm medan allt är fint i Götet, men dagens seminarie/minikonferens (twittertag #optsthlm) på ämnet webboptimering/webbprestanda förtjänar inget annat än lovord! Talarnas ämnen och innehåll var mycket väl utspridda över hela problemrymden från server till klient och allt där mellan. Continue reading

CKEditor och bliki 2.0

I min egen TODO-lista har jag länge haft på tapeten att fixa en egen wiki (programvara), eftersom alla jag stött på innan saknat något. Så idag gick jag igång på en reflektion som diskuterades (med Peter Lindh) kring wikis – varför skall det vara så omständligt att korrigera något litet, som t ex stavfel? Hela sidan skall laddas om, man skall rulla fram till rätt ställe och i värsta fall även se till att ha lite av markup-syntaxen i huvudet + hålla ordning på var i markup-stacken man befinner sig. Nej tack.

Så wiki.wendt.se föddes, jag tankade hem CKEditor (istället för TinyMCE som jag använt många gånger tidigare) och tittade även på andra editorer. CKEditor fungerade dock fortfarande bra även på sidor med mycket innehåll – den blev inte slö efter att man skrivit in tillräckligt mycket text.

Ctrl+X för snabb redigering

En sak som jag verkligen uppskattat med wordpress är det lilla stöd man försökte ge den som skall skriva in sin text. Det går t ex att trycka CTRL+1 för att göra ett stycke till en rubrik av storlek 1 (h1), 2 för h2, …
Detta saknades i CKEditor så det lade jag en dryg timme på innan jag hittade korrekt lösning till.

Keystrokes kallas kortkommandon i CKEditor och de kan justeras genom konfigurationsobjektet som anges när man via JavaScript drar igång editorn. En keystroke består av sifferkombination (1049 för Control+1 t ex) och namn på ett kommando att exekvera (editor.execCommand). Första problemet var att endast bold, italic och liknande icke-blocks-stilar fanns som kommandon.

I plugins/format/plugin.js lade jag till följande rad för att registrera kommandon “globalt”:
editor.addCommand(tag, new CKEDITOR.styleCommand(style));

Det var inte trivialt att hitta var man skulle jacka in sig, men trivialt när det väl var hittat :) En försvårande faktor är att CKEditor nyss kom i ny utgåva (version 3.x) och all dokumentation inte riktigt är lika uppdaterad som den varit för den förra utgåvan (version 2.x).

Packningsverktyget saknas, samt instruktioner

När man väl ändrat i _source-katalogen och vill få allt packat igen får man dra hem en jar från http://svn.fckeditor.net/CKPackager/trunk/bin/ och exekvera denna. Instruktioner om att “det är så man får göra” går bara att hitta på forumet …
http://cksource.com/forums/viewtopic.php?p=46072#p46072

Lista saknas

Det saknas en sammanställning över vilka tangentbindningar som används från början, och vilka kommandon man faktiskt kan binda upp (att byta till h1 fanns alltså inte out of the box).
* Enklast är att bryta (med ckeditor_source.js som källa, dvs icke-minifierat) i core/editor.js i metoden addCommand.
* JavaDocen för CKEditor har lista på default bindings (keystrokes).

Jag saknar korrekt bindning för
* image
* outdent (motsats till indent), pga att svensk tangentbordslayout saknar dedikerad tangent för tecknet <,
* numbered list, och
* bullet list.
Följande är dock konfigurerade manuellt och fungerar fint:
[ CKEDITOR.CTRL + 90 /*Z*/, ‘undo’ ],
[ CKEDITOR.CTRL + 89 /*Y*/, ‘redo’ ],
[ CKEDITOR.CTRL + CKEDITOR.SHIFT + 90 /*Z*/, ‘redo’ ],
[ CKEDITOR.CTRL + 76 /*L*/, ‘link’ ],
[ CKEDITOR.CTRL + 66 /*B*/, ‘bold’ ],
[ CKEDITOR.CTRL + 73 /*I*/, ‘italic’ ],
[ CKEDITOR.CTRL + 85 /*U*/, ‘underline’ ],
[ CKEDITOR.CTRL + 48 /*0*/, ‘p’ ],
[ CKEDITOR.CTRL + 49 /*1*/, ‘h1′ ],
[ CKEDITOR.CTRL + 50 /*2*/, ‘h2′ ],
[ CKEDITOR.CTRL + 51 /*3*/, ‘h3′ ],
[ CKEDITOR.CTRL + 52 /*4*/, ‘h4′ ],
[ CKEDITOR.CTRL + 53 /*5*/, ‘h5′ ],
[ CKEDITOR.CTRL + 54 /*6*/, ‘h6′ ]

En av CKEditors fördelar är att länk-dialogen som visas är ett lager och inte ett eget fönster som TinyMCE använder. Fördelen är att det går snabbare att skriva in en URL pga att man slipper vänta på att en sida skall laddas.

Vanlig bläddring först: “läsläge”

Nästa problem att tackla var att editorn inte skall störa det vanliga läsande förrän man faktiskt vill ändra något. CKEditor har inget readonly läge som supportas. Forumet bjuder dock på ett par hack, men det var inte felfritt.

Tappar höjd

Tyvärr lider dpck CKEditor.replace() av att höjden på det element som ersätts inte bevaras. Så jag har nu gjort så att när en sida på wikin laddas så lyssnar jag efter dblclick-event (med ExtJS Core) och när det kommer drar jag iväg anropet till CKEditor.replace(divID, config) och populerar config.height med rätt höjd.
var replaceDivwithEditor = function() {
var el = Ext.get(‘editorDiv’);
var height = el.getHeight();
var padding = el.getPadding(‘tb’);
var scroll = el.getScroll();

var toolbarheight = 60;
ckConfig.height = height + padding + toolbarheight;
CKEDITOR.replace(‘editorDiv’, ckConfig);
};

Börja redigering automatiskt

Allra helst hade jag velat att det man dubbelklickade på i läsläge skulle vara markerat när man hamnar i skrivläge. Men dagen har blivit efter midnatt och det är dags att fortsätta en annan dag.

Multipla redigerare

Ett annat önskemål är att kunna stödja flera upphovsmäns petande i samma sida samtidigt, såsom EtherPad fungerar. Andra har visat att det inte är omöjligt att göra, jag har dock inte hittat någon som integrerat det med CKEditor eller annan icke-radbaserad plain text editor.

http://etherpad.wendt.se/

Roadmap

En liten snabb roadmap för att byta ut bloggen/Fredriks anteckningar mot en egen blogg igen:

Must haves:
# säkerhet
# versionshanterad lagring (kanske CouchDB)
# RSS-feed (enklare med SQL?)
# hantering av nuvarande material, dvs dess URL:er – innehållet är ju redan HTML
# mediauppladdningsplugin (CKFind är tydligen inte OSS)

Och optional:
* SEO (taggar borde räcka)
* ev kommentarsfunktion
* arkivfunktioner
* OpenID
* syntaxfärgning av kod

Google får ta hand om sökning.

JSConf.eu-sammanfattning på dotNetForum

Fick glädjande nog til minuter på dagens dotNetForum till att presentera konferensen JSConf.eu. Tio minuter är väldigt lite tid, speciellt när projektorn och min dator inte är överens (fick lösas med att starta om X, varpå gconf kände igen “skärmarna” och använda rätt inställning direkt).

Fler personer än väntat kom fram efteråt och hade bra frågor – riktigt kul! Förhoppningsvis får jag komma tillbaka och prata mer om hur man optimerar webbplatser – det var detta ämne som verkade väckt störst intresse. :)

Presentationen (PDF)

Presentation (ODP)