10.04.2015, 22:20
|
|
Соединяю Node.js и Ext JS
|
|
Регистрация: 25.06.2009
Сообщений: 1,033
|
|
Нет поддержки элемента SVGSVGElement (в частности опции baseVal)
Здравствуйте!
Ext.dom.Element не поддерживает напрямую элемент SVG. В итоге происходят всякие ошибки например с аттрибутом className этого элемента.
Дело в том, что аттрибут className с точки зрения Ext.dom.Element просто строка, где перечислены через пробел классы. А когда речь идет об элементе SVG, то этот аттрибут имеет тип SVGAnimatedString (причем это не класс, а интерфейс), и значение классов хранятся не в className, а в className.baseVal.
Чтобы решить как-то эту проблему я сделал override для класса Ext.dom.Element, где заменил тела методов, где идет работа с аттрибутом className. Но решение не универсальное, так как имеется ряд проблем (кроме аттрибута className, есть еще аттрибуты такого рода, команда new SVGAnimatedString() не работает и возможно еще будут проблемы в будущем, плюс неизвестно где в недрах Ext JS идет обращение напрямую, что тоже доставляет). Из-за этого решение больше похоже на костыль, который иногда не срабатывает.
Причем часто получается, что элемент SVG создаю не я сам, а где-то в недрах Ext JS (например, когда я пользуюсь опцией autoEl). В этом случае получается что класс Ext.dom.Element я не могу заменить на свой.
Есть ли более надежные решения этой проблемы?
П.С. В добавок override не возможен будет, если потребуется использовать переменные visFly, scrollFly, caFly, к которым доступ из скорректированных методов невозможен. Эти переменные описаны в файле с классом Ext.dom.Element.
Последний раз редактировалось khusamov, 10.04.2015 в 22:24.
|
|
11.04.2015, 09:48
|
Профессор
|
|
Регистрация: 19.11.2012
Сообщений: 178
|
|
А Surface нельзя применить в вашем случае?
Можете показать, как оформили overrride?
|
|
11.04.2015, 12:30
|
|
Соединяю Node.js и Ext JS
|
|
Регистрация: 25.06.2009
Сообщений: 1,033
|
|
Цитата:
|
А Surface нельзя применить в вашем случае?
|
Пока не получается. Там нет поддержки элемента G. Там нет поддержки именно SVG. Там сделана возможность рисовать, а способ отрисовки (SVG или canvas или еще что придумаем) уже сам выбирает как ему отрисовывать.
Иными словами это библиотека для рисования (графиков). А мне нужна библиотека для создания SVG-документа. И полный контроль над всеми элементами этого документа.
Вот код хака:
// Хак
// Поддержка аттрибутов SVG-элементов
Ext.override(Ext.dom.Element, hack1());
function hack1() {
var WIN = window,
DOC = document,
windowId = 'ext-window',
documentId = 'ext-document',
WIDTH = 'width',
HEIGHT = 'height',
MIN_WIDTH = 'min-width',
MIN_HEIGHT = 'min-height',
MAX_WIDTH = 'max-width',
MAX_HEIGHT = 'max-height',
TOP = 'top',
RIGHT = 'right',
BOTTOM = 'bottom',
LEFT = 'left',
VISIBILITY = 'visibility',
HIDDEN = 'hidden',
DISPLAY = "display",
NONE = "none",
ZINDEX = "z-index",
POSITION = "position",
RELATIVE = "relative",
STATIC = "static",
SEPARATOR = '-',
wordsRe = /\w/g,
spacesRe = /\s+/,
classNameSplitRegex = /[\s]+/,
transparentRe = /^(?:transparent|(?:rgba[(](?:\s*\d+\s*[,]){3}\s*0\s*[)]))$/i,
adjustDirect2DTableRe = /table-row|table-.*-group/,
borders = {
t: 'border-top-width',
r: 'border-right-width',
b: 'border-bottom-width',
l: 'border-left-width'
},
paddings = {
t: 'padding-top',
r: 'padding-right',
b: 'padding-bottom',
l: 'padding-left'
},
margins = {
t: 'margin-top',
r: 'margin-right',
b: 'margin-bottom',
l: 'margin-left'
},
paddingsTLRB = [paddings.l, paddings.r, paddings.t, paddings.b],
bordersTLRB = [borders.l, borders.r, borders.t, borders.b],
numberRe = /\d+$/,
unitRe = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
defaultUnit = 'px',
camelRe = /(-[a-z])/gi,
cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
pxRe = /^\d+(?:\.\d*)?px$/i,
propertyCache = {},
camelReplaceFn = function(m, a) {
return a.charAt(1).toUpperCase();
},
visibilityCls = Ext.baseCSSPrefix + 'hidden-visibility',
displayCls = Ext.baseCSSPrefix + 'hidden-display',
offsetsCls = Ext.baseCSSPrefix + 'hidden-offsets',
noTouchScrollCls = Ext.baseCSSPrefix + 'no-touch-scroll',
CREATE_ATTRIBUTES = {
style: 'style',
className: 'className',
cls: 'cls',
classList: 'classList',
text: 'text',
hidden: 'hidden',
html: 'html',
children: 'children'
}, visFly, scrollFly, caFly;
return {
addCls: function(names, prefix, suffix) {
var me = this,
hasNewCls, dom, map, classList, i, ln, name,
elementData = me.getData();
if (!names) {
return me;
}
if (!elementData.isSynchronized) {
me.synchronize();
}
dom = me.dom;
map = elementData.classMap;
classList = elementData.classList;
prefix = prefix ? prefix + SEPARATOR : '';
suffix = suffix ? SEPARATOR + suffix : '';
if (typeof names === 'string') {
names = names.split(spacesRe);
}
for (i = 0, ln = names.length; i < ln; i++) {
name = prefix + names[i] + suffix;
if (!map[name]) {
map[name] = true;
classList.push(name);
hasNewCls = true;
}
}
if (hasNewCls) {
//dom.className = classList.join(' ');
me._saveAttr(dom, "className", classList.join(' '));
}
return me;
},
setCls: function(className) {
var me = this,
elementData = me.getData(),
map = elementData.classMap,
i, ln, name;
if (typeof className === 'string') {
className = className.split(spacesRe);
}
for (i = 0, ln = className.length; i < ln; i++) {
name = className[i];
if (!map[name]) {
map[name] = true;
}
}
elementData.classList = className.slice();
//me.dom.className = className.join(' ');
me._saveAttr(me.dom, "className", className.join(' '));
},
removeCls: function(names, prefix, suffix) {
var me = this,
hasNewCls, dom, map, classList, i, ln, name,
elementData = me.getData();
if (!names) {
return me;
}
if (!elementData.isSynchronized) {
me.synchronize();
}
if (!suffix) {
suffix = '';
}
dom = me.dom;
map = elementData.classMap;
classList = elementData.classList;
prefix = prefix ? prefix + SEPARATOR : '';
suffix = suffix ? SEPARATOR + suffix : '';
if (typeof names === 'string') {
names = names.split(spacesRe);
}
for (i = 0, ln = names.length; i < ln; i++) {
name = prefix + names[i] + suffix;
if (map[name]) {
delete map[name];
Ext.Array.remove(classList, name);
hasNewCls = true;
}
}
if (hasNewCls) {
//dom.className = classList.join(' ');
me._saveAttr(dom, "className", classList.join(' '));
}
return me;
},
synchronize: function() {
var me = this,
dom = me.dom,
hasClassMap = {},
//className = dom.className,
className = me._loadAttr(dom, "className"),
classList, i, ln, name,
elementData = me.getData();
if (className && className.length > 0) {
//classList = dom.className.split(classNameSplitRegex);
classList = me._loadAttr(dom, "className").split(classNameSplitRegex);
for (i = 0, ln = classList.length; i < ln; i++) {
name = classList[i];
hasClassMap[name] = true;
}
}
else {
classList = [];
}
elementData.classList = classList;
elementData.classMap = hasClassMap;
elementData.isSynchronized = true;
return me;
},
set: function(attributes, useSet) {
var me = this,
dom = me.dom,
attribute, value;
for (attribute in attributes) {
if (attributes.hasOwnProperty(attribute)) {
value = attributes[attribute];
if (attribute === 'style') {
me.applyStyles(value);
}
else if (attribute === 'cls') {
//dom.className = value;
me._saveAttr(dom, "className", value);
}
else if (useSet !== false) {
if (value === undefined) {
dom.removeAttribute(attribute);
} else {
dom.setAttribute(attribute, value);
}
}
else {
dom[attribute] = value;
}
}
}
return me;
},
_loadAttr: function(element, attributeName) {
if (element instanceof SVGElement) {
return element[attributeName].baseVal;
} else {
return element[attributeName];
}
},
_saveAttr: function(element, attributeName, attributeValue) {
if (element instanceof SVGElement) {
element[attributeName].baseVal = attributeValue;
} else {
element[attributeName] = attributeValue;
}
}
};
}
|
|
13.04.2015, 09:21
|
Профессор
|
|
Регистрация: 19.11.2012
Сообщений: 178
|
|
Мне сейчас тоже нужен SVG. Стоит задача подружить ExtJs и GetOrgChart, которая рисует оргстукруру в SVG. Как вариант, можно встроить одну из спциализированных библиотек. Вы, кстати, не знаете, как получить доступ к инлайн тегу svg?
|
|
13.04.2015, 11:53
|
|
Соединяю Node.js и Ext JS
|
|
Регистрация: 25.06.2009
Сообщений: 1,033
|
|
Сообщение от novikov
|
Вы, кстати, не знаете, как получить доступ к инлайн тегу svg?
|
Я уже начал писать библиотеку. Могу выслать по почте (я ее через неделю опубликую на Github и собираюсь позже делать мануал, спецификацию и проект, чтобы другие могли ее использовать и развивать).
Мне нужна будет критика и внесение рац-предложений.
Тег SVG ничем не отличается от тега, допустим, DIV или P. Так что брать аналогично. Вставлять тоже аналогично.
|
|
13.04.2015, 11:59
|
|
Соединяю Node.js и Ext JS
|
|
Регистрация: 25.06.2009
Сообщений: 1,033
|
|
Специализированные библиотеки странные. VML добавляют. Цель у них - рисовать. Причем рисовать графики.
Моя цель - рисовать именно SVG. Полная реализация SVG под Ext JS. Чтобы можно было использовать все фичи доступные в SVG 1.1. Причем рисовать чтобы строить векторные редакторы. То есть в моей библиотеке есть такие сущности как рабочий стол + холст, масштабирование и движение холста мышкой, управляющие элементы объектов холста и прочее.
Поэтому я решил, раз написание базовой библиотеки занимает мало времени (неделя), то лучше создать свою библиотеку причем в духе Ext JS - это поддержка контейнеров (add, query и прочее), стиль программирования Ext, поддержка событий, поддержка свойств компонентов - например draggable и так далее.
|
|
13.04.2015, 15:39
|
Профессор
|
|
Регистрация: 19.11.2012
Сообщений: 178
|
|
Ваши планы на одну неделю меня лично впечатляют. Когда опубликуете, дайте знать. Интересно будет ознакомиться.
|
|
13.04.2015, 16:31
|
|
Соединяю Node.js и Ext JS
|
|
Регистрация: 25.06.2009
Сообщений: 1,033
|
|
Сообщение от novikov
|
Ваши планы на одну неделю меня лично впечатляют. Когда опубликуете, дайте знать. Интересно будет ознакомиться.
|
Да там кода очень мало получится. Потому увидите что это действительно работы на одну неделю.
Позже отдельным топиком опубликую ссылку на свою библиотеку.
|
|
|
|