]> git.mxchange.org Git - friendica.git/blob - simplepie/demo/for_the_demo/source_files/sIFR-r245/sIFR.as
darkzero textareas hard to read
[friendica.git] / simplepie / demo / for_the_demo / source_files / sIFR-r245 / sIFR.as
1 /*=:project
2     scalable Inman Flash Replacement (sIFR) version 3.
3
4   =:file
5     Copyright: 2006 Mark Wubben.
6     Author: Mark Wubben, <http://novemberborn.net/>
7
8   =:history
9     * IFR: Shaun Inman
10     * sIFR 1: Mike Davidson, Shaun Inman and Tomas Jogin
11     * sIFR 2: Mike Davidson, Shaun Inman, Tomas Jogin and Mark Wubben
12
13   =:license
14     This software is licensed and provided under the CC-GNU LGPL.
15     See <http://creativecommons.org/licenses/LGPL/2.1/>    
16 */
17
18 import SifrStyleSheet;
19
20 class sIFR {
21   public static var DEFAULT_TEXT                 = 'Rendered with sIFR 3, revision 245';
22   public static var CSS_ROOT_CLASS               = 'sIFR-root';
23   public static var DEFAULT_WIDTH                = 300;
24   public static var DEFAULT_HEIGHT               = 100;
25   public static var DEFAULT_ANTI_ALIAS_TYPE      = 'advanced';
26   public static var MARGIN_LEFT                  = -3;
27   public static var PADDING_BOTTOM               = 5; // Extra padding to make sure the movie is high enough in most cases.
28   public static var LEADING_REMAINDER            = 2; // Flash uses the specified leading minus 2 as the applied leading.
29
30   public static var MAX_FONT_SIZE                = 126;
31   public static var ALIASING_MAX_FONT_SIZE       = 48;
32   
33   //= Holds CSS properties and other rendering properties for the Flash movie.
34   //  *Don't overwrite!*
35   public static var styles:SifrStyleSheet        = new SifrStyleSheet();
36   //= Allow sIFR to be run from localhost
37   public static var fromLocal:Boolean            = true;
38   //= Array containing domains for which sIFR may render text. Used to prevent
39   //  hotlinking. Use `*` to allow all domains.
40   public static var domains:Array                = [];
41   //= Whether kerning is enabled by default. This can be overriden from the client side.
42   //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002811.html>.
43   public static var defaultKerning:Boolean       = true;
44   //= Default value which can be overriden from the client side.
45   //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002788.html>.
46   public static var defaultSharpness:Number      = 0;
47   //= Default value which can be overriden from the client side.
48   //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002787.html>.
49   public static var defaultThickness:Number      = 0;
50   //= Default value which can be overriden from the client side.
51   //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002732.html>.
52   public static var defaultOpacity:Number        = -1; // Use client settings
53   //= Default value which can be overriden from the client side.
54   //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002788.html>.
55   public static var defaultBlendMode:Number      = -1; // Use cliest settings
56   //= Overrides the grid fit type as defined on the client side.
57   //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002444.html>.
58   public static var enforcedGridFitType:String   = null;
59   //= If `true` sIFR won't override the anti aliasing set in the Flash IDE when exporting.
60   //  Thickness and sharpness won't be affected either.
61   public static var preserveAntiAlias:Boolean    = false;
62   //= If `true` sIFR will disable anti-aliasing if the font size is larger than `ALIASING_MAX_FONT_SIZE`.
63   //  This setting is *independent* from `preserveAntiAlias`.
64   public static var conditionalAntiAlias:Boolean = true;
65   //= Sets the anti alias type. By default it's `DEFAULT_ANTI_ALIAS_TYPE`.
66   //  See also <http://livedocs.macromedia.com/flash/8/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00002733.html>.
67   public static var antiAliasType:String         = null;
68   //= Flash filters can be added to this array and will be applied to the text field.
69   public static var filters:Array                = [];
70   //= A mapping from the names of the filters to their actual objecs, used when transforming
71   //  filters defined on the client. You can add additional filters here so they'll be supported
72   //  when defined on the client.
73   public static var filterMap:Object             = {
74     DisplacementMapFilter : flash.filters.DisplacementMapFilter,
75     ColorMatrixFilter     : flash.filters.ColorMatrixFilter,
76     ConvolutionFilter     : flash.filters.ConvolutionFilter,
77     GradientBevelFilter   : flash.filters.GradientBevelFilter,
78     GradientGlowFilter    : flash.filters.GradientGlowFilter,
79     BevelFilter           : flash.filters.BevelFilter,
80     GlowFilter            : flash.filters.GlowFilter,
81     BlurFilter            : flash.filters.BlurFilter,
82     DropShadowFilter      : flash.filters.DropShadowFilter
83   };
84
85   private static var instance;
86   
87   private var textField;
88   private var content;
89   private var realHeight;
90   private var originalHeight;
91   private var currentHeight;
92   private var fontSize;
93   private var tuneWidth;
94   private var tuneHeight;
95   
96
97   
98   //= Sets the default styles for `sIFR.styles`. This method is called
99   //  directly in `sifr.fla`, before options are applied.
100   public static function setDefaultStyles() {
101     sIFR.styles.parseCSS([
102       '.', CSS_ROOT_CLASS, ' { color: #000000; }',
103       'strong { display: inline; font-weight: bold; } ',
104       'em { display: inline; font-style: italic; }',
105       'a { color: #0000FF; text-decoration: underline; }',
106       'a:hover { color: #0000FF; text-decoration: none; }'
107     ].join(''));
108   }
109   
110   //= Validates the domain sIFR is being used on.
111   //  Returns `true` if the domain is valid, `false` otherwise.  
112   public static function checkDomain():Boolean {
113     if(sIFR.domains.length == 0) return true;
114
115     var domain = (new LocalConnection()).domain();
116     if(sIFR.fromLocal) sIFR.domains.push('localhost');
117     
118     for(var i = 0; i < sIFR.domains.length; i++) {
119       var match = sIFR.domains[i];
120       if(match == '*' || match == domain) return true;
121
122       var wildcard = match.lastIndexOf('*');
123       if(wildcard > -1) {
124         match = match.substr(wildcard + 1);
125         var matchPosition = domain.lastIndexOf(match);
126         if(matchPosition > -1 && (matchPosition + match.length) == domain.length) return true;
127       }
128     }
129     
130     return false;
131   }
132   
133   //= Runs sIFR. Called automatically.
134   public static function run() {
135     var holder  = _root.holder;
136     var content = checkDomain() ? unescape(_root.content) : DEFAULT_TEXT
137     if(content == 'undefined' || content == '') {
138       content = DEFAULT_TEXT;
139       fscommand('resetmovie', '');
140     } else fscommand('ping', '');
141
142     // Sets stage parameters
143     Stage.scaleMode = 'noscale';
144     Stage.align = 'TL';
145     Stage.showMenu = false;
146     
147     // Other parameters
148     var opacity = parseInt(_root.opacity);
149     if(!isNaN(opacity)) holder._alpha = sIFR.defaultOpacity == -1 ? opacity : sIFR.defaultOpacity;
150     else holder._alpha = 100;
151     _root.blendMode = sIFR.defaultBlendMode == -1 ? _root.blendmode : sIFR.defaultBlendMode;
152
153     sIFR.instance = new sIFR(holder.txtF, content);
154     // This should ignore resizes from the callback. Disabled for now.
155 /*    if(_root.zoomsupport == 'true') Stage.addListener({onResize: function() { sIFR.instance.scale() }});*/
156
157     // Setup callbacks
158     _root.watch('callbackTrigger', function() { 
159       sIFR.callback();
160       return false;
161     });
162   }
163   
164   private static function eval(str) {
165     var as;
166     
167     if(str.charAt(0) == '{') { // Ah, we need to create an object
168       as = {};
169       str = str.substring(1, str.length - 1);
170       var $ = str.split(',');
171       for(var i = 0; i < $.length; i++) {
172         var $1 = $[i].split(':');
173         as[$1[0]] = sIFR.eval($1[1]);
174       }
175     } else if(str.charAt(0) == '"') { // String
176       as = str.substring(1, str.length - 1);
177     } else if(str == 'true' || str == 'false') { // Boolean
178       as = str == 'true';
179     } else { // Float
180       as = parseFloat(str);
181     }
182     
183     return as;
184   }
185   
186   private function applyFilters() {
187     var $filters = this.textField.filters;
188     $filters = $filters.concat(sIFR.filters);
189     
190     var $ = _root.flashfilters.split(';'); // name,prop:value,...;
191     for(var i = 0; i < $.length; i++) {
192       var $1 = $[i].split(',');
193       
194       var newFilter = new sIFR.filterMap[$1[0]]();
195       for(var j = 1; j < $1.length; j++) {
196         var $2 = $1[j].split(':');
197         newFilter[$2[0]] = sIFR.eval(unescape($2[1]));
198       }
199       
200       $filters.push(newFilter);
201     }
202
203     this.textField.filters = $filters;
204   }
205   
206   private function sIFR(textField, content) {
207     this.textField = textField;
208     this.content   = content;
209
210     var offsetLeft = parseInt(_root.offsetleft);
211     textField._x = MARGIN_LEFT + (isNaN(offsetLeft) ? 0 : offsetLeft);
212     var offsetTop = parseInt(_root.offsettop);
213     if(!isNaN(offsetTop)) textField._y += offsetTop;
214     
215     tuneWidth = parseInt(_root.tunewidth);
216     if(isNaN(tuneWidth)) tuneWidth = 0;
217     tuneHeight = parseInt(_root.tuneheight);
218     if(isNaN(tuneHeight)) tuneHeight = 0;
219
220     textField._width = tuneWidth + (isNaN(parseInt(_root.width)) ? DEFAULT_WIDTH : parseInt(_root.width));
221     textField._height = tuneHeight + (isNaN(parseInt(_root.height)) ? DEFAULT_HEIGHT : parseInt(_root.height));
222     textField.wordWrap = true;
223     textField.selectable = _root.selectable == 'true';
224     textField.gridFitType = sIFR.enforcedGridFitType || _root.gridfittype;
225     this.applyFilters();
226
227     // Determine font-size and the number of lines
228     this.fontSize = parseInt(_root.size);
229     if(isNaN(this.fontSize)) this.fontSize = 26;
230     styles.fontSize = this.fontSize;
231     
232     if(!sIFR.preserveAntiAlias && (sIFR.conditionalAntiAlias && this.fontSize < ALIASING_MAX_FONT_SIZE
233     || !sIFR.conditionalAntiAlias)) {
234       textField.antiAliasType = sIFR.antiAliasType || DEFAULT_ANTI_ALIAS_TYPE;      
235     }
236
237     if(!sIFR.preserveAntiAlias || !isNaN(parseInt(_root.sharpness))) {
238       textField.sharpness = parseInt(_root.sharpness);
239     }
240     if(isNaN(textField.sharpness)) textField.sharpness = sIFR.defaultSharpness;
241
242     if(!sIFR.preserveAntiAlias || !isNaN(parseInt(_root.thickness))) {
243       textField.thickness = parseInt(_root.thickness);
244     }
245     if(isNaN(textField.thickness)) textField.thickness = sIFR.defaultThickness;
246     
247     // Set font-size and other styles
248     sIFR.styles.parseCSS(unescape(_root.css));
249     
250     var rootStyle = styles.getStyle('.sIFR-root') || {};
251     rootStyle.fontSize = this.fontSize; // won't go higher than 126!
252     styles.setStyle('.sIFR-root', rootStyle);
253     textField.styleSheet = styles;
254     
255     this.write(content);
256     this.repaint();
257   }
258   
259   private function repaint() {
260     var leadingFix = this.isSingleLine() ? sIFR.styles.latestLeading : 0;
261     if(leadingFix > 0) leadingFix -= LEADING_REMAINDER;
262
263     // Flash wants to scroll the movie by one line, by adding the fontSize to the
264     // textField height this is no longer happens. We also add the absolute tuneHeight,
265     // to prevent a negative value from triggering the bug. We won't send the fake
266     // value to the JavaScript side, though.
267     textField._height = textField.textHeight + PADDING_BOTTOM + this.fontSize + Math.abs(tuneHeight) + tuneHeight - leadingFix;
268     this.realHeight = textField._height - this.fontSize - Math.abs(tuneHeight);
269     var arg = 'height:' + this.realHeight;
270     if(_root.fitexactly == 'true') arg += ',width:' + (textField.textWidth + tuneWidth);
271     fscommand('resize', arg);
272         
273     this.originalHeight = textField._height;
274     this.currentHeight = Stage.height;
275
276     textField._xscale = textField._yscale = parseInt(_root.zoom);
277   }
278   
279   private function write(content) {
280     this.textField.htmlText = ['<p class="', CSS_ROOT_CLASS, '">', 
281                                 content, '</p>'
282                               ].join('');
283   }
284   
285   private function isSingleLine() {
286     return Math.round((this.textField.textHeight - sIFR.styles.latestLeading) / this.fontSize) == 1;
287   }
288
289   //= Scales the text field to the new scale of the Flash movie itself.
290   public function scale() {
291     this.currentHeight = Stage.height;
292     var scale = 100 * Math.round(this.currentHeight / this.originalHeight);
293     textField._xscale = textField._yscale = scale;
294   }
295   
296   private function calculateRatios() {
297     var strings = ['X', 'X<br>X', 'X<br>X<br>X', 'X<br>X<br>X<br>X'];
298     var results = {};
299
300     for(var i = 1; i <= strings.length; i++) {
301       var size = 6;
302     
303       this.write(strings[i - 1]);
304       while(size < MAX_FONT_SIZE) {
305         var rootStyle = sIFR.styles.getStyle('.sIFR-root') || {};
306         rootStyle.fontSize = size;
307         sIFR.styles.setStyle('.sIFR-root', rootStyle);
308         this.textField.styleSheet = sIFR.styles;
309         this.repaint();
310         var ratio = (this.realHeight - PADDING_BOTTOM) / i / size;
311         if(!results[size]) results[size] = ratio;
312         else results[size] = ((i - 1) * results[size] + ratio) / i;
313         size++;
314       }
315     }
316
317     var sizes = [], ratios = [];
318     var ratiosToSizes = {}, sizesToRatios = {};
319
320     for(var size in results) {
321       if(results[size] == Object.prototype[size]) continue;
322       var ratio = results[size];
323       ratiosToSizes[ratio] = Math.max(ratio, parseInt(size));
324     }
325
326     for(var ratio in ratiosToSizes) {
327       if(ratiosToSizes[ratio] == Object.prototype[ratio]) continue;
328       sizesToRatios[ratiosToSizes[ratio]] = roundDecimals(ratio, 2);
329       sizes.push(ratiosToSizes[ratio]);
330     }
331
332     sizes.sort(function(a, b) { return a - b; });
333     for(var j = 0; j < sizes.length - 1; j++) ratios.push(sizes[j], sizesToRatios[sizes[j]]);
334     ratios.push(sizesToRatios[sizes[sizes.length - 1]]);
335
336     fscommand('debug:ratios', '[' + ratios.join(',') + ']');
337   }
338   
339   private function roundDecimals(value, decimals) {
340     return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
341   }
342   
343   public static function callback() {
344     switch(_root.callbackType) {
345       case 'replacetext':
346         sIFR.instance.content = _root.callbackValue;
347         sIFR.instance.write(_root.callbackValue);
348         sIFR.instance.repaint();
349         break;
350       case 'resettext':
351         sIFR.instance.write('');
352         sIFR.instance.write(sIFR.instance.content);
353         break;
354       case 'ratios':
355         sIFR.instance.calculateRatios();
356         break;
357     }
358   }
359 }