Browse Source

Detach styles from html string

pull/36/head
Artur Arseniev 10 years ago
parent
commit
50c0f3b7f4
  1. 2
      src/dom_components/model/Components.js
  2. 7
      src/parser/main.js
  3. 24
      src/parser/model/ParserHtml.js
  4. 48
      test/specs/parser/model/ParserHtml.js

2
src/dom_components/model/Components.js

@ -50,7 +50,7 @@ define([ 'backbone', 'require'],
add: function(models, opt){ add: function(models, opt){
if(typeof models === 'string') if(typeof models === 'string')
models = this.editor.Parser.parseHtml(models); models = this.editor.Parser.parseHtml(models).html;
return Backbone.Collection.prototype.add.apply(this, [models, opt]); return Backbone.Collection.prototype.add.apply(this, [models, opt]);
}, },

7
src/parser/main.js

@ -18,8 +18,13 @@ define(function(require) {
return { return {
/**
* Parse HTML string and return valid model
* @param {string} str HTML string
* @return {Object}
*/
parseHtml: function(str){ parseHtml: function(str){
return pHtml.parse(str); return pHtml.parse(str, pCss);
}, },
parseCss: function(str){ parseCss: function(str){

24
src/parser/model/ParserHtml.js

@ -152,9 +152,11 @@ define(function(require) {
/** /**
* Parse HTML string to a desired model object * Parse HTML string to a desired model object
* @param {string} str HTML string * @param {string} str HTML string
* @param {ParserCss} parserCss In case there is style tags inside HTML
* @return {Object} * @return {Object}
*/ */
parse: function(str){ parse: function(str, parserCss){
var res = { html: [], css: []};
var el = document.createElement('div'); var el = document.createElement('div');
el.innerHTML = str; el.innerHTML = str;
var scripts = el.querySelectorAll('script'); var scripts = el.querySelectorAll('script');
@ -164,12 +166,30 @@ define(function(require) {
while (i--) while (i--)
scripts[i].parentNode.removeChild(scripts[i]); scripts[i].parentNode.removeChild(scripts[i]);
// Detach style tags and parse them
if(parserCss){
var styleStr = '';
var styles = el.querySelectorAll('style');
var j = styles.length;
while (j--){
styleStr = styles[j].innerHTML + styleStr;
styles[j].parentNode.removeChild(styles[j]);
}
if(styleStr)
res.css = parserCss.parse(styleStr);
}
var result = this.parseNode(el); var result = this.parseNode(el);
if(result.length == 1) if(result.length == 1)
result = result[0]; result = result[0];
return result; res.html = result;
return res;
}, },
}; };

48
test/specs/parser/model/ParserHtml.js

@ -1,6 +1,6 @@
var path = 'Parser/'; var path = 'Parser/';
define([path + 'model/ParserHtml',], define([path + 'model/ParserHtml', path + 'model/ParserCss'],
function(ParserHtml) { function(ParserHtml, ParserCss) {
return { return {
run : function(){ run : function(){
@ -21,13 +21,13 @@ define([path + 'model/ParserHtml',],
it('Simple div node', function() { it('Simple div node', function() {
var str = '<div></div>'; var str = '<div></div>';
var result = { tagName: 'div'}; var result = { tagName: 'div'};
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Simple article node', function() { it('Simple article node', function() {
var str = '<article></article>'; var str = '<article></article>';
var result = { tagName: 'article'}; var result = { tagName: 'article'};
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Node with attributes', function() { it('Node with attributes', function() {
@ -41,7 +41,7 @@ define([path + 'model/ParserHtml',],
'strange': 'test5' 'strange': 'test5'
} }
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Parse style string to object', function() { it('Parse style string to object', function() {
@ -71,7 +71,7 @@ define([path + 'model/ParserHtml',],
test: 'value', test: 'value',
} }
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Class attribute is isolated', function() { it('Class attribute is isolated', function() {
@ -81,7 +81,7 @@ define([path + 'model/ParserHtml',],
attributes: { id: 'test1'}, attributes: { id: 'test1'},
classes: ['test2', 'test3', 'test4'] classes: ['test2', 'test3', 'test4']
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Parse images nodes', function() { it('Parse images nodes', function() {
@ -92,7 +92,7 @@ define([path + 'model/ParserHtml',],
src: './index.html', src: './index.html',
attributes: { id: 'test1'}, attributes: { id: 'test1'},
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Parse text nodes', function() { it('Parse text nodes', function() {
@ -103,7 +103,7 @@ define([path + 'model/ParserHtml',],
type: 'text', type: 'text',
content: 'test2 ', content: 'test2 ',
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Parse text with few text tags', function() { it('Parse text with few text tags', function() {
@ -114,7 +114,7 @@ define([path + 'model/ParserHtml',],
type: 'text', type: 'text',
content: '<br> test2 <br> a b <b>b</b> <i>i</i> <u>u</u> test ', content: '<br> test2 <br> a b <b>b</b> <i>i</i> <u>u</u> test ',
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Parse text with few text tags and nested node', function() { it('Parse text with few text tags and nested node', function() {
@ -136,7 +136,7 @@ define([path + 'model/ParserHtml',],
content: '<i>i</i> <u>u</u> test ', content: '<i>i</i> <u>u</u> test ',
}], }],
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Parse nested nodes', function() { it('Parse nested nodes', function() {
@ -160,7 +160,7 @@ define([path + 'model/ParserHtml',],
}, },
] ]
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Parse nested text nodes', function() { it('Parse nested text nodes', function() {
@ -181,7 +181,7 @@ define([path + 'model/ParserHtml',],
content: ' content2', content: ' content2',
}], }],
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Parse nested span text nodes', function() { it('Parse nested span text nodes', function() {
@ -205,20 +205,34 @@ define([path + 'model/ParserHtml',],
content: ' content2', content: ' content2',
}], }],
}; };
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Parse multiple nodes', function() { it('Parse multiple nodes', function() {
var str = '<div></div><div></div>'; var str = '<div></div><div></div>';
var result = [{ tagName: 'div'},{ tagName: 'div'}]; var result = [{ tagName: 'div'},{ tagName: 'div'}];
obj.parse(str).should.deep.equal(result); obj.parse(str).html.should.deep.equal(result);
}); });
it('Remove script tags', function() { it('Remove script tags', function() {
var str = '<div><script>var test;</script></div><div></div><script>var test2;</script>'; var str = '<div><script>var test;</script></div><div></div><script>var test2;</script>';
var result = [{ tagName: 'div'},{ tagName: 'div'}]; var result = [{ tagName: 'div'},{ tagName: 'div'}];
console.log(obj.parse(str)); obj.parse(str).html.should.deep.equal(result);
obj.parse(str).should.deep.equal(result); });
it('Isolate styles', function() {
var str = '<div><style>.a{color: red}</style></div><div></div><style>.b{color: blue}</style>';
var resHtml = [{ tagName: 'div'},{ tagName: 'div'}];
var resCss = [{
selectors: ['a'],
style: { color: 'red'}
},{
selectors: ['b'],
style: { color: 'blue'}
}]
var res = obj.parse(str, new ParserCss());
res.html.should.deep.equal(resHtml);
res.css.should.deep.equal(resCss);
}); });
}); });

Loading…
Cancel
Save