-
Notifications
You must be signed in to change notification settings - Fork 9
/
ParseHTML.js
118 lines (111 loc) · 3.47 KB
/
ParseHTML.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
ParseHTML-React-Native (Version 0.1)
Coded by: Simar (github.com/iSimar)
GitHub Project: https://github.com/iSimar/ParseHTML-React-Native
*/
'use strict';
var React = require('react-native');
var {
View,
Text,
StyleSheet
} = React;
var ParseHTML = React.createClass({
getInitialState: function() {
var defaultTagToStyle = {
'<b>': {fontWeight: 'bold'},
'<i>': {fontStyle: 'italic'},
'<normal>': {fontStyle: 'normal'},
};
if(this.props.customTagToStyle){
for(var i in Object.keys(this.props.customTagToStyle)){
defaultTagToStyle[Object.keys(this.props.customTagToStyle)[i]] = this.props.customTagToStyle[Object.keys(this.props.customTagToStyle)[i]];
}
}
return {
tagToStyle: defaultTagToStyle,
};
},
_getNextHTMLTag: function(html_code, tags_to_look_for){
var min = -1;
var nextTag = "";
for (var i = 0; i < tags_to_look_for.length; i++) {
var tag = tags_to_look_for[i];
var nextIndex = html_code.indexOf(tag);
if(min == -1){
min = nextIndex;
nextTag = tag;
}
else{
if(min>nextIndex && nextIndex != -1){
min = nextIndex;
nextTag = tag;
}
}
}
return {"tag": nextTag, "indexStart": min};
},
_buildHTMLParseTree: function(html_code){
return this._buildHTMLParseTreeOverload(html_code, []);
},
_buildHTMLParseTreeOverload: function(html_code, segments, style){
if(segments==undefined)
segments = [];
if(style==undefined)
style = [];
var nextTag = this._getNextHTMLTag(html_code, Object.keys(this.state.tagToStyle));
if(nextTag.indexStart != -1){
if(nextTag.indexStart>0){
segments.push({
"text": html_code.slice(0, nextTag.indexStart),
"style": style,
});
}
var endTag = "</"+(nextTag.tag).slice(1);
var indexEnd = html_code.indexOf(endTag);
var new_text = html_code.slice(nextTag.indexStart+nextTag.tag.length, indexEnd);
segments.push({"segments": this._buildHTMLParseTreeOverload(new_text, [], style.concat([this.state.tagToStyle[nextTag.tag]]))});
return this._buildHTMLParseTreeOverload(html_code.slice(indexEnd+endTag.length, html_code.length), segments);
}
else{
if(html_code!=''){
segments.push({"text": html_code,
"style": style});
}
return segments;
}
},
_renderHTMLParseTree: function(parseTree){
return parseTree.map((segment)=>{
if(segment.segments)
return this._renderHTMLParseTree(segment.segments)
return <Text style={segment.style}>{segment.text}</Text>;
});
},
_decodeHTMLEntities: function(str){
return String(str)
.replace(///g, '/')
.replace(/'/g, '\'')
.replace(/"/g, '\"')
.replace(/<a\s+(?:[^>]*?\s+)?href="([^"]*)" rel="nofollow">(.*)?<\/a>/g, "$1")
.replace(/>/g, '>')
.replace(/</g, '<')
.replace(/<br(>|\s|\/)*/g, '\n');
},
render: function() {
return (
<View style={[styles.container, this.props.style]}>
<Text>
{this._renderHTMLParseTree(this._buildHTMLParseTree(this._decodeHTMLEntities(this.props.code)))}
</Text>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFFFFF',
},
});
module.exports = ParseHTML;