Март 2011

Руководство по actionscript. часть 3, стр. 063

Использование сущностей XML для специальных символов

В расширении Е4Х реализованы особая интерпретация и правила для определенных символов пунктуации, когда они используются в литерале XML или в выражении присваивания значения XML-элементу. В табл. 18.2 показано, как включать эти символы в документ XML с помощью языка ActionScript. В левом столбце таблицы перечислены символы, а в остальных столбцах показан код, необходимый для включения этих символов в четырех различных контекстах. Для сравнения следующий код демонстрирует пример каждого из четырех типов контекста (контекст представлен текстом некийТекст).

II Текст литерала атрибута

var xml:XML =

II Текст, присваиваемый атрибуту

xml.@другойНекийАтрибут = «некийТекст»

II Текстовый узел в литерале элемента

var xml:XML = ^екм7екс7″

// Текстовый узел, присваиваемый элементу xml. другойНекийЭлемент = «некийТекст»;

Таблица 18.2. Присваивание специальных символов пунктуации

Символ Текст литерала атрибута Текст, присваиваемый атрибуту Текстовый узел в литерале элемента Текстовый узел, присваиваемый элементу

\ \\ \\ \\

& & & & &

II " \» или " V

•** 1

< < < < <

> > > > >

Новая строка (\п) Не поддерживается* Не поддерживается* Не поддерживает — \п

{ { { &#х7В {

} } } } }

В данных контекстах последовательность новой строки \п автоматически преобразуется в сущность &#хА;.

Руководство по actionscript. часть 3, стр. 064

Чтобы включить символ ‘ в значение атрибута, отделенного символамииспользуйте управляющую последовательность '.

Допускается применять последовательность \п, если значение элемента является вычисляемым. Например,

var val:Stri ng = «Newlines \n are \n okay \n here!»: var paragraph:XML =

{val}

:

В отличие от строк, в литерале XML символ обратного слэша (\) никогда не интерпретируется как начало управляющей последовательности.

Стоит отметить, что, хотя символы > и & могут быть использованы в любом литерале XML, когда среда Flash встречает их в текстовом узле при парсин-ге XML-документа, она автоматически преобразует эти символы в сущности > и &атр; соответственно. Подобным образом, когда среда выполнения встречает символ & в значении атрибута при парсинге документа XML, она автоматически преобразует этот символ в сущность &атр;. Однако при использовании в контексте строки эти сущности будут преобразованы обратно в исходные символы. Чтобы увидеть текстовый узел без преобразования его сущностей, используйте метод экземпляра toXMLString ( ) класса XML. Это демонстрирует следующий код:

var р:ХМ1_ = &>: trace(p. toString( )): // Выводит: &> trace(p. toXMLString( )): // Выводит:

&>

Наконец, обратите внимание, что, хотя символ 1 может использоваться для отделения значения атрибута в литерале XML, в процессе парсинга он преобразуется в символ «. Это демонстрирует следующий код:

var p:XML = :

trace(p. toXMLString( )): // Выводит:



Присваивание значений объекту XMLList

Как уже говорилось в подразд. «Изменение содержимого элемсч 1та», не существует разницы между присваиванием значения объекту XMLList, содержащему один-единственный экземпляр класса XML, и присваиванием значения непосредственно этому экземпляру класса XML. Тем не менее присваивание значения объекту XMLList, содержащему более одного экземпляра класса XML, может иметь множество различных результатов. В зависимости от типа присваиваемого значения и типа экземпляров класса XML, находящихся в списке, список может быть пзмеч кч i или даже полностью заменен.

Единственный типичный сценарий использования операции присваивания значения экземпляру класса XMLList — замена ребенка элемента-родителя новым XML-элементом или списком элементов. Например, следующий код заменяет два ребенка элемента одним элементом :

var doc:XML =

Errors are your friends

Backup often

:

doc* =

Practice coding everyday

; // Выдает:


Practice coding everyday



Присваивание значения объекту XMLList является редко используемой операцией, поэтому ее тщательное рассмотрение выходит за рамки этой книги. Читателям, интересующимся гротескными ситуациями в программировании, которой, например, является попытка присвоить список инструкций обработки списку атрибутов, предоставляется возможность самостоятельно познакомиться с ними.

Руководство по actionscript. часть 3, стр. 065

Загрузка XML-данных

Для наглядности в большинстве примеров этой главы ХМL-данные были записаны в виде литералов. Однако в реальных приложениях они зачастую загружаются из внешнего источника.

Для загрузки ХМL-данных из внешнего источника в экземпляр класса XML используйте такую последовательность действий.

1. Создайте объект URLRequest, описав местоположение внешних данных XML (это может быть либо файл, либо серверный сценарий, возвращающий данные в формате XML).

2. Создайте объект URLLoader и используйте его метод load ( ) для загрузки данных XML.

3. Подождите, пока загрузятся данные XML.

4. Передайте загруженные данные XML в конструктор нового экземпляра класса XML.

Хотя подробное рассмотрение классов URLRequest и URLLoader выходит за рамки этой главы, в листинге 18.13 представлен код, необходимый для загрузки XML-данных в экземпляр класса XML. Используемый в примере класс XMLLoader расширяет класс Sprite, чтобы его можно было откомпилировать в качестве основного класса приложения для тестирования. Информацию о классах URLRequest и URLLoader можно найти в справочнике по языку ActionScript корпорации Adobe. Информацию об обработке событий можно получить в гл. 12.

Листинг 18.13. Загрузка данных XML из внешнего источника

package { import flash. display.*; import flash. events.*; import flash. net.*;

// Демонстрирует код, необходимый для загрузки XML-данных

// из внешнего источника

public class XMLLoader extends Sprite {

// Переменная, которой будут присвоены загруженные XML-данные

private var novel:XML;

// Объект, используемый для загрузки XML-данных private var urlLoader:URLLoader;

// Конструктор

public function XMLLoader ( ) { // Указываем местоположение внешнего источника XML-данных var urlRequest:URLRequest = new URLRequest(«novel. xml»); // Создаем объект, который умеет загружать внешние текстовые данные urlLoader = new URLLoader( );

// Регистрируем обработчик, чтобы получить событие об окончании // загрузки XML-данных

urlLoader. addEventLi stener(Event. COMPLETE, completeLi stener); // Загружаем XML-данные urlLoader.1oad(ur1 Request);

}

// Метод, вызываемый автоматически по окончании загрузки XML-данных

private function completeListener(e:Event):void { // Строка, содержащая загруженные XML-данные, присваивается переменной // data объекта URLLoader (то есть urlLoader. data). Чтобы создать // новый экземпляр класса XML из этой загруженной строки, мы передаем // ее в конструктор класса XML novel = new XML(urlLoader. data);

trace(novel. toXMLString( )); // Отображаем загруженные XML-данные,

// преобразованные в объект XML

Обратите внимание, что все операции загрузки данных в языке ActionScript, включая операцию, представленную в листинге 18.13, попадают под действие ограничений безопасности приложения Flash Player. Полную информацию об ограничениях безопасности можно найти в гл. 19.

Руководство по actionscript. часть 3, стр. 066



Item Price
3-legged Coffee Table 79.99

Руководство по actionscript. часть 3, стр. 067

Для обращения к уточненным пространствам имен элементам и атрибутам из листинга 18.14 мы должны сначала получить ссылку на используемые пространства имен. Чтобы получить ссылку на пространство http: / /www. example. com/ furniture, мы вызываем метод экземпляра namespace ( ) класса XML над корневым узлом документа, передавая в качестве аргумента префикс «shop». В результате метод namespace ( ) возвращает объект Namespace, представляющий пространство имен http://www. example. com/furniture. Мы присваиваем этот объект переменной shopNS для дальнейшего использования, var shopNS:Namespace = catalog. namespaceCshop»);

В качестве альтернативы, если известен идентификатор URI пространства имен, можно создать ссылку на объект Namespace, используя конструктор одноименного класса:

var shopNS:Namespace = new Namespace(«http://www. example. com/furniture»):

Чтобы получить ссылку на пространство имен, используемое по умолчанию, мы вызываем метод namespace ( ) над корневым узлом документа, не передавая префикс пространства имен:

var htmlNS:Namespace = catalog. namespace( ):

В качестве альтернативы, если известен идентификатор URI пространства имен, мы можем создать ссылку на объект Namespace, используемый по умолчанию, с помощью конструктора одноименного класса:

var htmlNS:Namespace = new Namespace(«http://www. w3.org/1999/xhtml»);

Для обращения к пространствам имен документа могут использоваться и методы inScopeNamespaces ( ) и namespaceDeclarations ( ). Дополнительную информацию можно найти в справочнике по языку ActionScript корпорации Adobe.

В расширении Е4Х атрибуты пространств имен XML не представляются в виде атрибутов (то есть к ним нельзя обратиться с помощью метода attributesC) или выражения некийЭлемент.®*). Вместо этого для обращения к объявлениям пространств имен элемента применяется метод экземпляра namespaceDeclarations() класса XML.

Теперь, когда у нас есть ссылка на объект Namespace, мы можем обращаться к уточненным пространством имен элементам и атрибутам, используя уточненные имена в следующем общем формате:

пространствоИмен::локальноеИмяЭлемента пространствоИмен::$локальноеИмяАтрибута

Например, вот так записывается уточненное имя элемента в коде на языке ActionScript:

shopNS::price

Обратите внимание на использование оператора уточнителя имени (: :), который отделяет имя пространства имен от локального имени.

Вот так можно обратиться к элементу , который уточняется пространством имен по умолчанию (http: / /www. w3 . org/1999/xhtml):

catalog. htmlNS::body

Для обращения к элементу, который является ребенком элемента , используется следующая запись:

catalog. htmlNS::body. shopNS::table

Для обращения к атрибуту shop: id используется такая запись:

catalog. htmlNS::body. shopNS::table.@shopNS::id

Для обращения к элементу мы можем использовать следующий «кошмарный» код:

catalog. htmlNS::body. shopNS: -.table. htmlNS::table. htmlNS: :tr[ 1].htmlNS::td[l].shopNS::price

Однако мы будем спать спокойнее, если воспользуемся преимуществом оператора «потомок» (. .) в двух местах, как показано в следующем коде:

catalog. .shopNS: -.table. .shopNS: :price

И все равно повторное использование shopNS: : слегка раздражает. Мы можем избежать нескольких лишних нажатий клавиш, попросив язык ActionScript автоматически уточнять все неуточненные имена элементов и атрибутов с помощью

выбранного пространства имен. Для этого мы используем инструкцию назначения пространства имен XML по умолчанию, которая имеет следующий вид:

default xml namespace = пространствоИменИлиСтрокаиЙ1

Например, следующий код заставляет язык ActionScript автоматически уточнять все неуточненные имена элементов и атрибутов с помощью пространства имен http://www. example. com/furniture:

default xml namespace = shopNS;

После выполнения этой инструкции пространство имен http: / / www. example. com/ furniture применяется ко всем неуточненным ссылкам на элементы и атрибуты, поэтому мы можем сократить следующий код:

catalog..shopNS::table..shopNS::price

до записи:

catalog..table..price

» «|СяР Из»за ошибки в приложении Flash Player 9 при выполнении предыдущего примера кода 1—1 (catalog..table..price) в первый раз возвращается значение undefined.

Руководство по actionscript. часть 3, стр. 068

В более полном примере документ каталога, скорее всего, будет содержать несколько элементов. Для обращения к определенному столу нам придется использовать фильтрующий предикат, как показано в следующем коде:

catalog..table.(@id == 4875)..price

В листинге 18.15 приведен код, который можно использовать для обращения и отображения информации обо всех столах из каталога.

Листинг 18.15. Отображение всех столов из каталога

var shopNS:Namespace = catalog. namespaceCshop»); default xml namespace = shopNS: for each (var table:XML in catalog..table) { trace(table..desc + «: » + table..price):

}

Как и в случае с именами элементов и атрибутов, мы можем использовать групповой символ свойств (*) с пространствами имен. Например, следующий код возвращает объект XMLList, представляющий все элементы

во всех пространствах имен:

catalog..*::table

Чтобы получить всех потомков на всех уровнях иерархии во всех пространствах имен или за пределами пространства имен, применяется следующий код:

объектХМ1. .*::* // элементы объектХМ!.. .$*::* II атрибуты

Чтобы получить всех детей во всех пространствах имен или за пределами пространства имен, используется такой код:

объектХМ1 .*’: :* // элементы объектХМ!..®*::* II атрибуты

Создание элементов и атрибутов, уточняемых пространствами имен

Для создания элементов и атрибутов, которые уточняются пространствами имен, мы используем синтаксис обращения к уточненным именам, рассмотренный в предыдущем разделе, вместе с методиками создания элементов и атрибутов, описанными в разд. «Изменение или создание нового содержимого XML».

Перед созданием имен, уточняемых пространствами имен, мы должны создать (или получить) ссылку на объект Namespace. Например, следующий код создает два объекта Namespace и присваивает их переменным htmlNS и shopNS для дальнейшего использования в уточненных именах:

var htmlNS-.Namespace = new NamespaceC’html».

Руководство по actionscript. часть 3, стр. 069

«http://www. w3.org/1999/xhtml»): var shopNS:Namespace = new NamespaceC’shop».

«http://www. example. com/furni ture»):

Когда создается не один элемент или атрибут, а целый документ, обычно (и это более удобно) применяется пространство имен по умолчанию, которое указывается в инструкции default XML namespace. Например, следующий код в качестве пространства имен по умолчанию устанавливает http: / /www. w3 . org/1999/xhtml:

default xml namespace = htmlNS:

Как только будет установлено пространство имен по умолчанию, все вновь создаваемые элементы (но не атрибуты), для которых пространство имен не указано явным образом, будут автоматически уточняться с помощью пространства имен по умолчанию. Например, следующий код создает элемент с локальным именем «html»; для него явно не указано пространство имен, поэтому это имя автоматически уточняется с помощью пространства имен по умолчанию (http: / / www. w3 . org/1999/xhtml):

var catalog:XML = ;

Данная строка кода генерирует следующий исходный код XML:



Чтобы добавить объявление пространства имен к указанному элементу, используется метод экземпляра addNamespace ( ) класса XML. Например, следующий код добавляет объявление нового пространства имен к предыдущему элементу:

catalog. addNamespace(shopNS);

Результирующий исходный код XML выглядит так:



Возможно, вы узнали приведенный элемент — это первая строка кода из документа каталога, представленного в листинге 18.14. Достроим оставшуюся часть этого документа. Вот теги и. Их имена автоматически уточняются пространством имен по умолчанию (http: / /www. w3 . org/1999/xhtml).

catalog. head. title = «Catalog»:

Теперь создадим элемент и его атрибут shop: id. Их имена уточняются пространством имен http: / /www. example. com/f urniture. Мы хотим получить исходный код XML, который выглядит следующим образом:



Для того чтобы создать данный элемент, воспользуемся следующим кодом на языке ActionScript:

catalog. body. shopNS::table = «»;

catalog. body. shopNS::table.@shopNS::id = «4875″;

Приведенный код вам должен быть знаком. За исключением синтаксиса уточнителя пространства имен shopNS : :, он аналогичен коду, который мы использовали ранее для создания элементов и атрибутов. Уточнитель пространства имен просто задает пространство для локальных имен table и id. В листинге 18.16 применяется та же методика для создания оставшейся части документа каталога. В примере обратите внимание на следующую строку кода:

catalog. body. shopNS::tablе. table. tr. td[l] = «Price»;

Она создает новый элемент с именем 11 td» непосредственно за существующим элементом catalog. body. shopNS : : table. table. tr. td [ 0 ].

Руководство по actionscript. часть 3, стр. 070

Листинг 18.16. Создание каталога мебели

// Создание пространств имен

var htmlNS:Namespace = new NamespaceChtml»,

«http://www. w3.org/1999/xhtml»); var shopNS:Namespace = new NamespaceCshop»,

«http://www. example. com/furniture»); // Задание пространства имен по умолчанию default xml namespace = htmlNS;

// Создание корневого элемента var catalog:XML = ;

// Добавление пространства имен furniture к корневому элементу catalog. addNamespace(shopNS);

// Создание оставшейся части документа

catalog. head. title = «Catalog»;

catalog. body. shopNS: -.table = «»;

catalog. body. shopNS: -.table.@shopNS::id = «4875″;

catalog. body. shopNS: .-table. table = «»;

catalog. body. shopNS: .-table. table.^border = «1″;

catalog. body. shopNS::table. table. tr. td = «Item»;

catalog. body. shopNS::table. table. tr. td[l] = «Price»;

catalog. body. shopNS: .-table. table. tr. Malign = «center»;

catalog. body. shopNS::table. table. tr[l] = «»;

catalog. body. shopNS::table. table. tr[l].Malign = «left»;

catalog. body. shopNS::table. table. tr[l].td. shopNS::desc =

«3-1 egged Coffee Table»:

catalog. body. shopNS::table. table. tr[l].td[l] = «»:

catalog. body. shopNS: :table. table. tr[l] .td[l] .shopNS: .-price = «79.99″:

Вот мы и рассмотрели все важнейшие темы, касающиеся расширения Е4Х. В оставшейся части этой главы будут рассмотрены два дополнительных вопроса: преобразование и равенство данных XML.

Руководство по actionscript. часть 3, стр. 071

Преобразование объектов XML и XMLList в строки

Как мы уже видели на протяжении этой главы, расширение Е4Х реализует собственные правила для преобразования экземпляров классов XML и XMLList в строку. Для информации в этом разделе описываются правила расширения Е4Х, применяемые для преобразования объектов XML и XMLList в строку. Не забывайте, что экземпляр класса XML может представлять пять различных типов содержимого: элемент, атрибут, текстовый узел, комментарий или инструкцию обработки. Мы рассмотрим правила преобразования для каждого типа в отдельности, но начнем с рассмотрения преобразования объекта XMLList в строку, чтобы подготовиться к дальнейшему обсуждению.

Преобразование объекта XMLList в строку

Когда объект XMLList содержит один-единственный экземпляр класса XML, результат вызова метода toString ( ) класса XMLList полностью совпадает с результатом вызова метода toString ( ) над этим единственным экземпляром класса XML. Например, в следующем коде переменная title ссылается на объект XMLList, чей единственный экземпляр класса XML представляет элемент. В результате преобразования значения переменной title в строку возвращается значение Ulys ses — именно оно было бы получено в результате вызова метода toString ( ) непосредственно над единственным экземпляром класса XML:

var novel:XML = Ulysses Joyce. James Penguin Books Ltd

// Создаем объект XMLList с одним-единственным экземпляром класса XML var title:XMLList = novel. TITLE; // Преобразуем объект XMLList в строку и отображаем ее. trace(title); // Отображает: Ulysses

Когда объект XMLList содержит несколько экземпляров класса XML, вызов метода toString ( ) класса XMLList возвращает строку, которая получается в результате вызова метода toXMLS tring ( ) над каждым экземпляром класса XML и объединения содержимого этих экземпляров, при этом содержимое каждого экземпляра размещается на отдельной строке. Например, в следующем коде объект XMLList, присваиваемый переменной details, содержит три экземпляра класса XML, которые представляют три элемента — , и :

// Создаем объект XMLList с тремя экземплярами класса XML var details:XMLList = novel.*;

Преобразование значения переменной details в строку возвращает исходный код ХМЬдля элементов, и :

// Преобразуем объект XMLList в строку и отображаем ее trace(details); // Выводит:

// Ulysses

// Joyce. James

// Penguin Books Ltd

Преобразование элемента XML в строку

Для экземпляров класса XML, представляющих элементы, метод toString ( ) этого класса возвращает один из двух результатов в зависимости от содержимого данного элемента. Если элемент содержит детей, метод toS tring ( ) класса XML возвращает исходный XML-код для этого элемента и его детей, отформатированный в соответствии с настройками переменных XML. ignoreWhi tespace, XML. pret tyPr in t ing и XML. pretty Indent. Например, в следующем коде элемент имеет три элемента-ребенка (, и ):

var novel:XML = Ulysses Joyce. James Penguin Books Ltd ;

Преобразование этого элемента в строку вернет исходный XML-код:

trace(novel. toString( )); //Отображает:

//

// Ulysses

// Joyce. James

// Penguin Books Ltd

//
;

Для элемента, не имеющего детей, метод toString ( ) класса XML вернет текст, содержащийся в этом элементе, без открывающего и закрывающего тегов. Например, следующий код преобразует элемент в строку. Результатом является строка Ulysses, а не Ulysses.

Руководство по actionscript. часть 3, стр. 072

Trace(novel. TITLE. toString( )); // Выводит: Ulysses

Если мы хотим получить строку, включающую текстовый узел и окружающие его теги, используется метод toXMLString ( ) класса XML, как показано в следующем коде:

trace(novel. TITLE. toXMLString( )): // Выводит: Ulysses

Стоит отметить, что правила преобразования строк для элементов XML, определенные в расширении Е4Х, изменяют способ обращения к концевым текстовым узлам в языке ActionScript. В языках ActionScript версий 1.0 и 2.0 для обращения к текстовым узлам использовалась переменная экземпляра firstChild класса XML (которая теперь, в языке ActionScript 3.0, является переменной экземпляра firstChild класса XMLDocument). Например, устаревшим эквивалентом следующей инструкции расширения Е4Х: trace(novel. TITLE. toStringC ));

будет являться:

trace(novel. fi rstChi1d. fi rstChi1d. fi rstChiId);

В расширении E4X к тексту элемента, не имеющего элементов-детей, в контексте строки можно обратиться непосредственно через имя этого элемента. Вот еще два примера кода с использованием расширения Е4Х (на этот раз мы опустили явный вызов метода toString ( ), поскольку среда Flash автоматически вызывает этот метод над любым аргументом, передаваемым в функцию trace ( ) ):

trace(novel. AUTHOR); // Выводит: Joyce, James trace(novel. PUBLISHER); // Выводит: Penguin Books Ltd

Далее представлено прямое сравнение устаревшего метода доступа к текстовым узлам с аналогичным методом доступа расширения Е4Х:

// Доступ к текстовому узлу в расширении Е4Х var msg:XML =

World

J. Programmer

Hello trace(msg. TO); // Выводит: World

trace(msg. FROM); // Выводит: J. Programmer trace(msg. MESSAGE); // Выводит: Hello

// Устаревший метод доступа к текстовому узлу

var msgDoc:XMLDocument = new XMLDocument(«»

+ «World»

+ «J. Programmer»

+ «Hello»

+ «»);

traceCmsgDoc. firstChild. firstChild. firstChild): // Выводит: World trace(msgDoc. firstChiId. childNodes[l].firstChild); // Выводит: J. Programmer traceCmsgDoc. firstChild. childNodes[2].firstChild): // Выводит: Hello

Преобразование атрибута в строку

Для экземпляров класса XML, которые представляют атрибуты, метод toString ( ) возвращает только значение этого атрибута, а не все его определение целиком. Например, следующий код преобразует атрибут ISBN предыдущего элемента в строку. Результатом преобразования является строка 0141182806, а не

isbn=’014ii82806\

traceCnovel.@ISBN. toString( )); // Выводит: 0141182806

Преобразование комментариев и инструкций обработки в строки

Когда метод toString ( ) класса XML вызывается над экземпляром класса XML, представляющим комментарий или инструкцию обработки, этот комментарий или инструкция обработки возвращается целиком:

XML. ignoreComments = false;

XML. ignoreProcessinglnstructions = false;

// Создаем фрагмент XML, включающий и комментарий, и инструкцию обработки

// (выделены полужирным шрифтом)

var novel:XML =





Ulysses

Joyce, James

Penguin Books Ltd ;

// Преобразуем комментарий в строку. // Выводит: trace(novel. comments( )[0].toString( ));

// Преобразуем инструкцию обработки в строку.



Полезные ссылки
Случайные записи
  • 12.03.2011">Руководство по actionscript. часть 3, стр. 129
  • 12.03.2011">Руководство по actionscript. часть 3, стр. 128
  • 28.02.2011">Руководство по actionscript. часть 6, стр. 005
  • 22.03.2011">Руководство по actionscript. часть 2, стр. 006
  • 16.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.27
  • 16.03.2011">Руководство по actionscript. часть 3, стр. 028
  • 16.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.25
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.90
  • 17.11.2011">Обзор SandyBridge E
  • 12.03.2011">Руководство по actionscript. часть 3, стр. 127
  • 27.02.2011">Руководство по actionscript. часть 6, стр. 025
  • 09.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.152
  • 13.03.2011">Руководство по actionscript. часть 3, стр. 114
  • 11.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.7
  • 13.03.2011">Руководство по actionscript. часть 3, стр. 112
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...