Archive for the 'flash' Category

AMFPHP i błąd 403 - Forbidden

Długo szukałem rozwiązania problemu, jaki pojawił się po przeniesieniu aplikacji AMFPHP z Windows na Linuksa. Skrypt gateway.php wywoływany z ‘palca’, czyli z URLa http://serwer/gateway.php odpowiadał prawidłowo. Browser już gorzej - nie wyświetlał prawego panelu z listą metod, a FireBug poproszony o przedstawienie odpowiedzi serwera napisał o błędzie 403 - Forbidden. Ciekawe, że w Google nie znalazłem nic konkretnego, na jednym tylko forum wskazówkę, że chodzi o prawa dostępu. To akurat było łatwe do wydedukowania. Śledztwo wykazało winnego - w skrypcie /core/shared/util/MethodTable.php, w linii 164 wywoływana jest funkcja touch($sourcePath) , gdzie $sourcePath wskazuje na nazwę uruchamianej usługi. Wystarczy ustawić Apaczowi prawo do zapisu pliku usługi (np. /services/Usluga.php) i od razu jest lepiej.

Piszą o AMFPHP na flashzone.pl.

wielokolumnowy układ tekstu w actionscript

Jest taki przykład w dokumentacji Flexa, jest też trochę o tym na blogu niejakiego Daniela. Jednak oba przykłady kończą się tam, gdzie zaczyna się próba przelewania HTMLa przez kilka ramek tekstowych. Dla zwykłego, czystego tekstu to proste - zobaczyć ile się nie zmieściło w ramce n i wlać to do ramki n+1, aż do ostatniej ramki albo końca tekstu.

W przypadku HTMLa jednak Flash nas nie oszczędza. Obliczenie pozycji, na której powinien nastąpić podział jest skomplikowane, bo trzeba uwzględnić - niewidoczne w ramce - tagi, w dodatku pamiętać o automatycznym zamykaniu ich i otwieraniu w kolejnych ramkach. Metody klasy TextField jak getLineOffset() zwracają pozycję w czystym tekście, a podział musi nastąpić w odpowiadającym jej miejscu HTMLa. Na dokładkę HTML, jaki naprawdę jest w obiekcie TextField zupełnie niekoniecznie przypomina ten, który przypisaliśmy do htmlText! Dlatego trzeba najpierw wlać tekst do ramki:

naszTextField.htmlText = nowyHtml;

potem pobrać go do zmiennej i dalej pracować już nad nim:

processedHtml = naszTextField.htmlText;

a oto procedurka przelewająca:

protected function flow():void
{
var lastSplit:                int     = 0;
var newSplit:                int     = 0;
var tb:                        VTextBox;
var tbNum:                    int        = linkedTextBoxes.length;
var tagsHeap:                Array      = new Array();
var opening:                String;
var closing:                String;
var tempText:                String;
var remainder:                String;
var remainLinesNum:            int;
var lastVisibleLineIndex:    int;
var cutIndex:                int;

// liczba stron, na jaką trzeba będzie podzielić tekst
pagesNum             = 0;
// pozycje podziału stron
splitIndices         = new Array();
splitIndices.push(0);
// pozostała do wlania część tekstu - najpierw cały
remainder = processedText;
textPieces = new Array();

while(remainder.length > 0) {
textPieces[pagesNum] = new Array();
for(var i:int = 0; i < tbNum; i++) {
// kolejna ramka tekstowa
tb = linkedTextBoxes[i];
trace(’strona ‘ + pagesNum + ‘, box nr ‘ + i);

// Jeśli tekst już się skończył, kolejne ramki bieżącej strony wypełniamy pustym tekstem.
// Jeśli tekst jeszcze jest, wlewamy pozostałą część i badamy ile się zmieściło
if(remainder.length == 0) {
textPieces[pagesNum][i] = ”;
} else {
// dodajemy na początek otwarcie wszystkich tagów kontynuowanych z poprzedniej ramki
opening                 = Html.getOpeningHtml(tagsHeap);
// wlewamy cały pozostały tekst
tb.htmlText             = opening + remainder;
// obliczamy, ile linii jest poza ramką
remainLinesNum             = tb.maxScrollV - 1;
trace(’poza ramką jest linii: ‘ + remainLinesNum);

if(remainLinesNum == 0) {
textPieces[pagesNum][i] = opening + remainder;
remainder = ”;
} else {
// obliczamy index ostatniej linii
lastVisibleLineIndex     = tb.numLines - remainLinesNum - 1;
trace(’indeks ostatniej linii: ‘ + lastVisibleLineIndex);
// pobieramy indeks ostatniego widocznego znaku
cutIndex                 = tb.getLineOffset(lastVisibleLineIndex) + tb.getLineLength(lastVisibleLineIndex) - 1;
trace(’cutIndex: ‘ + cutIndex);
trace(’cut rigth after …’ + tb.getLineText(lastVisibleLineIndex));
// pozostawiamy tylko mieszczącą się część tekstu
tempText                = remainder.substring(0, cutIndex);
remainder                = remainder.substr(cutIndex);
// uzupełniamy listę otwartych tagów
tagsHeap                 = Html.getTags(tempText, tagsHeap);
// pobieramy tagi do zamknięcia w ramce
closing = Html.getClosingHtml(tagsHeap);
textPieces[pagesNum][i] = opening + tempText + closing;
}
}
}
pagesNum++;
}

displayPage(0);
}

A oto link do video, w świetle którego całe powyższe rozważanie wkrótce straci sens.

wyrażenia regularne w AS3 i HTML

Przy okazji obsługi tekstu wielokolumnowego ze stylami CSS i automatycznym dzieleniem na strony i ramki tekstowe pojawił się problem HTMLa. Kiedy tekst przelewa się z jednej ramki (TextField) do drugiej, trzeba obsłużyć zamykanie tagów na końcu pierwszej ramki i otwieranie ich na początku drugiej. Ponieważ praca jest w trakcie, to na razie tylko tyle, że znalazłem stronę do testowania wyrażeń w AS3, zrobioną we fleksie.

A wyrażenia, jakimi zbieram z tekstu otwierające i zamykające tagi:

openTag     = /<\s*(\w+)([^>]*[^/])?>/gi;
closeTag    = /</(\w+)\s*>/gi;

Next Page »