r58331 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r58330‎ | r58331 | r58332 >
Date:18:11, 29 October 2009
Author:tparscal
Status:deferred (Comments)
Tags:
Comment:
Initial version of a "designMode in an iframe" alternative to a normal text-area control for the wikiEditor.
Modified paths:
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.code.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.code.js
@@ -1,7 +1,7 @@
22 /**
3 - * TOC Module for wikiEditor
 3+ * Code Module for wikiEditor
44 */
5 -( function( $ ) { $.wikiEditor.modules.$editor = {
 5+( function( $ ) { $.wikiEditor.modules.code = {
66
77 /**
88 * API accessible functions
@@ -10,193 +10,94 @@
1111 //
1212 },
1313 /**
14 - *
15 - */
16 -languages: {
17 - csharp : 'C#',
18 - css : 'CSS',
19 - generic : 'Generic',
20 - html : 'HTML',
21 - java : 'Java',
22 - javascript : 'JavaScript',
23 - perl : 'Perl',
24 - ruby : 'Ruby',
25 - php : 'PHP',
26 - text : 'Text',
27 - sql : 'SQL',
28 - vbscript : 'VBScript'
29 -},
30 -/**
3114 * Internally used functions
3215 */
3316 fn: {
 17+ // Create the iframe and set things up
3418 create: function( context, config ) {
35 - context.$textarea
36 - .attr( 'disabled', true )
37 - .css( 'overflow', 'hidden' );
38 - context.modules.editor.$iframe = $( '<iframe></iframe>' )
39 - .css( {
40 - 'width': context.$textarea.css( 'width' ),
41 - 'height': context.$textarea.css( 'height' ),
42 - 'border': '1px solid gray',
43 - 'visibility': 'hidden',
44 - 'position': 'absolute'
45 - });
 19+ context.$iframe = $( '<iframe></iframe>' )
4620 .attr( 'frameborder', 0 )
47 - context.$textarea
48 - .css( 'overflow', 'auto' );
49 -
50 -
51 - var self = document.createElement('iframe');
52 -
53 - self.textarea = obj;
54 - self.textarea.disabled = true;
55 - self.textarea.style.overflow = 'hidden';
56 -
57 - self.style.height = self.textarea.clientHeight +'px';
58 - self.style.width = self.textarea.clientWidth +'px';
59 - self.textarea.style.overflow = 'auto';
60 -
61 - self.style.border = '1px solid gray';
62 - self.frameBorder = 0; // remove IE internal iframe border
63 - self.style.visibility = 'hidden';
64 - self.style.position = 'absolute';
65 -
66 -
67 - self.editor = self.contentWindow.CodePress;
68 - self.editor.body = self.contentWindow.document.getElementsByTagName('body')[0];
69 - self.editor.setCode(self.textarea.value);
70 - self.setOptions();
71 - self.editor.syntaxHighlight('init');
72 - self.textarea.style.display = 'none';
73 - self.style.position = 'static';
74 - self.style.visibility = 'visible';
75 - self.style.display = 'inline';
 21+ .css( {
 22+ 'backgroundColor': 'white',
 23+ 'width': '100%',
 24+ 'height': context.$textarea.height(),
 25+ 'display': 'none'
 26+ })
 27+ .insertAfter( context.$textarea );
 28+ context.$iframe[0].contentWindow.document.open();
 29+ context.$iframe[0].contentWindow.document.write(
 30+ '<html><head><title>wikiEditor</title></head><body style="margin:0;padding:0;width:100%;height:100%;">' +
 31+ '<pre style="margin:0;padding:0;width:100%;height:100%;white-space:pre-wrap;"></pre></body></html>'
 32+ );
 33+ context.$iframe[0].contentWindow.document.close();
 34+ context.$iframe[0].contentWindow.document.designMode = 'on';
 35+ context.modules.code = {
 36+ 'editor': {
 37+ 'container': context.$iframe.contents().find( 'body > pre' ),
 38+ 'active': false,
 39+ 'config': {}
 40+ }
 41+ };
 42+ // Make it happen!
 43+ $.wikiEditor.modules.code.fn.active( context, true );
7644 },
77 - language: function( context, language ) {
78 - if ( language != undefined ) {
79 - if(obj) self.textarea.value = document.getElementById(obj) ? document.getElementById(obj).value : obj;
80 - if(!self.textarea.disabled) return;
81 - self.language = language ? language : self.getLanguage();
82 - self.src = CodePress.path+'codepress.html?language='+self.language+'&ts='+(new Date).getTime();
83 - if(self.attachEvent) self.attachEvent('onload',self.initialize);
84 - else self.addEventListener('load',self.initialize,false);
85 -
86 - var config = { "language": "generic", "engine": null };
87 - var language = "generic"; var engine = "older";
88 - var ua = navigator.userAgent;
89 - var ts = (new Date).getTime(); // timestamp to avoid cache
90 - var lh = location.href;
91 -
92 - if(ua.match('MSIE')) engine = 'msie';
93 - else if(ua.match('KHTML')) engine = 'khtml';
94 - else if(ua.match('Opera')) engine = 'opera';
95 - else if(ua.match('Gecko')) engine = 'gecko';
96 - if(lh.match('language=')) language = lh.replace(/.*language=(.*?)(&.*)?$/,'$1');
97 -
98 - html = '\
99 -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html>\
100 -<head><title>wikiEditor</title><meta name="description" content="wikiEditor" /><script type="text/javascript">\
101 - <link type="text/css" href="codepress.css?ts='+ts+'" rel="stylesheet" />\
102 - <link type="text/css" href="languages/'+language+'.css?ts='+ts+'" rel="stylesheet" id="cp-lang-style" />\
103 - <script type="text/javascript" src="engines/'+engine+'.js?ts='+ts+'"></script>\
104 - <script type="text/javascript" src="languages/'+language+'.js?ts='+ts+'"></script>\
105 -</head>\
106 -';
107 -
108 -<script type="text/javascript">
109 -if(engine == "msie" || engine == "gecko") document.write('<body><pre> </pre></body>');
110 -else if(engine == "opera") document.write('<body></body>');
111 -// else if(engine == "khtml") document.write('<body> </body>');
112 -</script>
113 -
114 -</html>
115 -
116 -
117 - ';
118 -
119 -
120 -
121 -
122 -
123 -
124 -
125 -
126 -
127 -
128 -
129 -
130 -
131 -
132 -
 45+ // Set config / get config
 46+ config: function( context, config ) {
 47+ if ( config != undefined ) {
 48+ $.extend( context.modules.code.editor.config, config );
13349 } else {
134 - for (language in CodePress.languages)
135 - if(self.options.match('\\b'+language+'\\b'))
136 - return CodePress.languages[language] ? language : 'generic';
 50+ return context.modules.code.editor.config;
13751 }
13852 },
139 - options: function( context, options ) {
140 - if ( options != undefined ) {
141 - $.extend( context.modules.editor.options, options );
142 - } else {
143 - return context.modules.editor.options;
144 - }
145 - },
 53+ // Set code / get code to whichever control (textarea or iframe) is active
14654 code: function( context, code ) {
14755 if ( code !== undefined ) {
14856 // Set
149 - self.textarea.disabled ? self.editor.setCode(code) : self.textarea.value = code;
 57+ context.modules.code.editor.active ?
 58+ context.modules.code.editor.container.text( code ) : context.$textarea.val( code );
15059 } else {
15160 // Get
152 - return self.textarea.disabled ? self.editor.getCode() : self.textarea.value;
 61+ context.modules.code.editor.active ?
 62+ context.modules.code.editor.container.text() : context.$textarea.val();
15363 }
15464 },
155 - // toggleReadOnly
156 - lock: function( context ) {
157 - self.textarea.readOnly = true;
158 - if(self.style.display != 'none') // prevent exception on FF + iframe with display:none
159 - self.editor.readOnly( true );
 65+ // Lock / unlock / get locked state of all editing controls
 66+ locked: function( context, value ) {
 67+ if ( value !== undefined ) {
 68+ if ( value ) {
 69+ context.$textarea.attr( 'readonly', true );
 70+ if ( context.$iframe.css( 'display' ) != 'none' ) { // prevent exception on FF + iframe with display:none
 71+ context.$iframe.attr( 'readonly', true );
 72+ }
 73+ } else {
 74+ context.$textarea.attr( 'readonly', false );
 75+ if ( context.$iframe.css( 'display' ) != 'none' ) { // prevent exception on FF + iframe with display:none
 76+ context.$iframe.attr( 'readonly', false );
 77+ }
 78+ }
 79+ } else {
 80+ return context.modules.code.editor.active ?
 81+ context.$iframe.attr( 'readonly' ) : context.$textarea.attr( 'readonly' );
 82+ }
16083 },
161 - unlock: function( context ) {
162 - self.textarea.readOnly = false;
163 - if(self.style.display != 'none') // prevent exception on FF + iframe with display:none
164 - self.editor.readOnly( false );
165 - },
166 - // toggleEditor
167 - on: function( context ) {
168 - self.textarea.disabled = true;
169 - self.setCode(self.textarea.value);
170 - self.editor.syntaxHighlight('init');
171 - self.style.display = 'inline';
172 - self.textarea.style.display = 'none';
173 - }
174 - off: function( context ) {
175 - self.textarea.value = self.getCode();
176 - self.textarea.disabled = false;
177 - self.style.display = 'none';
178 - self.textarea.style.display = 'inline';
179 - }
180 -
181 -
182 -
183 - CodePress.run = function() {
184 - s = document.getElementsByTagName('script');
185 - for(var i=0,n=s.length;i<n;i++) {
186 - if(s[i].src.match('codepress.js')) {
187 - CodePress.path = s[i].src.replace('codepress.js','');
 84+ // Activate / deactivate / get active state of the iframe
 85+ active: function( context, value ) {
 86+ if ( value !== undefined ) {
 87+ if ( value && !context.modules.code.editor.active ) {
 88+ context.$textarea.attr( 'disabled', true );
 89+ context.modules.code.editor.container.text( context.$textarea.val() );
 90+ context.$textarea.hide();
 91+ context.$iframe.show();
 92+ } else if ( !value && context.modules.code.editor.active ) {
 93+ context.$textarea.attr( 'disabled', false );
 94+ context.$textarea.val( context.modules.code.editor.container.text() );
 95+ context.$textarea.show();
 96+ context.$iframe.hide();
18897 }
 98+ } else {
 99+ return context.modules.code.editor.active;
189100 }
190 - t = document.getElementsByTagName('textarea');
191 - for(var i=0,n=t.length;i<n;i++) {
192 - if(t[i].className.match('codepress')) {
193 - id = t[i].id;
194 - t[i].id = id+'_cp';
195 - eval(id+' = new CodePress(t[i])');
196 - t[i].parentNode.insertBefore(eval(id), t[i]);
197 - }
198 - }
199101 }
200 -
201102 }
202103
203104 }; } ) ( jQuery );
\ No newline at end of file

Comments

#Comment by Catrope (talk | contribs)   19:52, 29 October 2009

context.$iframe.contents().find( 'body > pre' )

Wouldn't just 'pre' be a faster selector (there's only one pre anyway)?
#Comment by Trevor Parscal (WMF) (talk | contribs)   07:46, 30 October 2009

I'm sure it would be...

Status & tagging log