diff --git a/index.html b/index.html index 1d32a1702..a5a16174d 100755 --- a/index.html +++ b/index.html @@ -36,6 +36,8 @@
+ +
Build your templates without coding
All text blocks could be edited easily with double clicking on it. You can create new text blocks with the command from the left panel
Hover me
diff --git a/src/dom_components/main.js b/src/dom_components/main.js index 2c60bd031..cf3e87d19 100644 --- a/src/dom_components/main.js +++ b/src/dom_components/main.js @@ -42,30 +42,30 @@ define(function(require) { ComponentView = require('./view/ComponentView'); var component, componentView; var defaultTypes = { - 'default': { - model: Component, - view: ComponentView, - }, - 'text': { - model: require('./model/ComponentText'), - view: require('./view/ComponentTextView'), - }, - 'image': { - model: require('./model/ComponentImage'), - view: require('./view/ComponentImageView'), + 'map': { + model: require('./model/ComponentMap'), + view: require('./view/ComponentMapView'), }, 'link': { model: require('./model/ComponentLink'), view: require('./view/ComponentLinkView'), }, - 'map': { - model: require('./model/ComponentMap'), - view: require('./view/ComponentMapView'), - }, 'video': { model: require('./model/ComponentVideo'), view: require('./view/ComponentVideoView'), - } + }, + 'image': { + model: require('./model/ComponentImage'), + view: require('./view/ComponentImageView'), + }, + 'text': { + model: require('./model/ComponentText'), + view: require('./view/ComponentTextView'), + }, + 'default': { + model: Component, + view: ComponentView, + }, }; return { @@ -119,6 +119,7 @@ define(function(require) { c.rte = c.em.get('rte') || ''; c.modal = c.em.get('Modal') || ''; c.am = c.em.get('AssetManager') || ''; + c.em.get('Parser').compTypes = defaultTypes; } component = new Component(c.wrapper, { diff --git a/src/dom_components/model/Component.js b/src/dom_components/model/Component.js index 515baa527..053af6491 100644 --- a/src/dom_components/model/Component.js +++ b/src/dom_components/model/Component.js @@ -194,11 +194,8 @@ define(['backbone','./Components', 'SelectorManager/model/Selectors', 'TraitMana * @private */ isComponent: function(el) { - var result = ''; - if(el.tagName == 'DIV') - result = {tagName: 'div'}; - return result; - } + return {tagName: el.tagName ? el.tagName.toLowerCase() : ''}; + }, }); }); diff --git a/src/dom_components/model/ComponentImage.js b/src/dom_components/model/ComponentImage.js index 519183f7e..6b1ff27e6 100644 --- a/src/dom_components/model/ComponentImage.js +++ b/src/dom_components/model/ComponentImage.js @@ -4,6 +4,7 @@ define(['./Component'], return Component.extend({ defaults: _.extend({}, Component.prototype.defaults, { + type: 'image', tagName: 'img', src: '', void: 1, @@ -31,5 +32,24 @@ define(['./Component'], return attr; } + },{ + + /** + * Detect if the passed element is a valid component. + * In case the element is valid an object abstracted + * from the element will be returned + * @param {HTMLElement} + * @return {Object} + * @private + */ + isComponent: function(el) { + var result = ''; + if(el.tagName == 'IMG'){ + result = {type: 'image', tagName: 'img'}; + result.src = el.src; + } + return result; + }, + }); }); diff --git a/src/dom_components/model/ComponentLink.js b/src/dom_components/model/ComponentLink.js index 5f29f40ac..95849f02b 100644 --- a/src/dom_components/model/ComponentLink.js +++ b/src/dom_components/model/ComponentLink.js @@ -8,5 +8,23 @@ define(['./ComponentText'], traits: ['title', 'href', 'target'], }), + },{ + + /** + * Detect if the passed element is a valid component. + * In case the element is valid an object abstracted + * from the element will be returned + * @param {HTMLElement} + * @return {Object} + * @private + */ + isComponent: function(el) { + var result = ''; + if(el.tagName == 'A'){ + result = {type: 'link', tagName: 'a'}; + } + return result; + }, + }); }); diff --git a/src/dom_components/model/ComponentMap.js b/src/dom_components/model/ComponentMap.js index ea2720e68..7ad0146d2 100644 --- a/src/dom_components/model/ComponentMap.js +++ b/src/dom_components/model/ComponentMap.js @@ -33,5 +33,24 @@ define(['./ComponentImage'], }], }), + },{ + + /** + * Detect if the passed element is a valid component. + * In case the element is valid an object abstracted + * from the element will be returned + * @param {HTMLElement} + * @return {Object} + * @private + */ + isComponent: function(el) { + var result = ''; + if(el.tagName == 'IFRAME' && + /maps\.google\.com/.test(el.src) ){ + result = {type: 'map', src: el.src, tagName: 'iframe'}; + } + return result; + }, + }); }); diff --git a/src/dom_components/model/ComponentVideo.js b/src/dom_components/model/ComponentVideo.js index 43d79e8d5..e13e766be 100644 --- a/src/dom_components/model/ComponentVideo.js +++ b/src/dom_components/model/ComponentVideo.js @@ -242,5 +242,36 @@ define(['./ComponentImage'], return url; }, + },{ + + /** + * Detect if the passed element is a valid component. + * In case the element is valid an object abstracted + * from the element will be returned + * @param {HTMLElement} + * @return {Object} + * @private + */ + isComponent: function(el) { + var result = ''; + var isYtProv = /youtube\.com\/embed/.test(el.src); + var isViProv = /player\.vimeo\.com\/video/.test(el.src); + var isExtProv = isYtProv || isViProv; + if(el.tagName == 'VIDEO' || + (el.tagName == 'IFRAME' && isExtProv) ){ + result = {type: 'video', tagName: 'video'}; + if(el.src) + result.src = el.src; + if(isExtProv){ + result.tagName = 'iframe'; + if(isYtProv) + result.provider = 'yt'; + else if(isViProv) + result.provider = 'vi'; + } + } + return result; + }, + }); }); diff --git a/src/parser/main.js b/src/parser/main.js index 42ef7e7f2..a410d9738 100644 --- a/src/parser/main.js +++ b/src/parser/main.js @@ -9,6 +9,8 @@ define(function(require) { return { + compTypes: '', + /** * Name of the module * @type {String} @@ -48,6 +50,7 @@ define(function(require) { * @return {Object} */ parseHtml: function(str){ + pHtml.compTypes = this.compTypes; return pHtml.parse(str, pCss); }, @@ -60,4 +63,4 @@ define(function(require) { return Parser; -}); \ No newline at end of file +}); diff --git a/src/parser/model/ParserHtml.js b/src/parser/model/ParserHtml.js index 8167701bb..1f1c30180 100644 --- a/src/parser/model/ParserHtml.js +++ b/src/parser/model/ParserHtml.js @@ -7,6 +7,8 @@ define(function(require) { return { + compTypes: '', + /** * Parse style string to object * @param {string} str @@ -68,6 +70,18 @@ define(function(require) { var prevSib = result[prevI]; model.tagName = node.tagName ? node.tagName.toLowerCase() : ''; + var ct = this.compTypes; + if(ct){ + var obj = ''; + for (var cType in ct) { + var component = ct[cType].model; + obj = component.isComponent(node); + if(obj) + break; + } + model = obj; + } + if(attrsLen) model.attributes = {}; @@ -197,4 +211,4 @@ define(function(require) { }; -}); \ No newline at end of file +}); diff --git a/test/specs/dom_components/model/Component.js b/test/specs/dom_components/model/Component.js index 0ab172687..ae31b7bba 100644 --- a/test/specs/dom_components/model/Component.js +++ b/test/specs/dom_components/model/Component.js @@ -2,8 +2,12 @@ define(['DomComponents', 'DomComponents/model/Component', 'DomComponents/model/ComponentImage', 'DomComponents/model/ComponentText', + 'DomComponents/model/ComponentLink', + 'DomComponents/model/ComponentMap', + 'DomComponents/model/ComponentVideo', 'DomComponents/model/Components'], - function(DomComponents, Component, ComponentImage, ComponentText, Components) { + function(DomComponents, Component, ComponentImage, ComponentText, + ComponentLink, ComponentMap, ComponentVideo, Components) { return { run : function(){ @@ -102,6 +106,18 @@ define(['DomComponents', obj.toHTML().should.equal('
'); }); + it('Component parse empty div', function() { + var el = document.createElement('div'); + obj = Component.isComponent(el); + obj.should.deep.equal({tagName: 'div'}); + }); + + it('Component parse span', function() { + var el = document.createElement('span'); + obj = Component.isComponent(el); + obj.should.deep.equal({tagName: 'span'}); + }); + }); describe('Image Component', function() { @@ -135,6 +151,25 @@ define(['DomComponents', obj.toHTML().should.equal('AltTest'); }); + it('Refuse not img element', function() { + var el = document.createElement('div'); + obj = ComponentImage.isComponent(el); + obj.should.equal(''); + }); + + it('Component parse img element', function() { + var el = document.createElement('img'); + obj = ComponentImage.isComponent(el); + obj.should.deep.equal({type: 'image', src: ''}); + }); + + it('Component parse img element with src', function() { + var el = document.createElement('img'); + el.src = 'http://localhost/'; + obj = ComponentImage.isComponent(el); + obj.should.deep.equal({type: 'image', src: 'http://localhost/'}); + }); + }); describe('Text Component', function() { @@ -165,6 +200,58 @@ define(['DomComponents', }); + describe('Link Component', function() { + + it('Component parse a element', function() { + var el = document.createElement('a'); + obj = ComponentLink.isComponent(el); + obj.should.deep.equal({type: 'link'}); + }); + + }); + + describe('Map Component', function() { + + it('Component parse map iframe', function() { + var src = 'https://maps.google.com/maps?&q=London,UK&z=11&t=q&output=embed'; + var el = $(''); + obj = ComponentMap.isComponent(el.get(0)); + obj.should.deep.equal({type: 'map', src: src}); + }); + + it('Component parse not map iframe', function() { + var el = $(''); + obj = ComponentMap.isComponent(el.get(0)); + obj.should.equal(''); + }); + + }); + + describe('Video Component', function() { + + it('Component parse video', function() { + var src = 'http://localhost/'; + var el = $(''); + obj = ComponentVideo.isComponent(el.get(0)); + obj.should.deep.equal({type: 'video'}); //src: src + }); + + it('Component parse youtube video iframe', function() { + var src = 'http://www.youtube.com/embed/jNQXAC9IVRw?'; + var el = $('