initial commit
[namibia] / public / scripts / ckeditor / _source / plugins / adobeair / plugin.js
1 /*
2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
4 */
5
6 (function()
7 {
8         var eventNameList = [ 'click', 'keydown', 'mousedown', 'keypress', 'mouseover', 'mouseout' ];
9
10         // Inline event callbacks assigned via innerHTML/outerHTML, such as
11         // onclick/onmouseover, are ignored in AIR.
12         // Use DOM2 event listeners to substitue inline handlers instead.
13         function convertInlineHandlers( container )
14         {
15                 // TODO: document.querySelectorAll is not supported in AIR.
16                 var children = container.getElementsByTag( '*' ),
17                         count = children.count(),
18                         child;
19
20                 for ( var i = 0; i < count; i++ )
21                 {
22                         child = children.getItem( i );
23
24                         (function( node )
25                         {
26                                 for ( var j = 0; j < eventNameList.length; j++ )
27                                 {
28                                         (function( eventName )
29                                         {
30                                                 var inlineEventHandler = node.getAttribute( 'on' + eventName );
31                                                 if ( node.hasAttribute( 'on' + eventName ) )
32                                                 {
33                                                         node.removeAttribute( 'on' + eventName );
34                                                         node.on( eventName, function( evt )
35                                                         {
36                                                                 var callFunc = /(return\s*)?CKEDITOR\.tools\.callFunction\(([^)]+)\)/.exec( inlineEventHandler ),
37                                                                         hasReturn = callFunc && callFunc[ 1 ],
38                                                                         callFuncArgs = callFunc &&  callFunc[ 2 ].split( ',' ),
39                                                                         preventDefault = /return false;/.test( inlineEventHandler );
40
41                                                                 if ( callFuncArgs )
42                                                                 {
43                                                                         var nums = callFuncArgs.length,
44                                                                                 argName;
45
46                                                                         for ( var i = 0; i < nums; i++ )
47                                                                         {
48                                                                                 // Trim spaces around param.
49                                                                                 callFuncArgs[ i ] = argName = CKEDITOR.tools.trim( callFuncArgs[ i ] );
50
51                                                                                 // String form param.
52                                                                                 var strPattern = argName.match( /^(["'])([^"']*?)\1$/ );
53                                                                                 if ( strPattern )
54                                                                                 {
55                                                                                         callFuncArgs[ i ] = strPattern[ 2 ];
56                                                                                         continue;
57                                                                                 }
58
59                                                                                 // Integer form param.
60                                                                                 if ( argName.match( /\d+/ ) )
61                                                                                 {
62                                                                                         callFuncArgs[ i ] = parseInt( argName, 10 );
63                                                                                         continue;
64                                                                                 }
65
66                                                                                 // Speical variables.
67                                                                                 switch( argName )
68                                                                                 {
69                                                                                         case 'this' :
70                                                                                                 callFuncArgs[ i ] = node.$;
71                                                                                                 break;
72                                                                                         case 'event' :
73                                                                                                 callFuncArgs[ i ] = evt.data.$;
74                                                                                                 break;
75                                                                                         case 'null' :
76                                                                                                 callFuncArgs [ i ] = null;
77                                                                                                 break;
78                                                                                 }
79                                                                         }
80
81                                                                         var retval = CKEDITOR.tools.callFunction.apply( window, callFuncArgs );
82                                                                         if ( hasReturn && retval === false )
83                                                                                  preventDefault = 1;
84                                                                 }
85
86                                                                 if ( preventDefault )
87                                                                         evt.data.preventDefault();
88                                                         });
89                                                 }
90                                         })( eventNameList[ j ] );
91                                 }
92                         })( child );
93                 }
94         }
95
96         CKEDITOR.plugins.add( 'adobeair',
97         {
98                 init : function( editor )
99                 {
100                         if ( !CKEDITOR.env.air )
101                                 return;
102
103                         // Body doesn't get default margin on AIR.
104                         editor.addCss( 'body { padding: 8px }' );
105
106                         editor.on( 'uiReady', function()
107                                 {
108                                         convertInlineHandlers( editor.container );
109
110                                         if ( editor.sharedSpaces )
111                                         {
112                                                 for ( var space in editor.sharedSpaces )
113                                                         convertInlineHandlers( editor.sharedSpaces[ space ] );
114                                         }
115
116                                         editor.on( 'elementsPathUpdate', function( evt ) { convertInlineHandlers( evt.data.space ); } );
117                                 });
118
119                         editor.on( 'contentDom', function()
120                                 {
121                                         // Hyperlinks are enabled in editable documents in Adobe
122                                         // AIR. Prevent their click behavior.
123                                         editor.document.on( 'click', function( ev )
124                                                 {
125                                                         ev.data.preventDefault( true );
126                                                 });
127                                 });
128                 }
129         });
130
131         CKEDITOR.ui.on( 'ready', function( evt )
132                 {
133                         var ui = evt.data;
134                         // richcombo, panelbutton and menu
135                         if ( ui._.panel )
136                         {
137                                 var panel = ui._.panel._.panel,
138                                                 holder;
139
140                                 ( function()
141                                 {
142                                         // Adding dom event listeners off-line are not supported in AIR,
143                                         // waiting for panel iframe loaded.
144                                         if ( !panel.isLoaded )
145                                         {
146                                                 setTimeout( arguments.callee, 30 );
147                                                 return;
148                                         }
149                                         holder = panel._.holder;
150                                         convertInlineHandlers( holder );
151                                 })();
152                         }
153                         else if ( ui instanceof CKEDITOR.dialog )
154                                 convertInlineHandlers( ui._.element );
155                 });
156 })();
157
158 CKEDITOR.dom.document.prototype.write = CKEDITOR.tools.override( CKEDITOR.dom.document.prototype.write,
159         function( original_write )
160         {
161                 function appendElement( parent, tagName, fullTag, text )
162                 {
163                         var node = parent.append( tagName ),
164                                 attrs = CKEDITOR.htmlParser.fragment.fromHtml( fullTag ).children[ 0 ].attributes;
165                         attrs && node.setAttributes( attrs );
166                         text && node.append( parent.getDocument().createText( text ) );
167                 }
168
169                 return function( html, mode )
170                         {
171                                 // document.write() or document.writeln() fail silently after
172                                 // the page load event in Adobe AIR.
173                                 // DOM manipulation could be used instead.
174                                 if ( this.getBody() )
175                                 {
176                                         // We're taking the below extra work only because innerHTML
177                                         // on <html> element doesn't work as expected.
178                                         var doc = this,
179                                                 head = this.getHead();
180
181                                         // Create style nodes for inline css. ( <style> content doesn't applied when setting via innerHTML )
182                                         html = html.replace( /(<style[^>]*>)([\s\S]*?)<\/style>/gi,
183                                                 function ( match, startTag, styleText )
184                                                 {
185                                                         appendElement( head, 'style', startTag, styleText );
186                                                         return '';
187                                                 });
188
189                                         html = html.replace( /<base\b[^>]*\/>/i,
190                                                 function( match )
191                                                 {
192                                                         appendElement( head, 'base', match );
193                                                         return '';
194                                                 });
195
196                                         html = html.replace( /<title>([\s\S]*)<\/title>/i,
197                                                 function( match, title )
198                                                 {
199                                                         doc.$.title = title;
200                                                         return '';
201                                                 });
202
203                                         // Move the rest of head stuff.
204                                         html = html.replace( /<head>([\s\S]*)<\/head>/i,
205                                                 function( headHtml )
206                                                 {
207                                                         // Inject the <head> HTML inside a <div>.
208                                                         // Do that before getDocumentHead because WebKit moves
209                                                         // <link css> elements to the <head> at this point.
210                                                         var div = new CKEDITOR.dom.element( 'div', doc );
211                                                         div.setHtml( headHtml );
212                                                         // Move the <div> nodes to <head>.
213                                                         div.moveChildren( head );
214                                                         return '';
215                                                 });
216
217                                         html.replace( /(<body[^>]*>)([\s\S]*)(?=$|<\/body>)/i,
218                                                 function( match, startTag, innerHTML )
219                                                 {
220                                                         doc.getBody().setHtml( innerHTML );
221                                                         var attrs = CKEDITOR.htmlParser.fragment.fromHtml( startTag ).children[ 0 ].attributes;
222                                                         attrs && doc.getBody().setAttributes( attrs );
223                                                 });
224                                 }
225                                 else
226                                         original_write.apply( this, arguments );
227                         };
228         });