Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 10.04.2015, 22:20
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 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.
Ответить с цитированием
  #2 (permalink)  
Старый 11.04.2015, 09:48
Профессор
Отправить личное сообщение для novikov Посмотреть профиль Найти все сообщения от novikov
 
Регистрация: 19.11.2012
Сообщений: 178

А Surface нельзя применить в вашем случае?

Можете показать, как оформили overrride?
Ответить с цитированием
  #3 (permalink)  
Старый 11.04.2015, 12:30
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 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;
        	}
        }
	};
	
}
Ответить с цитированием
  #4 (permalink)  
Старый 13.04.2015, 09:21
Профессор
Отправить личное сообщение для novikov Посмотреть профиль Найти все сообщения от novikov
 
Регистрация: 19.11.2012
Сообщений: 178

Мне сейчас тоже нужен SVG. Стоит задача подружить ExtJs и GetOrgChart, которая рисует оргстукруру в SVG. Как вариант, можно встроить одну из спциализированных библиотек. Вы, кстати, не знаете, как получить доступ к инлайн тегу svg?
Ответить с цитированием
  #5 (permalink)  
Старый 13.04.2015, 11:53
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Сообщение от novikov Посмотреть сообщение
Вы, кстати, не знаете, как получить доступ к инлайн тегу svg?
Я уже начал писать библиотеку. Могу выслать по почте (я ее через неделю опубликую на Github и собираюсь позже делать мануал, спецификацию и проект, чтобы другие могли ее использовать и развивать).

Мне нужна будет критика и внесение рац-предложений.

Тег SVG ничем не отличается от тега, допустим, DIV или P. Так что брать аналогично. Вставлять тоже аналогично.
Ответить с цитированием
  #6 (permalink)  
Старый 13.04.2015, 11:59
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Специализированные библиотеки странные. VML добавляют. Цель у них - рисовать. Причем рисовать графики.

Моя цель - рисовать именно SVG. Полная реализация SVG под Ext JS. Чтобы можно было использовать все фичи доступные в SVG 1.1. Причем рисовать чтобы строить векторные редакторы. То есть в моей библиотеке есть такие сущности как рабочий стол + холст, масштабирование и движение холста мышкой, управляющие элементы объектов холста и прочее.

Поэтому я решил, раз написание базовой библиотеки занимает мало времени (неделя), то лучше создать свою библиотеку причем в духе Ext JS - это поддержка контейнеров (add, query и прочее), стиль программирования Ext, поддержка событий, поддержка свойств компонентов - например draggable и так далее.
Ответить с цитированием
  #7 (permalink)  
Старый 13.04.2015, 15:39
Профессор
Отправить личное сообщение для novikov Посмотреть профиль Найти все сообщения от novikov
 
Регистрация: 19.11.2012
Сообщений: 178

Ваши планы на одну неделю меня лично впечатляют. Когда опубликуете, дайте знать. Интересно будет ознакомиться.
Ответить с цитированием
  #8 (permalink)  
Старый 13.04.2015, 16:31
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Сообщение от novikov Посмотреть сообщение
Ваши планы на одну неделю меня лично впечатляют. Когда опубликуете, дайте знать. Интересно будет ознакомиться.
Да там кода очень мало получится. Потому увидите что это действительно работы на одну неделю.

Позже отдельным топиком опубликую ссылку на свою библиотеку.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Переадресация если нет элемента fAmOus Элементы интерфейса 4 12.07.2012 11:42
Почему нет движения элемента? DZHETIGAPA Элементы интерфейса 14 20.04.2011 11:15