1 | 1 | simandl | /* |
2 | | | star-light - version 1.0.2 (2005/06/06) |
3 | | | Copyright 2005, Dean Edwards |
4 | | | License: http://creativecommons.org/licenses/LGPL/2.1/ |
5 | | | */ |
6 | | | |
7 | | | /* --- (include) /my/src?fix-ie5.js --- */ |
8 | | | /* --- (require) /my/src?ICommon.js --- */ |
9 | | | /* --- (require) /my/src?ParseMaster.js --- */ |
10 | | | |
11 | | | // constants |
12 | | | function get_IGNORE(){return "$1"}; |
13 | | | function get_LINE_COMMENT(){return /\/\/[^\n]*\n/}; |
14 | | | function get_BLOCK_COMMENT(){return /\/\*[^*]*\*+([^\/][^*]*\*+)*\//}; |
15 | | | function get_SGML_COMMENT(){return /<!\s*(--([^-]|[\r\n]|-[^-])*--\s*)>/}; |
16 | | | function get_STRING1(){return /'[^']*'/}; |
17 | | | function get_STRING2(){return /"[^"]*"/}; |
18 | | | function get_NUMBER(){return /\b[+-]?(\d*\.?\d+|\d+\.?\d*)([eE][+-]?\d+)?\b/}; |
19 | | | |
20 | | | // read-only |
21 | | | function get_parser(){return _parser}; |
22 | | | |
23 | | | function refresh() { |
24 | | | parse(true); |
25 | | | }; |
26 | | | |
27 | | | // initialise |
28 | | | tabStop = -1; // tabs to spaces |
29 | | | urls = false; |
30 | | | email = false; |
31 | | | userRefresh = false; |
32 | | | function parse(refresh) { |
33 | | | try { |
34 | | | if (refresh || !userRefresh) { |
35 | | | var $parsed = parser.exec(); |
36 | | | if ($parsed) innerHTML = $parsed; |
37 | | | } |
38 | | | } catch ($ignore) { |
39 | | | }}; |
40 | | | |
41 | | | // constants |
42 | | | var $BASE_TAG = "<span>$1</span>"; |
43 | | | var $ELEMENT_NODE = 1; // DOM constant |
44 | | | var $TEXT_NODE = 3; |
45 | | | // internal references |
46 | | | var _parser = new ParseMaster; |
47 | | | |
48 | | | // create and add a new pattern to the patterns collection |
49 | | | _parser.specialize({ |
50 | | | add: function($expression, $style, $replacement) { |
51 | | | // if "expression" is a string, assume it's a keyword list |
52 | | | // e.g. expression = "...each|else|end|for|goto..." |
53 | | | if (typeof $expression == "string") $expression = new RegExp("\\b(" + $expression + ")\\b"); |
54 | | | // allow some patterns to be ignored during parsing |
55 | | | // the IGNORE flag is for readability only |
56 | | | if ($style == IGNORE) $style = $replacement = ""; |
57 | | | else if ($style) $replacement = _stylise($replacement || $BASE_TAG, $style); |
58 | | | // call the ancestor method to create the pattern |
59 | | | this.inherit(new RegExp(_decode(String($expression).slice(1, -1))), $replacement || "$1"); |
60 | | | }, |
61 | | | // global init function (called from the HTC) |
62 | | | exec: function() { |
63 | | | // retrieve this element's text content |
64 | | | var $text = _decode(_getText(element)); |
65 | | | // parse the text |
66 | | | $text = this.inherit($text); |
67 | | | // parse urls / emails |
68 | | | $text = _parseUrls($text); |
69 | | | // update this element's html content |
70 | | | return _parseWhiteSpace(_encode($text)); |
71 | | | } |
72 | | | }); |
73 | | | |
74 | | | // add a style attribute to a replacement string (usually <span>text</span>) |
75 | | | function _stylise($replacement, $style) { |
76 | | | return $replacement.replace(/>/, " style='" + $style + "'>"); |
77 | | | }; |
78 | | | |
79 | | | // retrieve the element's text |
80 | | | function _getText($node) { |
81 | | | var $text = ""; |
82 | | | // loop through text nodes |
83 | | | var $childNodes = $node.childNodes; |
84 | | | for (var i = 0; ($node = $childNodes[i]); i++) { |
85 | | | switch ($node.nodeType) { |
86 | | | case $ELEMENT_NODE: |
87 | | | $text += ($node.tagName == "BR") ? "\r" : _getText($node); |
88 | | | break; |
89 | | | case $TEXT_NODE: |
90 | | | $text += $node.nodeValue; |
91 | | | break; |
92 | | | } |
93 | | | } |
94 | | | // ensure that we have the same text for both platforms (mozilla/explorer) |
95 | | | return $text.replace(/\r/g, "\n") + "\n"; |
96 | | | }; |
97 | | | |
98 | | | // fix tabs and spaces |
99 | | | function _parseWhiteSpace($text) { |
100 | | | var $leadingSpace = /(\n[ ]*) /g; |
101 | | | while ($leadingSpace.test($text)) { |
102 | | | $text = $text.replace($leadingSpace, "$1 "); |
103 | | | } |
104 | | | // fix tabs |
105 | | | var $stop = ""; |
106 | | | if (tabStop > 0) { |
107 | | | var $count = tabStop; |
108 | | | while ($count--) $stop += " "; |
109 | | | $text = $text.replace(/\t/g, $stop); |
110 | | | } |
111 | | | // yuk. me no like :-( |
112 | | | if (/MSIE/.test(navigator.appVersion)) { |
113 | | | // get line-spacing working properly for IE |
114 | | | $text = $text.replace(/\n(<\/\w+>)?/g, "$1<br>").replace(/<br><br>/g, "<p><br></p>"); |
115 | | | } |
116 | | | return $text; |
117 | | | }; |
118 | | | |
119 | | | function _parseUrls($text) { |
120 | | | if (urls) $text = $text.replace(/(http:\/\/+[\w\/\-%&#=.,?+$]+)/g, "<a href='$1'>$1</a>"); |
121 | | | if (email) $text = $text.replace(/([\w.-]+@[\w.-]+\.\w+)/g, "<a href='mailto:$1'>$1</a>"); |
122 | | | return $text; |
123 | | | }; |
124 | | | |
125 | | | // encode special characters |
126 | | | function _encode($text) { |
127 | | | return $text.split("\x02").join("<").split("\x03").join("&"); |
128 | | | }; |
129 | | | |
130 | | | // decode special characters |
131 | | | function _decode($text) { |
132 | | | // patterns need "<" encoded |
133 | | | return $text.split("<").join("\x02").split("&").join("\x03"); |
134 | | | }; |