Нет поддержки элемента 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. |
|
Цитата:
Иными словами это библиотека для рисования (графиков). А мне нужна библиотека для создания 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; } } }; } |
Мне сейчас тоже нужен SVG. Стоит задача подружить ExtJs и GetOrgChart, которая рисует оргстукруру в SVG. Как вариант, можно встроить одну из спциализированных библиотек. Вы, кстати, не знаете, как получить доступ к инлайн тегу svg?
|
Цитата:
Мне нужна будет критика и внесение рац-предложений. Тег SVG ничем не отличается от тега, допустим, DIV или P. Так что брать аналогично. Вставлять тоже аналогично. |
Специализированные библиотеки странные. VML добавляют. Цель у них - рисовать. Причем рисовать графики.
Моя цель - рисовать именно SVG. Полная реализация SVG под Ext JS. Чтобы можно было использовать все фичи доступные в SVG 1.1. Причем рисовать чтобы строить векторные редакторы. То есть в моей библиотеке есть такие сущности как рабочий стол + холст, масштабирование и движение холста мышкой, управляющие элементы объектов холста и прочее. Поэтому я решил, раз написание базовой библиотеки занимает мало времени (неделя), то лучше создать свою библиотеку причем в духе Ext JS - это поддержка контейнеров (add, query и прочее), стиль программирования Ext, поддержка событий, поддержка свойств компонентов - например draggable и так далее. |
Ваши планы на одну неделю меня лично впечатляют. Когда опубликуете, дайте знать. Интересно будет ознакомиться.
|
Цитата:
Позже отдельным топиком опубликую ссылку на свою библиотеку. |
Часовой пояс GMT +3, время: 02:26. |