Dokumentace

Transkript

Dokumentace
České vysoké učení technické v Praze
Fakulta elektrotechnická
Semestrální práce z předmětu Návrh uživatelského rozhraní
Remote Flash Usability testing
Autor: Lukáš Skřivánek
Email: [email protected]
Datum: 28.5.2006
Remote Flash Usability testing
Lukáš Skřivánek
Zadání
Navrhněte systém, který zaznamená interakci člověka (stisky kláves, pohyb kurzoru myši,
klikání myši, dragování objektů, atd.) s flash animací. Tento systém poté umožní zpětné
přehrání těchto interakcí.
Vámi navržený systém by měl obsahovat tlačítka na pozastavení, zastavení a převinutí
zaznamenaných akcí.
Návrh řešení
Celý systém lze rozdělit na dvě oddělitelné části – část určená pro záznam (recorder)
a část určená pro pozdější přehrání zaznamenaných akcí (player).
Recorder
Recoder lze realizovat dvěma způsoby, buď jako flash animaci, která do sebe vloží
zaznamenávanou flash animaci nebo jako samostatný soubor *.as obsahující pouze
zdrojový text ActionScriptu, který se přilinkuje k testované flash animaci.
Událostní model funguje tak, že existují odesílatelé událostí (dispatcher), ke kterým se
mohou zaregistrovat posluchači (listener) obsahující funkce (metody) obsluhující danou
událost. Odesílatele i posluchače událostí lze v ActionScriptu 2.0 vytvořit, nám však
k záznamu událostí stačí vytvořit jen posluchače obsluhujícího události myši a klávesnice
a zaregistrovat ho u globálního odesílatele událostí “Mouse”, v případě myši, a “Key”,
v případě klávesnice. Tito odesílatelé přímo odrážejí reakce uživatele.
V rozumných programovacích jazycích získá metoda posluchače jako parametr objekt
reprezentující událost nesoucí veškeré informace o dané události. Potom stačí tento objekt
serializovat a uložit pro pozdější načtení playerem. Bohužel v ActionScriptu 2.0 se tento
parametr nepředává a je třeba informace o události získávat z globálních proměnných
(např. _xmouse, _ymouse) nebo z globálního odesílatele událostí (např. Key.getAscii(),
Key.getCode()), avšak po posbírání informací již nic nebrání uložení události.
Player
Úkolem playeru je načíst a deserializovat nebo jinak zrekonstruovat recorderem uložený
objekt události a ve správný čas ho pomocí odesílatele, u kterého jsou zaregistrováni
všichni posluchači přehrávané flash animace, předat těmto posluchačům. Na to flash
animace zareaguje stejně jako by byla akce právě vyvolána uživatelem.
Toto je jediné správné řešení problému. Bohužel v ActionScriptu 2.0 je znemožněno hned
ze dvou důvodů. Prvním důvodem je výše zmíněné předávání objektu události posluchači
jako parametru. Tím, že se informace o události musí číst z globálních proměnných je
třeba je při vyslání naší události nastavit na příslušné hodnoty, avšak ne všechny lze
změnit. Druhým vážnějším důvodem je nemožnost vyslání události pomocí globálních
odesílatelů “Mouse” a “Key”, ke kterým jsou zaregistrováni všichni posluchači přehrávané
flash animace. Věřím, že v některé z příštích verzí ActionScriptu již toto možné bude a že
1
Remote Flash Usability testing
Lukáš Skřivánek
samotné odeslání nastaví příslušné globální proměnné, čímž odpadne i prvně zmíněný
problém, nebo dokonce začne používat předávání objektu události jako parametru
posluchači.
Paradoxem této situace je, že lze vytvořit jakýsi objekt události i vlastního odesílatele
události, který již námi vytvořenou událost odeslat umí. Bohužel u našeho odesílatele
nejsou zaregistrováni posluchači přehrávané flash animace. Ideální by tedy bylo, kdyby šlo
přesměrovat registrace posluchačů z globálních odesílatelů “Key” a “Mouse” na našeho
odesílatele a tím dokonce zastínit interakci uživatele v době přehrávání flash animace, což
ovšem samožřejmě nejde.
Další řešení již není zcela ideální, ale pokud by bylo možné získat z odesílatele veškeré
posluchače, které jsou u něho zaregistrováni, bylo by možné volat obslužné funkce
(metody) “ručně”. Ovšem ani toto odesílatelé událostí v ActionScriptu 2.0 neumožňují.
Implementace
Recorder
Při implementaci recorderu jsme sáhli po variantě samostatného souboru obsahujícího
zdrojový text ActionScriptu *.as, který se bude linkovat s flash animací, ve které chceme
odchytávat interakce uživatele.
Pro ukládání dat jsme zvolili cestu přes PHP skript, přestože současná verze produktu
Macromedia Flash 8.0 umí ukládat do souboru pomocí JavaScriptu, protože chceme
ukládat interakce do databáze MySQL. Pro komunikaci s PHP skriptem používáme XML
verze 1.0.
Na začátku pomocí PHP skriptu získáme z databáze číslo nového uživatele a toto číslo v
databázi rezervujeme s událostí start, dále vytvoříme dva posluchače obsluhující události
onKeyDown, onKeyUp, onMouseDown, onMouseUp a onMouseMove. V obsluze
těchto událostí se tvoří XML soubor, který obsahuje číslo uživatele, url flash animace, čas
události, číslo snímku, na kterém došlo k události, druh události a další informace o
události. Čas události se měří od první interakce uživatele (první událost je v čase 0).
Události jsou odesílány v průběhu záznamu po předem daném množství událostí. Záznam
končí zavřením flash animace, ale v tuto chvíli je potřeba odeslat poslední zaznamenané
události.
O nedokonalosti událostního modelu v ActionScriptu 2.0 již bylo v tomto dokumentu
řečeno mnohé a proto čtenáře jistě nepřekvapí, že neobsahuje událost ukončení
přehrávače flash animace. Tímto faktem vstupuje do hry JavaScript, mimochodem jazyk
podobný ActionScriptu, a omezení zaznamenávání interakcí uživatele pouze s flash
animací umístěné v HTML stránce. JavaScript totiž umožňuje nejen zachytit událost
ukončení setrvání HTML stránky v prohlížeči, ale dokonce volat zpřístupněné funkce
ActionScriptu v přehrávané flash animaci.
Pro snazší pochopení provázání jednotlivých programovacích jazyků a toků dat slouží
následující obrázek:
2
Remote Flash Usability testing
Lukáš Skřivánek
Ve chvíli uzavření prohlížeče, načtení jiné stránky či obnovení stránky je JavaScriptem
odchycena událost onUnload a JavaScript volá funkci ActionScriptu onClose(). Tato
funkce přidá poslední událost end s časovým razítkem a odešle poslední události skriptu
PHP.
PHP skript obsluhuje požadavky ActionScriptu tak, že buď načte z databáze číslo
posledního uživate, to zvýší a předá zpět flash animaci, nebo přijme XML soubor, ten
přečte a pomocí SQL uloží data v něm obsažená do databáze.
Než začneme databázi jako uložiště událostí využívat je třeba v ní vytvořit tabulku. Naše
tabulka obsahuje atributy: ID, UrlSwf, UserID, Frame, Time, Kind, MouseX, MouseY, Ascii,
KeyCode.
Player
Z důvodů uvedených v části o návrhu řešení není v současné době možné implementovat
player podle prvotní vize v ActionScriptu 2.0. Možným řešením je buď vyčkat příchodu
vyšších verzí ActionScriptu nebo jiných technologií spojených s Macromedia Flashem
nebo sáhnout po jiných nastrojích jakými může být například Win32 API, jenž bude posílat
události přímo přehrávači flash animace.
Instalace
Recorder
Pro správnou funkci recorderu je nutné mít:
1. zdrojový soubor recorderu (recorder.as - příloha č. 1)
2. zdrojový soubor testované flash animace (*.fla)
3. html stránku, která bude obsahovat flash animaci (recorder.html - příloha č. 3)
4. PHP skript pro ukládání událostí (save.php - příloha č. 2)
5. schéma tabulky (sql.txt - příloha č. 4)
6. funkční webový server s podporou PHP skriptů
7. databázový server MySQL
3
Remote Flash Usability testing
Lukáš Skřivánek
1. Ve zdrojovém souboru recorderu (recorder.as) je třeba modifikovat cestu k PHP skriptu
určenému k ukládání událostí:
_global.php_name = "http://www.server.cz/save.php";
a volitelně je možné změnit po kolika událostech má docházet k odesílání:
_global.send_count = 50;
2. Zdrojový soubor testované flash animace je třeba modifikovat tak, že na první snímek
animace vložíme akci:
#include "recorder.as"
Na konci toho řádku nesmí být středník. Tato akce způsobí přilinkování souboru
recorder.as k flash animaci. Pokud se soubor recorder.as nachází v jiném adresáři nebo je
přejmenován, je třeba změnit cestu a název vkládaného souboru. Pak již stačí jen
spuštěním animaci znovu přeložit.
3. V html stránce je třeba modifikovat cestu k flash animaci a to hned na dvou místech:
<param name="movie" value="animace.swf">
a
<embed src="animace.swf" ....
Pokud budete vytvářet stránku svoji, upozorňuji, že je nezbytně nutné, aby obsahovala
<param name="allowScriptAccess" value="always" />
v tagu objekt flash animace a AllowScriptAccess="always" v tagu embeded. Bez
tohoto by nefungovala komunikace mezi JavaScriptem a ActionScriptem. V mnohých
zdrojích se dočtete, že hodnota always je u atributu AllowScriptAccess automatická bez
uvedení, ale není to pravda.
4. V PHP skriptu je třeba správně nastavit adresu k MySQL serveru:
$SQL_Server="mysql.server.cz";
uživatelské jméno v MySQL:
$SQL_Login="user name";
heslo:
$SQL_Password="password";
databázi:
$SQL_Databaze="databaze";
4
Remote Flash Usability testing
Lukáš Skřivánek
a název tabulky, kterou vytvoříme za chvíli:
$SQL_Table="recorder";
5. Podle tohoto schématu je třeba vytvořit tabulku v databázi. Pokud chcete zvolit jiný
název tabulky nezapomeňte správně nastavit v PHP skriptu proměnnou $SQL_Table
(část 4.). Jiné zásahy do schématu se provádět nemusí.
Body 6 a 7 přesahují rámec tohoto textu a nejsou ani cílem, stačí mít funkční webový
server s podporou PHP skriptů. Do jeho adresáře s publikovanými html a php stránkami
přikopírovat soubory:
•
nově přeloženou flash animaci (*.swf)
•
html stránku, která bude obsahovat flash animaci (recorder.html)
•
PHP skript pro ukládání událostí (save.php)
Zároveň Vám musí fungovat MySQL server a musíte mít správně nastavené veškeré výše
zmíněné proměnné (cesty, jména, hesla ...) a vytvořenou tabulku (bod 5.).
Pak již stačí zadat do prohlížeče adresu:
http://adresaVasehoWebovehoServeru/cesta/recorder.html.
Měla by se Vám zobrazit html stránka obsahující vaši flash animaci. Při první interakci
s touto animací se začnou veškeré interakce zaznamenávat (včetně té první) a záznam
skončí až při uzavření okna prohlížeče, načtení jiné stránky nebo obnovení stránky(v tom
případě může začít záznam znovu pod novým uživatelem).
Závěr
Ač celý dokument vyznívá proti produktu Macromedia Flash a ActionScriptu, je třeba říci,
že se jedná o velmi kvalitní kreslící a prezentační nástroj, ve kterém lze dokonce tvořit
aplikace a hry, je uživatelsky přívětivý, intuitivní a velmi dobře se v něm pracuje.
ActionScript samotný je jazyk, který prochází vývojem a tím se stává stále mocnějším
nástrojem. Podle mého názoru jeho událostní model není zatím zcela vyzrálý, avšak je
třeba si uvědomit, že na podobné účely není určený ani navržený a pro běžné aplikace je
plně dostačující.
Celá práce byla realizována v Macromedia Flashi 8.0 Trial version a je pravděpodobné, že
v nižších verzích nebude korektně fungovat zvláště zpřístupnění funkcí z ActionScriptu
pro JavaScript. (ExternalInterface.addCallback("onClose", null, onClose);)
Zdroje
http://www.macromedia.com
http://www.adobe.com/cfusion/tdrc/index.cfm?product=flashpro&loc=en_us – Trial version
5
Remote Flash Usability testing
Lukáš Skřivánek
http://www.brajeshwar.com/reference/as2/
http://livedocs.macromedia.com/flash/mx2004/
http://www.adobe.com/support/flash/action_scripts/actionscript_dictionary/
http://www.kirupa.com/developer/oop2/AS2OOPindex.htm
http://www.actionscript.org/tutorials.shtml
http://flash.jakpsatweb.cz/
6
Remote Flash Usability testing
Lukáš Skřivánek
Příloha č. 1 - recorder.as
import flash.external.*;
// option variable
_global.php_name = "http://www.server.cz/save.php";
_global.send_count = 50;
// do not change
_global.capture_count = 0;
_global.t0 = 0;
_global.user = 0;
// create XML
_global.EventXML = new XML();
_global.EventXML.contentType = "text/xml";
_global.EventXML.xmlDecl = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
_global.EventXML.appendChild( EventXML.createElement("swfEvents") );
_global.UserXML = new XML();
_global.NothingXML = new XML();
//read user ID
randomize = Math.random()*Math.random();
_global.UserXML.load(_global.php_name+"?id="+randomize);
_global.UserXML.onLoad = userOnLoad;
function userOnLoad(success:Boolean) {
if (success) {
if (_global.UserXML.firstChild.nextSibling.nodeName == "user") {
_global.user = _global.UserXML.firstChild.nextSibling.firstChild.nodeValue;
_level0.vypis=_global.user;
} else {
fatal_error("RECORDER: Connection failed! (2)");
}
} else {
fatal_error("RECORDER: Connection failed! (1)");
}
}
//print error
function fatal_error(mess:String){
_level0.createEmptyMovieClip("error", _level0.getNextHighestDepth());
_level0.error.createTextField("mess", 1, 0, 0, 200, 20);
_level0.error.mess.background=true;
_level0.error.mess.backgroundColor = 0xFF0000;
_level0.error.mess.text = mess;
}
//end capture
function onClose()
{
time=getTimer();
if(_global.t0==0){
_global.t0=time;
}
_global.EventXML.lastChild.appendChild( EventXML.createElement("end") );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createTextNode(time-_global.t0) );
ESend();
}
ExternalInterface.addCallback("onClose", null, onClose);
//save events
function ESend() {
//set user and url
_global.EventXML.firstChild.insertBefore(EventXML.createElement("user"),
_global.EventXML.firstChild.firstChild);
_global.EventXML.firstChild.firstChild.appendChild( EventXML.createTextNode(_global.user) );
_global.EventXML.firstChild.insertBefore(EventXML.createElement("url"),
_global.EventXML.firstChild.firstChild);
_global.EventXML.firstChild.firstChild.appendChild( EventXML.createTextNode(_level0._url) );
//send XML
randomize = Math.random()*Math.random();
_global.EventXML.sendAndLoad(_global.php_name+"?id="+randomize,_global.NothingXML);
7
Remote Flash Usability testing
Lukáš Skřivánek
//create new XML
_global.capture_count = 0;
_global.EventXML = new XML();
_global.EventXML.contentType = "text/xml";
_global.EventXML.xmlDecl = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
_global.EventXML.appendChild( EventXML.createElement("swfEvents") );
}
//save events
function EventsSend() {
_global.capture_count++;
if((_global.capture_count > _global.send_count)&&(_global.user!=0)){
ESend();
}
}
//create mouseListener
var mouseListener:Object = new Object();
mouseListener.onMouseDown = function() {
time=getTimer();
if(_global.t0==0){
_global.t0=time;
}
_global.EventXML.lastChild.appendChild( EventXML.createElement("event") );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("time") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(time_global.t0) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("frame") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode(_level0._currentframe) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("kind") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode("onMouseDown") );
_global.mouse_x = _xmouse;
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("mouse_x") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(mouse_x)
);
_global.mouse_y = _ymouse;
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("mouse_y") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(mouse_y)
);
EventsSend();
};
mouseListener.onMouseUp = function() {
time=getTimer();
if(_global.t0==0){
_global.t0=time;
}
_global.EventXML.lastChild.appendChild( EventXML.createElement("event") );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("time") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(time_global.t0) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("frame") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode(_level0._currentframe) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("kind") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode("onMouseUp") );
_global.mouse_x = _xmouse;
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("mouse_x") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(mouse_x)
);
_global.mouse_y = _ymouse;
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("mouse_y") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(mouse_y)
);
EventsSend();
};
mouseListener.onMouseMove = function() {
time=getTimer();
if(_global.t0==0){
_global.t0=time;
}
_global.EventXML.lastChild.appendChild( EventXML.createElement("event") );
8
Remote Flash Usability testing
Lukáš Skřivánek
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("time") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(time_global.t0) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("frame") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode(_level0._currentframe) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("kind") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode("onMouseMove") );
_global.mouse_x = _xmouse;
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("mouse_x") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(mouse_x)
);
_global.mouse_y = _ymouse;
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("mouse_y") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(mouse_y)
);
EventsSend();
};
Mouse.addListener(mouseListener);
//create keyListener
var keyListener:Object = new Object();
keyListener.onKeyDown = function() {
time=getTimer();
if(_global.t0==0){
_global.t0=time;
}
_global.EventXML.lastChild.appendChild( EventXML.createElement("event") );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("time") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(time_global.t0) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("frame") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode(_level0._currentframe) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("kind") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode("onKeyDown") );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("ascii") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode(Key.getAscii()) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("code") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode(Key.getCode()) );
EventsSend();
};
keyListener.onKeyUp = function() {
time=getTimer();
if(_global.t0==0){
_global.t0=time;
}
_global.EventXML.lastChild.appendChild( EventXML.createElement("event") );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("time") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild( EventXML.createTextNode(time_global.t0) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("frame") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode(_level0._currentframe) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("kind") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode("onKeyUp") );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("ascii") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode(Key.getAscii()) );
_global.EventXML.lastChild.lastChild.appendChild( EventXML.createElement("code") );
_global.EventXML.lastChild.lastChild.lastChild.appendChild(
EventXML.createTextNode(Key.getCode()) );
EventsSend();
};
Key.addListener(keyListener);
9
Remote Flash Usability testing
Lukáš Skřivánek
Příloha č. 2 – save.php
<?php
//option variable - SQL
$SQL_Server="mysql.server.cz";
$SQL_Login="user name";
$SQL_Password="password";
$SQL_Databaze="databaze";
$SQL_Table="recorder";
//do not change
//connect database
$Spojeni = mysql_connect($SQL_Server, $SQL_Login, $SQL_Password);
if ($Spojeni) {
$DB = mysql_select_db($SQL_Databaze, $Spojeni);
if ($DB) {
mysql_query("SET CHARACTER SET utf8");
if(IsSet($HTTP_RAW_POST_DATA)){
//save XML
$dom = domxml_open_mem($HTTP_RAW_POST_DATA);
$root = $dom->document_element();
$url="unknown";
$user=0; // zero is ban
$frame=0;
$time=0;
//parse XML
function parse_node($node) {
global $SQL_Table, $url, $user, $frame, $time;
if ($node->has_child_nodes()) {
foreach($node->child_nodes() as $n) {
if ($n->node_name()=='url'){
foreach($n->child_nodes() as $text) {
$url=$text->node_value();
}
}
if ($n->node_name()=='user'){
foreach($n->child_nodes() as $text) {
$user=$text->node_value();
}
}
if ($n->node_name()=='end'){
foreach($n->child_nodes() as $text) {
$endtime=$text->node_value();
}
if($user!=0){
$UP = mysql_query("INSERT INTO $SQL_Table (UrlSwf,UserID,Frame,Time,Kind)
VALUES('$url',$user, 0, $endtime, 'end')");
}
}
if ($n->node_name()=='event'){
foreach($n->child_nodes() as $text) {
if ($text->node_name()=='time'){
foreach($text->child_nodes() as $value) {
$time=$value->node_value();
}
}
if ($text->node_name()=='frame'){
foreach($text->child_nodes() as $value) {
$frame=$value->node_value();
}
}
if ($text->node_name()=='kind'){
foreach($text->child_nodes() as $value) {
$kind=$value->node_value();
}
}
if ($text->node_name()=='mouse_x'){
foreach($text->child_nodes() as $value) {
$mouse_x=$value->node_value();
}
10
Remote Flash Usability testing
Lukáš Skřivánek
}
if ($text->node_name()=='mouse_y'){
foreach($text->child_nodes() as $value) {
$mouse_y=$value->node_value();
}
}
if ($text->node_name()=='ascii'){
foreach($text->child_nodes() as $value) {
$ascii=$value->node_value();
}
}
if ($text->node_name()=='code'){
foreach($text->child_nodes() as $value) {
$code=$value->node_value();
}
}
}
if (($kind=="onKeyUp")||($kind=="onKeyDown")){
if($user!=0){
$UP = mysql_query("INSERT INTO $SQL_Table
(UrlSwf,UserID,Frame,Time,Kind,Ascii,KeyCode) VALUES('$url',$user, $frame, $time, '$kind', $ascii,
$code)");
$kind="";
$ascii=0;
$code=0;
}
}else{
if($user!=0){
$UP = mysql_query("INSERT INTO $SQL_Table
(UrlSwf,UserID,Frame,Time,Kind,MouseX,MouseY) VALUES('$url',$user, $frame, $time, '$kind', $mouse_x,
$mouse_y)");
$kind="";
$mouse_x=0;
$mouse_y=0;
}
}
}
}
}
}
parse_node($root);
$dom->free();
}else{
//read and send user ID
$result = mysql_query("SELECT COALESCE( MAX( UserID ) , 0 ) AS MAXUSER FROM $SQL_Table");
$row = mysql_fetch_array($result);
$maxid = $row['MAXUSER'];
$maxid++;
$UP = mysql_query("INSERT INTO $SQL_Table (UrlSwf,UserID,Frame,Time,Kind)
VALUES('unknown',$maxid, 0, 0, 'start')");
header("Content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
echo "<user>";
echo $maxid;
echo "</user>";
}
}
}
@mysql_close ($Spojeni);
?>
11
Remote Flash Usability testing
Lukáš Skřivánek
Příloha č. 3 – recorder.html
<html>
<head>
<title>NUR - FLASH - Recorder</title>
<script type="text/javascript">
/* <![CDATA[ */
function onClose(){
window.document.myFlash.onClose();
}
/* ]]> */
</script>
</head>
<body onUnload="onClose();alert('Recording was finished!');return true;">
<p>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swf
lash.cab#version=8,0,0,0"
width="550" height="400" id="myFlash">
<param name="movie" value="animace.swf">
<param name="allowScriptAccess" value="always" />
<param name="quality" value="high">
<embed src="animace.swf" quality="high" width="550" height="400"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Pr
od_Version=ShockwaveFlash"
name="myFlash"
swLiveConnect="true"
AllowScriptAccess="always">
</embed>
</object>
</p>
</body>
</html>
12
Remote Flash Usability testing
Lukáš Skřivánek
Příloha č. 4 – sql.txt
CREATE TABLE `recorder` (
`ID` INT NOT NULL AUTO_INCREMENT,
`UrlSwf` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL
,
`UserID` INT NOT NULL,
`Frame` INT NOT NULL,
`Time` INT UNSIGNED NOT NULL,
`Kind` VARCHAR( 20 ) CHARACTER SET utf8 COLLATE utf8_czech_ci NOT NULL,
`MouseX` MEDIUMINT,
`MouseY` MEDIUMINT,
`Ascii` TINYINT UNSIGNED,
`KeyCode` SMALLINT,
PRIMARY KEY ( `ID` )
);
13

Podobné dokumenty

ActionScript

ActionScript animace a jejich interpretaci. Předdefinovaný XML Socket objekt umožňuje vytvářet plynulé spojení se serverem k propouštění XML dat pro aplikace v reálném čase.

Více

Vyuºití JavaScriptových knihoven - ExtBrain

Vyuºití JavaScriptových knihoven - ExtBrain V jádře jQuery jsou zakomponovány funkce pro správu událostí (event handling). Pokud je daná událost na elementu vyvolána, je spuštěna akce, která se k dané události váže. Základem připojování udál...

Více

Postřehová hra Zadání projektu 1 Moje cíle

Postřehová hra Zadání projektu 1 Moje cíle 5 – pokud je výbuch (datový typ boolean) true, metoda g2d nastaví na „Objektu“, čtvereci patřičnou barvou. 6 – pokud je výbuch (datový typ boolean, na začátku je nastaven jako false) true, metoda g...

Více

Aliens atack - Gymnázium Arabská

Aliens atack - Gymnázium Arabská parametr souřadnice y. Další třída byla catcher, která zastupuje plosinu. Catcher má parametr souřadnice x. Dalším postupem bylo nahrání těchto dvou obrázků do canvasu. Hlavní myšlenka kódu je vytv...

Více

Appendix to ces news 2012: Longest words

Appendix to ces news 2012: Longest words As result we have a corpus containing only well-formed sentences in the language under consideration. The sentences are in random order; hence, sharing the corpus does not violate copyright law bec...

Více

Univerzita Palackého v Olomouci - Katedra geoinformatiky

Univerzita Palackého v Olomouci - Katedra geoinformatiky animace se snímky přehrávají stanovenou rychlostí. Vloţené objekty mohou obsahovat vlastní časovou osu, která funguje nezávisle na hlavní, při ovládání objektu je třeba její snímky adresovat přes j...

Více

Porovnani projektu Wikidata a DBpedia jako zdroju

Porovnani projektu Wikidata a DBpedia jako zdroju volby ve Francii, obce v Německu, atp.). Důsledkem bylo, že data extrahovaná z anglické verze Wikipedie, kterých byla většina, měla jako subjekt URI obsahující název článku v angličtině, a data ext...

Více

Jak na Google Tag Manager

Jak na Google Tag Manager zvolíme název účtu, jak ukazuje obrázek níže. Z důvodu přehlednosti je dobré používat unikátní název. V případě, že má firma/vlastník vícero webových stránek, vytváříme jeden účet, ve kterém bude p...

Více